{"_id":"@attest-protocol/attest-ts","_rev":"2-d4f76a3aeb5f69a02a7e6e7219278ac5","name":"@attest-protocol/attest-ts","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@attest-protocol/attest-ts","version":"0.1.0","author":{"name":"Otto Jongerius"},"license":"Apache-2.0","_id":"@attest-protocol/attest-ts@0.1.0","maintainers":[{"name":"ojongerius","email":"otto.jongerius@gmail.com"}],"dist":{"shasum":"779ca142bec17a19716de5caec57e5a0315e6877","tarball":"https://registry.npmjs.org/@attest-protocol/attest-ts/-/attest-ts-0.1.0.tgz","fileCount":63,"integrity":"sha512-1hcIJ18nXQMSx2ScLaX7FhgeowZtUt4dX+Q19xUS0+TBpmqAv5wdBVCGYLttiV7jF9vvfCmyAaP21y2YbqiUjA==","signatures":[{"sig":"MEYCIQClEOxJdmRvi3W1Ya9PYu0YlsZ90I0bsraDct2Sd97rLAIhAMUP5zivLj7IVCI+wzN+EAdxIN0vKoBBbrLZvYGI91Rt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":66091},"pnpm":{"onlyBuiltDependencies":["lefthook"]},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./store":{"types":"./dist/store/index.d.ts","default":"./dist/store/index.js"},"./receipt":{"types":"./dist/receipt/index.d.ts","default":"./dist/receipt/index.js"},"./taxonomy":{"types":"./dist/taxonomy/index.d.ts","default":"./dist/taxonomy/index.js"}},"gitHead":"a910ea62628d9f4a0957bd523bec3aaed1b29ca6","scripts":{"lint":"biome check .","test":"vitest run","build":"tsc","check":"pnpm run typecheck && pnpm run lint","lint:fix":"biome check --write .","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"ojongerius","email":"otto.jongerius@gmail.com"},"_npmVersion":"11.9.0","description":"TypeScript SDK for the Action Receipts protocol","directories":{},"_nodeVersion":"25.6.1","_hasShrinkwrap":false,"packageManager":"pnpm@10.33.0","devDependencies":{"vitest":"^4.1.2","lefthook":"^2.1.4","typescript":"^6.0.2","@types/node":"^25.5.0","@biomejs/biome":"^2.4.9"},"_npmOperationalInternal":{"tmp":"tmp/attest-ts_0.1.0_1774900684762_0.7542942807911788","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@attest-protocol/attest-ts","version":"0.2.0","description":"TypeScript SDK for the Action Receipts protocol","license":"Apache-2.0","author":{"name":"Otto Jongerius"},"repository":{"type":"git","url":"git+https://github.com/attest-protocol/attest-ts.git"},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./receipt":{"types":"./dist/receipt/index.d.ts","default":"./dist/receipt/index.js"},"./store":{"types":"./dist/store/index.d.ts","default":"./dist/store/index.js"},"./taxonomy":{"types":"./dist/taxonomy/index.d.ts","default":"./dist/taxonomy/index.js"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","lint":"biome check .","lint:fix":"biome check --write .","check":"pnpm run typecheck && pnpm run lint","test":"vitest run","test:watch":"vitest"},"pnpm":{"onlyBuiltDependencies":["lefthook"]},"packageManager":"pnpm@10.33.0","devDependencies":{"@biomejs/biome":"^2.4.9","@types/node":"^25.5.0","lefthook":"^2.1.4","typescript":"^6.0.2","vitest":"^4.1.2"},"gitHead":"656277587168ef28be6b8f0b2d5c68670ce33512","_id":"@attest-protocol/attest-ts@0.2.0","bugs":{"url":"https://github.com/attest-protocol/attest-ts/issues"},"homepage":"https://github.com/attest-protocol/attest-ts#readme","_nodeVersion":"22.22.1","_npmVersion":"11.12.1","dist":{"integrity":"sha512-+dWA//wQqqBlqwSEDrynp9YNnHzoxg9SfimxDxGxmwt/bHNTyZNGx5mZRnZaJPcVLkvFq/wbothzzKfirAqHgg==","shasum":"b458810963c9433ef4e677c26f6381b553c92488","tarball":"https://registry.npmjs.org/@attest-protocol/attest-ts/-/attest-ts-0.2.0.tgz","fileCount":63,"unpackedSize":70198,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attest-protocol%2fattest-ts@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD0DKjcsKKfi/Z4NPPMXuEaYGqkI9bDvjZnVvhtWjXlegIhAN1JkoYHj9fdXT0zqyBb7OEGWJb7C09EO80r2UVUR23G"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c2fd4b1e-a859-442a-b832-fedc41912662"}},"directories":{},"maintainers":[{"name":"ojongerius","email":"otto.jongerius@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/attest-ts_0.2.0_1775026396793_0.19255325517258903"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-30T19:58:04.698Z","modified":"2026-04-01T06:53:17.197Z","0.1.0":"2026-03-30T19:58:04.901Z","0.2.0":"2026-04-01T06:53:16.917Z"},"author":{"name":"Otto Jongerius"},"license":"Apache-2.0","description":"TypeScript SDK for the Action Receipts protocol","maintainers":[{"name":"ojongerius","email":"otto.jongerius@gmail.com"}],"readme":"<div align=\"center\">\n\n# @attest-protocol/attest-ts\n\n### TypeScript SDK for the Action Receipts protocol\n\n[![npm](https://img.shields.io/npm/v/@attest-protocol/attest-ts)](https://www.npmjs.com/package/@attest-protocol/attest-ts)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-ESM-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![Node.js](https://img.shields.io/badge/Node.js-22+-339933?logo=node.js&logoColor=white)](https://nodejs.org/)\n\n---\n\nCreate, sign, hash-chain, store, and verify cryptographically signed audit trails for AI agent actions.\n\nZero runtime dependencies — uses only `node:crypto` and `node:sqlite`.\n\n[Spec](https://github.com/attest-protocol/spec) &bull; [Reference Implementation](https://github.com/ojongerius/attest) &bull; [npm](https://www.npmjs.com/package/@attest-protocol/attest-ts)\n\n</div>\n\n---\n\n## Why receipts?\n\nAI agents that read files, run commands, and browse the web are powerful — but that power needs accountability. When an agent operates autonomously, you need to know exactly what it did, prove that the record hasn't been tampered with, and keep sensitive details private.\n\n**Use cases:**\n\n- **Post-incident review** — an agent ran overnight and something broke. The receipt chain shows exactly which actions it took, in what order, and whether each succeeded or failed — with cryptographic proof the log hasn't been altered after the fact.\n- **Compliance and audit** — regulated environments require evidence of what systems did and why. Receipts are W3C Verifiable Credentials with Ed25519 signatures, giving auditors a tamper-evident trail they can independently verify.\n- **Safer autonomous agents** — agents can query their own audit trail mid-session. Before taking a high-risk action, they can check what they've already done and whether previous steps succeeded, enabling self-correcting workflows.\n- **Multi-agent trust** — when agents collaborate, receipts serve as proof of prior actions. Agent B can verify that Agent A actually completed step 1 before proceeding to step 2, without trusting a shared log.\n- **Usage tracking** — every action is classified by type and risk level, giving you a structured breakdown of what agents spent their time on.\n\n### Beyond local storage\n\nToday, this SDK stores receipts locally in SQLite — fully under your control. The [Attest Protocol](https://github.com/attest-protocol/spec) is designed for receipts to travel further when you choose: publishing to a shared ledger, forwarding to a compliance system, or exchanging between agents as proof of prior actions. The receipts are portable W3C Verifiable Credentials, but where they go is always your decision.\n\n## Install\n\n```sh\nnpm install @attest-protocol/attest-ts\n```\n\n## Quick start\n\n### Create and sign a receipt\n\n```typescript\nimport {\n  createReceipt,\n  generateKeyPair,\n  hashReceipt,\n  signReceipt,\n} from \"@attest-protocol/attest-ts\";\n\n// Generate an Ed25519 key pair\nconst keys = generateKeyPair();\n\n// Create an unsigned receipt\nconst unsigned = createReceipt({\n  issuer: { id: \"did:agent:my-agent\" },\n  principal: { id: \"did:user:alice\" },\n  action: {\n    type: \"filesystem.file.read\",\n    risk_level: \"low\",\n    target: { system: \"local\", resource: \"/docs/report.md\" },\n  },\n  outcome: { status: \"success\" },\n  chain: {\n    sequence: 1,\n    previous_receipt_hash: null,\n    chain_id: \"chain_session-1\",\n  },\n});\n\n// Sign and hash\nconst receipt = signReceipt(unsigned, keys.privateKey, \"did:agent:my-agent#key-1\");\nconst hash = hashReceipt(receipt);\n```\n\n### Store and query\n\n```typescript\nimport { openStore } from \"@attest-protocol/attest-ts\";\n\nconst store = openStore(\"receipts.db\");\nstore.insert(receipt, hash);\n\n// Query by chain\nconst chain = store.getChain(\"chain_session-1\");\n\n// Query with filters\nconst highRisk = store.query({ riskLevel: \"high\", status: \"success\" });\n\n// Summary statistics\nconst stats = store.stats();\n\nstore.close();\n```\n\n### Verify a chain\n\n```typescript\nimport { verifyChain, verifyStoredChain } from \"@attest-protocol/attest-ts\";\n\n// Verify an array of receipts\nconst result = verifyChain(receipts, publicKey);\nconsole.log(result.valid);          // true if all signatures and hash links check out\nconsole.log(result.length);         // number of receipts verified\n\n// Or verify directly from the store\nconst storeResult = verifyStoredChain(store, \"chain_session-1\", publicKey);\n```\n\n### Classify tool calls\n\n```typescript\nimport { classifyToolCall, loadTaxonomyConfig } from \"@attest-protocol/attest-ts\";\n\n// Built-in classification\nconst result = classifyToolCall(\"read_file\");\n// → { action_type: \"unknown\", risk_level: \"medium\" }\n\n// With custom mappings\nconst mappings = loadTaxonomyConfig(\"taxonomy.json\");\nconst mapped = classifyToolCall(\"read_file\", mappings);\n// → { action_type: \"filesystem.file.read\", risk_level: \"low\" }\n```\n\n## What is an Action Receipt?\n\nA [W3C Verifiable Credential](https://www.w3.org/TR/vc-data-model-2.0/) signed with Ed25519, recording:\n\n| Field | What it captures |\n|:---|:---|\n| **Action** | What happened, classified by a [standardized taxonomy](https://github.com/attest-protocol/spec/tree/main/spec/taxonomy) |\n| **Principal** | Who authorized it (human or organization) |\n| **Issuer** | Which agent performed it |\n| **Outcome** | Success/failure, reversibility, undo method |\n| **Chain** | SHA-256 hash link to the previous receipt (tamper-evident) |\n| **Privacy** | Parameters are hashed, never stored in plaintext |\n\n## API reference\n\n### Receipt creation and signing\n\n```typescript\nimport {\n  createReceipt,       // Build an unsigned receipt from input fields\n  generateKeyPair,     // Ed25519 key pair (PEM-encoded)\n  signReceipt,         // Sign with Ed25519Signature2020 proof\n  verifyReceipt,       // Verify a single receipt's signature\n} from \"@attest-protocol/attest-ts\";\n```\n\n### Hashing and canonicalization\n\n```typescript\nimport {\n  canonicalize,        // RFC 8785 JSON canonicalization\n  hashReceipt,         // Hash receipt (excluding proof) → \"sha256:<hex>\"\n  sha256,              // Hash arbitrary data → \"sha256:<hex>\"\n} from \"@attest-protocol/attest-ts\";\n```\n\n### Chain verification\n\n```typescript\nimport {\n  verifyChain,         // Verify signatures, hash links, and sequence numbering\n} from \"@attest-protocol/attest-ts\";\n```\n\n### Storage (SQLite)\n\n```typescript\nimport {\n  openStore,           // Open or create a receipt store\n  ReceiptStore,        // Insert, query, get by ID, get chain, stats\n  verifyStoredChain,   // Load a chain from store and verify integrity\n} from \"@attest-protocol/attest-ts\";\n```\n\n### Taxonomy\n\n```typescript\nimport {\n  classifyToolCall,    // Map tool names → action types + risk levels\n  loadTaxonomyConfig,  // Load tool→action mappings from a JSON config file\n  ALL_ACTIONS,         // All 15 built-in action types\n  resolveActionType,   // Look up action type with fallback to \"unknown\"\n} from \"@attest-protocol/attest-ts\";\n```\n\n### Subpath imports\n\nFor more targeted imports:\n\n```typescript\nimport { createReceipt, signReceipt } from \"@attest-protocol/attest-ts/receipt\";\nimport { openStore } from \"@attest-protocol/attest-ts/store\";\nimport { classifyToolCall } from \"@attest-protocol/attest-ts/taxonomy\";\n```\n\n## Project structure\n\n```\nsrc/\n  receipt/      # Receipt creation, Ed25519 signing, RFC 8785 hashing, chain verification\n  store/        # SQLite persistence and chain integrity verification\n  taxonomy/     # Action type classification (15 types) + config file loading\n```\n\n## Development\n\n```sh\npnpm install\npnpm run test          # 101 tests\npnpm run check         # typecheck + lint\npnpm run build         # compile to dist/\n```\n\n| | |\n|:---|:---|\n| **Language** | TypeScript ESM, strict mode |\n| **Linting** | Biome (tabs, double quotes) |\n| **Testing** | Vitest (colocated `*.test.ts` files) |\n| **Runtime deps** | Zero — `node:crypto` and `node:sqlite` only |\n\n## Ecosystem\n\n| Repository | Description |\n|:---|:---|\n| [attest-protocol/spec](https://github.com/attest-protocol/spec) | Protocol specification, JSON Schemas, canonical taxonomy |\n| **@attest-protocol/attest-ts** (this package) | TypeScript SDK |\n| [ojongerius/attest](https://github.com/ojongerius/attest) | MCP proxy + CLI (reference implementation, consumes this SDK) |\n| [attest-protocol/attest-py](https://github.com/attest-protocol/attest-py) | Python SDK ([PyPI](https://pypi.org/project/attest-protocol/)) |\n\n## License\n\nApache 2.0 — see [LICENSE](LICENSE).\n","readmeFilename":"README.md","homepage":"https://github.com/attest-protocol/attest-ts#readme","repository":{"type":"git","url":"git+https://github.com/attest-protocol/attest-ts.git"},"bugs":{"url":"https://github.com/attest-protocol/attest-ts/issues"}}