Run a LangChain chain, get a tamper-evident audit record — a Certified Execution Record (CER) — from NexArt, and verify it locally or on-chain.
NexArt produces Certified Execution Records — cryptographically-sealed, locally-verifiable audit records for AI operations. Each CER contains a hash of the model, input, output, and parameters, sealed into a certificateHash. Any modification after creation is detectable.
This repo shows two patterns:
| Example | File | What it covers |
|---|---|---|
| Certify a chain run | src/01-certify-run.ts |
Real LangChain chain → CER → local verification → save to disk |
| Agent tool calls | src/02-agent-tools.ts |
wrapTool() for tool evidence + certifyDecision() for final output |
LangChain chain.invoke(...)
│
▼ input + output
createLangChainCer({ provider, model, input, output, ... })
│
▼
CerAiExecutionBundle
├── bundleType: "cer.ai.execution.v1"
├── certificateHash: "sha256:..." ← tamper-evident fingerprint
├── createdAt: "..."
└── snapshot
├── executionId
├── provider / model
├── input / inputHash
└── output / outputHash
The certificateHash covers all of { bundleType, version, createdAt, snapshot } using canonical JSON + SHA-256. You can verify it offline at any time with verifyCer() or the @nexart/cli tool.
- Node.js 18+
- An OpenAI API key — required for Example 1 only; Example 2 runs fully offline
- npm or pnpm
git clone https://github.com/nexart-io/nexart-langchain
cd nexart-langchain
npm installCopy .env.example to .env and fill in your OpenAI key:
cp .env.example .env# Required for Example 1 — real OpenAI call
# Get your key at: https://platform.openai.com/api-keys
OPENAI_API_KEY=sk-...
# Optional — only needed for NexArt node attestation
# Get your key at: https://nexart.io/dashboard/api
# NEXART_NODE_URL=https://node.nexart.io
# NEXART_API_KEY=nxa_...Example 2 (02-agent-tools.ts) runs fully offline and does not need any API key.
Makes a real call to gpt-4o-mini and creates a CER from the result.
npm run example:certify
# or
npx tsx src/01-certify-run.tsExpected output:
Invoking chain (model: gpt-4o-mini)...
Question: What is the capital of France? Answer in one sentence.
Answer: The capital of France is Paris.
=== NexArt CER created ===
Execution ID: 3f1c7a2b-...
Certificate hash: sha256:a3f1e7b2...
Bundle type: cer.ai.execution.v1
Created at: 2026-03-25T12:00:00.000Z
Verified locally: true
Bundle saved to: cer.json
Verify via CLI:
npx @nexart/cli ai verify cer.json
npx @nexart/cli ai verify cer.json --json
The resulting cer.json is a complete, self-contained CER bundle you can share, store, or pass to any NexArt verifier.
Wraps a simulated tool call and certifies the agent's final decision. Fully offline.
npm run example:agent
# or
npx tsx src/02-agent-tools.tsExpected output:
=== NexArt agent-tools example ===
[1] Calling wrapped tool (fetch-weather)...
→ fetching weather for: Paris
Temperature: 22°C
Condition: sunny
Tool CER hash: sha256:...
Tool call evidence: 1 call(s)
[2] Certifying agent decision...
Recommendation: Light clothing recommended — no umbrella needed.
Decision CER hash: sha256:...
Workflow ID: weather-agent-v1
=== Verification ===
Tool CER: VERIFIED
Decision CER: VERIFIED
Both CERs are tamper-evident and independently auditable.
Each certificateHash is the permanent, verifiable fingerprint of that record.
# Using the @nexart/cli tool
npx @nexart/cli ai verify cer.json
# Machine-readable JSON output
npx @nexart/cli ai verify cer.json --jsonimport { verifyCer } from '@nexart/ai-execution';
import { readFileSync } from 'fs';
const bundle = JSON.parse(readFileSync('cer.json', 'utf-8'));
const result = verifyCer(bundle);
console.log(result.ok); // true = not tampered
console.log(result.code); // "OK"Visit verify.nexart.io and paste the certificateHash to look up an attested bundle on the NexArt node.
Synchronous — no network required. Creates a CER from any LangChain run input and output.
import { createLangChainCer } from '@nexart/ai-execution';
const { bundle, certificateHash, executionId } = createLangChainCer({
provider: 'openai',
model: 'gpt-4o-mini',
input: { messages: [{ role: 'user', content: 'What is 2+2?' }] },
output: '4',
parameters: { temperature: 0 },
});The input and output fields accept any shape LangChain produces — AIMessage, plain strings, structured objects, etc.
Like createLangChainCer() for local use, but also supports optional node attestation when nodeUrl and apiKey are provided.
import { certifyLangChainRun } from '@nexart/ai-execution';
// Local only — synchronous, no network:
const { bundle, certificateHash } = certifyLangChainRun({
provider: 'openai',
model: 'gpt-4o-mini',
input: { messages: [...] },
output: '...',
});
// With NexArt node attestation — async:
const { bundle, receipt } = await certifyLangChainRun({
provider: 'openai',
model: 'gpt-4o-mini',
input: { messages: [...] },
output: '...',
nodeUrl: process.env.NEXART_NODE_URL, // https://node.nexart.io
apiKey: process.env.NEXART_API_KEY,
});Wraps any async tool function. Each call automatically produces a CER without extra code.
import { wrapTool } from '@nexart/agent-kit';
const myTool = wrapTool({
name: 'my-tool',
source: 'my-agent',
run: async (args: { query: string }) => callExternalApi(args.query),
});
const { result, bundle, certificateHash } = await myTool({ query: 'hello' });Certifies a final agent decision — a routing choice, approval, selection, or any model output.
import { certifyDecision } from '@nexart/agent-kit';
const { bundle, certificateHash } = await certifyDecision({
decision: 'Approve deployment based on health check results',
output: 'APPROVED',
provider: 'openai',
model: 'gpt-4o',
});| Package | Version | Purpose |
|---|---|---|
@nexart/ai-execution |
^0.12.0 |
CER creation and verification |
@nexart/agent-kit |
^0.1.1 |
wrapTool, certifyDecision |
@langchain/core |
^0.3.0 |
LangChain prompt templates, parsers |
@langchain/openai |
^0.3.0 |
ChatOpenAI model |
dotenv |
^16.0.0 |
.env file loading |
- NexArt: nexart.io
- Verify a CER: verify.nexart.io
- Docs: docs.nexart.io
- LangChain JS: js.langchain.com
MIT