@atbash/sdk 0.5.5 → 0.5.7-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -334,8 +334,8 @@ function setupTelemetry(config) {
334
334
  if (meterProvider) return;
335
335
  if (isTelemetryOptedOut()) return;
336
336
  defaultSource = config.source ?? "sdk";
337
- const ATBASH_HONEYCOMB_KEY = "YOUR_INGEST_KEY_HERE";
338
- const apiKey = process.env.HONEYCOMB_API_KEY ?? ATBASH_HONEYCOMB_KEY;
337
+ const apiKey = process.env.HONEYCOMB_API_KEY ?? native.HONEYCOMB_KEY;
338
+ if (!apiKey) return;
339
339
  const exporter = new import_exporter_metrics_otlp_http.OTLPMetricExporter({
340
340
  url: "https://api.honeycomb.io/v1/metrics",
341
341
  headers: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src-ts/index.ts","../src-ts/native.ts","../src-ts/random.ts","../src-ts/constants.ts","../src-ts/chain-config.ts","../src-ts/endpoint.ts","../src-ts/errors.ts","../src-ts/http/client.ts","../src-ts/keyLoader.ts","../src-ts/normalize.ts","../src-ts/opentel/telemetry.ts","../src-ts/userConfig.ts","../src-ts/client.ts","../src-ts/redact.ts","../src-ts/signature.ts"],"sourcesContent":["/**\n * Atbash SDK for Node.js — public surface.\n *\n * Crypto / redaction / memory primitives are re-exported from the NAPI-bound\n * Rust core as plain functions; the HTTP-facing surface (`judgeAction`,\n * `logToolCall`, `get*`) lives on the `Atbash` class.\n */\nimport { native } from \"./native.js\";\nimport type {\n AgentAuth,\n KeyPair,\n MemoryDiffResult,\n MemoryEntry,\n MemorySnapshot,\n RedactResult,\n} from \"./types.js\";\n\nexport { Atbash } from \"./client.js\";\nexport {\n DEFAULT_BLOCKCHAIN_RID,\n DEFAULT_CHROMIA_NODE_URLS,\n DEFAULT_ENDPOINT,\n} from \"./constants.js\";\nexport { AtbashAPIError, SignatureVerificationError } from \"./errors.js\";\nexport {\n normalizeVerdict,\n normalizeStatus,\n pubkeyToHex,\n} from \"./normalize.js\";\nexport type * from \"./types.js\";\n\n// config loading (file/env resolution, endpoint validation, key file)\nexport {\n type AtbashUserConfig,\n getConfigDir,\n getConfigPath,\n loadUserConfig,\n saveUserConfig,\n resolve,\n} from \"./userConfig.js\";\nexport {\n type JudgeEndpointConfig,\n type ValidatedEndpoint,\n validateJudgeEndpoint,\n} from \"./endpoint.js\";\nexport { resolveKeyPath, loadAgentFromFile } from \"./keyLoader.js\";\nexport { redactJsonStrings, type SecretKind } from \"./redact.js\";\nexport { verifyJudgeResponseSignature } from \"./signature.js\";\nexport {\n flushTelemetry,\n recordCall,\n recordDuration,\n setupTelemetry,\n shutdownTelemetry,\n type ClientSource,\n type TelemetryConfig,\n} from \"./opentel/telemetry.js\";\n\n/* ── crypto / redaction / memory primitives (Rust core) ────────────────── */\n\nexport function isValidPrivateKey(hex: string): boolean {\n return native.isValidPrivateKey(hex);\n}\n\nexport function derivePublicKey(privkey: string): string {\n return native.derivePublicKey(privkey);\n}\n\nexport function generateKeypair(): KeyPair {\n return native.generateKeypair();\n}\n\nexport function loadAgent(privkey: string): AgentAuth {\n return native.loadAgent(privkey);\n}\n\nexport function signLogToolCall(\n toolCallId: string,\n action: string,\n context: string,\n toolName: string,\n toolArgsJson: string,\n privkey: string,\n blockchainRid: string,\n): string {\n return native.signLogToolCall(\n toolCallId,\n action,\n context,\n toolName,\n toolArgsJson,\n privkey,\n blockchainRid,\n );\n}\n\nexport function signJudgeAction(\n judgmentId: string,\n action: string,\n context: string,\n extra: string,\n privkey: string,\n blockchainRid: string,\n): string {\n return native.signJudgeAction(\n judgmentId,\n action,\n context,\n extra,\n privkey,\n blockchainRid,\n );\n}\n\nexport function verifySignature(\n body: Buffer,\n signatureHex: string,\n pubkeyHex: string,\n): boolean {\n return native.verifySignature(body, signatureHex, pubkeyHex);\n}\n\nexport function normalizeForMatching(text: string): string {\n return native.normalizeForMatching(text);\n}\n\nexport function containsEvasionCharacters(text: string): boolean {\n return native.containsEvasionCharacters(text);\n}\n\nexport function redactSecrets(text: string): RedactResult {\n return native.redactSecrets(text);\n}\n\nexport function containsSecret(text: string): boolean {\n return native.containsSecret(text);\n}\n\nexport function createMemorySnapshot(\n entries: MemoryEntry[],\n takenAt: number,\n): MemorySnapshot {\n return native.createMemorySnapshot(entries, takenAt);\n}\n\nexport function diffMemorySnapshots(\n before: MemorySnapshot,\n after: MemorySnapshot,\n): MemoryDiffResult {\n return native.diffMemorySnapshots(before, after);\n}\n","/**\n * Typed loader for the NAPI-RS native addon.\n *\n * The addon's platform-resolution glue is generated at the package root as\n * CommonJS (`../index.js`, see `napi build`). We load it once here via\n * `createRequire` so the rest of the surface gets a typed handle. tsup keeps\n * `../index.js` out of the bundle (see tsup.config.ts) so the require survives\n * to runtime, resolving relative to the compiled file in `dist/`.\n */\nimport { createRequire } from \"node:module\";\n\nimport type {\n AgentAuth,\n KeyPair,\n MemoryDiffResult,\n MemoryEntry,\n MemorySnapshot,\n RedactResult,\n} from \"./types.js\";\n\n/** Shape of the NAPI-RS addon (mirrors index.d.ts, typed against our structs). */\nexport interface NativeBindings {\n isValidPrivateKey(s: string): boolean;\n derivePublicKey(s: string): string;\n generateKeypair(): KeyPair;\n loadAgent(privkey: string): AgentAuth;\n signLogToolCall(\n toolCallId: string,\n action: string,\n context: string,\n toolName: string,\n toolArgsJson: string,\n privkey: string,\n blockchainRid: string,\n ): string;\n signJudgeAction(\n judgmentId: string,\n action: string,\n context: string,\n extra: string,\n privkey: string,\n blockchainRid: string,\n ): string;\n verifySignature(\n body: Buffer,\n signatureHex: string,\n pubkeyHex: string,\n ): boolean;\n normalizeForMatching(s: string): string;\n containsEvasionCharacters(s: string): boolean;\n redactSecrets(s: string): RedactResult;\n containsSecret(s: string): boolean;\n createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;\n diffMemorySnapshots(\n before: MemorySnapshot,\n after: MemorySnapshot,\n ): MemoryDiffResult;\n DEFAULT_BLOCKCHAIN_RID: string;\n DEFAULT_PRIVATE_BLOCKCHAIN_RID: string;\n DEFAULT_ENDPOINT: string;\n defaultChromiaNodeUrls(): string[];\n defaultPrivateNodeUrls(): string[];\n}\n\n// tsup emits both ESM (dist/index.mjs) and CJS (dist/index.js). In the CJS\n// bundle `import.meta.url` is empty but Node provides `__filename`; in the ESM\n// bundle it's the reverse. Pick whichever anchor exists so `createRequire`\n// resolves `../index.js` relative to the compiled file in `dist/`.\ndeclare const __filename: string | undefined;\nconst anchor = typeof __filename !== \"undefined\" ? __filename : import.meta.url;\nconst require = createRequire(anchor);\nexport const native: NativeBindings = require(\"../index.js\") as NativeBindings;\n","/**\n * Universal random helpers backed by the Web Crypto API — available on\n * Node ≥18 and every modern browser. Avoids importing `node:crypto` so the\n * same source compiles for both the Node and browser bundles.\n */\n\nexport function randomBytes(size: number): Uint8Array {\n const buf = new Uint8Array(size);\n globalThis.crypto.getRandomValues(buf);\n return buf;\n}\n\nexport function randomHex(size: number): string {\n const buf = randomBytes(size);\n let hex = \"\";\n for (let i = 0; i < buf.length; i++) {\n hex += buf[i].toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n","/**\n * Public wire constants — all sourced from the Rust core so every\n * language binding agrees byte-for-byte. To switch dev ↔ prod, edit\n * `core/src/constants.rs` and rebuild the native binding; no edits\n * here are needed.\n */\nimport { native } from \"./native.js\";\n\nexport const DEFAULT_ENDPOINT: string = native.DEFAULT_ENDPOINT;\n\nexport const DEFAULT_CHROMIA_NODE_URLS: readonly string[] = Object.freeze(\n native.defaultChromiaNodeUrls(),\n);\n\nexport const DEFAULT_BLOCKCHAIN_RID: string = native.DEFAULT_BLOCKCHAIN_RID;\n","/**\n * Internal chain-config plumbing. Maps the `Network` selector type to the\n * known public / private chains. Not part of the public SDK surface — the\n * consumer-facing API is `Network` + `ChainOpts`. This file is consumed\n * internally by the chain resolver and the HTTP client.\n *\n * BRIDs come from the Rust core via NAPI so all language bindings agree\n * byte-for-byte; node URLs are wire constants that live alongside them.\n */\nimport {\n DEFAULT_BLOCKCHAIN_RID,\n DEFAULT_CHROMIA_NODE_URLS,\n} from \"./constants.js\";\nimport { native } from \"./native.js\";\nimport type { Network } from \"./types.js\";\n\nconst DEFAULT_PRIVATE_NODE_URLS: readonly string[] = Object.freeze(\n native.defaultPrivateNodeUrls(),\n);\n\nconst DEFAULT_PRIVATE_BLOCKCHAIN_RID: string =\n native.DEFAULT_PRIVATE_BLOCKCHAIN_RID;\n\nexport interface ChainConfig {\n readonly network: Network;\n readonly blockchainRid: string;\n readonly nodeUrls: readonly string[];\n}\n\nexport const PUBLIC_CHAIN: ChainConfig = {\n network: \"public\",\n blockchainRid: DEFAULT_BLOCKCHAIN_RID,\n nodeUrls: DEFAULT_CHROMIA_NODE_URLS,\n};\n\nexport const PRIVATE_CHAIN: ChainConfig = {\n network: \"private\",\n blockchainRid: DEFAULT_PRIVATE_BLOCKCHAIN_RID,\n nodeUrls: DEFAULT_PRIVATE_NODE_URLS,\n};\n\nexport function chainForNetwork(network: Network): ChainConfig {\n return network === \"private\" ? PRIVATE_CHAIN : PUBLIC_CHAIN;\n}\n","/**\n * Judge endpoint validation. Rejects anything that could silently redirect\n * verdicts: non-https, embedded credentials, or hosts outside the trusted\n * allowlist. A self-hosted judge is allowed only when it also supplies a\n * response-signing pubkey so the SDK can detect a compromised judge.\n */\nimport { DEFAULT_ENDPOINT } from \"./constants.js\";\n\nexport type JudgeEndpointConfig =\n | { policy?: \"default\"; endpoint?: string }\n | { policy: \"self-hosted\"; endpoint: string; verifyPubKey: string };\n\nexport interface ValidatedEndpoint {\n url: string;\n policy: \"default\" | \"self-hosted\";\n verifyPubKey: string | null;\n}\n\nconst ALLOWED_JUDGE_HOSTS: ReadonlySet<string> = new Set([\n \"atbash.ai\",\n \"www.atbash.ai\",\n \"chromia-verified-ai-dev-two.vercel.app\",\n]);\n\nexport function validateJudgeEndpoint(\n judge?: JudgeEndpointConfig,\n): ValidatedEndpoint {\n const policy: \"default\" | \"self-hosted\" =\n judge?.policy === \"self-hosted\" ? \"self-hosted\" : \"default\";\n const candidate = judge?.endpoint?.trim() || DEFAULT_ENDPOINT;\n\n let parsed: URL;\n try {\n parsed = new URL(candidate);\n } catch {\n throw new Error(\n `[atbash] invalid judge endpoint URL: ${candidate}. ` +\n `Refusing to load — fix the URL or omit it to use the default (${DEFAULT_ENDPOINT}).`,\n );\n }\n\n if (parsed.protocol !== \"https:\") {\n throw new Error(\n `[atbash] judge endpoint must use https:// (got \"${parsed.protocol}\"). ` +\n `Refusing to load — plaintext endpoints leak verdicts and enable trivial MITM bypass.`,\n );\n }\n\n if (parsed.username || parsed.password) {\n throw new Error(\n `[atbash] judge endpoint must not contain credentials (user:pass@host). ` +\n `Refusing to load — credentials embedded in URLs leak to logs and process listings.`,\n );\n }\n\n const normalisedUrl = parsed.origin;\n\n if (policy === \"self-hosted\") {\n const verifyPubKey = (judge as { verifyPubKey?: string } | undefined)\n ?.verifyPubKey;\n const key = verifyPubKey?.trim().toLowerCase();\n if (!key || !/^[0-9a-f]{66}$/.test(key)) {\n throw new Error(\n `[atbash] judge endpoint policy \"self-hosted\" requires verifyPubKey ` +\n `to be a 66-hex-char compressed secp256k1 pubkey. Refusing to load — ` +\n `self-hosted judges must produce signed responses so the SDK can ` +\n `detect a malicious or compromised judge.`,\n );\n }\n return { url: normalisedUrl, policy, verifyPubKey: key };\n }\n\n if (!ALLOWED_JUDGE_HOSTS.has(parsed.hostname.toLowerCase())) {\n throw new Error(\n `[atbash] judge endpoint hostname \"${parsed.hostname}\" is not in the trusted allowlist. ` +\n `Allowed: ${[...ALLOWED_JUDGE_HOSTS].join(\", \")}. ` +\n `To use a self-hosted judge, set BOTH policy=\"self-hosted\" AND verifyPubKey ` +\n `to the 66-hex pubkey of your judge's response-signing key. ` +\n `Refusing to load — silent endpoint redirection is a known attack vector (F-003).`,\n );\n }\n\n return { url: normalisedUrl, policy, verifyPubKey: null };\n}\n","/**\n * SDK exceptions.\n *\n * `AtbashAPIError` is thrown for any non-2xx HTTP response from the judge or\n * risk-engine API. It surfaces the raw body in `Error.message` and appends\n * dashboard-aware hints for the common operational failure modes.\n */\nimport { DEFAULT_ENDPOINT } from \"./constants.js\";\n\nexport class AtbashAPIError extends Error {\n /** HTTP status code (or 0 if the request never completed). */\n readonly status: number;\n /** Raw response body text (may be empty). */\n readonly body: string;\n\n constructor(\n status: number,\n body: string,\n statusText = \"\",\n endpoint: string = DEFAULT_ENDPOINT,\n ) {\n super(enrich(status, body, statusText, endpoint));\n this.name = \"AtbashAPIError\";\n this.status = status;\n this.body = body;\n }\n}\n\nexport class SignatureVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SignatureVerificationError\";\n }\n}\n\n/** Append dashboard-aware hints for common operational failure modes. */\nfunction enrich(\n status: number,\n body: string,\n statusText: string,\n endpoint: string,\n): string {\n const dashboard = endpoint.replace(/\\/+$/, \"\") || DEFAULT_ENDPOINT;\n let msg = `API error ${status}: ${body || statusText}`;\n const lowered = body.toLowerCase();\n if (lowered.includes(\"agent not registered\")) {\n msg += `\\n → Onboard the agent at ${dashboard}/risk-engine/agents`;\n } else if (\n lowered.includes(\"agent has no policy\") ||\n lowered.includes(\"no policy configured\")\n ) {\n msg += `\\n → Attach a policy at ${dashboard}/risk-engine/agents`;\n } else if (\n lowered.includes(\"agent is jailed\") ||\n lowered.includes(\"jailed\")\n ) {\n msg += `\\n → Unjail the agent at ${dashboard}/risk-engine/agents`;\n } else if (\n lowered.includes(\"audit tier\") ||\n lowered.includes(\"verdict disabled\") ||\n lowered.includes(\"verdict not supported\")\n ) {\n msg += `\\n → Upgrade the org tier at ${dashboard}/risk-engine/settings`;\n } else if (status >= 400 && status < 500) {\n msg += `\\n → Dashboard: ${dashboard}/risk-engine/feed`;\n }\n return msg;\n}\n","/**\n * Thin typed fetch wrapper.\n *\n * openapi-typescript emits types only (no runtime client), so this is the\n * single hand-written transport — generic `get`/`post` over global `fetch`\n * with a per-request timeout. The endpoint-specific request/response *shapes*\n * are pulled from the generated `schema.ts` at the call sites in client.ts, so\n * the wire contract still lives in spec/openapi.yaml. Methods return the raw\n * `Response` so the caller can read the exact bytes the server signed before\n * any decode (judge signature verification) — mirroring the Python surface's\n * use of raw httpx (DECISIONS 2026-05-22).\n */\nexport type QueryValue = string | number | boolean | undefined | null;\n\nexport class HttpClient {\n readonly baseUrl: string;\n readonly timeoutMs: number;\n\n constructor(baseUrl: string, timeoutMs: number) {\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n this.timeoutMs = timeoutMs;\n }\n\n buildUrl(path: string, query?: Record<string, QueryValue>): string {\n const url = new URL(this.baseUrl + path);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null && v !== \"\") {\n url.searchParams.set(k, String(v));\n }\n }\n }\n return url.toString();\n }\n\n async get(\n path: string,\n query?: Record<string, QueryValue>,\n headers?: Record<string, string>,\n ): Promise<Response> {\n return this.fetch(this.buildUrl(path, query), {\n method: \"GET\",\n ...(headers && { headers }),\n });\n }\n\n async post(\n path: string,\n body: unknown,\n headers?: Record<string, string>,\n ): Promise<Response> {\n return this.fetch(this.buildUrl(path), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n });\n }\n\n private async fetch(url: string, init: RequestInit): Promise<Response> {\n return fetch(url, { ...init, signal: AbortSignal.timeout(this.timeoutMs) });\n }\n}\n","/**\n * Agent key file loading. The key file lives at\n * `~/.config/atbash/guard-client-key` by default and is either JSON\n * (`{ privKey, pubKey }`) or `key=value` lines (`privkey=…`, `pubkey=…`).\n * Only the private key is needed — the pubkey is re-derived by the Rust core\n * via `loadAgent`.\n */\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { native } from \"./native.js\";\nimport type { AgentAuth } from \"./types.js\";\n\nconst DEFAULT_KEY_PATH_REL = \".config/atbash/guard-client-key\";\n\nexport function resolveKeyPath(input?: string): string {\n if (input) return expandHome(input);\n const home = process.env.HOME || homedir() || \"\";\n return join(home, DEFAULT_KEY_PATH_REL);\n}\n\nfunction expandHome(p: string): string {\n if (!p.startsWith(\"~/\")) return p;\n const home = process.env.HOME || homedir() || \"\";\n return join(home, p.slice(2));\n}\n\nfunction readKeyFile(keyPath: string): { privKey: string; pubKey: string } {\n const content = String(readFileSync(keyPath, \"utf8\") || \"\").trim();\n let privKey = \"\";\n let pubKey = \"\";\n\n if (content.startsWith(\"{\")) {\n const creds = JSON.parse(content);\n privKey = String(\n creds.privKey || creds.privkey || creds.privateKey || \"\",\n ).trim();\n pubKey = String(\n creds.pubKey || creds.pubkey || creds.publicKey || \"\",\n ).trim();\n } else {\n for (const line of content.split(/\\r?\\n/)) {\n if (line.startsWith(\"privkey=\"))\n privKey = line.slice(\"privkey=\".length).trim();\n if (line.startsWith(\"pubkey=\"))\n pubKey = line.slice(\"pubkey=\".length).trim();\n }\n }\n\n if (!privKey || !pubKey) {\n throw new Error(`atbash key file missing priv/pub key fields: ${keyPath}`);\n }\n\n privKey = privKey.replace(/^0x/, \"\");\n return { privKey, pubKey };\n}\n\nexport function loadAgentFromFile(keyPath?: string): AgentAuth {\n const resolved = resolveKeyPath(keyPath);\n const { privKey } = readKeyFile(resolved);\n return native.loadAgent(privKey);\n}\n","/** Normalize wire shapes (verdict casing, status, pubkey) to canonical forms. */\nimport type { JudgmentState, Verdict } from \"./types.js\";\n\nexport function normalizeVerdict(raw: unknown): Verdict {\n if (raw === null || raw === undefined) return \"No verdict\";\n const v = String(raw).toUpperCase();\n if (v === \"ALLOW\" || v === \"GREEN\") return \"ALLOW\";\n if (v === \"HOLD\" || v === \"YELLOW\") return \"HOLD\";\n if (v === \"BLOCK\" || v === \"RED\") return \"BLOCK\";\n return \"HOLD\";\n}\n\nexport function normalizeStatus(raw: unknown): JudgmentState {\n const s = String(raw ?? \"\").toLowerCase();\n if (s === \"pending\" || s === \"answered\" || s === \"error\") return s;\n return \"error\";\n}\n\n/** Wire pubkey may be a hex string, a Buffer/Uint8Array, or `{ data: [...] }`. */\nexport function pubkeyToHex(val: unknown): string {\n if (!val) return \"\";\n if (typeof val === \"string\") return val;\n if (val instanceof Uint8Array) return Buffer.from(val).toString(\"hex\");\n if (typeof val === \"object\") {\n const data = (val as { data?: unknown }).data;\n if (Array.isArray(data)) return Buffer.from(data).toString(\"hex\");\n }\n return \"\";\n}\n","/**\n * Atbash SDK Telemetry — OpenTelemetry metrics for usage tracking.\n *\n * Tracks: function call counts, latency, source (CLI/plugin/SDK),\n * and agent identity. ON by default.\n *\n * Opt-out: create ~/.config/atbash/telemetry.json with { \"enabled\": false }\n * The file must be readable by the SDK process. If missing, corrupted, or\n * unreadable → telemetry stays ON. Environment variables cannot disable\n * telemetry (prevents agent bypass via env-var injection).\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { Counter, Histogram } from \"@opentelemetry/api\";\nimport { OTLPMetricExporter } from \"@opentelemetry/exporter-metrics-otlp-http\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport {\n MeterProvider,\n PeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\n\n// ── Types ───────────────────────────────────────────────────────\n\nexport type ClientSource =\n | \"cli\"\n | \"sdk\"\n | \"plugin:openclaw\"\n | \"plugin:langchain\"\n | \"plugin:langgraph\"\n | \"plugin:hermes\"\n | \"plugin:eliza\"\n | \"plugin:crewai\"\n | \"plugin:mcp\"\n | \"plugin:autogen\"\n | \"plugin:jeenai\"\n | (string & {});\n\nexport interface TelemetryConfig {\n /** Must be true to send any telemetry. Default: false */\n enabled: boolean;\n /** Where calls originate */\n source?: ClientSource;\n /** Flush interval in ms. Default: 60000 */\n exportIntervalMs?: number;\n}\n\n// ── State (module-level so recordCall/recordDuration can access) ─\n\nlet meterProvider: MeterProvider | null = null;\nlet callCounter: Counter | null = null;\nlet durationHistogram: Histogram | null = null;\nlet defaultSource: ClientSource = \"sdk\";\n\n// ── Setup ───────────────────────────────────────────────────────\n\n/**\n * Check if telemetry is disabled via the protected config file.\n * Only ~/.config/atbash/telemetry.json with { \"enabled\": false } disables it.\n * Missing, corrupted, or unreadable file → telemetry stays ON.\n */\nfunction isTelemetryOptedOut(): boolean {\n try {\n const home = process.env.HOME || homedir() || \"\";\n const filePath = join(home, \".config\", \"atbash\", \"telemetry.json\");\n const raw = readFileSync(filePath, \"utf-8\").trim();\n if (!raw) return false;\n const config = JSON.parse(raw) as { enabled?: boolean };\n return config.enabled === false;\n } catch {\n return false; // missing/corrupted/unreadable → telemetry ON\n }\n}\n\n/**\n * Auto-initialize telemetry on first recordCall if not already set up.\n * Reads opt-out from the protected config file, not from environment\n * variables (env vars are too easy for an attacker-controlled agent to\n * clear).\n */\nfunction autoInit(): void {\n if (meterProvider) return;\n if (isTelemetryOptedOut()) return;\n setupTelemetry({ enabled: true });\n}\n\nexport function setupTelemetry(config: TelemetryConfig): void {\n if (!config.enabled) return;\n if (meterProvider) return; // already initialized\n if (isTelemetryOptedOut()) return; // protected file opt-out\n\n defaultSource = config.source ?? \"sdk\";\n\n // Built-in Atbash ingest key — safe to embed because it can only\n // write metrics, not read or delete them.\n const ATBASH_HONEYCOMB_KEY = \"YOUR_INGEST_KEY_HERE\"; // replaced at publish time\n const apiKey = process.env.HONEYCOMB_API_KEY ?? ATBASH_HONEYCOMB_KEY;\n\n const exporter = new OTLPMetricExporter({\n url: \"https://api.honeycomb.io/v1/metrics\",\n headers: {\n \"x-honeycomb-team\": apiKey,\n },\n });\n\n const reader = new PeriodicExportingMetricReader({\n exporter,\n exportIntervalMillis: config.exportIntervalMs ?? 60_000,\n });\n\n meterProvider = new MeterProvider({\n resource: resourceFromAttributes({\n \"service.name\": \"atbash-sdk\",\n }),\n readers: [reader],\n });\n\n const meter = meterProvider.getMeter(\"atbash-sdk\");\n\n callCounter = meter.createCounter(\"atbash.sdk.function.calls\", {\n description: \"Number of SDK function calls\",\n });\n\n durationHistogram = meter.createHistogram(\"atbash.sdk.function.duration_ms\", {\n description: \"SDK function execution duration\",\n unit: \"ms\",\n });\n}\n\n// ── Recording ───────────────────────────────────────────────────\n\n/**\n * Record a function call. Call at the START of each tracked function.\n * Safe to call even if telemetry is disabled — does nothing.\n */\nexport function recordCall(\n functionName: string,\n source?: ClientSource,\n agentPubkey?: string,\n): void {\n autoInit();\n if (!callCounter) return;\n\n callCounter.add(1, {\n \"function.name\": functionName,\n source: source ?? defaultSource,\n ...(agentPubkey && { \"agent.pubkey\": agentPubkey }),\n });\n}\n\n/**\n * Record function duration. Call at the END of each tracked function.\n * Safe to call even if telemetry is disabled — does nothing.\n */\nexport function recordDuration(\n functionName: string,\n durationMs: number,\n status: \"success\" | \"error\",\n source?: ClientSource,\n): void {\n if (!durationHistogram) return;\n\n durationHistogram.record(durationMs, {\n \"function.name\": functionName,\n status: status,\n source: source ?? defaultSource,\n });\n}\n\n// ── Shutdown ────────────────────────────────────────────────────\n\n/**\n * Force-flush pending metrics without shutting down.\n * Use in short-lived processes (CLI) to ensure data is sent.\n */\nexport async function flushTelemetry(): Promise<void> {\n if (!meterProvider) return;\n await meterProvider.forceFlush();\n}\n\n/**\n * Flush pending metrics and shut down. Call before process exits.\n */\nexport async function shutdownTelemetry(): Promise<void> {\n if (!meterProvider) return;\n await meterProvider.shutdown();\n meterProvider = null;\n callCounter = null;\n durationHistogram = null;\n}\n","/**\n * User config file + env resolution. Config lives at\n * `~/.config/atbash/config.json`. `resolve` reads a single field with\n * precedence: explicit flag → env var → config file → \"\".\n */\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface AtbashUserConfig {\n agentKey?: string;\n orgName?: string;\n judgeEndpoint?: string;\n blockchainRid?: string;\n provider?: string;\n providerModel?: string;\n}\n\nconst ENV_MAP: Record<keyof AtbashUserConfig, string> = {\n agentKey: \"ATBASH_AGENT_KEY\",\n orgName: \"ATBASH_ORG_NAME\",\n judgeEndpoint: \"ATBASH_ENDPOINT\",\n blockchainRid: \"ATBASH_BLOCKCHAIN_RID\",\n provider: \"ATBASH_PROVIDER\",\n providerModel: \"ATBASH_PROVIDER_MODEL\",\n};\n\nexport function getConfigDir(): string {\n const home = process.env.HOME || homedir() || \"\";\n return join(home, \".config\", \"atbash\");\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.json\");\n}\n\nexport function loadUserConfig(): AtbashUserConfig {\n try {\n const p = getConfigPath();\n if (!existsSync(p)) return {};\n const raw = readFileSync(p, \"utf-8\").trim();\n if (!raw) return {};\n return JSON.parse(raw) as AtbashUserConfig;\n } catch (err) {\n console.error(\"Failed to load config file\", err);\n return {};\n }\n}\n\nexport function saveUserConfig(config: AtbashUserConfig): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n const filePath = getConfigPath();\n writeFileSync(filePath, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n chmodSync(filePath, 0o600);\n}\n\nexport function resolve(\n key: keyof AtbashUserConfig,\n flagValue?: string,\n): string {\n if (flagValue) return flagValue;\n const envName = ENV_MAP[key];\n if (envName) {\n const envVal = process.env[envName];\n if (envVal) return envVal;\n }\n const fileVal = loadUserConfig()[key];\n if (fileVal != null) return String(fileVal);\n return \"\";\n}\n","/**\n * `Atbash` — the Node SDK client. Composes the Rust core (signing, identity,\n * redaction; via NAPI) with the judge / risk-engine HTTP surface.\n *\n * For `/api/risk-engine` we parse the raw JSON ourselves: that endpoint is\n * RPC-style with `?action=`, and the spec encodes its response as a single\n * `oneOf` — generator dispatch is dict-ambiguous (TierInfo vs ToolCallFull).\n * Each method knows the action it called and casts deterministically.\n */\nimport { randomHex } from \"./random.js\";\n\nimport {\n PRIVATE_CHAIN,\n PUBLIC_CHAIN,\n type ChainConfig,\n} from \"./chain-config.js\";\nimport { DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT } from \"./constants.js\";\nimport { validateJudgeEndpoint } from \"./endpoint.js\";\nimport { AtbashAPIError, SignatureVerificationError } from \"./errors.js\";\nimport { HttpClient, type QueryValue } from \"./http/client.js\";\nimport type { components } from \"./http/schema.js\";\nimport { loadAgentFromFile } from \"./keyLoader.js\";\nimport { native } from \"./native.js\";\nimport { normalizeStatus, normalizeVerdict, pubkeyToHex } from \"./normalize.js\";\nimport { recordCall, recordDuration } from \"./opentel/telemetry.js\";\nimport { resolve } from \"./userConfig.js\";\nimport type {\n AgentAuth,\n AgentPolicy,\n AtbashLogger,\n AtbashOptions,\n ChainOpts,\n Decision,\n FromConfigOptions,\n HeldAction,\n HeldActionReview,\n JudgeOptions,\n JudgeResult,\n JudgmentStatus,\n KeyPair,\n LogToolCallOptions,\n LogToolCallResult,\n Network,\n OrgSubscription,\n RedactResult,\n TierInfo,\n ToolCallFull,\n ToolCallInput,\n ToolCallRecord,\n} from \"./types.js\";\n\ntype JudgeRequestWire = components[\"schemas\"][\"JudgeRequest\"];\n\n/** `tc-<unix_ms>-<8 hex chars>`. */\nfunction generateToolCallId(): string {\n return `tc-${Date.now()}-${randomHex(4)}`;\n}\n\nexport class Atbash {\n readonly auth: AgentAuth;\n readonly endpoint: string;\n readonly nodeUrls: readonly string[];\n readonly blockchainRid: string;\n /** Default org name used by `auditToolCall` / `judgeAction`. */\n readonly orgName?: string;\n /** Default judge response-signing pubkey, if configured (see fromConfig). */\n readonly verifyPubKey?: string;\n /** When true (default), `auditToolCall` denies on any error. */\n readonly failClosed: boolean;\n private readonly logger: AtbashLogger;\n private readonly http: HttpClient;\n /**\n * Per-client cache of resolved chains. Keyed by orgName so repeated\n * calls don't re-hit the dashboard. Cleared by `clearChainCache()`.\n */\n private readonly _chainCache = new Map<string, ChainConfig>();\n /**\n * Cached bearer token for risk-engine / insurance read calls. Built\n * lazily as a signed `log_tool_call` tx and refreshed every 4 min so\n * server-side replay protection windows never expire it mid-session.\n */\n private _authBearer: { hex: string; issuedAt: number } | null = null;\n\n constructor(privkey: string, options: AtbashOptions = {}) {\n this.auth = native.loadAgent(privkey);\n this.endpoint =\n (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\\/+$/, \"\") ||\n DEFAULT_ENDPOINT;\n this.nodeUrls = options.nodeUrls\n ? [...options.nodeUrls]\n : DEFAULT_CHROMIA_NODE_URLS;\n this.blockchainRid = options.blockchainRid ?? native.DEFAULT_BLOCKCHAIN_RID;\n this.orgName = options.orgName;\n this.verifyPubKey = options.verifyPubKey;\n this.failClosed = options.failClosed !== false;\n this.logger = options.logger ?? {};\n this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 30_000);\n\n if (this.endpoint !== DEFAULT_ENDPOINT) {\n this.logger.warn?.(\"[atbash] running on non-default judge endpoint\", {\n endpoint: this.endpoint,\n verifying: this.verifyPubKey\n ? \"with response-signature pubkey configured\"\n : \"without signature verification\",\n });\n }\n }\n\n /**\n * Construct from resolved config: explicit overrides → env vars → the\n * `~/.config/atbash/config.json` file (see userConfig.resolve). The private\n * key comes from `agentKey` (override/env/file) or, failing that, the agent\n * key file (`~/.config/atbash/guard-client-key`). The judge endpoint is\n * validated against the trusted allowlist / self-hosted policy; a\n * self-hosted endpoint's `verifyPubKey` becomes the client default.\n */\n static fromConfig(options: FromConfigOptions = {}): Atbash {\n const validated = validateJudgeEndpoint(\n options.judge ?? { endpoint: resolve(\"judgeEndpoint\") || undefined },\n );\n\n const agentKey = resolve(\"agentKey\", options.agentKey);\n const auth: AgentAuth = agentKey\n ? native.loadAgent(agentKey)\n : loadAgentFromFile(options.keyPath);\n\n const blockchainRid =\n resolve(\"blockchainRid\", options.blockchainRid) || undefined;\n\n return new Atbash(auth.privkey, {\n endpoint: validated.url,\n blockchainRid,\n timeoutMs: options.timeoutMs,\n nodeUrls: options.nodeUrls,\n orgName: options.orgName,\n verifyPubKey: validated.verifyPubKey ?? undefined,\n failClosed: options.failClosed,\n logger: options.logger,\n });\n }\n\n get pubkey(): string {\n return this.auth.pubkey;\n }\n\n get privkey(): string {\n return this.auth.privkey;\n }\n\n /* ── agent existence (/api/ai/exists) ──────────────────────────────────── */\n\n /** GET /api/ai/exists?pubkey=… — defaults to this client's pubkey. */\n async checkAgentExists(pubkey?: string): Promise<boolean> {\n const pk = pubkey ?? this.auth.pubkey;\n return this.track(\"checkAgentExists\", pk, async () => {\n const resp = await this.http.get(\n \"/api/ai/exists\",\n { pubkey: pk },\n this.authHeaders(),\n );\n await this.raiseIfError(resp);\n const data = (await this.json(resp)) as { registered?: unknown } | null;\n return Boolean(data?.registered);\n });\n }\n\n /* ── log_tool_call (sign-only) ─────────────────────────────────────────── */\n\n /**\n * Pre-flight `checkAgentExists`, then sign `log_tool_call` locally and\n * return the signed tx hex. The server broadcasts to chain.\n */\n async logToolCall(\n action: string,\n context = \"\",\n options: LogToolCallOptions = {},\n ): Promise<LogToolCallResult> {\n const start = performance.now();\n recordCall(\"logToolCall\", undefined, this.auth.pubkey);\n\n let exists: boolean;\n try {\n exists = await this.checkAgentExists();\n } catch (err) {\n recordDuration(\"logToolCall\", performance.now() - start, \"error\");\n return { success: false, toolCallId: null, error: errorMessage(err) };\n }\n if (!exists) {\n recordDuration(\"logToolCall\", performance.now() - start, \"error\");\n return {\n success: false,\n toolCallId: null,\n error:\n \"Agent not registered. Onboard the agent at the dashboard before \" +\n \"submitting actions.\",\n };\n }\n\n const toolCallId = generateToolCallId();\n const brid = options.chainOpts?.blockchainRid ?? this.blockchainRid;\n try {\n const signedHex = native.signLogToolCall(\n toolCallId,\n action,\n context,\n options.toolName ?? \"\",\n options.toolArgsJson ?? \"\",\n this.auth.privkey,\n brid,\n );\n recordDuration(\"logToolCall\", performance.now() - start, \"success\");\n return { success: true, toolCallId, signedHex };\n } catch (err) {\n recordDuration(\"logToolCall\", performance.now() - start, \"error\");\n return { success: false, toolCallId: null, error: errorMessage(err) };\n }\n }\n\n /* ── judge_action ──────────────────────────────────────────────────────── */\n\n /**\n * Sign log_tool_call + optionally judge_action, POST /api/v1/judge.\n *\n * `verifyPubKey` checks the `X-Atbash-Signature` header against the exact\n * response bytes via the Rust core's `verifySignature`.\n */\n async judgeAction(\n action: string,\n context = \"\",\n options: JudgeOptions = {},\n ): Promise<JudgeResult> {\n return this.track(\"judgeAction\", this.auth.pubkey, () =>\n this._judgeAction(action, context, options),\n );\n }\n\n private async _judgeAction(\n action: string,\n context: string,\n options: JudgeOptions,\n ): Promise<JudgeResult> {\n if (!action?.trim()) {\n throw new Error(\"action is required and cannot be empty.\");\n }\n\n // Resolve chain when orgName is provided. Order:\n // 1. org_networks map (authoritative post-upgrade — wins over any\n // stale BRID hint on chainOpts).\n // 2. Caller-pinned chainOpts.blockchainRid (no map entry).\n // 3. Per-chain subscription resolution (no map, no pin).\n let chainOpts: ChainOpts | undefined = options.chainOpts;\n if (options.orgName) {\n const mapNetwork = await this.getActiveNetworkForOrg(options.orgName);\n if (mapNetwork) {\n chainOpts = { network: mapNetwork };\n } else if (!chainOpts?.blockchainRid) {\n // No map entry — hand the fetched result (null) to the fallback\n // resolver so it doesn't re-hit /api/org-network for the same org.\n const resolved = await this.resolveChainFromMap(options.orgName, null);\n chainOpts = { ...chainOpts, network: resolved.network };\n }\n }\n const brid = this.bridFromChainOpts(chainOpts);\n\n const logResult = await this.logToolCall(action, context, {\n toolName: options.toolName,\n toolArgsJson: options.toolArgsJson,\n chainOpts,\n });\n if (!logResult.success || !logResult.toolCallId || !logResult.signedHex) {\n throw new Error(logResult.error || \"Failed to sign log_tool_call\");\n }\n\n let signedJudgeAction: string | undefined;\n if (!options.provider) {\n const judgmentId = generateToolCallId();\n signedJudgeAction = native.signJudgeAction(\n judgmentId,\n action,\n context || \"\",\n \"\",\n this.auth.privkey,\n brid,\n );\n }\n\n const body: JudgeRequestWire = {\n tool_call_id: logResult.toolCallId,\n agent_pubkey: this.auth.pubkey,\n action,\n signed_log_tool_call: logResult.signedHex,\n };\n if (signedJudgeAction) body.signed_judge_action = signedJudgeAction;\n if (context) body.context = context;\n if (options.provider) body.provider = options.provider;\n if (options.toolName) body.tool_name = options.toolName;\n if (options.model) body.model = options.model;\n\n let resp: Response;\n try {\n resp = await this.http.post(\"/api/v1/judge\", body);\n } catch (err) {\n throw this.transportError(err);\n }\n if (!resp.ok) throw await this.httpError(resp);\n\n // Read the raw bytes before any decode so signature verification runs\n // against exactly what the server signed.\n const bodyBytes = Buffer.from(await resp.arrayBuffer());\n const verifyPubKey = options.verifyPubKey ?? this.verifyPubKey;\n if (verifyPubKey !== undefined) {\n const sig = resp.headers.get(\"X-Atbash-Signature\");\n if (!sig) {\n throw new SignatureVerificationError(\n \"missing X-Atbash-Signature header\",\n );\n }\n let ok: boolean;\n try {\n ok = native.verifySignature(bodyBytes, sig, verifyPubKey);\n } catch (err) {\n throw new SignatureVerificationError(\n `signature verification threw: ${errorMessage(err)}`,\n );\n }\n if (!ok) {\n throw new SignatureVerificationError(\n \"signature does not verify against configured verifyPubKey\",\n );\n }\n }\n\n const data = parseJson(bodyBytes) as Record<string, unknown>;\n return {\n verdict: normalizeVerdict(data.verdict),\n actionType: String(data.action_type ?? \"\"),\n reason: String(data.reason ?? \"\"),\n confidence: Number(data.confidence ?? 0),\n provider: String(data.provider ?? \"\"),\n latencyMs: Number(data.latency_ms ?? 0),\n toolCallId: String(data.tool_call_id ?? logResult.toolCallId),\n onChain: Boolean(data.on_chain),\n enforced: Boolean(data.enforced),\n enforcementMode: String(data.enforcement_mode ?? \"\"),\n };\n }\n\n /* ── audit_tool_call (redact → judge → decision) ───────────────────────── */\n\n /**\n * High-level guard: redact secrets, submit for judgement, and collapse the\n * result into an allow/deny `Decision`. Fails closed by default — any error\n * (judge unreachable, unrecognized verdict) denies unless `failClosed` is\n * explicitly false.\n */\n async auditToolCall(input: ToolCallInput): Promise<Decision> {\n const toolName = input.toolName || \"unknown\";\n\n // Redact secret-shaped values BEFORE signing so they never reach the\n // signed bytes, the request body, the on-chain log, or the LLM prompt.\n const argsRedaction = native.redactSecrets(stringifyArgs(input.args));\n const ctxRedaction = native.redactSecrets(input.context ?? toolName);\n const argsJson = argsRedaction.redacted;\n const actionText = truncate(argsJson);\n const contextText = ctxRedaction.redacted;\n const totalRedactions =\n argsRedaction.found.length + ctxRedaction.found.length;\n if (totalRedactions > 0) {\n const kinds = [\n ...new Set([\n ...argsRedaction.found.map((f) => f.kind),\n ...ctxRedaction.found.map((f) => f.kind),\n ]),\n ];\n this.logger.warn?.(\"[atbash] redacted secrets before judge call\", {\n tool: toolName,\n count: totalRedactions,\n kinds,\n });\n }\n\n try {\n this.logger.info?.(\"[atbash] judge API called\", { tool: toolName });\n const result = await this.judgeAction(actionText, contextText, {\n toolName,\n toolArgsJson: argsJson,\n orgName: this.orgName,\n });\n\n // AUDIT tier — server returns no verdict (log only, no AI enforcement).\n if (result.verdict === \"No verdict\") {\n return {\n allow: true,\n verdict: \"ALLOW\",\n reason:\n result.reason ||\n \"audit tier — request logged on-chain, no AI enforcement\",\n toolCallId: result.toolCallId,\n };\n }\n\n const action = result.actionType;\n if (action === \"block\") {\n return {\n allow: false,\n verdict: \"BLOCK\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n if (action === \"hold_for_user_confirm\") {\n return {\n allow: false,\n verdict: \"HOLD\",\n reason: result.reason || \"held for human confirmation\",\n toolCallId: result.toolCallId,\n };\n }\n if (action === \"allow\") {\n // If verdict conflicts with action_type (server confusion), respect the\n // more restrictive signal rather than blindly allowing.\n if (result.verdict === \"HOLD\") {\n return {\n allow: false,\n verdict: \"HOLD\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n if (result.verdict === \"BLOCK\") {\n return {\n allow: false,\n verdict: \"BLOCK\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n return {\n allow: true,\n verdict: \"ALLOW\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n\n return this.fail(\n \"unrecognized action_type from judge\",\n result.toolCallId,\n );\n } catch (err) {\n const message = errorMessage(err);\n this.logger.warn?.(\"[atbash] judge API failed\", { reason: message });\n return this.fail(message);\n }\n }\n\n private fail(reason: string, toolCallId?: string): Decision {\n return { allow: !this.failClosed, verdict: \"ERROR\", reason, toolCallId };\n }\n\n /* ── judgment status ───────────────────────────────────────────────────── */\n\n async getJudgmentStatus(\n judgmentId: string,\n agentPubkey?: string,\n ): Promise<JudgmentStatus> {\n const pk = agentPubkey ?? this.auth.pubkey;\n return this.track(\"getJudgmentStatus\", pk, async () => {\n const resp = await this.http.get(\n \"/api/v1/judge\",\n { tool_call_id: judgmentId, agent_pubkey: pk },\n this.authHeaders(),\n );\n await this.raiseIfError(resp);\n const data = ((await this.json(resp)) ?? {}) as Record<string, unknown>;\n return {\n status: normalizeStatus(data.status),\n verdict: normalizeVerdict(data.verdict),\n reason: String(data.reason ?? \"\"),\n judgmentId: String(data.judgmentId ?? judgmentId),\n onChain: optBool(data.onChain),\n cached: optBool(data.cached),\n responseTimeMs: optNumber(data.responseTimeMs),\n };\n });\n }\n\n /* ── risk-engine queries (action-dispatched GET) ───────────────────────── */\n\n getToolCalls(maxCount: number): Promise<ToolCallRecord[]> {\n return this.track(\"getToolCalls\", undefined, () =>\n this.riskEngineRecords(\"tool-calls\", { limit: maxCount }),\n );\n }\n\n getOrgToolCalls(\n orgName: string,\n maxCount: number,\n ): Promise<ToolCallRecord[]> {\n return this.track(\"getOrgToolCalls\", undefined, () =>\n this.riskEngineRecords(\"org-tool-calls\", {\n org: orgName,\n limit: maxCount,\n }),\n );\n }\n\n getAgentToolCalls(\n agentPubkey: string,\n maxCount: number,\n ): Promise<ToolCallRecord[]> {\n return this.track(\"getAgentToolCalls\", agentPubkey, () =>\n this.riskEngineRecords(\"agent-tool-calls\", {\n agent: agentPubkey,\n limit: maxCount,\n }),\n );\n }\n\n async getToolCallCount(): Promise<number> {\n return this.track(\"getToolCallCount\", undefined, async () => {\n const raw = await this.riskEngineGet(\"tool-call-count\", {});\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n });\n }\n\n async getToolCallFull(toolCallId: string): Promise<ToolCallFull | null> {\n return this.track(\"getToolCallFull\", undefined, async () => {\n const raw = await this.riskEngineGet(\"tool-call-full\", {\n tool_call_id: toolCallId,\n });\n if (!isRecord(raw)) return null;\n return toToolCallFull(raw);\n });\n }\n\n async getOrgTierInfo(orgName: string): Promise<TierInfo | null> {\n return this.track(\"getOrgTierInfo\", undefined, async () => {\n const raw = await this.riskEngineGet(\"org-tier-info\", { org: orgName });\n if (!isRecord(raw)) return null;\n return {\n orgName: String(raw.org_name ?? \"\"),\n tier: String(raw.tier ?? \"\"),\n verdictEnabled: Boolean(raw.verdict_enabled),\n enforcementEnabled: Boolean(raw.enforcement_enabled),\n };\n });\n }\n\n async getPendingHeldActions(\n orgName: string,\n maxCount: number,\n ): Promise<HeldAction[]> {\n return this.track(\"getPendingHeldActions\", undefined, async () => {\n const raw = await this.riskEngineGet(\"pending-held-actions\", {\n org: orgName,\n limit: maxCount,\n });\n if (!Array.isArray(raw)) return [];\n return raw.map((item) => toHeldAction(item as Record<string, unknown>));\n });\n }\n\n async getHeldActionReviews(\n orgName: string,\n maxCount: number,\n ): Promise<HeldActionReview[]> {\n return this.track(\"getHeldActionReviews\", undefined, async () => {\n const raw = await this.riskEngineGet(\"held-action-reviews\", {\n org: orgName,\n limit: maxCount,\n });\n if (!Array.isArray(raw)) return [];\n return raw.map((item) =>\n toHeldActionReview(item as Record<string, unknown>),\n );\n });\n }\n\n /* ── risk-engine batched (action-dispatched POST) ──────────────────────── */\n\n getAgentDetail(agentPubkey: string): Promise<Record<string, unknown>> {\n return this.track(\"getAgentDetail\", agentPubkey, () =>\n this.riskEnginePost({ action: \"agent-detail-batch\", agent: agentPubkey }),\n );\n }\n\n async getAgentPolicy(agentPubkey: string): Promise<AgentPolicy> {\n return this.track(\"getAgentPolicy\", agentPubkey, async () => {\n const raw = await this.riskEnginePost({\n action: \"agent-policy-batch\",\n agent: agentPubkey,\n });\n return {\n policy: String(raw.policy ?? \"\"),\n isJailed: Boolean(raw.is_jailed),\n isCustom: Boolean(raw.is_custom),\n defaultPolicy: String(raw.default_policy ?? \"\"),\n };\n });\n }\n\n /* ── safety stats (/api/insurance?action=safety-stats) ─────────────────── */\n\n async getSafetyStats(): Promise<Record<string, unknown>> {\n return this.track(\"getSafetyStats\", undefined, async () => {\n const resp = await this.http.get(\n \"/api/insurance\",\n { action: \"safety-stats\" },\n this.authHeaders(),\n );\n await this.raiseIfError(resp);\n const data = ((await this.json(resp)) ?? {}) as Record<string, unknown>;\n // TS unwraps `.data` when present.\n if (isRecord(data.data)) return data.data;\n return data;\n });\n }\n\n /* ── chain resolution (org → chain) ────────────────────────────────────── */\n\n /**\n * Org's subscription on a specific chain. The `network` arg selects\n * which chain to query; without it, the dashboard picks the default.\n * Returns null when the org has no record on that chain.\n */\n async getOrgSubscription(\n orgName: string,\n network?: Network,\n ): Promise<OrgSubscription | null> {\n return this.track(\"getOrgSubscription\", undefined, async () => {\n const params: Record<string, QueryValue> = { org: orgName };\n if (network) params.network = network;\n const raw = await this.riskEngineGet(\"org-subscription\", params);\n if (!isRecord(raw)) return null;\n return coerceOrgSubscription(raw, orgName);\n });\n }\n\n /**\n * Read the org's active network from the dashboard's off-chain\n * `org_networks` map. The map is the authoritative source after a\n * plan switch — subscription rows on the source chain go stale, but\n * the map is updated on every assign. Returns null when there's no\n * entry (caller falls back to per-chain subscription resolution).\n */\n async getActiveNetworkForOrg(orgName: string): Promise<Network | null> {\n try {\n const resp = await this.http.get(\n \"/api/org-network\",\n { org: orgName },\n this.authHeaders(),\n );\n if (resp.status !== 200) return null;\n const data = (await this.json(resp)) as {\n network?: string | null;\n } | null;\n if (data?.network === \"public\" || data?.network === \"private\") {\n return data.network;\n }\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Resolve which chain an org's actions should run against. Cached\n * per-client by orgName. Resolution order:\n * 1. `org_networks` map (authoritative).\n * 2. Per-chain subscription fallback — public + private records\n * are fetched in parallel, with `is_private_blockchain` and\n * `assigned_at` reconciling mixed states.\n * Defaults to the public chain when nothing else resolves.\n */\n async resolveChainForOrg(orgName: string): Promise<ChainConfig> {\n const cached = this._chainCache.get(orgName);\n if (cached) return cached;\n const mapNetwork = await this.getActiveNetworkForOrg(orgName);\n return this.resolveChainFromMap(orgName, mapNetwork);\n }\n\n /**\n * Resolve a chain given an already-fetched `org_networks` map result.\n * Split out from {@link resolveChainForOrg} so callers that have already\n * queried the map (the judge path) don't fetch /api/org-network twice.\n * Caches per orgName like its caller.\n */\n private async resolveChainFromMap(\n orgName: string,\n mapNetwork: Network | null,\n ): Promise<ChainConfig> {\n const cached = this._chainCache.get(orgName);\n if (cached) return cached;\n\n if (mapNetwork) {\n const chain = mapNetwork === \"private\" ? PRIVATE_CHAIN : PUBLIC_CHAIN;\n this._chainCache.set(orgName, chain);\n return chain;\n }\n\n // Fallback: both subscription rows can exist after a plan switch\n // because `admin_assign_subscription` writes only to the destination\n // chain. Reconcile with `is_private_blockchain` + `assigned_at`.\n try {\n const [pubSub, privSub] = await Promise.all([\n this.getOrgSubscription(orgName, \"public\").catch(() => null),\n this.getOrgSubscription(orgName, \"private\").catch(() => null),\n ]);\n\n if (pubSub?.is_private_blockchain) {\n this._chainCache.set(orgName, PRIVATE_CHAIN);\n return PRIVATE_CHAIN;\n }\n if (pubSub && privSub) {\n const chain =\n privSub.assigned_at > pubSub.assigned_at\n ? PRIVATE_CHAIN\n : PUBLIC_CHAIN;\n this._chainCache.set(orgName, chain);\n return chain;\n }\n if (pubSub) {\n this._chainCache.set(orgName, PUBLIC_CHAIN);\n return PUBLIC_CHAIN;\n }\n if (privSub?.is_private_blockchain) {\n this._chainCache.set(orgName, PRIVATE_CHAIN);\n return PRIVATE_CHAIN;\n }\n } catch {\n // Fall through to public default if subscription lookup fails.\n }\n this._chainCache.set(orgName, PUBLIC_CHAIN);\n return PUBLIC_CHAIN;\n }\n\n /** Drop any cached chain resolutions. Useful in tests. */\n clearChainCache(): void {\n this._chainCache.clear();\n }\n\n /* ── internals ─────────────────────────────────────────────────────────── */\n\n /**\n * Wrap an SDK method body in telemetry — records the call at start\n * and a success/error duration at end. Re-throws on failure so the\n * caller sees the original exception. Pass `agentPubkey` when the\n * method is keyed to a specific agent; tracked methods that don't\n * depend on an agent (read queries) pass `undefined`.\n */\n private async track<T>(\n name: string,\n agentPubkey: string | undefined,\n fn: () => Promise<T>,\n ): Promise<T> {\n const start = performance.now();\n recordCall(name, undefined, agentPubkey);\n try {\n const result = await fn();\n recordDuration(name, performance.now() - start, \"success\");\n return result;\n } catch (err) {\n recordDuration(name, performance.now() - start, \"error\");\n throw err;\n }\n }\n\n /**\n * Pick the BRID for a given per-call chain override. `blockchainRid`\n * takes precedence; otherwise `network` maps to one of the known\n * chains; otherwise the client's default.\n */\n private bridFromChainOpts(chainOpts?: ChainOpts): string {\n if (chainOpts?.blockchainRid) return chainOpts.blockchainRid;\n if (chainOpts?.network === \"private\") return PRIVATE_CHAIN.blockchainRid;\n if (chainOpts?.network === \"public\") return PUBLIC_CHAIN.blockchainRid;\n return this.blockchainRid;\n }\n\n /**\n * Get-or-create a Bearer token for dashboard reads. The token is a\n * signed `log_tool_call` op (locally signed, never submitted) — the\n * dashboard verifies the signature against the agent's pubkey. Cached\n * for 4 minutes; refreshed after that so a long-lived client never\n * trips the server's replay window.\n */\n private getAuthBearer(): string {\n const now = Date.now();\n if (this._authBearer && now - this._authBearer.issuedAt < 4 * 60 * 1000) {\n return this._authBearer.hex;\n }\n const nonce = `auth-${now.toString(36)}-${randomHex(4)}`;\n const hex = native.signLogToolCall(\n nonce,\n `auth:${now}`,\n \"\",\n \"auth-bearer\",\n \"\",\n this.auth.privkey,\n this.blockchainRid,\n );\n this._authBearer = { hex, issuedAt: now };\n return hex;\n }\n\n private authHeaders(): Record<string, string> {\n return { Authorization: `Bearer ${this.getAuthBearer()}` };\n }\n\n private async riskEngineGet(\n action: string,\n params: Record<string, QueryValue>,\n ): Promise<unknown> {\n let resp: Response;\n try {\n resp = await this.http.get(\n \"/api/risk-engine\",\n { action, ...params },\n this.authHeaders(),\n );\n } catch (err) {\n throw this.transportError(err);\n }\n if (resp.status !== 200) throw await this.httpError(resp);\n return this.json(resp);\n }\n\n private async riskEnginePost(\n body: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n let resp: Response;\n try {\n resp = await this.http.post(\"/api/risk-engine\", body, this.authHeaders());\n } catch (err) {\n throw this.transportError(err);\n }\n if (resp.status !== 200) throw await this.httpError(resp);\n const data = await this.json(resp);\n return isRecord(data) ? data : {};\n }\n\n private async riskEngineRecords(\n action: string,\n params: Record<string, QueryValue>,\n ): Promise<ToolCallRecord[]> {\n const raw = await this.riskEngineGet(action, params);\n if (!Array.isArray(raw)) return [];\n return raw.map((item) => toToolCallRecord(item as Record<string, unknown>));\n }\n\n private async raiseIfError(resp: Response): Promise<void> {\n if (resp.ok) return;\n throw await this.httpError(resp);\n }\n\n /** Wrap a failed HTTP *response* (non-2xx / non-200) as an AtbashAPIError. */\n private async httpError(resp: Response): Promise<AtbashAPIError> {\n return new AtbashAPIError(\n resp.status,\n await safeText(resp),\n resp.statusText,\n this.endpoint,\n );\n }\n\n /** Wrap a *transport* failure (fetch threw, no response) as an AtbashAPIError. */\n private transportError(err: unknown): AtbashAPIError {\n return new AtbashAPIError(0, errorMessage(err), \"\", this.endpoint);\n }\n\n private async json(resp: Response): Promise<unknown> {\n const text = await safeText(resp);\n if (!text) return null;\n const parsed = tryParseJson(text);\n return parsed === undefined ? null : parsed;\n }\n\n /* ── crypto / redaction passthroughs (Rust core) ───────────────────────── */\n\n static generateKeypair(): KeyPair {\n return native.generateKeypair();\n }\n\n static isValidPrivateKey(hex: string): boolean {\n return native.isValidPrivateKey(hex);\n }\n\n static derivePublicKey(privkey: string): string {\n return native.derivePublicKey(privkey);\n }\n\n static redactSecrets(text: string): RedactResult {\n return native.redactSecrets(text);\n }\n\n static normalizeForMatching(text: string): string {\n return native.normalizeForMatching(text);\n }\n\n static containsEvasionCharacters(text: string): boolean {\n return native.containsEvasionCharacters(text);\n }\n}\n\n/* ── record converters ─────────────────────────────────────────────────── */\n\n/** Fields shared by ToolCallRecord and ToolCallFull. */\nfunction baseToolCall(raw: Record<string, unknown>) {\n return {\n toolCallId: String(raw.tool_call_id ?? \"\"),\n agentPubkey: pubkeyToHex(raw.agent_pubkey),\n toolName: String(raw.tool_name ?? \"\"),\n commandText: String(raw.command_text ?? \"\"),\n contextText: String(raw.context_text ?? \"\"),\n orgName: String(raw.org_name ?? \"\"),\n };\n}\n\nfunction toToolCallRecord(raw: Record<string, unknown>): ToolCallRecord {\n return {\n ...baseToolCall(raw),\n toolArgsJson: String(raw.tool_args_json ?? \"\"),\n rowid: Number(raw.rowid ?? 0),\n };\n}\n\nfunction toToolCallFull(raw: Record<string, unknown>): ToolCallFull {\n return {\n ...baseToolCall(raw),\n toolArgsJson: optString(raw.tool_args_json),\n createdAt: optNumber(raw.created_at),\n actionType: optString(raw.action_type),\n resultStatus: optString(raw.result_status),\n verdictColor: optString(raw.verdict_color),\n verdictReason: optString(raw.verdict_reason),\n verdictSource: optString(raw.verdict_source),\n verdictResponseTimeMs: optNumber(raw.verdict_response_time_ms),\n };\n}\n\nfunction toHeldAction(raw: Record<string, unknown>): HeldAction {\n return {\n judgmentId: String(raw.judgment_id ?? \"\"),\n agentPubkey: pubkeyToHex(raw.agent_pubkey),\n actionText: String(raw.action_text ?? \"\"),\n actionContext: String(raw.action_context ?? \"\"),\n verdict: normalizeVerdict(raw.verdict),\n reason: String(raw.reason ?? \"\"),\n createdAt: Number(raw.created_at ?? 0),\n };\n}\n\nfunction toHeldActionReview(raw: Record<string, unknown>): HeldActionReview {\n return {\n judgmentId: String(raw.judgment_id ?? \"\"),\n actionText: String(raw.action_text ?? \"\"),\n status: String(raw.status ?? \"\"),\n reviewNote: String(raw.review_note ?? \"\"),\n reviewedAt: Number(raw.reviewed_at ?? 0),\n createdAt: Number(raw.created_at ?? 0),\n reviewedBy:\n optString(raw.reviewed_by) || pubkeyToHex(raw.reviewed_by) || undefined,\n };\n}\n\nfunction coerceOrgSubscription(\n raw: Record<string, unknown>,\n orgName: string,\n): OrgSubscription {\n return {\n org_name: String(raw.org_name ?? orgName),\n subscription_name: String(raw.subscription_name ?? \"\"),\n agent_number: Number(raw.agent_number ?? 0),\n is_private_blockchain: Boolean(raw.is_private_blockchain),\n monthly_price: Number(raw.monthly_price ?? 0),\n yearly_price: Number(raw.yearly_price ?? 0),\n duration_months: Number(raw.duration_months ?? 0),\n assigned_at: Number(raw.assigned_at ?? 0),\n expires_at: Number(raw.expires_at ?? 0),\n is_active: Boolean(raw.is_active),\n };\n}\n\n/* ── small helpers ─────────────────────────────────────────────────────── */\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction optString(v: unknown): string | undefined {\n if (v === null || v === undefined) return undefined;\n return typeof v === \"string\" ? v : String(v);\n}\n\nfunction optNumber(v: unknown): number | undefined {\n if (v === null || v === undefined) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction optBool(v: unknown): boolean | undefined {\n if (v === null || v === undefined) return undefined;\n return Boolean(v);\n}\n\n/** Parse JSON, returning `undefined` (not throwing) on malformed input. */\nfunction tryParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction parseJson(bytes: Buffer): unknown {\n const parsed = tryParseJson(bytes.toString(\"utf-8\"));\n return parsed === undefined ? {} : parsed;\n}\n\nasync function safeText(resp: Response): Promise<string> {\n try {\n return await resp.text();\n } catch {\n return \"\";\n }\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction stringifyArgs(args: unknown): string {\n if (args === null || args === undefined) return \"\";\n if (typeof args === \"string\") return args;\n try {\n return JSON.stringify(args);\n } catch {\n return String(args);\n }\n}\n\nconst MAX_ACTION_LEN = 4000;\nfunction truncate(text: string): string {\n if (text.length <= MAX_ACTION_LEN) return text;\n return text.slice(0, MAX_ACTION_LEN) + \"…\";\n}\n","/**\n * TS-side helpers that compose the Rust core's `redactSecrets`. The core\n * handles single-string redaction; recursive / JSON-aware shapes belong\n * up here so the FFI surface stays minimal.\n */\nimport { native } from \"./native.js\";\n\n/**\n * Canonical secret kinds reported by the Rust core in `SecretMatch.kind`.\n * Wire is permissive (modelled as a free string in {@link SecretMatch})\n * so unknown kinds don't break callers; use this union when narrowing.\n */\nexport type SecretKind =\n | \"anthropic\"\n | \"openai\"\n | \"openai_project\"\n | \"github\"\n | \"google\"\n | \"google_oauth\"\n | \"aws_access_key\"\n | \"aws_secret_key\"\n | \"stripe\"\n | \"slack\"\n | \"slack_webhook\"\n | \"sendgrid\"\n | \"twilio_sid\"\n | \"mailgun\"\n | \"npm_token\"\n | \"jwt\"\n | \"private_key_pem\"\n | \"context_secret\"\n | \"bearer\"\n | \"base64\"\n | \"generic_token\";\n\n/**\n * Walk a JSON-shaped value and redact secrets inside every string leaf.\n * Object keys are not touched; only values. Arrays and nested objects\n * are recursed structurally so the returned value has the same shape.\n */\nexport function redactJsonStrings<T>(value: T): T {\n if (typeof value === \"string\") {\n return native.redactSecrets(value).redacted as unknown as T;\n }\n if (Array.isArray(value)) {\n return value.map((v) => redactJsonStrings(v)) as unknown as T;\n }\n if (value !== null && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = redactJsonStrings(v);\n }\n return out as unknown as T;\n }\n return value;\n}\n","/**\n * Standalone judge-response signature verification.\n *\n * `Atbash.judgeAction` already verifies the response signature inline when\n * `verifyPubKey` is set. This wrapper exposes the same check for use\n * outside of `judgeAction` — webhook receivers, stored response replay,\n * test fixtures — preserving the legacy SDK's `{ ok, reason }` contract.\n *\n * Validation (hex format, length bounds, secp256k1 verify) happens in\n * the Rust core via `native.verifySignature`, so all language bindings\n * agree byte-for-byte on what counts as a valid signature.\n */\nimport { native } from \"./native.js\";\n\nexport function verifyJudgeResponseSignature(\n bodyBytes: Uint8Array,\n signatureHex: string | null,\n pubKeyHex: string,\n): { ok: boolean; reason?: string } {\n if (!signatureHex) {\n return { ok: false, reason: \"missing X-Atbash-Signature header\" };\n }\n\n const body = Buffer.isBuffer(bodyBytes) ? bodyBytes : Buffer.from(bodyBytes);\n\n let isValid: boolean;\n try {\n isValid = native.verifySignature(body, signatureHex, pubKeyHex);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err ?? \"\");\n // Rust core throws on malformed inputs (non-hex, wrong length, etc.).\n // Surface that distinct from \"well-formed but doesn't verify\" so callers\n // can log differently if they want.\n if (\n message.includes(\"signature is not hex\") ||\n message.includes(\"signature length out of range\")\n ) {\n return { ok: false, reason: \"malformed signature header\" };\n }\n return { ok: false, reason: `signature verification threw: ${message}` };\n }\n\n return isValid\n ? { ok: true }\n : {\n ok: false,\n reason: \"signature does not verify against configured verifyPubKey\",\n };\n}\n"],"mappings":"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","names":["require","import_node_fs","import_node_os","import_node_path","import_node_fs","import_node_os","import_node_path"]}
1
+ {"version":3,"sources":["../src-ts/index.ts","../src-ts/native.ts","../src-ts/random.ts","../src-ts/constants.ts","../src-ts/chain-config.ts","../src-ts/endpoint.ts","../src-ts/errors.ts","../src-ts/http/client.ts","../src-ts/keyLoader.ts","../src-ts/normalize.ts","../src-ts/opentel/telemetry.ts","../src-ts/userConfig.ts","../src-ts/client.ts","../src-ts/redact.ts","../src-ts/signature.ts"],"sourcesContent":["/**\n * Atbash SDK for Node.js — public surface.\n *\n * Crypto / redaction / memory primitives are re-exported from the NAPI-bound\n * Rust core as plain functions; the HTTP-facing surface (`judgeAction`,\n * `logToolCall`, `get*`) lives on the `Atbash` class.\n */\nimport { native } from \"./native.js\";\nimport type {\n AgentAuth,\n KeyPair,\n MemoryDiffResult,\n MemoryEntry,\n MemorySnapshot,\n RedactResult,\n} from \"./types.js\";\n\nexport { Atbash } from \"./client.js\";\nexport {\n DEFAULT_BLOCKCHAIN_RID,\n DEFAULT_CHROMIA_NODE_URLS,\n DEFAULT_ENDPOINT,\n} from \"./constants.js\";\nexport { AtbashAPIError, SignatureVerificationError } from \"./errors.js\";\nexport {\n normalizeVerdict,\n normalizeStatus,\n pubkeyToHex,\n} from \"./normalize.js\";\nexport type * from \"./types.js\";\n\n// config loading (file/env resolution, endpoint validation, key file)\nexport {\n type AtbashUserConfig,\n getConfigDir,\n getConfigPath,\n loadUserConfig,\n saveUserConfig,\n resolve,\n} from \"./userConfig.js\";\nexport {\n type JudgeEndpointConfig,\n type ValidatedEndpoint,\n validateJudgeEndpoint,\n} from \"./endpoint.js\";\nexport { resolveKeyPath, loadAgentFromFile } from \"./keyLoader.js\";\nexport { redactJsonStrings, type SecretKind } from \"./redact.js\";\nexport { verifyJudgeResponseSignature } from \"./signature.js\";\nexport {\n flushTelemetry,\n recordCall,\n recordDuration,\n setupTelemetry,\n shutdownTelemetry,\n type ClientSource,\n type TelemetryConfig,\n} from \"./opentel/telemetry.js\";\n\n/* ── crypto / redaction / memory primitives (Rust core) ────────────────── */\n\nexport function isValidPrivateKey(hex: string): boolean {\n return native.isValidPrivateKey(hex);\n}\n\nexport function derivePublicKey(privkey: string): string {\n return native.derivePublicKey(privkey);\n}\n\nexport function generateKeypair(): KeyPair {\n return native.generateKeypair();\n}\n\nexport function loadAgent(privkey: string): AgentAuth {\n return native.loadAgent(privkey);\n}\n\nexport function signLogToolCall(\n toolCallId: string,\n action: string,\n context: string,\n toolName: string,\n toolArgsJson: string,\n privkey: string,\n blockchainRid: string,\n): string {\n return native.signLogToolCall(\n toolCallId,\n action,\n context,\n toolName,\n toolArgsJson,\n privkey,\n blockchainRid,\n );\n}\n\nexport function signJudgeAction(\n judgmentId: string,\n action: string,\n context: string,\n extra: string,\n privkey: string,\n blockchainRid: string,\n): string {\n return native.signJudgeAction(\n judgmentId,\n action,\n context,\n extra,\n privkey,\n blockchainRid,\n );\n}\n\nexport function verifySignature(\n body: Buffer,\n signatureHex: string,\n pubkeyHex: string,\n): boolean {\n return native.verifySignature(body, signatureHex, pubkeyHex);\n}\n\nexport function normalizeForMatching(text: string): string {\n return native.normalizeForMatching(text);\n}\n\nexport function containsEvasionCharacters(text: string): boolean {\n return native.containsEvasionCharacters(text);\n}\n\nexport function redactSecrets(text: string): RedactResult {\n return native.redactSecrets(text);\n}\n\nexport function containsSecret(text: string): boolean {\n return native.containsSecret(text);\n}\n\nexport function createMemorySnapshot(\n entries: MemoryEntry[],\n takenAt: number,\n): MemorySnapshot {\n return native.createMemorySnapshot(entries, takenAt);\n}\n\nexport function diffMemorySnapshots(\n before: MemorySnapshot,\n after: MemorySnapshot,\n): MemoryDiffResult {\n return native.diffMemorySnapshots(before, after);\n}\n","/**\n * Typed loader for the NAPI-RS native addon.\n *\n * The addon's platform-resolution glue is generated at the package root as\n * CommonJS (`../index.js`, see `napi build`). We load it once here via\n * `createRequire` so the rest of the surface gets a typed handle. tsup keeps\n * `../index.js` out of the bundle (see tsup.config.ts) so the require survives\n * to runtime, resolving relative to the compiled file in `dist/`.\n */\nimport { createRequire } from \"node:module\";\n\nimport type {\n AgentAuth,\n KeyPair,\n MemoryDiffResult,\n MemoryEntry,\n MemorySnapshot,\n RedactResult,\n} from \"./types.js\";\n\n/** Shape of the NAPI-RS addon (mirrors index.d.ts, typed against our structs). */\nexport interface NativeBindings {\n isValidPrivateKey(s: string): boolean;\n derivePublicKey(s: string): string;\n generateKeypair(): KeyPair;\n loadAgent(privkey: string): AgentAuth;\n signLogToolCall(\n toolCallId: string,\n action: string,\n context: string,\n toolName: string,\n toolArgsJson: string,\n privkey: string,\n blockchainRid: string,\n ): string;\n signJudgeAction(\n judgmentId: string,\n action: string,\n context: string,\n extra: string,\n privkey: string,\n blockchainRid: string,\n ): string;\n verifySignature(\n body: Buffer,\n signatureHex: string,\n pubkeyHex: string,\n ): boolean;\n normalizeForMatching(s: string): string;\n containsEvasionCharacters(s: string): boolean;\n redactSecrets(s: string): RedactResult;\n containsSecret(s: string): boolean;\n createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;\n diffMemorySnapshots(\n before: MemorySnapshot,\n after: MemorySnapshot,\n ): MemoryDiffResult;\n DEFAULT_BLOCKCHAIN_RID: string;\n DEFAULT_PRIVATE_BLOCKCHAIN_RID: string;\n DEFAULT_ENDPOINT: string;\n HONEYCOMB_KEY: string;\n defaultChromiaNodeUrls(): string[];\n defaultPrivateNodeUrls(): string[];\n}\n\n// tsup emits both ESM (dist/index.mjs) and CJS (dist/index.js). In the CJS\n// bundle `import.meta.url` is empty but Node provides `__filename`; in the ESM\n// bundle it's the reverse. Pick whichever anchor exists so `createRequire`\n// resolves `../index.js` relative to the compiled file in `dist/`.\ndeclare const __filename: string | undefined;\nconst anchor = typeof __filename !== \"undefined\" ? __filename : import.meta.url;\nconst require = createRequire(anchor);\nexport const native: NativeBindings = require(\"../index.js\") as NativeBindings;\n","/**\n * Universal random helpers backed by the Web Crypto API — available on\n * Node ≥18 and every modern browser. Avoids importing `node:crypto` so the\n * same source compiles for both the Node and browser bundles.\n */\n\nexport function randomBytes(size: number): Uint8Array {\n const buf = new Uint8Array(size);\n globalThis.crypto.getRandomValues(buf);\n return buf;\n}\n\nexport function randomHex(size: number): string {\n const buf = randomBytes(size);\n let hex = \"\";\n for (let i = 0; i < buf.length; i++) {\n hex += buf[i].toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n","/**\n * Public wire constants — all sourced from the Rust core so every\n * language binding agrees byte-for-byte. To switch dev ↔ prod, edit\n * `core/src/constants.rs` and rebuild the native binding; no edits\n * here are needed.\n */\nimport { native } from \"./native.js\";\n\nexport const DEFAULT_ENDPOINT: string = native.DEFAULT_ENDPOINT;\n\nexport const DEFAULT_CHROMIA_NODE_URLS: readonly string[] = Object.freeze(\n native.defaultChromiaNodeUrls(),\n);\n\nexport const DEFAULT_BLOCKCHAIN_RID: string = native.DEFAULT_BLOCKCHAIN_RID;\n","/**\n * Internal chain-config plumbing. Maps the `Network` selector type to the\n * known public / private chains. Not part of the public SDK surface — the\n * consumer-facing API is `Network` + `ChainOpts`. This file is consumed\n * internally by the chain resolver and the HTTP client.\n *\n * BRIDs come from the Rust core via NAPI so all language bindings agree\n * byte-for-byte; node URLs are wire constants that live alongside them.\n */\nimport {\n DEFAULT_BLOCKCHAIN_RID,\n DEFAULT_CHROMIA_NODE_URLS,\n} from \"./constants.js\";\nimport { native } from \"./native.js\";\nimport type { Network } from \"./types.js\";\n\nconst DEFAULT_PRIVATE_NODE_URLS: readonly string[] = Object.freeze(\n native.defaultPrivateNodeUrls(),\n);\n\nconst DEFAULT_PRIVATE_BLOCKCHAIN_RID: string =\n native.DEFAULT_PRIVATE_BLOCKCHAIN_RID;\n\nexport interface ChainConfig {\n readonly network: Network;\n readonly blockchainRid: string;\n readonly nodeUrls: readonly string[];\n}\n\nexport const PUBLIC_CHAIN: ChainConfig = {\n network: \"public\",\n blockchainRid: DEFAULT_BLOCKCHAIN_RID,\n nodeUrls: DEFAULT_CHROMIA_NODE_URLS,\n};\n\nexport const PRIVATE_CHAIN: ChainConfig = {\n network: \"private\",\n blockchainRid: DEFAULT_PRIVATE_BLOCKCHAIN_RID,\n nodeUrls: DEFAULT_PRIVATE_NODE_URLS,\n};\n\nexport function chainForNetwork(network: Network): ChainConfig {\n return network === \"private\" ? PRIVATE_CHAIN : PUBLIC_CHAIN;\n}\n","/**\n * Judge endpoint validation. Rejects anything that could silently redirect\n * verdicts: non-https, embedded credentials, or hosts outside the trusted\n * allowlist. A self-hosted judge is allowed only when it also supplies a\n * response-signing pubkey so the SDK can detect a compromised judge.\n */\nimport { DEFAULT_ENDPOINT } from \"./constants.js\";\n\nexport type JudgeEndpointConfig =\n | { policy?: \"default\"; endpoint?: string }\n | { policy: \"self-hosted\"; endpoint: string; verifyPubKey: string };\n\nexport interface ValidatedEndpoint {\n url: string;\n policy: \"default\" | \"self-hosted\";\n verifyPubKey: string | null;\n}\n\nconst ALLOWED_JUDGE_HOSTS: ReadonlySet<string> = new Set([\n \"atbash.ai\",\n \"www.atbash.ai\",\n \"chromia-verified-ai-dev-two.vercel.app\",\n]);\n\nexport function validateJudgeEndpoint(\n judge?: JudgeEndpointConfig,\n): ValidatedEndpoint {\n const policy: \"default\" | \"self-hosted\" =\n judge?.policy === \"self-hosted\" ? \"self-hosted\" : \"default\";\n const candidate = judge?.endpoint?.trim() || DEFAULT_ENDPOINT;\n\n let parsed: URL;\n try {\n parsed = new URL(candidate);\n } catch {\n throw new Error(\n `[atbash] invalid judge endpoint URL: ${candidate}. ` +\n `Refusing to load — fix the URL or omit it to use the default (${DEFAULT_ENDPOINT}).`,\n );\n }\n\n if (parsed.protocol !== \"https:\") {\n throw new Error(\n `[atbash] judge endpoint must use https:// (got \"${parsed.protocol}\"). ` +\n `Refusing to load — plaintext endpoints leak verdicts and enable trivial MITM bypass.`,\n );\n }\n\n if (parsed.username || parsed.password) {\n throw new Error(\n `[atbash] judge endpoint must not contain credentials (user:pass@host). ` +\n `Refusing to load — credentials embedded in URLs leak to logs and process listings.`,\n );\n }\n\n const normalisedUrl = parsed.origin;\n\n if (policy === \"self-hosted\") {\n const verifyPubKey = (judge as { verifyPubKey?: string } | undefined)\n ?.verifyPubKey;\n const key = verifyPubKey?.trim().toLowerCase();\n if (!key || !/^[0-9a-f]{66}$/.test(key)) {\n throw new Error(\n `[atbash] judge endpoint policy \"self-hosted\" requires verifyPubKey ` +\n `to be a 66-hex-char compressed secp256k1 pubkey. Refusing to load — ` +\n `self-hosted judges must produce signed responses so the SDK can ` +\n `detect a malicious or compromised judge.`,\n );\n }\n return { url: normalisedUrl, policy, verifyPubKey: key };\n }\n\n if (!ALLOWED_JUDGE_HOSTS.has(parsed.hostname.toLowerCase())) {\n throw new Error(\n `[atbash] judge endpoint hostname \"${parsed.hostname}\" is not in the trusted allowlist. ` +\n `Allowed: ${[...ALLOWED_JUDGE_HOSTS].join(\", \")}. ` +\n `To use a self-hosted judge, set BOTH policy=\"self-hosted\" AND verifyPubKey ` +\n `to the 66-hex pubkey of your judge's response-signing key. ` +\n `Refusing to load — silent endpoint redirection is a known attack vector (F-003).`,\n );\n }\n\n return { url: normalisedUrl, policy, verifyPubKey: null };\n}\n","/**\n * SDK exceptions.\n *\n * `AtbashAPIError` is thrown for any non-2xx HTTP response from the judge or\n * risk-engine API. It surfaces the raw body in `Error.message` and appends\n * dashboard-aware hints for the common operational failure modes.\n */\nimport { DEFAULT_ENDPOINT } from \"./constants.js\";\n\nexport class AtbashAPIError extends Error {\n /** HTTP status code (or 0 if the request never completed). */\n readonly status: number;\n /** Raw response body text (may be empty). */\n readonly body: string;\n\n constructor(\n status: number,\n body: string,\n statusText = \"\",\n endpoint: string = DEFAULT_ENDPOINT,\n ) {\n super(enrich(status, body, statusText, endpoint));\n this.name = \"AtbashAPIError\";\n this.status = status;\n this.body = body;\n }\n}\n\nexport class SignatureVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SignatureVerificationError\";\n }\n}\n\n/** Append dashboard-aware hints for common operational failure modes. */\nfunction enrich(\n status: number,\n body: string,\n statusText: string,\n endpoint: string,\n): string {\n const dashboard = endpoint.replace(/\\/+$/, \"\") || DEFAULT_ENDPOINT;\n let msg = `API error ${status}: ${body || statusText}`;\n const lowered = body.toLowerCase();\n if (lowered.includes(\"agent not registered\")) {\n msg += `\\n → Onboard the agent at ${dashboard}/risk-engine/agents`;\n } else if (\n lowered.includes(\"agent has no policy\") ||\n lowered.includes(\"no policy configured\")\n ) {\n msg += `\\n → Attach a policy at ${dashboard}/risk-engine/agents`;\n } else if (\n lowered.includes(\"agent is jailed\") ||\n lowered.includes(\"jailed\")\n ) {\n msg += `\\n → Unjail the agent at ${dashboard}/risk-engine/agents`;\n } else if (\n lowered.includes(\"audit tier\") ||\n lowered.includes(\"verdict disabled\") ||\n lowered.includes(\"verdict not supported\")\n ) {\n msg += `\\n → Upgrade the org tier at ${dashboard}/risk-engine/settings`;\n } else if (status >= 400 && status < 500) {\n msg += `\\n → Dashboard: ${dashboard}/risk-engine/feed`;\n }\n return msg;\n}\n","/**\n * Thin typed fetch wrapper.\n *\n * openapi-typescript emits types only (no runtime client), so this is the\n * single hand-written transport — generic `get`/`post` over global `fetch`\n * with a per-request timeout. The endpoint-specific request/response *shapes*\n * are pulled from the generated `schema.ts` at the call sites in client.ts, so\n * the wire contract still lives in spec/openapi.yaml. Methods return the raw\n * `Response` so the caller can read the exact bytes the server signed before\n * any decode (judge signature verification) — mirroring the Python surface's\n * use of raw httpx (DECISIONS 2026-05-22).\n */\nexport type QueryValue = string | number | boolean | undefined | null;\n\nexport class HttpClient {\n readonly baseUrl: string;\n readonly timeoutMs: number;\n\n constructor(baseUrl: string, timeoutMs: number) {\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n this.timeoutMs = timeoutMs;\n }\n\n buildUrl(path: string, query?: Record<string, QueryValue>): string {\n const url = new URL(this.baseUrl + path);\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null && v !== \"\") {\n url.searchParams.set(k, String(v));\n }\n }\n }\n return url.toString();\n }\n\n async get(\n path: string,\n query?: Record<string, QueryValue>,\n headers?: Record<string, string>,\n ): Promise<Response> {\n return this.fetch(this.buildUrl(path, query), {\n method: \"GET\",\n ...(headers && { headers }),\n });\n }\n\n async post(\n path: string,\n body: unknown,\n headers?: Record<string, string>,\n ): Promise<Response> {\n return this.fetch(this.buildUrl(path), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify(body),\n });\n }\n\n private async fetch(url: string, init: RequestInit): Promise<Response> {\n return fetch(url, { ...init, signal: AbortSignal.timeout(this.timeoutMs) });\n }\n}\n","/**\n * Agent key file loading. The key file lives at\n * `~/.config/atbash/guard-client-key` by default and is either JSON\n * (`{ privKey, pubKey }`) or `key=value` lines (`privkey=…`, `pubkey=…`).\n * Only the private key is needed — the pubkey is re-derived by the Rust core\n * via `loadAgent`.\n */\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { native } from \"./native.js\";\nimport type { AgentAuth } from \"./types.js\";\n\nconst DEFAULT_KEY_PATH_REL = \".config/atbash/guard-client-key\";\n\nexport function resolveKeyPath(input?: string): string {\n if (input) return expandHome(input);\n const home = process.env.HOME || homedir() || \"\";\n return join(home, DEFAULT_KEY_PATH_REL);\n}\n\nfunction expandHome(p: string): string {\n if (!p.startsWith(\"~/\")) return p;\n const home = process.env.HOME || homedir() || \"\";\n return join(home, p.slice(2));\n}\n\nfunction readKeyFile(keyPath: string): { privKey: string; pubKey: string } {\n const content = String(readFileSync(keyPath, \"utf8\") || \"\").trim();\n let privKey = \"\";\n let pubKey = \"\";\n\n if (content.startsWith(\"{\")) {\n const creds = JSON.parse(content);\n privKey = String(\n creds.privKey || creds.privkey || creds.privateKey || \"\",\n ).trim();\n pubKey = String(\n creds.pubKey || creds.pubkey || creds.publicKey || \"\",\n ).trim();\n } else {\n for (const line of content.split(/\\r?\\n/)) {\n if (line.startsWith(\"privkey=\"))\n privKey = line.slice(\"privkey=\".length).trim();\n if (line.startsWith(\"pubkey=\"))\n pubKey = line.slice(\"pubkey=\".length).trim();\n }\n }\n\n if (!privKey || !pubKey) {\n throw new Error(`atbash key file missing priv/pub key fields: ${keyPath}`);\n }\n\n privKey = privKey.replace(/^0x/, \"\");\n return { privKey, pubKey };\n}\n\nexport function loadAgentFromFile(keyPath?: string): AgentAuth {\n const resolved = resolveKeyPath(keyPath);\n const { privKey } = readKeyFile(resolved);\n return native.loadAgent(privKey);\n}\n","/** Normalize wire shapes (verdict casing, status, pubkey) to canonical forms. */\nimport type { JudgmentState, Verdict } from \"./types.js\";\n\nexport function normalizeVerdict(raw: unknown): Verdict {\n if (raw === null || raw === undefined) return \"No verdict\";\n const v = String(raw).toUpperCase();\n if (v === \"ALLOW\" || v === \"GREEN\") return \"ALLOW\";\n if (v === \"HOLD\" || v === \"YELLOW\") return \"HOLD\";\n if (v === \"BLOCK\" || v === \"RED\") return \"BLOCK\";\n return \"HOLD\";\n}\n\nexport function normalizeStatus(raw: unknown): JudgmentState {\n const s = String(raw ?? \"\").toLowerCase();\n if (s === \"pending\" || s === \"answered\" || s === \"error\") return s;\n return \"error\";\n}\n\n/** Wire pubkey may be a hex string, a Buffer/Uint8Array, or `{ data: [...] }`. */\nexport function pubkeyToHex(val: unknown): string {\n if (!val) return \"\";\n if (typeof val === \"string\") return val;\n if (val instanceof Uint8Array) return Buffer.from(val).toString(\"hex\");\n if (typeof val === \"object\") {\n const data = (val as { data?: unknown }).data;\n if (Array.isArray(data)) return Buffer.from(data).toString(\"hex\");\n }\n return \"\";\n}\n","/**\n * Atbash SDK Telemetry — OpenTelemetry metrics for usage tracking.\n *\n * Tracks: function call counts, latency, source (CLI/plugin/SDK),\n * and agent identity. ON by default.\n *\n * Opt-out: create ~/.config/atbash/telemetry.json with { \"enabled\": false }\n * The file must be readable by the SDK process. If missing, corrupted, or\n * unreadable → telemetry stays ON. Environment variables cannot disable\n * telemetry (prevents agent bypass via env-var injection).\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { Counter, Histogram } from \"@opentelemetry/api\";\nimport { OTLPMetricExporter } from \"@opentelemetry/exporter-metrics-otlp-http\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport {\n MeterProvider,\n PeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\nimport { native } from \"../native.js\";\n\n// ── Types ───────────────────────────────────────────────────────\n\nexport type ClientSource =\n | \"cli\"\n | \"sdk\"\n | \"plugin:openclaw\"\n | \"plugin:langchain\"\n | \"plugin:langgraph\"\n | \"plugin:hermes\"\n | \"plugin:eliza\"\n | \"plugin:crewai\"\n | \"plugin:mcp\"\n | \"plugin:autogen\"\n | \"plugin:jeenai\"\n | (string & {});\n\nexport interface TelemetryConfig {\n /** Must be true to send any telemetry. Default: false */\n enabled: boolean;\n /** Where calls originate */\n source?: ClientSource;\n /** Flush interval in ms. Default: 60000 */\n exportIntervalMs?: number;\n}\n\n// ── State (module-level so recordCall/recordDuration can access) ─\n\nlet meterProvider: MeterProvider | null = null;\nlet callCounter: Counter | null = null;\nlet durationHistogram: Histogram | null = null;\nlet defaultSource: ClientSource = \"sdk\";\n\n// ── Setup ───────────────────────────────────────────────────────\n\n/**\n * Check if telemetry is disabled via the protected config file.\n * Only ~/.config/atbash/telemetry.json with { \"enabled\": false } disables it.\n * Missing, corrupted, or unreadable file → telemetry stays ON.\n */\nfunction isTelemetryOptedOut(): boolean {\n try {\n const home = process.env.HOME || homedir() || \"\";\n const filePath = join(home, \".config\", \"atbash\", \"telemetry.json\");\n const raw = readFileSync(filePath, \"utf-8\").trim();\n if (!raw) return false;\n const config = JSON.parse(raw) as { enabled?: boolean };\n return config.enabled === false;\n } catch {\n return false; // missing/corrupted/unreadable → telemetry ON\n }\n}\n\n/**\n * Auto-initialize telemetry on first recordCall if not already set up.\n * Reads opt-out from the protected config file, not from environment\n * variables (env vars are too easy for an attacker-controlled agent to\n * clear).\n */\nfunction autoInit(): void {\n if (meterProvider) return;\n if (isTelemetryOptedOut()) return;\n setupTelemetry({ enabled: true });\n}\n\nexport function setupTelemetry(config: TelemetryConfig): void {\n if (!config.enabled) return;\n if (meterProvider) return; // already initialized\n if (isTelemetryOptedOut()) return; // protected file opt-out\n\n defaultSource = config.source ?? \"sdk\";\n\n // Built-in Atbash ingest key comes from the Rust core (feature-gated by\n // --features prod at build time). Safe to embed — the key only writes\n // metrics, cannot read or delete them. Empty in dev flavor → telemetry\n // silently no-ops. Runtime env var can still override for debugging.\n const apiKey = process.env.HONEYCOMB_API_KEY ?? native.HONEYCOMB_KEY;\n if (!apiKey) return; // dev flavor with no override → skip setup entirely\n\n const exporter = new OTLPMetricExporter({\n url: \"https://api.honeycomb.io/v1/metrics\",\n headers: {\n \"x-honeycomb-team\": apiKey,\n },\n });\n\n const reader = new PeriodicExportingMetricReader({\n exporter,\n exportIntervalMillis: config.exportIntervalMs ?? 60_000,\n });\n\n meterProvider = new MeterProvider({\n resource: resourceFromAttributes({\n \"service.name\": \"atbash-sdk\",\n }),\n readers: [reader],\n });\n\n const meter = meterProvider.getMeter(\"atbash-sdk\");\n\n callCounter = meter.createCounter(\"atbash.sdk.function.calls\", {\n description: \"Number of SDK function calls\",\n });\n\n durationHistogram = meter.createHistogram(\"atbash.sdk.function.duration_ms\", {\n description: \"SDK function execution duration\",\n unit: \"ms\",\n });\n}\n\n// ── Recording ───────────────────────────────────────────────────\n\n/**\n * Record a function call. Call at the START of each tracked function.\n * Safe to call even if telemetry is disabled — does nothing.\n */\nexport function recordCall(\n functionName: string,\n source?: ClientSource,\n agentPubkey?: string,\n): void {\n autoInit();\n if (!callCounter) return;\n\n callCounter.add(1, {\n \"function.name\": functionName,\n source: source ?? defaultSource,\n ...(agentPubkey && { \"agent.pubkey\": agentPubkey }),\n });\n}\n\n/**\n * Record function duration. Call at the END of each tracked function.\n * Safe to call even if telemetry is disabled — does nothing.\n */\nexport function recordDuration(\n functionName: string,\n durationMs: number,\n status: \"success\" | \"error\",\n source?: ClientSource,\n): void {\n if (!durationHistogram) return;\n\n durationHistogram.record(durationMs, {\n \"function.name\": functionName,\n status: status,\n source: source ?? defaultSource,\n });\n}\n\n// ── Shutdown ────────────────────────────────────────────────────\n\n/**\n * Force-flush pending metrics without shutting down.\n * Use in short-lived processes (CLI) to ensure data is sent.\n */\nexport async function flushTelemetry(): Promise<void> {\n if (!meterProvider) return;\n await meterProvider.forceFlush();\n}\n\n/**\n * Flush pending metrics and shut down. Call before process exits.\n */\nexport async function shutdownTelemetry(): Promise<void> {\n if (!meterProvider) return;\n await meterProvider.shutdown();\n meterProvider = null;\n callCounter = null;\n durationHistogram = null;\n}\n","/**\n * User config file + env resolution. Config lives at\n * `~/.config/atbash/config.json`. `resolve` reads a single field with\n * precedence: explicit flag → env var → config file → \"\".\n */\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface AtbashUserConfig {\n agentKey?: string;\n orgName?: string;\n judgeEndpoint?: string;\n blockchainRid?: string;\n provider?: string;\n providerModel?: string;\n}\n\nconst ENV_MAP: Record<keyof AtbashUserConfig, string> = {\n agentKey: \"ATBASH_AGENT_KEY\",\n orgName: \"ATBASH_ORG_NAME\",\n judgeEndpoint: \"ATBASH_ENDPOINT\",\n blockchainRid: \"ATBASH_BLOCKCHAIN_RID\",\n provider: \"ATBASH_PROVIDER\",\n providerModel: \"ATBASH_PROVIDER_MODEL\",\n};\n\nexport function getConfigDir(): string {\n const home = process.env.HOME || homedir() || \"\";\n return join(home, \".config\", \"atbash\");\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.json\");\n}\n\nexport function loadUserConfig(): AtbashUserConfig {\n try {\n const p = getConfigPath();\n if (!existsSync(p)) return {};\n const raw = readFileSync(p, \"utf-8\").trim();\n if (!raw) return {};\n return JSON.parse(raw) as AtbashUserConfig;\n } catch (err) {\n console.error(\"Failed to load config file\", err);\n return {};\n }\n}\n\nexport function saveUserConfig(config: AtbashUserConfig): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n const filePath = getConfigPath();\n writeFileSync(filePath, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n chmodSync(filePath, 0o600);\n}\n\nexport function resolve(\n key: keyof AtbashUserConfig,\n flagValue?: string,\n): string {\n if (flagValue) return flagValue;\n const envName = ENV_MAP[key];\n if (envName) {\n const envVal = process.env[envName];\n if (envVal) return envVal;\n }\n const fileVal = loadUserConfig()[key];\n if (fileVal != null) return String(fileVal);\n return \"\";\n}\n","/**\n * `Atbash` — the Node SDK client. Composes the Rust core (signing, identity,\n * redaction; via NAPI) with the judge / risk-engine HTTP surface.\n *\n * For `/api/risk-engine` we parse the raw JSON ourselves: that endpoint is\n * RPC-style with `?action=`, and the spec encodes its response as a single\n * `oneOf` — generator dispatch is dict-ambiguous (TierInfo vs ToolCallFull).\n * Each method knows the action it called and casts deterministically.\n */\nimport { randomHex } from \"./random.js\";\n\nimport {\n PRIVATE_CHAIN,\n PUBLIC_CHAIN,\n type ChainConfig,\n} from \"./chain-config.js\";\nimport { DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT } from \"./constants.js\";\nimport { validateJudgeEndpoint } from \"./endpoint.js\";\nimport { AtbashAPIError, SignatureVerificationError } from \"./errors.js\";\nimport { HttpClient, type QueryValue } from \"./http/client.js\";\nimport type { components } from \"./http/schema.js\";\nimport { loadAgentFromFile } from \"./keyLoader.js\";\nimport { native } from \"./native.js\";\nimport { normalizeStatus, normalizeVerdict, pubkeyToHex } from \"./normalize.js\";\nimport { recordCall, recordDuration } from \"./opentel/telemetry.js\";\nimport { resolve } from \"./userConfig.js\";\nimport type {\n AgentAuth,\n AgentPolicy,\n AtbashLogger,\n AtbashOptions,\n ChainOpts,\n Decision,\n FromConfigOptions,\n HeldAction,\n HeldActionReview,\n JudgeOptions,\n JudgeResult,\n JudgmentStatus,\n KeyPair,\n LogToolCallOptions,\n LogToolCallResult,\n Network,\n OrgSubscription,\n RedactResult,\n TierInfo,\n ToolCallFull,\n ToolCallInput,\n ToolCallRecord,\n} from \"./types.js\";\n\ntype JudgeRequestWire = components[\"schemas\"][\"JudgeRequest\"];\n\n/** `tc-<unix_ms>-<8 hex chars>`. */\nfunction generateToolCallId(): string {\n return `tc-${Date.now()}-${randomHex(4)}`;\n}\n\nexport class Atbash {\n readonly auth: AgentAuth;\n readonly endpoint: string;\n readonly nodeUrls: readonly string[];\n readonly blockchainRid: string;\n /** Default org name used by `auditToolCall` / `judgeAction`. */\n readonly orgName?: string;\n /** Default judge response-signing pubkey, if configured (see fromConfig). */\n readonly verifyPubKey?: string;\n /** When true (default), `auditToolCall` denies on any error. */\n readonly failClosed: boolean;\n private readonly logger: AtbashLogger;\n private readonly http: HttpClient;\n /**\n * Per-client cache of resolved chains. Keyed by orgName so repeated\n * calls don't re-hit the dashboard. Cleared by `clearChainCache()`.\n */\n private readonly _chainCache = new Map<string, ChainConfig>();\n /**\n * Cached bearer token for risk-engine / insurance read calls. Built\n * lazily as a signed `log_tool_call` tx and refreshed every 4 min so\n * server-side replay protection windows never expire it mid-session.\n */\n private _authBearer: { hex: string; issuedAt: number } | null = null;\n\n constructor(privkey: string, options: AtbashOptions = {}) {\n this.auth = native.loadAgent(privkey);\n this.endpoint =\n (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\\/+$/, \"\") ||\n DEFAULT_ENDPOINT;\n this.nodeUrls = options.nodeUrls\n ? [...options.nodeUrls]\n : DEFAULT_CHROMIA_NODE_URLS;\n this.blockchainRid = options.blockchainRid ?? native.DEFAULT_BLOCKCHAIN_RID;\n this.orgName = options.orgName;\n this.verifyPubKey = options.verifyPubKey;\n this.failClosed = options.failClosed !== false;\n this.logger = options.logger ?? {};\n this.http = new HttpClient(this.endpoint, options.timeoutMs ?? 30_000);\n\n if (this.endpoint !== DEFAULT_ENDPOINT) {\n this.logger.warn?.(\"[atbash] running on non-default judge endpoint\", {\n endpoint: this.endpoint,\n verifying: this.verifyPubKey\n ? \"with response-signature pubkey configured\"\n : \"without signature verification\",\n });\n }\n }\n\n /**\n * Construct from resolved config: explicit overrides → env vars → the\n * `~/.config/atbash/config.json` file (see userConfig.resolve). The private\n * key comes from `agentKey` (override/env/file) or, failing that, the agent\n * key file (`~/.config/atbash/guard-client-key`). The judge endpoint is\n * validated against the trusted allowlist / self-hosted policy; a\n * self-hosted endpoint's `verifyPubKey` becomes the client default.\n */\n static fromConfig(options: FromConfigOptions = {}): Atbash {\n const validated = validateJudgeEndpoint(\n options.judge ?? { endpoint: resolve(\"judgeEndpoint\") || undefined },\n );\n\n const agentKey = resolve(\"agentKey\", options.agentKey);\n const auth: AgentAuth = agentKey\n ? native.loadAgent(agentKey)\n : loadAgentFromFile(options.keyPath);\n\n const blockchainRid =\n resolve(\"blockchainRid\", options.blockchainRid) || undefined;\n\n return new Atbash(auth.privkey, {\n endpoint: validated.url,\n blockchainRid,\n timeoutMs: options.timeoutMs,\n nodeUrls: options.nodeUrls,\n orgName: options.orgName,\n verifyPubKey: validated.verifyPubKey ?? undefined,\n failClosed: options.failClosed,\n logger: options.logger,\n });\n }\n\n get pubkey(): string {\n return this.auth.pubkey;\n }\n\n get privkey(): string {\n return this.auth.privkey;\n }\n\n /* ── agent existence (/api/ai/exists) ──────────────────────────────────── */\n\n /** GET /api/ai/exists?pubkey=… — defaults to this client's pubkey. */\n async checkAgentExists(pubkey?: string): Promise<boolean> {\n const pk = pubkey ?? this.auth.pubkey;\n return this.track(\"checkAgentExists\", pk, async () => {\n const resp = await this.http.get(\n \"/api/ai/exists\",\n { pubkey: pk },\n this.authHeaders(),\n );\n await this.raiseIfError(resp);\n const data = (await this.json(resp)) as { registered?: unknown } | null;\n return Boolean(data?.registered);\n });\n }\n\n /* ── log_tool_call (sign-only) ─────────────────────────────────────────── */\n\n /**\n * Pre-flight `checkAgentExists`, then sign `log_tool_call` locally and\n * return the signed tx hex. The server broadcasts to chain.\n */\n async logToolCall(\n action: string,\n context = \"\",\n options: LogToolCallOptions = {},\n ): Promise<LogToolCallResult> {\n const start = performance.now();\n recordCall(\"logToolCall\", undefined, this.auth.pubkey);\n\n let exists: boolean;\n try {\n exists = await this.checkAgentExists();\n } catch (err) {\n recordDuration(\"logToolCall\", performance.now() - start, \"error\");\n return { success: false, toolCallId: null, error: errorMessage(err) };\n }\n if (!exists) {\n recordDuration(\"logToolCall\", performance.now() - start, \"error\");\n return {\n success: false,\n toolCallId: null,\n error:\n \"Agent not registered. Onboard the agent at the dashboard before \" +\n \"submitting actions.\",\n };\n }\n\n const toolCallId = generateToolCallId();\n const brid = options.chainOpts?.blockchainRid ?? this.blockchainRid;\n try {\n const signedHex = native.signLogToolCall(\n toolCallId,\n action,\n context,\n options.toolName ?? \"\",\n options.toolArgsJson ?? \"\",\n this.auth.privkey,\n brid,\n );\n recordDuration(\"logToolCall\", performance.now() - start, \"success\");\n return { success: true, toolCallId, signedHex };\n } catch (err) {\n recordDuration(\"logToolCall\", performance.now() - start, \"error\");\n return { success: false, toolCallId: null, error: errorMessage(err) };\n }\n }\n\n /* ── judge_action ──────────────────────────────────────────────────────── */\n\n /**\n * Sign log_tool_call + optionally judge_action, POST /api/v1/judge.\n *\n * `verifyPubKey` checks the `X-Atbash-Signature` header against the exact\n * response bytes via the Rust core's `verifySignature`.\n */\n async judgeAction(\n action: string,\n context = \"\",\n options: JudgeOptions = {},\n ): Promise<JudgeResult> {\n return this.track(\"judgeAction\", this.auth.pubkey, () =>\n this._judgeAction(action, context, options),\n );\n }\n\n private async _judgeAction(\n action: string,\n context: string,\n options: JudgeOptions,\n ): Promise<JudgeResult> {\n if (!action?.trim()) {\n throw new Error(\"action is required and cannot be empty.\");\n }\n\n // Resolve chain when orgName is provided. Order:\n // 1. org_networks map (authoritative post-upgrade — wins over any\n // stale BRID hint on chainOpts).\n // 2. Caller-pinned chainOpts.blockchainRid (no map entry).\n // 3. Per-chain subscription resolution (no map, no pin).\n let chainOpts: ChainOpts | undefined = options.chainOpts;\n if (options.orgName) {\n const mapNetwork = await this.getActiveNetworkForOrg(options.orgName);\n if (mapNetwork) {\n chainOpts = { network: mapNetwork };\n } else if (!chainOpts?.blockchainRid) {\n // No map entry — hand the fetched result (null) to the fallback\n // resolver so it doesn't re-hit /api/org-network for the same org.\n const resolved = await this.resolveChainFromMap(options.orgName, null);\n chainOpts = { ...chainOpts, network: resolved.network };\n }\n }\n const brid = this.bridFromChainOpts(chainOpts);\n\n const logResult = await this.logToolCall(action, context, {\n toolName: options.toolName,\n toolArgsJson: options.toolArgsJson,\n chainOpts,\n });\n if (!logResult.success || !logResult.toolCallId || !logResult.signedHex) {\n throw new Error(logResult.error || \"Failed to sign log_tool_call\");\n }\n\n let signedJudgeAction: string | undefined;\n if (!options.provider) {\n const judgmentId = generateToolCallId();\n signedJudgeAction = native.signJudgeAction(\n judgmentId,\n action,\n context || \"\",\n \"\",\n this.auth.privkey,\n brid,\n );\n }\n\n const body: JudgeRequestWire = {\n tool_call_id: logResult.toolCallId,\n agent_pubkey: this.auth.pubkey,\n action,\n signed_log_tool_call: logResult.signedHex,\n };\n if (signedJudgeAction) body.signed_judge_action = signedJudgeAction;\n if (context) body.context = context;\n if (options.provider) body.provider = options.provider;\n if (options.toolName) body.tool_name = options.toolName;\n if (options.model) body.model = options.model;\n\n let resp: Response;\n try {\n resp = await this.http.post(\"/api/v1/judge\", body);\n } catch (err) {\n throw this.transportError(err);\n }\n if (!resp.ok) throw await this.httpError(resp);\n\n // Read the raw bytes before any decode so signature verification runs\n // against exactly what the server signed.\n const bodyBytes = Buffer.from(await resp.arrayBuffer());\n const verifyPubKey = options.verifyPubKey ?? this.verifyPubKey;\n if (verifyPubKey !== undefined) {\n const sig = resp.headers.get(\"X-Atbash-Signature\");\n if (!sig) {\n throw new SignatureVerificationError(\n \"missing X-Atbash-Signature header\",\n );\n }\n let ok: boolean;\n try {\n ok = native.verifySignature(bodyBytes, sig, verifyPubKey);\n } catch (err) {\n throw new SignatureVerificationError(\n `signature verification threw: ${errorMessage(err)}`,\n );\n }\n if (!ok) {\n throw new SignatureVerificationError(\n \"signature does not verify against configured verifyPubKey\",\n );\n }\n }\n\n const data = parseJson(bodyBytes) as Record<string, unknown>;\n return {\n verdict: normalizeVerdict(data.verdict),\n actionType: String(data.action_type ?? \"\"),\n reason: String(data.reason ?? \"\"),\n confidence: Number(data.confidence ?? 0),\n provider: String(data.provider ?? \"\"),\n latencyMs: Number(data.latency_ms ?? 0),\n toolCallId: String(data.tool_call_id ?? logResult.toolCallId),\n onChain: Boolean(data.on_chain),\n enforced: Boolean(data.enforced),\n enforcementMode: String(data.enforcement_mode ?? \"\"),\n };\n }\n\n /* ── audit_tool_call (redact → judge → decision) ───────────────────────── */\n\n /**\n * High-level guard: redact secrets, submit for judgement, and collapse the\n * result into an allow/deny `Decision`. Fails closed by default — any error\n * (judge unreachable, unrecognized verdict) denies unless `failClosed` is\n * explicitly false.\n */\n async auditToolCall(input: ToolCallInput): Promise<Decision> {\n const toolName = input.toolName || \"unknown\";\n\n // Redact secret-shaped values BEFORE signing so they never reach the\n // signed bytes, the request body, the on-chain log, or the LLM prompt.\n const argsRedaction = native.redactSecrets(stringifyArgs(input.args));\n const ctxRedaction = native.redactSecrets(input.context ?? toolName);\n const argsJson = argsRedaction.redacted;\n const actionText = truncate(argsJson);\n const contextText = ctxRedaction.redacted;\n const totalRedactions =\n argsRedaction.found.length + ctxRedaction.found.length;\n if (totalRedactions > 0) {\n const kinds = [\n ...new Set([\n ...argsRedaction.found.map((f) => f.kind),\n ...ctxRedaction.found.map((f) => f.kind),\n ]),\n ];\n this.logger.warn?.(\"[atbash] redacted secrets before judge call\", {\n tool: toolName,\n count: totalRedactions,\n kinds,\n });\n }\n\n try {\n this.logger.info?.(\"[atbash] judge API called\", { tool: toolName });\n const result = await this.judgeAction(actionText, contextText, {\n toolName,\n toolArgsJson: argsJson,\n orgName: this.orgName,\n });\n\n // AUDIT tier — server returns no verdict (log only, no AI enforcement).\n if (result.verdict === \"No verdict\") {\n return {\n allow: true,\n verdict: \"ALLOW\",\n reason:\n result.reason ||\n \"audit tier — request logged on-chain, no AI enforcement\",\n toolCallId: result.toolCallId,\n };\n }\n\n const action = result.actionType;\n if (action === \"block\") {\n return {\n allow: false,\n verdict: \"BLOCK\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n if (action === \"hold_for_user_confirm\") {\n return {\n allow: false,\n verdict: \"HOLD\",\n reason: result.reason || \"held for human confirmation\",\n toolCallId: result.toolCallId,\n };\n }\n if (action === \"allow\") {\n // If verdict conflicts with action_type (server confusion), respect the\n // more restrictive signal rather than blindly allowing.\n if (result.verdict === \"HOLD\") {\n return {\n allow: false,\n verdict: \"HOLD\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n if (result.verdict === \"BLOCK\") {\n return {\n allow: false,\n verdict: \"BLOCK\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n return {\n allow: true,\n verdict: \"ALLOW\",\n reason: result.reason,\n toolCallId: result.toolCallId,\n };\n }\n\n return this.fail(\n \"unrecognized action_type from judge\",\n result.toolCallId,\n );\n } catch (err) {\n const message = errorMessage(err);\n this.logger.warn?.(\"[atbash] judge API failed\", { reason: message });\n return this.fail(message);\n }\n }\n\n private fail(reason: string, toolCallId?: string): Decision {\n return { allow: !this.failClosed, verdict: \"ERROR\", reason, toolCallId };\n }\n\n /* ── judgment status ───────────────────────────────────────────────────── */\n\n async getJudgmentStatus(\n judgmentId: string,\n agentPubkey?: string,\n ): Promise<JudgmentStatus> {\n const pk = agentPubkey ?? this.auth.pubkey;\n return this.track(\"getJudgmentStatus\", pk, async () => {\n const resp = await this.http.get(\n \"/api/v1/judge\",\n { tool_call_id: judgmentId, agent_pubkey: pk },\n this.authHeaders(),\n );\n await this.raiseIfError(resp);\n const data = ((await this.json(resp)) ?? {}) as Record<string, unknown>;\n return {\n status: normalizeStatus(data.status),\n verdict: normalizeVerdict(data.verdict),\n reason: String(data.reason ?? \"\"),\n judgmentId: String(data.judgmentId ?? judgmentId),\n onChain: optBool(data.onChain),\n cached: optBool(data.cached),\n responseTimeMs: optNumber(data.responseTimeMs),\n };\n });\n }\n\n /* ── risk-engine queries (action-dispatched GET) ───────────────────────── */\n\n getToolCalls(maxCount: number): Promise<ToolCallRecord[]> {\n return this.track(\"getToolCalls\", undefined, () =>\n this.riskEngineRecords(\"tool-calls\", { limit: maxCount }),\n );\n }\n\n getOrgToolCalls(\n orgName: string,\n maxCount: number,\n ): Promise<ToolCallRecord[]> {\n return this.track(\"getOrgToolCalls\", undefined, () =>\n this.riskEngineRecords(\"org-tool-calls\", {\n org: orgName,\n limit: maxCount,\n }),\n );\n }\n\n getAgentToolCalls(\n agentPubkey: string,\n maxCount: number,\n ): Promise<ToolCallRecord[]> {\n return this.track(\"getAgentToolCalls\", agentPubkey, () =>\n this.riskEngineRecords(\"agent-tool-calls\", {\n agent: agentPubkey,\n limit: maxCount,\n }),\n );\n }\n\n async getToolCallCount(): Promise<number> {\n return this.track(\"getToolCallCount\", undefined, async () => {\n const raw = await this.riskEngineGet(\"tool-call-count\", {});\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n });\n }\n\n async getToolCallFull(toolCallId: string): Promise<ToolCallFull | null> {\n return this.track(\"getToolCallFull\", undefined, async () => {\n const raw = await this.riskEngineGet(\"tool-call-full\", {\n tool_call_id: toolCallId,\n });\n if (!isRecord(raw)) return null;\n return toToolCallFull(raw);\n });\n }\n\n async getOrgTierInfo(orgName: string): Promise<TierInfo | null> {\n return this.track(\"getOrgTierInfo\", undefined, async () => {\n const raw = await this.riskEngineGet(\"org-tier-info\", { org: orgName });\n if (!isRecord(raw)) return null;\n return {\n orgName: String(raw.org_name ?? \"\"),\n tier: String(raw.tier ?? \"\"),\n verdictEnabled: Boolean(raw.verdict_enabled),\n enforcementEnabled: Boolean(raw.enforcement_enabled),\n };\n });\n }\n\n async getPendingHeldActions(\n orgName: string,\n maxCount: number,\n ): Promise<HeldAction[]> {\n return this.track(\"getPendingHeldActions\", undefined, async () => {\n const raw = await this.riskEngineGet(\"pending-held-actions\", {\n org: orgName,\n limit: maxCount,\n });\n if (!Array.isArray(raw)) return [];\n return raw.map((item) => toHeldAction(item as Record<string, unknown>));\n });\n }\n\n async getHeldActionReviews(\n orgName: string,\n maxCount: number,\n ): Promise<HeldActionReview[]> {\n return this.track(\"getHeldActionReviews\", undefined, async () => {\n const raw = await this.riskEngineGet(\"held-action-reviews\", {\n org: orgName,\n limit: maxCount,\n });\n if (!Array.isArray(raw)) return [];\n return raw.map((item) =>\n toHeldActionReview(item as Record<string, unknown>),\n );\n });\n }\n\n /* ── risk-engine batched (action-dispatched POST) ──────────────────────── */\n\n getAgentDetail(agentPubkey: string): Promise<Record<string, unknown>> {\n return this.track(\"getAgentDetail\", agentPubkey, () =>\n this.riskEnginePost({ action: \"agent-detail-batch\", agent: agentPubkey }),\n );\n }\n\n async getAgentPolicy(agentPubkey: string): Promise<AgentPolicy> {\n return this.track(\"getAgentPolicy\", agentPubkey, async () => {\n const raw = await this.riskEnginePost({\n action: \"agent-policy-batch\",\n agent: agentPubkey,\n });\n return {\n policy: String(raw.policy ?? \"\"),\n isJailed: Boolean(raw.is_jailed),\n isCustom: Boolean(raw.is_custom),\n defaultPolicy: String(raw.default_policy ?? \"\"),\n };\n });\n }\n\n /* ── safety stats (/api/insurance?action=safety-stats) ─────────────────── */\n\n async getSafetyStats(): Promise<Record<string, unknown>> {\n return this.track(\"getSafetyStats\", undefined, async () => {\n const resp = await this.http.get(\n \"/api/insurance\",\n { action: \"safety-stats\" },\n this.authHeaders(),\n );\n await this.raiseIfError(resp);\n const data = ((await this.json(resp)) ?? {}) as Record<string, unknown>;\n // TS unwraps `.data` when present.\n if (isRecord(data.data)) return data.data;\n return data;\n });\n }\n\n /* ── chain resolution (org → chain) ────────────────────────────────────── */\n\n /**\n * Org's subscription on a specific chain. The `network` arg selects\n * which chain to query; without it, the dashboard picks the default.\n * Returns null when the org has no record on that chain.\n */\n async getOrgSubscription(\n orgName: string,\n network?: Network,\n ): Promise<OrgSubscription | null> {\n return this.track(\"getOrgSubscription\", undefined, async () => {\n const params: Record<string, QueryValue> = { org: orgName };\n if (network) params.network = network;\n const raw = await this.riskEngineGet(\"org-subscription\", params);\n if (!isRecord(raw)) return null;\n return coerceOrgSubscription(raw, orgName);\n });\n }\n\n /**\n * Read the org's active network from the dashboard's off-chain\n * `org_networks` map. The map is the authoritative source after a\n * plan switch — subscription rows on the source chain go stale, but\n * the map is updated on every assign. Returns null when there's no\n * entry (caller falls back to per-chain subscription resolution).\n */\n async getActiveNetworkForOrg(orgName: string): Promise<Network | null> {\n try {\n const resp = await this.http.get(\n \"/api/org-network\",\n { org: orgName },\n this.authHeaders(),\n );\n if (resp.status !== 200) return null;\n const data = (await this.json(resp)) as {\n network?: string | null;\n } | null;\n if (data?.network === \"public\" || data?.network === \"private\") {\n return data.network;\n }\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * Resolve which chain an org's actions should run against. Cached\n * per-client by orgName. Resolution order:\n * 1. `org_networks` map (authoritative).\n * 2. Per-chain subscription fallback — public + private records\n * are fetched in parallel, with `is_private_blockchain` and\n * `assigned_at` reconciling mixed states.\n * Defaults to the public chain when nothing else resolves.\n */\n async resolveChainForOrg(orgName: string): Promise<ChainConfig> {\n const cached = this._chainCache.get(orgName);\n if (cached) return cached;\n const mapNetwork = await this.getActiveNetworkForOrg(orgName);\n return this.resolveChainFromMap(orgName, mapNetwork);\n }\n\n /**\n * Resolve a chain given an already-fetched `org_networks` map result.\n * Split out from {@link resolveChainForOrg} so callers that have already\n * queried the map (the judge path) don't fetch /api/org-network twice.\n * Caches per orgName like its caller.\n */\n private async resolveChainFromMap(\n orgName: string,\n mapNetwork: Network | null,\n ): Promise<ChainConfig> {\n const cached = this._chainCache.get(orgName);\n if (cached) return cached;\n\n if (mapNetwork) {\n const chain = mapNetwork === \"private\" ? PRIVATE_CHAIN : PUBLIC_CHAIN;\n this._chainCache.set(orgName, chain);\n return chain;\n }\n\n // Fallback: both subscription rows can exist after a plan switch\n // because `admin_assign_subscription` writes only to the destination\n // chain. Reconcile with `is_private_blockchain` + `assigned_at`.\n try {\n const [pubSub, privSub] = await Promise.all([\n this.getOrgSubscription(orgName, \"public\").catch(() => null),\n this.getOrgSubscription(orgName, \"private\").catch(() => null),\n ]);\n\n if (pubSub?.is_private_blockchain) {\n this._chainCache.set(orgName, PRIVATE_CHAIN);\n return PRIVATE_CHAIN;\n }\n if (pubSub && privSub) {\n const chain =\n privSub.assigned_at > pubSub.assigned_at\n ? PRIVATE_CHAIN\n : PUBLIC_CHAIN;\n this._chainCache.set(orgName, chain);\n return chain;\n }\n if (pubSub) {\n this._chainCache.set(orgName, PUBLIC_CHAIN);\n return PUBLIC_CHAIN;\n }\n if (privSub?.is_private_blockchain) {\n this._chainCache.set(orgName, PRIVATE_CHAIN);\n return PRIVATE_CHAIN;\n }\n } catch {\n // Fall through to public default if subscription lookup fails.\n }\n this._chainCache.set(orgName, PUBLIC_CHAIN);\n return PUBLIC_CHAIN;\n }\n\n /** Drop any cached chain resolutions. Useful in tests. */\n clearChainCache(): void {\n this._chainCache.clear();\n }\n\n /* ── internals ─────────────────────────────────────────────────────────── */\n\n /**\n * Wrap an SDK method body in telemetry — records the call at start\n * and a success/error duration at end. Re-throws on failure so the\n * caller sees the original exception. Pass `agentPubkey` when the\n * method is keyed to a specific agent; tracked methods that don't\n * depend on an agent (read queries) pass `undefined`.\n */\n private async track<T>(\n name: string,\n agentPubkey: string | undefined,\n fn: () => Promise<T>,\n ): Promise<T> {\n const start = performance.now();\n recordCall(name, undefined, agentPubkey);\n try {\n const result = await fn();\n recordDuration(name, performance.now() - start, \"success\");\n return result;\n } catch (err) {\n recordDuration(name, performance.now() - start, \"error\");\n throw err;\n }\n }\n\n /**\n * Pick the BRID for a given per-call chain override. `blockchainRid`\n * takes precedence; otherwise `network` maps to one of the known\n * chains; otherwise the client's default.\n */\n private bridFromChainOpts(chainOpts?: ChainOpts): string {\n if (chainOpts?.blockchainRid) return chainOpts.blockchainRid;\n if (chainOpts?.network === \"private\") return PRIVATE_CHAIN.blockchainRid;\n if (chainOpts?.network === \"public\") return PUBLIC_CHAIN.blockchainRid;\n return this.blockchainRid;\n }\n\n /**\n * Get-or-create a Bearer token for dashboard reads. The token is a\n * signed `log_tool_call` op (locally signed, never submitted) — the\n * dashboard verifies the signature against the agent's pubkey. Cached\n * for 4 minutes; refreshed after that so a long-lived client never\n * trips the server's replay window.\n */\n private getAuthBearer(): string {\n const now = Date.now();\n if (this._authBearer && now - this._authBearer.issuedAt < 4 * 60 * 1000) {\n return this._authBearer.hex;\n }\n const nonce = `auth-${now.toString(36)}-${randomHex(4)}`;\n const hex = native.signLogToolCall(\n nonce,\n `auth:${now}`,\n \"\",\n \"auth-bearer\",\n \"\",\n this.auth.privkey,\n this.blockchainRid,\n );\n this._authBearer = { hex, issuedAt: now };\n return hex;\n }\n\n private authHeaders(): Record<string, string> {\n return { Authorization: `Bearer ${this.getAuthBearer()}` };\n }\n\n private async riskEngineGet(\n action: string,\n params: Record<string, QueryValue>,\n ): Promise<unknown> {\n let resp: Response;\n try {\n resp = await this.http.get(\n \"/api/risk-engine\",\n { action, ...params },\n this.authHeaders(),\n );\n } catch (err) {\n throw this.transportError(err);\n }\n if (resp.status !== 200) throw await this.httpError(resp);\n return this.json(resp);\n }\n\n private async riskEnginePost(\n body: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n let resp: Response;\n try {\n resp = await this.http.post(\"/api/risk-engine\", body, this.authHeaders());\n } catch (err) {\n throw this.transportError(err);\n }\n if (resp.status !== 200) throw await this.httpError(resp);\n const data = await this.json(resp);\n return isRecord(data) ? data : {};\n }\n\n private async riskEngineRecords(\n action: string,\n params: Record<string, QueryValue>,\n ): Promise<ToolCallRecord[]> {\n const raw = await this.riskEngineGet(action, params);\n if (!Array.isArray(raw)) return [];\n return raw.map((item) => toToolCallRecord(item as Record<string, unknown>));\n }\n\n private async raiseIfError(resp: Response): Promise<void> {\n if (resp.ok) return;\n throw await this.httpError(resp);\n }\n\n /** Wrap a failed HTTP *response* (non-2xx / non-200) as an AtbashAPIError. */\n private async httpError(resp: Response): Promise<AtbashAPIError> {\n return new AtbashAPIError(\n resp.status,\n await safeText(resp),\n resp.statusText,\n this.endpoint,\n );\n }\n\n /** Wrap a *transport* failure (fetch threw, no response) as an AtbashAPIError. */\n private transportError(err: unknown): AtbashAPIError {\n return new AtbashAPIError(0, errorMessage(err), \"\", this.endpoint);\n }\n\n private async json(resp: Response): Promise<unknown> {\n const text = await safeText(resp);\n if (!text) return null;\n const parsed = tryParseJson(text);\n return parsed === undefined ? null : parsed;\n }\n\n /* ── crypto / redaction passthroughs (Rust core) ───────────────────────── */\n\n static generateKeypair(): KeyPair {\n return native.generateKeypair();\n }\n\n static isValidPrivateKey(hex: string): boolean {\n return native.isValidPrivateKey(hex);\n }\n\n static derivePublicKey(privkey: string): string {\n return native.derivePublicKey(privkey);\n }\n\n static redactSecrets(text: string): RedactResult {\n return native.redactSecrets(text);\n }\n\n static normalizeForMatching(text: string): string {\n return native.normalizeForMatching(text);\n }\n\n static containsEvasionCharacters(text: string): boolean {\n return native.containsEvasionCharacters(text);\n }\n}\n\n/* ── record converters ─────────────────────────────────────────────────── */\n\n/** Fields shared by ToolCallRecord and ToolCallFull. */\nfunction baseToolCall(raw: Record<string, unknown>) {\n return {\n toolCallId: String(raw.tool_call_id ?? \"\"),\n agentPubkey: pubkeyToHex(raw.agent_pubkey),\n toolName: String(raw.tool_name ?? \"\"),\n commandText: String(raw.command_text ?? \"\"),\n contextText: String(raw.context_text ?? \"\"),\n orgName: String(raw.org_name ?? \"\"),\n };\n}\n\nfunction toToolCallRecord(raw: Record<string, unknown>): ToolCallRecord {\n return {\n ...baseToolCall(raw),\n toolArgsJson: String(raw.tool_args_json ?? \"\"),\n rowid: Number(raw.rowid ?? 0),\n };\n}\n\nfunction toToolCallFull(raw: Record<string, unknown>): ToolCallFull {\n return {\n ...baseToolCall(raw),\n toolArgsJson: optString(raw.tool_args_json),\n createdAt: optNumber(raw.created_at),\n actionType: optString(raw.action_type),\n resultStatus: optString(raw.result_status),\n verdictColor: optString(raw.verdict_color),\n verdictReason: optString(raw.verdict_reason),\n verdictSource: optString(raw.verdict_source),\n verdictResponseTimeMs: optNumber(raw.verdict_response_time_ms),\n };\n}\n\nfunction toHeldAction(raw: Record<string, unknown>): HeldAction {\n return {\n judgmentId: String(raw.judgment_id ?? \"\"),\n agentPubkey: pubkeyToHex(raw.agent_pubkey),\n actionText: String(raw.action_text ?? \"\"),\n actionContext: String(raw.action_context ?? \"\"),\n verdict: normalizeVerdict(raw.verdict),\n reason: String(raw.reason ?? \"\"),\n createdAt: Number(raw.created_at ?? 0),\n };\n}\n\nfunction toHeldActionReview(raw: Record<string, unknown>): HeldActionReview {\n return {\n judgmentId: String(raw.judgment_id ?? \"\"),\n actionText: String(raw.action_text ?? \"\"),\n status: String(raw.status ?? \"\"),\n reviewNote: String(raw.review_note ?? \"\"),\n reviewedAt: Number(raw.reviewed_at ?? 0),\n createdAt: Number(raw.created_at ?? 0),\n reviewedBy:\n optString(raw.reviewed_by) || pubkeyToHex(raw.reviewed_by) || undefined,\n };\n}\n\nfunction coerceOrgSubscription(\n raw: Record<string, unknown>,\n orgName: string,\n): OrgSubscription {\n return {\n org_name: String(raw.org_name ?? orgName),\n subscription_name: String(raw.subscription_name ?? \"\"),\n agent_number: Number(raw.agent_number ?? 0),\n is_private_blockchain: Boolean(raw.is_private_blockchain),\n monthly_price: Number(raw.monthly_price ?? 0),\n yearly_price: Number(raw.yearly_price ?? 0),\n duration_months: Number(raw.duration_months ?? 0),\n assigned_at: Number(raw.assigned_at ?? 0),\n expires_at: Number(raw.expires_at ?? 0),\n is_active: Boolean(raw.is_active),\n };\n}\n\n/* ── small helpers ─────────────────────────────────────────────────────── */\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction optString(v: unknown): string | undefined {\n if (v === null || v === undefined) return undefined;\n return typeof v === \"string\" ? v : String(v);\n}\n\nfunction optNumber(v: unknown): number | undefined {\n if (v === null || v === undefined) return undefined;\n const n = Number(v);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction optBool(v: unknown): boolean | undefined {\n if (v === null || v === undefined) return undefined;\n return Boolean(v);\n}\n\n/** Parse JSON, returning `undefined` (not throwing) on malformed input. */\nfunction tryParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction parseJson(bytes: Buffer): unknown {\n const parsed = tryParseJson(bytes.toString(\"utf-8\"));\n return parsed === undefined ? {} : parsed;\n}\n\nasync function safeText(resp: Response): Promise<string> {\n try {\n return await resp.text();\n } catch {\n return \"\";\n }\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction stringifyArgs(args: unknown): string {\n if (args === null || args === undefined) return \"\";\n if (typeof args === \"string\") return args;\n try {\n return JSON.stringify(args);\n } catch {\n return String(args);\n }\n}\n\nconst MAX_ACTION_LEN = 4000;\nfunction truncate(text: string): string {\n if (text.length <= MAX_ACTION_LEN) return text;\n return text.slice(0, MAX_ACTION_LEN) + \"…\";\n}\n","/**\n * TS-side helpers that compose the Rust core's `redactSecrets`. The core\n * handles single-string redaction; recursive / JSON-aware shapes belong\n * up here so the FFI surface stays minimal.\n */\nimport { native } from \"./native.js\";\n\n/**\n * Canonical secret kinds reported by the Rust core in `SecretMatch.kind`.\n * Wire is permissive (modelled as a free string in {@link SecretMatch})\n * so unknown kinds don't break callers; use this union when narrowing.\n */\nexport type SecretKind =\n | \"anthropic\"\n | \"openai\"\n | \"openai_project\"\n | \"github\"\n | \"google\"\n | \"google_oauth\"\n | \"aws_access_key\"\n | \"aws_secret_key\"\n | \"stripe\"\n | \"slack\"\n | \"slack_webhook\"\n | \"sendgrid\"\n | \"twilio_sid\"\n | \"mailgun\"\n | \"npm_token\"\n | \"jwt\"\n | \"private_key_pem\"\n | \"context_secret\"\n | \"bearer\"\n | \"base64\"\n | \"generic_token\";\n\n/**\n * Walk a JSON-shaped value and redact secrets inside every string leaf.\n * Object keys are not touched; only values. Arrays and nested objects\n * are recursed structurally so the returned value has the same shape.\n */\nexport function redactJsonStrings<T>(value: T): T {\n if (typeof value === \"string\") {\n return native.redactSecrets(value).redacted as unknown as T;\n }\n if (Array.isArray(value)) {\n return value.map((v) => redactJsonStrings(v)) as unknown as T;\n }\n if (value !== null && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = redactJsonStrings(v);\n }\n return out as unknown as T;\n }\n return value;\n}\n","/**\n * Standalone judge-response signature verification.\n *\n * `Atbash.judgeAction` already verifies the response signature inline when\n * `verifyPubKey` is set. This wrapper exposes the same check for use\n * outside of `judgeAction` — webhook receivers, stored response replay,\n * test fixtures — preserving the legacy SDK's `{ ok, reason }` contract.\n *\n * Validation (hex format, length bounds, secp256k1 verify) happens in\n * the Rust core via `native.verifySignature`, so all language bindings\n * agree byte-for-byte on what counts as a valid signature.\n */\nimport { native } from \"./native.js\";\n\nexport function verifyJudgeResponseSignature(\n bodyBytes: Uint8Array,\n signatureHex: string | null,\n pubKeyHex: string,\n): { ok: boolean; reason?: string } {\n if (!signatureHex) {\n return { ok: false, reason: \"missing X-Atbash-Signature header\" };\n }\n\n const body = Buffer.isBuffer(bodyBytes) ? bodyBytes : Buffer.from(bodyBytes);\n\n let isValid: boolean;\n try {\n isValid = native.verifySignature(body, signatureHex, pubKeyHex);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err ?? \"\");\n // Rust core throws on malformed inputs (non-hex, wrong length, etc.).\n // Surface that distinct from \"well-formed but doesn't verify\" so callers\n // can log differently if they want.\n if (\n message.includes(\"signature is not hex\") ||\n message.includes(\"signature length out of range\")\n ) {\n return { ok: false, reason: \"malformed signature header\" };\n }\n return { ok: false, reason: `signature verification threw: ${message}` };\n }\n\n return isValid\n ? { ok: true }\n : {\n ok: false,\n reason: \"signature does not verify against configured verifyPubKey\",\n };\n}\n"],"mappings":"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","names":["require","import_node_fs","import_node_os","import_node_path","import_node_fs","import_node_os","import_node_path"]}
package/dist/index.mjs CHANGED
@@ -275,8 +275,8 @@ function setupTelemetry(config) {
275
275
  if (meterProvider) return;
276
276
  if (isTelemetryOptedOut()) return;
277
277
  defaultSource = config.source ?? "sdk";
278
- const ATBASH_HONEYCOMB_KEY = "YOUR_INGEST_KEY_HERE";
279
- const apiKey = process.env.HONEYCOMB_API_KEY ?? ATBASH_HONEYCOMB_KEY;
278
+ const apiKey = process.env.HONEYCOMB_API_KEY ?? native.HONEYCOMB_KEY;
279
+ if (!apiKey) return;
280
280
  const exporter = new OTLPMetricExporter({
281
281
  url: "https://api.honeycomb.io/v1/metrics",
282
282
  headers: {