{"_id":"@abstraxn/warrant","name":"@abstraxn/warrant","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@abstraxn/warrant","version":"0.1.0","description":"KYI Warrant server SDK — createMandate() and check() before agent actions (ALLOW / DENY / ESCALATE)","type":"module","main":"./dist/src/index.js","types":"./dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js","default":"./dist/src/index.js"}},"scripts":{"build":"rimraf dist && tsc","prepublishOnly":"npm run build","prepack":"npm run build"},"keywords":["abstraxn","kyi","warrant","agent","policy","mandate","web3","ai-agent","authorization"],"author":{"name":"Abstraxn Labs"},"license":"MIT","homepage":"https://docs.abstraxn.com/guides/kyi/overview","engines":{"node":">=18"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"dependencies":{"@noble/hashes":"^1.7.1","canonicalize":"^2.1.0"},"devDependencies":{"@types/node":"^25.0.3","rimraf":"^6.1.2","typescript":"^5.9.3"},"gitHead":"f1e0cdd3333706c1ce3c87067504a500f799ab8e","_id":"@abstraxn/warrant@0.1.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-8C8cTyVXQaPTjA63FXliDxxnUSe8rt5n6e0gDJB85cVtkyyxB1V3yqOEd5XOb6AbsdKSIjCZn3a0b/QktEDXOg==","shasum":"827311e95830ebfd7ee2fe306bb47598d8d4ad44","tarball":"https://registry.npmjs.org/@abstraxn/warrant/-/warrant-0.1.0.tgz","fileCount":7,"unpackedSize":15375,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDwFdaHfvZqzvbO19Ss0HkAMJjjxWm+P5wrXhN4pTQZPQIgc6H1lgD2RGVpZUoAjkzSB/Nmnn+AdplLa2H23+B+X/E="}]},"_npmUser":{"name":"sandeep_sj","email":"sandeepsj26899@gmail.com"},"directories":{},"maintainers":[{"name":"shubham.antier","email":"shubham.singla@antiersolutions.com"},{"name":"sandeep_sj","email":"sandeepsj26899@gmail.com"},{"name":"abhi883","email":"abhishek.upadhyay@antiersolutions.com"},{"name":"pankaj829","email":"pankajdogra829@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/warrant_0.1.0_1788161215522_0.6007560453810938"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T07:26:55.283Z","0.1.0":"2026-08-31T07:26:55.724Z","modified":"2026-08-31T07:26:56.032Z"},"maintainers":[{"name":"shubham.antier","email":"shubham.singla@antiersolutions.com"},{"name":"sandeep_sj","email":"sandeepsj26899@gmail.com"},{"name":"abhi883","email":"abhishek.upadhyay@antiersolutions.com"},{"name":"pankaj829","email":"pankajdogra829@gmail.com"}],"description":"KYI Warrant server SDK — createMandate() and check() before agent actions (ALLOW / DENY / ESCALATE)","homepage":"https://docs.abstraxn.com/guides/kyi/overview","keywords":["abstraxn","kyi","warrant","agent","policy","mandate","web3","ai-agent","authorization"],"author":{"name":"Abstraxn Labs"},"license":"MIT","readme":"# @abstraxn/warrant\n\nServer / Node SDK for **KYI Framework → Warrant** — create sealed mandates and gate agent actions with `ALLOW` / `DENY` / `ESCALATE` before execution.\n\nRelated packages:\n\n| Package | Role |\n|---------|------|\n| `@abstraxn/warrant` | Server / Node client (`createMandate`, `check`) |\n| `@abstraxn/warrant-react` | MandateForm + deterministic Readback |\n| `@abstraxn/warrant-verifier` | Offline receipt verify + CLI |\n\n## Installation\n\n```bash\nnpm install @abstraxn/warrant\n```\n\n```bash\nyarn add @abstraxn/warrant\n```\n\n```bash\npnpm add @abstraxn/warrant\n```\n\n**Requires Node.js 18+** (global `fetch`).\n\n## Prerequisites\n\n- **Node.js** >= 18 (global `fetch`)\n- **Application API key** from the [Abstraxn Dashboard](https://dashboard.abstraxn.com) (create / manage mandates)\n- **Warrant API URL** — optional; defaults to `https://api-warrant.abstraxn.com`\n\n---\n\n## API keys (per-mandate, like Agent Kit per-agent)\n\n| Key | Who | Use |\n|-----|-----|-----|\n| **Application API key** | Business / dashboard | Create & manage mandates |\n| **Mandate API key** | Runtime agent / MCP / Kong | `check()` under that mandate only |\n\nOn `createMandate`, KYI mints a Kong key and returns it once as `result.apiKey`. Store it securely — runtime agents use **that** key, not the business app key.\n\n---\n\n## Basic integration\n\n### 1. Initialize (admin — application key)\n\n```typescript\nimport { Warrant } from '@abstraxn/warrant';\n\nconst admin = new Warrant({\n  apiKey: process.env.ABSTRAXN_API_KEY!, // application API key\n  // apiUrl optional — defaults to https://api-warrant.abstraxn.com\n});\n```\n\n### 2. Create a mandate\n\n```typescript\nimport {\n  Warrant,\n  hashMandateRules,\n  mandateSealMessage,\n} from '@abstraxn/warrant';\n\nconst rules = {\n  rules: [\n    { type: 'amount_max_per_action', value: 100, currency: 'USD' },\n    {\n      type: 'counterparty_allowlist',\n      value: ['0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'],\n    },\n  ],\n};\n\nconst hash = hashMandateRules(rules); // JCS + SHA-256 — must match KYI\nconst message = mandateSealMessage(hash);\n// wallet: eth_personalSign(message) → owner_signature\n// owner_pubkey_ref: `eip155:<chainId>:${address.toLowerCase()}`\n\nconst mandate = (await admin.createMandate({\n  agent_id: 'agent_web3_demo',\n  principal_id: '0xowner…',\n  domain: 'web3',\n  rules,\n  owner_signature: '0x…', // EIP-191 or Ed25519 seal\n  owner_pubkey_ref: 'eip155:80002:0xowner…',\n  valid_until: null,\n})) as { id: string; apiKey: string; status: string };\n\n// Store mandate.apiKey once — returned only on create.\nconsole.log('Mandate ID:', mandate.id);\nconsole.log('Mandate API Key:', mandate.apiKey);\n```\n\nKYI verifies EIP-191 (`eip155:…`) and Ed25519 (`ed25519:<pubkeyHex>`) seals on create. Passkey (`webauthn:…`) needs `WARRANT_SEAL_ALLOW_UNVERIFIED=webauthn` until full assertion verify ships.\n\n### 3. Runtime check (mandate key)\n\n```typescript\nconst warrant = new Warrant({\n  apiKey: process.env.WARRANT_MANDATE_API_KEY!, // per-mandate key\n});\n\nconst decision = await warrant.check({\n  agent_id: 'agent_web3_demo', // must match mandate; forced from key when using mandate key\n  domain: 'web3',\n  action_type: 'transfer',\n  value: { amount: 40, currency: 'USD' },\n  counterparty: {\n    id: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n    type: 'evm_address',\n  },\n});\n\nif (decision.verdict !== 'ALLOW') {\n  throw new Error(`Blocked: ${decision.reasons.map((r) => r.code).join(', ')}`);\n}\n// proceed with the real transfer / MCP tool\n```\n\n---\n\n## Configuration\n\n| Option    | Required | Default | Description |\n|-----------|----------|---------|-------------|\n| `apiUrl`  | No       | `https://api-warrant.abstraxn.com` (or `WARRANT_URL` / `KYI_URL` env) | KYI Warrant base URL |\n| `apiKey`  | Yes      | —       | Application or mandate API key (`x-api-key`) |\n| `onError` | No       | `'deny'` | Behavior when Warrant is unreachable |\n\n### `onError` behavior\n\n| Value | When API / network fails |\n|-------|--------------------------|\n| `'deny'` | Returns a synthetic `DENY` decision (`WARRANT_UNREACHABLE`) |\n| `'escalate'` | Returns a synthetic `ESCALATE` decision |\n| `'bypass_with_receipt'` | Re-throws the error (caller handles) |\n\n---\n\n## API reference\n\n### `createMandate(params)`\n\nCreates a sealed mandate. Requires the **application** API key.\n\n```typescript\ntype CreateMandateParams = {\n  agent_id: string;\n  principal_id: string;\n  domain: string;\n  rules: RuleSet;\n  owner_signature: string;\n  owner_pubkey_ref: string;\n  valid_until?: string | null;\n};\n```\n\n### Seal helpers\n\n| Export | Description |\n|--------|-------------|\n| `hashMandateRules(rules)` | JCS + SHA-256 hex (same as KYI `mandate.hash`) |\n| `canonicalRulesJson(rules)` | JCS string of rules |\n| `mandateSealMessage(hash)` | EIP-191 / Ed25519 message to sign |\n\n### `check(action)`\n\nEvaluates an action against active mandates. Prefer the **mandate** API key at runtime.\n\n```typescript\ntype NormalizedAction = {\n  agent_id: string;\n  domain: string;\n  action_type: string;\n  value: { amount: number; currency: string };\n  counterparty?: { id: string; type: string } | null;\n  items?: Array<{ name: string; category?: string }> | null;\n  timestamp?: string; // default: now (ISO)\n};\n\ntype Decision = {\n  decision_id: string;\n  verdict: 'ALLOW' | 'DENY' | 'ESCALATE';\n  reasons: Array<{ code: string; layer: string; detail?: unknown }>;\n  matched_mandate_ids: string[];\n  inputs_digest: string;\n  receipt_id: string;\n  evaluated_at: string;\n};\n```\n\n### Rule types\n\n```typescript\ntype Rule =\n  | { type: 'amount_max_per_action'; value: number; currency: string }\n  | { type: 'category_denylist'; value: string[] }\n  | { type: 'counterparty_allowlist'; value: string[] }\n  | {\n      type: 'time_window';\n      value: { days: string[]; from: string; to: string; tz: string };\n    };\n```\n\n---\n\n## Environment variables (typical)\n\n```env\n# Optional — omit apiUrl in code to use production default\n# WARRANT_URL=https://api-warrant.abstraxn.com\nABSTRAXN_API_KEY=<application api key>\nWARRANT_MANDATE_API_KEY=<per-mandate key from createMandate>\nWARRANT_AGENT_ID=agent_web3_demo\n```\n\n---\n\n## Examples\n\n- `abstraxn-agent-examples/examples/09-warrant-gated-transfer` — Next app wrapping MCP `transfer` with `warrant.check()`\n- `kyi-pocs/` — passkey, wallet, and web3 CLI POCs\n\n---\n\n## Security notes\n\n- Treat mandate `apiKey` like an agent secret — encrypt at rest; never ship in public frontend bundles.\n- Always call `check()` **before** irreversible actions (transfers, orders, MCP commit tools).\n- Fail closed: default `onError: 'deny'` when Warrant is unreachable.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-1b18b12a4ba5d17cc3e9b6a7fe7d3a8d"}