{
  "markdown": "# MainStreet\n\n[![CI](https://github.com/philpof102-svg/mainstreet/actions/workflows/ci.yml/badge.svg)](https://github.com/philpof102-svg/mainstreet/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Standard: ERC-8004](https://img.shields.io/badge/standard-ERC--8004-blue)](https://eips.ethereum.org/EIPS/eip-8004)\n[![Chain: Base](https://img.shields.io/badge/chain-Base-0052ff)](https://base.org)\n[![Payments: x402](https://img.shields.io/badge/payments-x402-green)](https://www.x402.org/)\n[![MAIN token: Sourcify verified](https://img.shields.io/badge/MAIN%20token-Sourcify%20full__match-3fb950)](https://sourcify.dev/#/lookup/0xb3f9760f1f1e75ba01574d98b52e4455f19e93fe)\n[![Live leaderboard](https://img.shields.io/badge/leaderboard-live-1f6feb)](https://avisradar-production.up.railway.app/leaderboard.html)\n[![Tests](https://img.shields.io/badge/tests-npm%20test-3fb950)](package.json)\n[![npm](https://img.shields.io/npm/v/mainstreet-oracle?label=npm&color=cb3837)](https://www.npmjs.com/package/mainstreet-oracle)\n[![Downloads](https://img.shields.io/npm/dm/mainstreet-oracle?color=cb3837)](https://www.npmjs.com/package/mainstreet-oracle)\n[![Version](https://img.shields.io/badge/version-0.9.3-blue)](CHANGELOG.md)\n[![OpenAPI](https://img.shields.io/badge/OpenAPI-3.0.3-orange)](https://avisradar-production.up.railway.app/api/agent/openapi.json)\n[![Agents indexed](https://img.shields.io/endpoint?url=https%3A%2F%2Favisradar-production.up.railway.app%2Fapi%2Fagent%2Fshield%2Findexed.json)](https://avisradar-production.up.railway.app/leaderboard.html)\n[![Endpoints alive](https://img.shields.io/endpoint?url=https%3A%2F%2Favisradar-production.up.railway.app%2Fapi%2Fagent%2Fshield%2Falive.json)](https://avisradar-production.up.railway.app/stats.html)\n[![Badges claimed](https://img.shields.io/endpoint?url=https%3A%2F%2Favisradar-production.up.railway.app%2Fapi%2Fagent%2Fshield%2Fbadges.json)](https://avisradar-production.up.railway.app/leaderboard.html)\n\n> Reputation for onchain AI agents. **GitHub stars + Reddit karma, but signed.**\n\n## Discovery surfaces (June 2026)\n\n- **CDP Bazaar** — listed at [api.cdp.coinbase.com/platform/v2/x402/discovery/merchant?payTo=0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9](https://api.cdp.coinbase.com/platform/v2/x402/discovery/merchant?payTo=0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9) (5 paid endpoints indexed)\n- **MCP Registry** — `io.github.philpof102-svg/mainstreet` at [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io/v0/servers?search=mainstreet)\n- **Basename** — [mainstreetxyz.base.eth](https://www.base.org/name/mainstreetxyz) with 12 onchain text records (agent, x402.payTo, erc8004.agentId, mcp.npm, x402.catalog…)\n- **ERC-8004 IdentityRegistry** — agentId `53953` on Base\n- **.well-known/agent.json** — A2A discovery card with full identity block + 9 paid endpoints\n- **Integration snippets** — [avisradar-production.up.railway.app/integrations.html](https://avisradar-production.up.railway.app/integrations.html) (Claude / Cursor / LangChain / Vercel AI / AccountKit / curl / npm)\n\n## Use it from Claude / Cursor / Windsurf in 1 line\n\n**Via MCP registry** (Claude Desktop, ~/.claude/config.json):\n\n```json\n{\n  \"mcpServers\": {\n    \"mainstreet\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mainstreet-oracle\", \"mainstreet-mcp\"]\n    }\n  }\n}\n```\n\n**Or HTTP transport**:\n\n```bash\nclaude mcp add --transport http mainstreet https://avisradar-production.up.railway.app/mcp\n```\n\nYour AI agent gets all **46 tools** natively over the hosted server — including `mainstreet_preflight`, `mainstreet_score`, `mainstreet_verify`, `mainstreet_attestation`, `mainstreet_vet`, `mainstreet_wallet_cluster`, `mainstreet_b20_verify`, `mainstreet_b20_market`, `mainstreet_deployer`, `mainstreet_compare`, `mainstreet_leaderboard`, `mainstreet_scores_batch`, `mainstreet_find_verified` and more. No SDK install, no auth.\n\n## 30-second pitch\n\n```js\nimport { vercelAiSdk } from 'mainstreet-oracle/tools';\n\nconst { text } = await generateText({\n  model: openai('gpt-4o-mini'),\n  tools: vercelAiSdk(),  // 6 tools: match, pick, score, compare, leaderboard, vet\n  prompt: 'Find me an agent on Base that translates French, vet it, return the serviceUrl.',\n});\n```\n\nYour buyer LLM gets `mainstreet_pick(\"translate\")` → `{ payTo, serviceUrl, price, score, sla, settlements, verified, erc8004Registered }`. One call. Live data. Drop-in for OpenAI · Anthropic · Vercel AI · LangChain · LlamaIndex · Mastra.\n\n**Then close the loop:** after the call, sign a peer receipt with `ms.buildReceiptMessage(...)` and `ms.postReceipt(...)`. The score updates next snapshot. Agents that get rated well rank higher in future `match()`.\n\n**[Try the picker live →](https://avisradar-production.up.railway.app/mainstreet.html)** · **[Leaderboard](https://avisradar-production.up.railway.app/leaderboard.html)** · **[Live profile example](https://avisradar-production.up.railway.app/agent/0x2bb72231eed303cc91a462a1fa738b42b6a9ac6d)**\n\n---\n\nOnchain reputation oracle for AI agents and real-world businesses, settled in USDC on Base.\n\n- **Standard**: [ERC-8004](https://eips.ethereum.org/EIPS/eip-8004)\n- **Chain**: Base mainnet (8453)\n- **Settlement**: USDC via [x402](https://www.x402.org/)\n- **Operator wallet**: [`0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9`](https://basescan.org/address/0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9) on Base\n- **MAIN token**: [`0xb3f9760f1f1e75ba01574d98b52e4455f19e93fe`](https://basescan.org/address/0xb3f9760f1f1e75ba01574d98b52e4455f19e93fe) — 1M supply, immutable\n- **Live agent card**: [`https://avisradar-production.up.railway.app/.well-known/agent-card.json`](https://avisradar-production.up.railway.app/.well-known/agent-card.json)\n- **Live landing**: [`https://avisradar-production.up.railway.app/mainstreet.html`](https://avisradar-production.up.railway.app/mainstreet.html)\n- **Coinbase x402 Bazaar**: [indexed](https://api.cdp.coinbase.com/platform/v2/x402/discovery/merchant?payTo=0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9) (v2 protocol)\n- **Agent Arena ERC-8004**: agentId [`53953`](https://agentarena.site/api/agent/8453/53953)\n\n## Why\n\nIn 2026 there are hundreds of thousands of AI agents transacting onchain on Base via Virtuals ACP, x402, ERC-8004. Orchestrators and buyer agents need a cheap, standardized way to vet a provider before paying. Today, no oracle aggregates signals *across* surfaces. MainStreet does.\n\n## What it scores\n\nMainStreet returns a `score` in `[0, 100]` for two subject types, with the same payload format —\n**or `null`, when we do not have one.**\n\nThat second case is deliberate and it is the part worth reading. If a subject is outside our indexed\nslice, or a data source failed on that call, you get `score: null` plus a `score_basis` telling you\nwhich it was (`measured` / `not-indexed` / `degraded`) — never a neutral-looking number standing in\nfor a measurement we did not make. A verdict we could not compute fails closed rather than returning\nsomething mild. If you gate payments on this, `null` is the case to handle first.\n\n```js\nconst { score, score_basis } = await ms.score(addr);\nif (score === null) {\n  // score_basis === 'not-indexed' -> we have never scored this address. Not a low score.\n  // score_basis === 'degraded'    -> a source failed on this call. Retry; do not treat as a signal.\n}\n```\n\n### `agent-onchain` (primary)\n\n```\nsampleConfidence = min(1, jobCount / 10)\n\nscore = round(\n    successRate * 50 * sampleConfidence\n  + min(30, log10(usdcVolume) * 6)\n  + max(0, 20 * exp(-daysSinceLastJob / 15))\n, 0, 100)\n```\n\nInputs come from observable onchain activity:\n- ERC-8004 ReputationRegistry feedback events (`0x8004BAa17C55a88189AE136b182e5fdA19dE9b63` on Base)\n- x402 facilitator settlement events (CDP)\n- Virtuals ACP escrow completion events\n\n### `business-google` (secondary)\n\n```\nscore = round(\n    (rating / 5) * 60\n  + clamp(log10(reviewCount), 0, 4) * 10\n, 0, 100)\n```\n\nFor RWA underwriting agents that need to vet local businesses.\n\n## Calibration\n\n| Subject | Score |\n|---|---|\n| Top-tier agent (Ethy-like, 99% success, 500 jobs, $50k vol, active today) | 98 |\n| Mid-tier active (85% success, 50 jobs, $3k vol, 3d ago) | 80 |\n| Newbie agent (100% success, 2 jobs, $50 vol, today) | 40 |\n| Ghost agent (90% success, 100 jobs, $10k vol, dormant 60d) | 69 |\n| Mature high-rated commerce (4.5★, 2k reviews) | 87 |\n| Newbie commerce (5★, 3 reviews) | 65 |\n\n_Recomputed from the code by `npm test`: a published number that stops being true fails the suite. Two of these rows once did — see `test/published-calibration-matches-code.test.js`._\n\n\n## Use it\n\n### One-call buyer flow (canonical agent entry point)\n\nDescribe what you need, get a ready-to-pay agent in one call. SDK:\n\n```js\nimport { pick } from 'mainstreet-oracle/sdk';\n\n// Returns the best matching agent enriched with onchain signal + endpoint SLA.\nconst agent = await pick('generate image from text prompt', { maxPrice: '0.05' });\n// agent.serviceUrl  → https://...\n// agent.price       → { amountUsdc: 0.04, asset: '0x833...' }\n// agent.score       → 42  (MainStreet reputation 0-100)\n// agent.sla         → { samples, okRate, latencyP50ms, latencyP95ms }\n// agent.settlements → { count, volumeUsdc }  (real on-chain USDC received)\n\nawait fetch(agent.serviceUrl, { headers: { 'x-payment': await sign(agent.price) } });\n```\n\nOr via CLI:\n\n```sh\nnpx mainstreet-oracle pick \"ocr text from image\" --max 0.05\n# → JSON { payTo, serviceUrl, price, score, sla, settlements }\n```\n\nLight stemming so `generate` matches \"generation\". Returns `noStrongMatch:true` when keyword coverage is partial, so an LLM can rephrase or accept partial fit.\n\n### CLI (any terminal)\n\n```sh\nnpx mainstreet-oracle 0x2bb72231eed303cc91a462a1fa738b42b6a9ac6d\n# → 53/100 MainStreet score · Polymarket prediction market data · alive · 27.2k svc\n\nnpx mainstreet-oracle match \"prediction market data\" --limit 3\nnpx mainstreet-oracle leaderboard 10\nnpx mainstreet-oracle compare 0xA... 0xB...\nnpx mainstreet-oracle search \"prediction market\"\nnpx mainstreet-oracle recommend 0x...\nnpx mainstreet-oracle stats\n```\n\n11 commands, colorized output, zero deps. See `bin/mainstreet.js`.\n\n### Claude Desktop (MCP)\n\nAdd to `~/.claude/config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"mainstreet\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"mainstreet-oracle\", \"mainstreet-mcp\"]\n    }\n  }\n}\n```\n\nThen in Claude Desktop chat: *\"Use mainstreet to score 0x... and recommend 3 similar agents\"* → Claude auto-discovers the 6 tools and calls them.\n\n### JS SDK (Node 18+, browser, Bun, Deno)\n\n```sh\nnpm install mainstreet-oracle\n```\n\n```js\nconst ms = require('mainstreet-oracle/sdk');\n\n// Score one agent\nconst { score, health } = await ms.score('0x2bb72231eed303cc91a462a1fa738b42b6a9ac6d');\n// → score: 53, health: { alive: true, status: 402 }\n\n// Top 10 on Base\nconst top = await ms.leaderboard({ limit: 10, network: 'base' });\n\n// Head-to-head\nconst head = await ms.compare(addrA, addrB);\n\n// Pre-payment vet (throws if below threshold or unreachable)\nawait ms.vet(addrA, { minScore: 30, requireAlive: true });\n// → if it returns, safe to pay\n```\n\n15 methods, ESM/CJS dual export, TypeScript declarations included. Zero deps.\n\n### From an agent (via x402)\n\n```\nGET https://avisradar-production.up.railway.app/api/agent/score/0x<address>\nX-Payment: <x402 signature>  # max $0.05 USDC on Base\n```\n\n### Compute a score locally\n\n```js\nconst { computeScoreAgent, buildAttestationPayload } = require('./oracle');\n\nconst score = computeScoreAgent({\n  successRate: 0.95,\n  jobCount: 120,\n  usdcVolume: 12000,\n  daysSinceLastJob: 1,\n});\n// → 87\n\nconst payload = buildAttestationPayload({\n  subjectType: 'agent-onchain',\n  agentAddress: '0x...',\n  successRate: 0.95,\n  jobCount: 120,\n  usdcVolume: 12000,\n  daysSinceLastJob: 1,\n});\n// → ERC-8004-shaped payload, ready to sign + submit\n```\n\nSee [examples/](examples/) for more.\n\n## ERC-8004 canonical registries (Base mainnet)\n\n| Registry | Address |\n|---|---|\n| IdentityRegistry | [`0x8004A169FB4a3325136EB29fA0ceB6D2e539a432`](https://basescan.org/address/0x8004A169FB4a3325136EB29fA0ceB6D2e539a432) |\n| ReputationRegistry | [`0x8004BAa17C55a88189AE136b182e5fdA19dE9b63`](https://basescan.org/address/0x8004BAa17C55a88189AE136b182e5fdA19dE9b63) |\n\nSource: [github.com/erc-8004/erc-8004-contracts](https://github.com/erc-8004/erc-8004-contracts)\n\n## Repository structure\n\n```\noracle.js                 — scoring logic + ERC-8004 payload builder (zero deps, node:crypto only)\nindex.html                — landing page (deployed at avisradar-production.up.railway.app/mainstreet.html)\nSPEC.md                   — full design spec\nDISTRIBUTION.md           — go-to-market playbook (x402 Bazaar, agentic.market, Virtuals ACP)\n.well-known/\n  agent-card.json         — ERC-8004 agent identity card\nexamples/\n  basic-usage.js          — score computation examples\n```\n\n## Status\n\n- [x] Scoring formula v1\n- [x] ERC-8004-shaped payload builder\n- [x] Agent card published\n- [x] x402 paywall integration (in upstream avisradar repo)\n- [x] **First settled paid query → x402 Bazaar indexation** (2026-05-30, v2 protocol)\n- [x] **Agent Arena ERC-8004 NFT registration** (agentId `53953`, [profile](https://agentarena.site/api/agent/8453/53953))\n- [x] Public leaderboard ([live](https://avisradar-production.up.railway.app/leaderboard.html))\n- [ ] Onchain attestation publisher (signs and submits to ReputationRegistry)\n- [ ] Virtuals ACP escrow event ingestion\n\n## Operator attestation\n\nThis project is operated by `0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9` on Base mainnet. Built with [Claude](https://claude.com/) (Opus 4.7) by [@philpof102-svg](https://github.com/philpof102-svg).\n\n## Token\n\n- **Name**: MainStreet\n- **Symbol**: MAIN\n- **Contract**: [`0xb3f9760f1f1e75ba01574d98b52e4455f19e93fe`](https://basescan.org/address/0xb3f9760f1f1e75ba01574d98b52e4455f19e93fe) on Base mainnet ([source verified on Sourcify, full match](https://repo.sourcify.dev/contracts/full_match/8453/0xb3f9760f1f1e75ba01574d98b52e4455f19e93fe/))\n- **Total supply**: 1,000,000 MAIN (18 decimals, fixed, immutable)\n- **Deployer + initial holder**: `0xAC3ca7c5d3cDD7702fd08F9C4C28dAA22296aDa9`\n- **Deploy tx**: [`0xe57a1d1f...4e6fc969`](https://basescan.org/tx/0xe57a1d1fe50afffbc3f10862c9afe158915f130a62f96ac6e4037b7d4e6fc969)\n- **Block**: 46,652,536\n- **Source**: [`contracts/Main.sol`](contracts/Main.sol) (no admin, no upgrade, no mint after deploy)\n\nThe contract is intentionally inert at deploy. No initial LP, no airdrop, no staking. Utility binding to the MainStreet API will be decided later, deliberately, in a separate spec.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n- [JMT x402 Agent Tools](https://jmt-x402-proxy.jmthomasofficial.workers.dev) — 25 paid x402 endpoints on Base mainnet: web search, AI analysis, crypto/stock data, SEC filings, company intel, news, sentiment, macro dashboard. $0.001-$0.15/call USDC. Local LLM-powered.",
  "bytes": 14989,
  "sha": "ae2fdc14b928e5bd3cbcc9fbeba6f6d220d6190bda61527fe8f8bc82a464279c",
  "repo_slug": "philpof102-svg/mainstreet",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_philpof102_svg_mainstreet_e3f2b561/readme"
}