Verifiable reasoning for AI agents on Solana.
Every decision an AI agent makes — every inference, tool call, retrieval and
decision — is captured as a ReasoningStep, sealed into a SHA-256 Merkle tree,
and the root is anchored on Solana mainnet. The full trace lives off-chain;
anyone can recompute the root byte-for-byte and check it against the on-chain
anchor. Opaque agents become transparent, tamper-evident systems.
This repository is the protocol core — the cryptographic library, the SDK, and the anchoring/verification service. No frontend, no fluff.
Live: glassboxsol.xyz · SDK on npm: npm install glassbox-sdk
Capture ─▶ Seal ─▶ Anchor ─▶ Verify
- Capture — the SDK records every step (
inference,tool_call,retrieval,decision,observation,delegation) as a hashed, chainedReasoningStep. - Seal — steps become leaves of a Merkle tree; the root is the trace's unique fingerprint.
- Anchor — the root is written to Solana mainnet through the SPL Memo program in a real, wallet/keypair-signed transaction.
- Verify — anyone recomputes the leaves and root from the off-chain trace and compares to the anchored root. No operator is trusted.
The Merkle/hashing code is isomorphic — the exact same implementation computes roots on the producing side and the verifying side, so verification is byte-for-byte deterministic.
Anchoring is not a mock. With a funded Solana keypair the SDK builds an SPL Memo
instruction carrying glassbox|v1|anchor|<taskId>|<merkleRoot>, signs it, and
broadcasts it to mainnet-beta, then confirms the transaction and returns its
signature and slot. The 32-byte Merkle root is permanently recorded in the
immutable ledger and is independently verifiable forever.
const glass = new GlassBox({
solana: { secretKey: process.env.SOLANA_SECRET_KEY, rpcUrl: process.env.SOLANA_RPC },
});
const trace = glass.startTrace('swap-analysis-001', { category: 'DeFi' });
trace.retrieval('Fetch SOL/USDC orderbook', { attributes: { source: 'jupiter-api' } });
trace.decision('Execute swap', { action: 'swap', confidence: 0.87 });
await trace.seal();
const { signature, onChain } = await trace.anchor(); // real mainnet txnpm install glassbox-sdknpx glassbox demo # seal → anchor → verify (set SOLANA_SECRET_KEY for a real mainnet tx)pnpm install
pnpm build # builds shared → sdk → apiRun the end-to-end example (seals, anchors, verifies):
pnpm example # set SOLANA_SECRET_KEY in packages/sdk/.env for a real mainnet anchor
# or:
pnpm demo # same flow via the CLI (glassbox demo)Without a key the example seals and verifies locally; with a funded key it performs a real mainnet anchor.
import { GlassBox } from 'glassbox-sdk';
const glass = new GlassBox({
solana: { secretKey: SECRET_KEY }, // real mainnet anchoring
inference: async ({ prompt }) => ({ text: await llm(prompt) }), // bring your own model
});
const trace = glass.startTrace('token-dd-001', {
title: 'Due diligence on a new SPL token',
category: 'Research',
});
trace.retrieval('Fetch mint metadata', { attributes: { source: 'helius-das' } });
trace.observation('Inspect LP lock', { output: { locked: false } });
// instrument ANY async op — timing & ok/error captured automatically
const quote = await trace.track('TOOL_CALL', 'Quote', () => myTool.run(params));
// optional model call, logged as an INFERENCE step
const view = await trace.infer('Assess risk', { prompt: '…' });
trace.decision('Assign rating', { action: 'rate', selected: 'high', confidence: 0.82 });
const { merkleRoot } = await trace.seal();
const { signature } = await trace.anchor(); // mainnet
const result = glass.verifyTrace(trace); // result.match === truetrace.track() is the adapter for any framework — wrap a tool call, a retriever,
or any async action and it is recorded as a step. No framework lock-in.
// fully local — recompute the tree, compare to the anchor, no network
const result = glass.verifyTrace(trace);
result.match; // true → computed root === anchored root
result.steps; // per-step leaf recomputation
// single-step Merkle inclusion proof
const proof = glass.proveStep(trace, 2);
proof.valid; // trueThe service exposes the same checks over HTTP.
A small NestJS service records anchored traces (re-verifying the Merkle root before storing) and serves verification. It starts empty and only ever holds real, submitted anchors. State is persisted to disk.
pnpm dev:api # http://localhost:4000/apiGET /health
POST /api/anchor record a trace (root re-verified server-side)
GET /api/traces?limit&offset list anchored traces
GET /api/traces/:id a single trace
GET /api/anchors?limit recent anchor records
GET /api/verify/:id recompute + compare the Merkle root
GET /api/verify/:id/proof?step Merkle inclusion proof for one step
WS / live anchor events (Socket.IO)
packages/
shared/ types, reasoning-step taxonomy, SHA-256 Merkle engine
sdk/ capture → seal → anchor (mainnet) → verify, + CLI & example
services/
api/ anchoring & verification service (REST + WebSocket)
- TypeScript across all packages, pnpm workspaces
- @solana/web3.js + the SPL Memo program for on-chain anchoring
- @noble/hashes (SHA-256) for the isomorphic Merkle engine
- NestJS + Socket.IO for the anchoring service
- Live app — https://glassboxsol.xyz
- npm — https://www.npmjs.com/package/glassbox-sdk
- X — https://x.com/GlassBoxProto
MIT