Pulse Protocol is an open-source autonomous agent scanner for Solana. Give it any wallet and X handle, and it returns one of three verdicts:
- AUTONOMOUS - agent appears to run without human intervention
- HYBRID - agent is assisted or gated by a human operator
- HUMAN - no agent behavior detected, this is a person
The scanner runs entirely locally. No inference servers, no LLM calls, no third parties. It's a deterministic behavioral heuristics engine in pure TypeScript. Read the code, run it, reproduce the verdict.
npm install -g pulse-protocol
pulse scan --handle someagent --wallet 6ySH9oiCNXKMnEudjghkaewryK8SqA2i7m1wGpchpumpverdict: HYBRID (72% confidence, aggregate 64.3/100)
- Five detectors. Posting cadence, on-chain cadence, voice consistency, timing anomalies, cross-source correlation.
- Deterministic. No LLMs, no randomness, no black boxes. Same input gives the same verdict every time.
- Pure TypeScript. Every detector is a regular function you can import and unit test.
- CLI and SDK. Use from the terminal or import it into your own tooling.
- Watchlist daemon. Re-scan a list of targets on an interval and webhook on verdict changes.
- Signed verdicts. Sign scan results with ed25519 and publish them verifiably.
- MIT licensed. Fork it, extend it, do whatever.
npm install -g pulse-protocolnpm install pulse-protocolCreate ~/.config/pulse/.env (or run pulse init):
HELIUS_API_KEY=your_helius_key
X_API_KEY=your_twitter_api_key
Both providers have free tiers that are more than enough for normal use. Helius is at helius.xyz. Any compatible X API provider works for X_API_KEY.
pulse scan \
--handle someagent \
--wallet 6ySH9oiCNXKMnEudjghkaewryK8SqA2i7m1wGpchpumpimport { PulseProtocol } from "pulse-protocol";
const pulse = new PulseProtocol({
heliusApiKey: process.env.HELIUS_API_KEY!,
xApiKey: process.env.X_API_KEY!,
});
const verdict = await pulse.scan({
handle: "someagent",
wallet: "6ySH9oiCNXKMnEudjghkaewryK8SqA2i7m1wGpchpump",
});
console.log(verdict.verdict); // "AUTONOMOUS" | "HYBRID" | "HUMAN"
console.log(verdict.confidence); // 0.0 - 1.0
console.log(verdict.aggregate_score); // 0 - 100
console.log(verdict.signals); // per-detector breakdownimport { PulseDaemon } from "pulse-protocol/daemon";
const daemon = new PulseDaemon({
config: {
heliusApiKey: process.env.HELIUS_API_KEY!,
xApiKey: process.env.X_API_KEY!,
},
watchlistPath: "./watchlist.yaml",
interval: "6h",
});
await daemon.start();Pulse Protocol fetches X posts and Solana transaction history for the target, then runs five independent detectors.
X posts + Solana txs
│
┌────────┴────────┐
│ │
▼ ▼
┌────────┐ ┌────────┐
│cadence │ │onchain │
├────────┤ ├────────┤
│ voice │ │timing │
└────────┘ └────────┘
▲ ▲
│ │
┌──┴────────┴──┐
│ correlation │
└──────┬───────┘
│
┌──────▼──────┐
│ aggregator │
└──────┬──────┘
│
▼
┌─────────────┐
│ verdict │
│ auto/hyb/hu │
└─────────────┘
Each detector returns a 0-100 score. The aggregator computes a weighted sum and applies a disagreement penalty: if two detectors diverge by more than 40 points, the verdict is downgraded to HYBRID.
| Detector | Weight | What it looks at |
|---|---|---|
cadence |
0.25 | X posting rhythm, hour-of-day entropy, sleep windows |
onchain |
0.25 | Transaction rhythm, burst patterns, program diversity |
voice |
0.20 | Lexical diversity, typo rate, phrase repetition |
timing |
0.15 | Discrete anomalies (sub-second replies, cron regularity) |
correlation |
0.15 | Pearson correlation between X and on-chain timelines |
Full methodology: docs/detection-methodology.md
| Aggregate score | Verdict |
|---|---|
| ≥ 80 | AUTONOMOUS |
| 40 - 79 | HYBRID |
| < 40 | HUMAN |
Disagreement between detectors (> 40 point spread) automatically downgrades to HYBRID.
pulse <command> [options]
Commands:
scan Scan a target and return a verdict
watch Start the watchlist daemon
init Create ~/.config/pulse/.env
feed Stream the public verdict feed
verify Verify a signed public verdict
Scan options:
--handle <handle> X / Twitter handle (no @)
--wallet <wallet> Solana wallet address
--out <format> pretty | json | verdict-only
--no-post Do not publish verdict
Full reference: docs/cli.md
import {
PulseProtocol, // main client
aggregate, // raw aggregator (take detector results, get verdict)
signVerdict, // sign a verdict with ed25519
verifyVerdict, // verify a signed public verdict
VERSION,
} from "pulse-protocol";
// Use detectors directly (without the full client):
import {
cadenceDetector,
onchainDetector,
voiceDetector,
timingDetector,
correlationDetector,
} from "pulse-protocol/detectors";Each detector is a pure function. No setup, no I/O, just math on input data. You can plug in your own X or on-chain source if you don't want to use Helius.
| Runtime | Supported |
|---|---|
| Node.js 18+ | ✅ |
| Bun 1.0+ | ✅ |
| Deno 1.40+ | ✅ |
| Cloudflare Workers | ✅ |
Early stage, built in public. The scoring rules work on the targets I've tested against. The rules are public, the code is public, and the weights are in src/core/aggregator.ts. If you find a target where Pulse Protocol gives a wrong verdict, open an issue with the target and the expected label and I'll look at it.
This is a solo project. There is no team, no company, no funding round, no Discord, no token sale. If any of those appear claiming to be Pulse Protocol, they are not.
- Core five-detector engine
- CLI and SDK
- Watchlist daemon
- Signed verdict format
- BSC / Base / Ethereum support
- Browser extension (inline verdicts on x.com profiles)
- Desktop app (real-time dashboard)
PRs welcome. See CONTRIBUTING.md for the dev setup.
The highest-value contribution is labeled targets: if you know of an agent that is definitely autonomous or definitely human, open an issue with the handle, the wallet, and a short reason. Labeled data helps recalibrate the detector weights.
Found a scoring bug or an adversarial pattern that lets a fake agent pass as AUTONOMOUS? Open a GitHub Security Advisory.
MIT. See LICENSE.
