diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/RIGHTS.md b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/RIGHTS.md new file mode 100644 index 0000000..036e249 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/RIGHTS.md @@ -0,0 +1,14 @@ +# Submission rights declaration + +Project: `BHRIGU Bitcoin Research State API` +Submission slug: `bhrigu-bitcoin-research-state-api` +Submitter: `Yulchiev A.Kh` +Date: `2026-09-08` + +The submitter confirms that they own, or have sufficient authorization for, the source code, service, frozen public research baseline, BHRIGU branding used in this package, and other materials submitted in this pull request. + +Subject to the official program terms, the submitter authorizes X-Agent to retain, reproduce, audit, test, archive, and publish the submitted program artifact for judging, fraud prevention, dispute handling, ecosystem submission, and post-award accountability. Closing the pull request, deleting a fork, or deleting an external repository does not revoke the official archive rights attached to an accepted and rewarded entry. + +Third-party components and their licenses: no bundled runtime dependencies. The service uses the Node.js runtime and calls public Binance market-data and mempool.space endpoints subject to their respective terms. See `source/THIRD_PARTY.md`. + +Exceptions or restrictions: authorization covers only the bounded source and materials actually present in this submission directory. ORION, private prompts, planners, evaluators, private corpora, unpublished research methods, credentials, wallet/payment code, and other protected BHRIGU internals are not included in the artifact and are not submitted. diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/SUBMISSION.md b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/SUBMISSION.md new file mode 100644 index 0000000..ce12669 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/SUBMISSION.md @@ -0,0 +1,51 @@ +# BHRIGU Bitcoin Research State API + +## Capability + +- **One-line description:** Returns a live, read-only Bitcoin research state combining Binance market time, Bitcoin protocol time, source freshness, and a precommitted observation window. +- **Who it helps:** AI agents and researchers that need a compact Bitcoin state with explicit provenance, time coordinates, and no trading authority. +- **Capability boundary:** Observation and research only. It does not trade, place orders, access wallets, move funds, read private account data, or provide a price target. + +## Live API + +- **API base URL:** https://bhrigu-bitcoin-research-state-api.vercel.app/v1 +- **Health-check URL:** https://bhrigu-bitcoin-research-state-api.vercel.app/health +- **Authentication:** none +- **Rate limits / known limits:** BTCUSDT only; outbound public sources have their own limits; each upstream call has an 8-second timeout; no SLA is claimed. +- **API contract:** `GET /v1/state` with optional `?symbol=BTCUSDT`. JSON response contains market, protocol_time, window, memory, authority, and limits objects. + +## Source and reproducibility + +- **Source repository:** https://github.com/AiBhrigu/bhrigu-bitcoin-research-state-api +- **Review commit:** `05a455ba1407f7b07de226f6c78eefda15b24880` +- **Source submitted in this PR:** `source/` +- **Run tests:** `npm ci && npm test` +- **Run locally:** `npm ci && npm start`, then `curl http://localhost:3000/v1/state` +- **Deploy:** deploy the exact review commit to Vercel with Node.js 22+; no environment variables or secrets are required. +- **Version binding:** `/health` and `/.well-known/xagent-verification.json` both expose the exact deployed Git commit. +## Verification + +Reproducible calls and expected results are in `verification/README.md`. + +- **Health-check result:** HTTP 200 with `status: ok` and exact review commit. +- **Capability call:** `GET /v1/state?symbol=BTCUSDT`. +- **Expected error behavior:** unsupported symbols return HTTP 400; non-GET state requests return HTTP 405; unavailable Binance market evidence fails closed rather than fabricating a live market state. + +## Security and data handling + +- **Data collected:** none. The service is stateless and does not accept user identity, account, wallet, or credential data. +- **Purpose and retention:** no user data is stored. A frozen public research baseline is shipped in source for comparison with live public observations. +- **Third parties / outbound network calls:** Binance public market-data-only endpoint and mempool.space public Bitcoin tip-height endpoint. +- **Secrets:** none required; none committed. +- **Known risks / restrictions:** public upstream availability and rate limits can affect live output. Market-source failure is fail-closed. Protocol tip failure is explicitly marked unavailable. Research state is not a trading signal. + +## MCP productization shape + +A future MCP wrapper can expose one read-only tool around `GET /v1/state`, with `symbol` constrained to `BTCUSDT`, no authorization scope, no side effects, and explicit source/freshness fields. MCP implementation is intentionally not required for this reviewed API artifact. + +## Support + +- **Team / builder:** BHRIGU / AiBhrigu +- **Contact:** https://x.com/bhrigu_io +- **Canonical project surface:** https://www.bhrigu.io/ +- **License / rights:** no general open-source license is granted. X-Agent review/archive rights are limited to the bounded submitted artifact and are declared in `RIGHTS.md`. diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/.gitignore b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/.gitignore new file mode 100644 index 0000000..0183d71 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +.vercel/ +.env* +.DS_Store +npm-debug.log* +.vercel diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/IP_BOUNDARY.md b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/IP_BOUNDARY.md new file mode 100644 index 0000000..eef865a --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/IP_BOUNDARY.md @@ -0,0 +1,28 @@ +# IP Boundary + +## Public artifact + +This repository intentionally contains only: + +- the read-only HTTP adapter; +- deterministic state-shaping logic; +- one frozen public observation baseline; +- public-source fetchers; +- tests and deployment metadata. + +## Explicitly excluded + +The following are not part of this artifact and must not be added during hackathon packaging: + +- ORION core or private services; +- private prompts, planners, evaluators, or routing contracts; +- private or unpublished corpora; +- unpublished reconstruction or forecasting methods; +- credentials, secrets, customer/account data; +- wallet, payment, transfer, withdrawal, or trade execution logic. + +## Law + +`EXPOSE MEANING / PROTECT MECHANISM` + +Any future submission must copy only the source already present in this bounded public repository unless separately reviewed and authorized. diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/README.md b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/README.md new file mode 100644 index 0000000..bc60cb6 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/README.md @@ -0,0 +1,60 @@ +# BHRIGU Bitcoin Research State API + +A bounded, read-only Bitcoin research capability built for the X-Agent Open Innovation track. + +It turns public Bitcoin evidence into one agent-callable research-state object: + +`FIELD → WINDOW → REALITY → MEMORY` + +## What it returns + +- live Binance Spot BTCUSDT market state; +- Bitcoin protocol-time coordinates; +- source and freshness evidence; +- the precommitted Sep 10, 2026 observation boundary; +- current-vs-baseline delta; +- explicit confirmation/invalidation phase; +- zero trading, wallet, payment, transfer, or private-account authority. + +## API + +`GET /v1/state` + +Optional query: `?symbol=BTCUSDT`. + +`GET /health` + +Returns the exact deployed Git commit. + +`GET /.well-known/xagent-verification.json` + +Returns the X-Agent slug and exact deployed Git commit. + +## Local run + +Requires Node.js 22+. + +```bash +npm test +npm start +curl http://localhost:3000/v1/state +``` + +No API key or account credential is required. + +## Public data dependencies + +- Binance public Spot 24h ticker for BTCUSDT. +- mempool.space public Bitcoin tip-height endpoint. + +If the Binance market source is unavailable, the capability fails closed instead of fabricating a live state. Protocol tip-height failure is exposed as unavailable while the frozen protocol epoch metadata remains explicit. + +## IP boundary + +This repository contains only the bounded public adapter and its frozen public research record. It does not contain ORION, private prompts, planners, evaluators, private corpora, unpublished reconstruction logic, credentials, account state, wallet code, payment code, or trading execution. + +See `IP_BOUNDARY.md`. + +## License / rights + +No general open-source license is granted by this repository. Any future X-Agent hackathon submission will use only the explicit rights declaration required for the submitted public artifact. diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/THIRD_PARTY.md b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/THIRD_PARTY.md new file mode 100644 index 0000000..7901e47 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/THIRD_PARTY.md @@ -0,0 +1,17 @@ +# Third-party public data + +## Binance Spot public market data + +Endpoint class: public market data, security type `NONE`. + +Used for BTCUSDT 24-hour ticker fields only. No Binance account authentication, API key, trading endpoint, wallet endpoint, transfer endpoint, or private account endpoint is used. + +## mempool.space public Bitcoin tip height + +Used only to retrieve the current public Bitcoin block height and derive position within the current halving epoch. + +If this source is unavailable, the API exposes the source as unavailable and does not substitute hidden data. + +## Runtime dependencies + +The project has no npm runtime dependencies. It uses only Node.js built-ins and the platform-provided `fetch` implementation. diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/about.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/about.mjs new file mode 100644 index 0000000..55c4c89 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/about.mjs @@ -0,0 +1,13 @@ +import { methodGate, sendJson } from "../lib/http.mjs"; + +export default function handler(req, res) { + if (!methodGate(req, res)) return; + sendJson(res, 200, { + name: "BHRIGU Bitcoin Research State API", + capability: "read-only Bitcoin research state", + endpoint: "/v1/state", + health: "/health", + verification: "/.well-known/xagent-verification.json", + boundary: "RESEARCH_STATE_NOT_TRADE" + }, "public, max-age=60"); +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/health.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/health.mjs new file mode 100644 index 0000000..1eadced --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/health.mjs @@ -0,0 +1,7 @@ +import { healthPayload } from "../lib/runtime.mjs"; +import { methodGate, sendJson } from "../lib/http.mjs"; + +export default function handler(req, res) { + if (!methodGate(req, res)) return; + sendJson(res, 200, healthPayload(), "public, max-age=30"); +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/state.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/state.mjs new file mode 100644 index 0000000..7fb5586 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/state.mjs @@ -0,0 +1,23 @@ +import { buildState } from "../lib/state.mjs"; +import { methodGate, sendJson } from "../lib/http.mjs"; + +export default async function handler(req, res) { + if (!methodGate(req, res)) return; + const url = new URL(req.url || "/v1/state", "http://localhost"); + const symbol = String(url.searchParams.get("symbol") || "BTCUSDT").toUpperCase(); + if (symbol !== "BTCUSDT") { + sendJson(res, 400, { error: "UNSUPPORTED_SYMBOL", supported: ["BTCUSDT"] }); + return; + } + try { + const state = await buildState(); + sendJson(res, 200, state, "public, max-age=10, s-maxage=10"); + } catch (error) { + sendJson(res, 502, { + error: "PUBLIC_MARKET_SOURCE_UNAVAILABLE", + source: "Binance Spot BTCUSDT", + detail: String(error.message || error), + trading_authority: false + }); + } +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/verification.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/verification.mjs new file mode 100644 index 0000000..13e7b12 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/api/verification.mjs @@ -0,0 +1,7 @@ +import { verificationPayload } from "../lib/runtime.mjs"; +import { methodGate, sendJson } from "../lib/http.mjs"; + +export default function handler(req, res) { + if (!methodGate(req, res)) return; + sendJson(res, 200, verificationPayload(), "public, max-age=30"); +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/http.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/http.mjs new file mode 100644 index 0000000..214d88f --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/http.mjs @@ -0,0 +1,14 @@ +export function sendJson(res, status, payload, cache = "no-store") { + res.statusCode = status; + res.setHeader("content-type", "application/json; charset=utf-8"); + res.setHeader("cache-control", cache); + res.setHeader("access-control-allow-origin", "*"); + res.setHeader("x-content-type-options", "nosniff"); + res.end(JSON.stringify(payload)); +} + +export function methodGate(req, res) { + if (req.method === "GET") return true; + sendJson(res, 405, { error: "METHOD_NOT_ALLOWED", allowed: ["GET"] }); + return false; +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/live.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/live.mjs new file mode 100644 index 0000000..b17c125 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/live.mjs @@ -0,0 +1,42 @@ +const BINANCE_TICKER = "https://data-api.binance.vision/api/v3/ticker/24hr?symbol=BTCUSDT"; +const MEMPOOL_TIP = "https://mempool.space/api/blocks/tip/height"; + +async function timedFetch(url, fetchImpl = fetch) { + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), 8000); + try { + const response = await fetchImpl(url, { signal: controller.signal, headers: { accept: "application/json,text/plain" } }); + if (!response.ok) throw new Error(`HTTP_${response.status}`); + return response; + } finally { + clearTimeout(timer); + } +} + +export async function fetchMarket(fetchImpl = fetch) { + const response = await timedFetch(BINANCE_TICKER, fetchImpl); + const d = await response.json(); + return { + venue: "Binance Spot", + symbol: "BTCUSDT", + last_price_usdt: Number(d.lastPrice), + change_24h_pct: Number(d.priceChangePercent), + high_24h_usdt: Number(d.highPrice), + low_24h_usdt: Number(d.lowPrice), + volume_24h_btc: Number(d.volume), + source_close_time_ms: Number(d.closeTime), + source: BINANCE_TICKER, + security_type: "NONE" + }; +} + +export async function fetchProtocol(fetchImpl = fetch) { + try { + const response = await timedFetch(MEMPOOL_TIP, fetchImpl); + const height = Number(await response.text()); + if (!Number.isInteger(height) || height < 840000) throw new Error("INVALID_HEIGHT"); + return { height, source: MEMPOOL_TIP, status: "live" }; + } catch (error) { + return { height: null, source: MEMPOOL_TIP, status: "unavailable", error: String(error.message || error) }; + } +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/runtime.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/runtime.mjs new file mode 100644 index 0000000..e421625 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/runtime.mjs @@ -0,0 +1,14 @@ +export const SLUG = "bhrigu-bitcoin-research-state-api"; +export const SCHEMA = "bhrigu_bitcoin_research_state_v0_1"; + +export function runtimeCommit() { + return process.env.BHRIGU_COMMIT || process.env.VERCEL_GIT_COMMIT_SHA || "LOCAL_DEV"; +} + +export function healthPayload() { + return { status: "ok", commit: runtimeCommit() }; +} + +export function verificationPayload() { + return { schemaVersion: 1, slug: SLUG, commit: runtimeCommit() }; +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/state.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/state.mjs new file mode 100644 index 0000000..e29818c --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/state.mjs @@ -0,0 +1,66 @@ +import { fetchMarket, fetchProtocol } from "./live.mjs"; +import { WINDOW } from "./window.mjs"; +import { SCHEMA, runtimeCommit } from "./runtime.mjs"; + +export async function buildState({ fetchImpl = fetch, now = new Date() } = {}) { + const [market, protocol] = await Promise.all([ + fetchMarket(fetchImpl), + fetchProtocol(fetchImpl) + ]); + const observedAt = now.toISOString(); + const sourceAgeMs = Math.max(0, now.getTime() - market.source_close_time_ms); + const freshness = sourceAgeMs <= 120000 ? "FRESH" : "STALE"; + const epochStart = 840000; + const nextEpoch = 1050000; + const height = protocol.height; + const progress = height === null ? null : Math.max(0, Math.min(1, (height - epochStart) / (nextEpoch - epochStart))); + const boundary = new Date(WINDOW.boundary_utc); + const phase = now < boundary ? "PRE_BOUNDARY" : "POST_BOUNDARY"; + const baseline = WINDOW.baseline.btcusdt_last_price; + const deltaPct = ((market.last_price_usdt - baseline) / baseline) * 100; + + return { + schema: SCHEMA, + commit: runtimeCommit(), + observed_at_utc: observedAt, + boundary: "RESEARCH_STATE_NOT_TRADE", + market: { ...market, freshness, source_age_ms: sourceAgeMs }, + protocol_time: { + halving_epoch: 4, + epoch_start_height: epochStart, + next_epoch_height: nextEpoch, + block_subsidy_btc: 3.125, + live_tip_height: height, + epoch_progress_pct: progress === null ? null : Number((progress * 100).toFixed(4)), + source: protocol.source, + source_status: protocol.status + }, + window: { + ...WINDOW, + phase, + current_vs_baseline_pct: Number(deltaPct.toFixed(4)), + comparison_status: phase === "PRE_BOUNDARY" ? "NOT_FINAL_BEFORE_BOUNDARY" : "REALITY_COMPARISON_OPEN" + }, + memory: { + law: "FIELD → WINDOW → REALITY → MEMORY", + append_only: true, + retroactive_rewrite: "forbidden" + }, + authority: { + trading: false, + wallet: false, + payment: false, + withdrawal: false, + transfer: false, + private_account_data: false, + credentials_read: false + }, + limits: { + method: "GET", + symbol: "BTCUSDT only", + auth: "none", + market_source: "public Binance Spot", + protocol_source: "public mempool.space tip height" + } + }; +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/window.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/window.mjs new file mode 100644 index 0000000..da05e97 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/lib/window.mjs @@ -0,0 +1,18 @@ +export const WINDOW = Object.freeze({ + id: "SEP_10_2026", + boundary_utc: "2026-09-10T00:00:00Z", + role: "precommitted_observation_boundary", + baseline: { + captured_at_utc: "2026-09-08T11:25:23Z", + btcusdt_last_price: 78474, + btcusdt_24h_change_pct: -1.226, + btcusdt_24h_high: 79643.5, + btcusdt_24h_low: 78179.98, + bitcoin_tip_height: 966060 + }, + invariants: { + retroactive_rewrite: "forbidden", + price_target: false, + trading_signal: false + } +}); diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/package-lock.json b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/package-lock.json new file mode 100644 index 0000000..d521274 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/package-lock.json @@ -0,0 +1,15 @@ +{ + "name": "bhrigu-bitcoin-research-state-api", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "bhrigu-bitcoin-research-state-api", + "version": "0.1.0", + "engines": { + "node": ">=22" + } + } + } +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/package.json b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/package.json new file mode 100644 index 0000000..09227c5 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/package.json @@ -0,0 +1,13 @@ +{ + "name": "bhrigu-bitcoin-research-state-api", + "version": "0.1.0", + "type": "module", + "description": "IP-safe read-only Bitcoin research state API for X-Agent Open Innovation.", + "scripts": { + "start": "node server.mjs", + "test": "node tests/acceptance.mjs" + }, + "engines": { + "node": ">=22" + } +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/server.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/server.mjs new file mode 100644 index 0000000..7fb9ec0 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/server.mjs @@ -0,0 +1,27 @@ +import http from "node:http"; +import { buildState } from "./lib/state.mjs"; +import { healthPayload, verificationPayload } from "./lib/runtime.mjs"; + +const port = Number(process.env.PORT || 3000); +const json = (res, status, body) => { + res.writeHead(status, { "content-type": "application/json", "access-control-allow-origin": "*" }); + res.end(JSON.stringify(body)); +}; + +http.createServer(async (req, res) => { + if (req.method !== "GET") return json(res, 405, { error: "METHOD_NOT_ALLOWED" }); + const url = new URL(req.url, `http://${req.headers.host}`); + if (url.pathname === "/health") return json(res, 200, healthPayload()); + if (url.pathname === "/.well-known/xagent-verification.json") return json(res, 200, verificationPayload()); + if (url.pathname === "/") return json(res, 200, { + name: "BHRIGU Bitcoin Research State API", + endpoint: "/v1/state", + boundary: "RESEARCH_STATE_NOT_TRADE" + }); + if (url.pathname !== "/v1/state") return json(res, 404, { error: "NOT_FOUND" }); + if ((url.searchParams.get("symbol") || "BTCUSDT").toUpperCase() !== "BTCUSDT") { + return json(res, 400, { error: "UNSUPPORTED_SYMBOL", supported: ["BTCUSDT"] }); + } + try { return json(res, 200, await buildState()); } + catch (error) { return json(res, 502, { error: "PUBLIC_MARKET_SOURCE_UNAVAILABLE", detail: String(error.message || error) }); } +}).listen(port, () => console.log(`BHRIGU research state API listening on ${port}`)); diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/tests/acceptance.mjs b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/tests/acceptance.mjs new file mode 100644 index 0000000..7846afe --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/tests/acceptance.mjs @@ -0,0 +1,75 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { buildState } from "../lib/state.mjs"; +import { healthPayload, verificationPayload, SLUG } from "../lib/runtime.mjs"; + +process.env.BHRIGU_COMMIT = "a".repeat(40); + +const fakeFetch = async (url) => { + if (String(url).includes("data-api.binance.vision")) { + return new Response(JSON.stringify({ + lastPrice: "79000.00", + priceChangePercent: "1.25", + highPrice: "80000.00", + lowPrice: "77000.00", + volume: "12345.67", + closeTime: Date.parse("2026-09-08T12:00:00Z") + }), { status: 200, headers: { "content-type": "application/json" } }); + } + if (String(url).includes("mempool.space")) return new Response("966100", { status: 200 }); + throw new Error("UNEXPECTED_URL"); +}; + +const health = healthPayload(); +assert.equal(health.status, "ok"); +assert.match(health.commit, /^[a-f0-9]{40}$/); +assert.deepEqual(verificationPayload(), { schemaVersion: 1, slug: SLUG, commit: "a".repeat(40) }); + +const pre = await buildState({ fetchImpl: fakeFetch, now: new Date("2026-09-08T12:00:30Z") }); +assert.equal(pre.market.symbol, "BTCUSDT"); +assert.equal(pre.market.last_price_usdt, 79000); +assert.equal(pre.market.freshness, "FRESH"); +assert.equal(pre.protocol_time.halving_epoch, 4); +assert.equal(pre.protocol_time.live_tip_height, 966100); +assert.equal(pre.window.phase, "PRE_BOUNDARY"); +assert.equal(pre.window.comparison_status, "NOT_FINAL_BEFORE_BOUNDARY"); +assert.equal(pre.memory.append_only, true); +assert.equal(pre.memory.retroactive_rewrite, "forbidden"); +assert.deepEqual(pre.authority, { + trading: false, + wallet: false, + payment: false, + withdrawal: false, + transfer: false, + private_account_data: false, + credentials_read: false +}); + +const post = await buildState({ fetchImpl: fakeFetch, now: new Date("2026-09-10T01:00:00Z") }); +assert.equal(post.window.phase, "POST_BOUNDARY"); +assert.equal(post.window.comparison_status, "REALITY_COMPARISON_OPEN"); +assert.equal(Number.isFinite(post.window.current_vs_baseline_pct), true); + +const here = path.dirname(fileURLToPath(import.meta.url)); +const root = path.resolve(here, ".."); +const liveSource = fs.readFileSync(path.join(root, "lib/live.mjs"), "utf8"); +const urls = [...liveSource.matchAll(/https:\/\/[^"\s]+/g)].map((m) => m[0]); +assert.deepEqual(urls.sort(), [ + "https://data-api.binance.vision/api/v3/ticker/24hr?symbol=BTCUSDT", + "https://mempool.space/api/blocks/tip/height" +].sort()); +const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")); +assert.equal(pkg.dependencies, undefined); + +await assert.rejects( + () => buildState({ fetchImpl: async () => { throw new Error("OFFLINE"); } }), + /OFFLINE/ +); + +console.log(JSON.stringify({ + schema: "bhrigu_bitcoin_research_state_acceptance_v0_1", + status: "PASS", + checks: 18 +}, null, 2)); diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/vercel.json b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/vercel.json new file mode 100644 index 0000000..828815b --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/source/vercel.json @@ -0,0 +1,8 @@ +{ + "rewrites": [ + { "source": "/", "destination": "/api/about" }, + { "source": "/health", "destination": "/api/health" }, + { "source": "/.well-known/xagent-verification.json", "destination": "/api/verification" }, + { "source": "/v1/state", "destination": "/api/state" } + ] +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/submission.json b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/submission.json new file mode 100644 index 0000000..4148612 --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/submission.json @@ -0,0 +1,10 @@ +{ + "schemaVersion": 1, + "name": "BHRIGU Bitcoin Research State API", + "slug": "bhrigu-bitcoin-research-state-api", + "sourceRepository": "https://github.com/AiBhrigu/bhrigu-bitcoin-research-state-api", + "reviewCommit": "05a455ba1407f7b07de226f6c78eefda15b24880", + "apiBaseUrl": "https://bhrigu-bitcoin-research-state-api.vercel.app/v1", + "healthCheckUrl": "https://bhrigu-bitcoin-research-state-api.vercel.app/health", + "deploymentProofUrl": "https://bhrigu-bitcoin-research-state-api.vercel.app/.well-known/xagent-verification.json" +} diff --git a/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/verification/README.md b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/verification/README.md new file mode 100644 index 0000000..fca149b --- /dev/null +++ b/submissions/mcp-hackathon/bhrigu-bitcoin-research-state-api/verification/README.md @@ -0,0 +1,72 @@ +# Verification evidence + +## Prerequisites + +- Review commit: `05a455ba1407f7b07de226f6c78eefda15b24880` +- API base URL: `https://bhrigu-bitcoin-research-state-api.vercel.app/v1` +- Authentication: none + +## 1. Health check + +```bash +curl --fail --silent --show-error \ + https://bhrigu-bitcoin-research-state-api.vercel.app/health +``` + +Expected response: + +```json +{"status":"ok","commit":"05a455ba1407f7b07de226f6c78eefda15b24880"} +``` + +## 2. Deployment proof + +```bash +curl --fail --silent --show-error \ + https://bhrigu-bitcoin-research-state-api.vercel.app/.well-known/xagent-verification.json +``` +Expected response: + +```json +{"schemaVersion":1,"slug":"bhrigu-bitcoin-research-state-api","commit":"05a455ba1407f7b07de226f6c78eefda15b24880"} +``` + +## 3. Capability call + +```bash +curl --fail --silent --show-error \ + 'https://bhrigu-bitcoin-research-state-api.vercel.app/v1/state?symbol=BTCUSDT' +``` + +Expected response properties: + +- `schema = bhrigu_bitcoin_research_state_v0_1` +- `commit` equals the review commit +- `market.symbol = BTCUSDT` +- `market.security_type = NONE` +- `market.freshness = FRESH` when current public Binance evidence is available +- `protocol_time.halving_epoch = 4` +- `window.id = SEP_10_2026` +- `memory.append_only = true` +- every field under `authority` is `false` +## 4. Safe failure behavior + +Unsupported symbol: + +```bash +curl --silent --show-error --write-out '\nHTTP %{http_code}\n' \ + 'https://bhrigu-bitcoin-research-state-api.vercel.app/v1/state?symbol=ETHUSDT' +``` + +Expected: HTTP 400 with `UNSUPPORTED_SYMBOL` and `BTCUSDT` as the only supported symbol. + +Non-read method: + +```bash +curl --silent --show-error --request POST --write-out '\nHTTP %{http_code}\n' \ + 'https://bhrigu-bitcoin-research-state-api.vercel.app/v1/state' +``` + +Expected: HTTP 405 with `METHOD_NOT_ALLOWED` and `GET` as the only allowed method. + +If Binance public market evidence is unavailable, the state endpoint returns a fail-closed error rather than inventing a live market state. If the Bitcoin tip-height source is unavailable, protocol `source_status` is explicitly `unavailable` while the fixed epoch metadata remains visible.