@hai.ai/jacs 0.6.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/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # JACS for Node.js
2
+
3
+ Node.js bindings for JACS (JSON Agent Communication Standard) -- an open data provenance toolkit for signing and verifying AI agent communications. JACS works standalone with no server required; optionally register with [HAI.ai](https://hai.ai) for cross-organization key discovery.
4
+
5
+ **Dependencies**: The `overrides` in `package.json` for `body-parser` and `qs` are for security (CVE-2024-45590). Do not remove them without re-auditing.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @hai.ai/jacs
11
+ ```
12
+
13
+ The npm package ships prebuilt native bindings for supported targets and does not compile Rust during `npm install`.
14
+
15
+ ## Quick Start
16
+
17
+ ```javascript
18
+ const jacs = require('@hai.ai/jacs/simple');
19
+
20
+ // Load your agent (run `jacs create` first if needed)
21
+ const agent = jacs.load('./jacs.config.json');
22
+
23
+ // Sign a message
24
+ const signed = jacs.signMessage({
25
+ action: 'approve',
26
+ amount: 100
27
+ });
28
+
29
+ // Verify it
30
+ const result = jacs.verify(signed.raw);
31
+ console.log(`Valid: ${result.valid}`);
32
+ console.log(`Signer: ${result.signerId}`);
33
+ ```
34
+
35
+ ## Core API
36
+
37
+ | Function | Description |
38
+ |----------|-------------|
39
+ | `create(options)` | Create a new agent programmatically (non-interactive) |
40
+ | `load(configPath)` | Load agent from config file |
41
+ | `verifySelf()` | Verify agent's own integrity |
42
+ | `updateAgent(data)` | Update agent document with new data |
43
+ | `updateDocument(id, data)` | Update existing document with new data |
44
+ | `signMessage(data)` | Sign any JSON data |
45
+ | `signFile(path, embed)` | Sign a file |
46
+ | `verify(doc)` | Verify signed document (JSON string) |
47
+ | `verifyStandalone(doc, opts?)` | Verify without loading an agent (one-off) |
48
+ | `verifyById(id)` | Verify a document by storage ID (`uuid:version`) |
49
+ | `registerWithHai(opts?)` | Register the loaded agent with HAI.ai |
50
+ | `getDnsRecord(domain, ttl?)` | Get DNS TXT record line for the agent |
51
+ | `getWellKnownJson()` | Get well-known JSON for `/.well-known/jacs-pubkey.json` |
52
+ | `reencryptKey(oldPw, newPw)` | Re-encrypt private key with new password |
53
+ | `getPublicKey()` | Get public key for sharing |
54
+ | `isLoaded()` | Check if agent is loaded |
55
+ | `trustAgent(json)` | Add an agent to the local trust store |
56
+ | `listTrustedAgents()` | List all trusted agent IDs |
57
+ | `untrustAgent(id)` | Remove an agent from the trust store |
58
+ | `isTrusted(id)` | Check if an agent is trusted |
59
+ | `getTrustedAgent(id)` | Get a trusted agent's JSON document |
60
+ | `audit(options?)` | Run a read-only security audit; optional `configPath`, `recentN` |
61
+ | `generateVerifyLink(doc, baseUrl?)` | Generate a shareable hai.ai verification URL for a signed document |
62
+
63
+ ## Types
64
+
65
+ ```typescript
66
+ interface SignedDocument {
67
+ raw: string; // Full JSON document
68
+ documentId: string; // UUID
69
+ agentId: string; // Signer's ID
70
+ timestamp: string; // ISO 8601
71
+ }
72
+
73
+ interface VerificationResult {
74
+ valid: boolean;
75
+ data?: any;
76
+ signerId: string;
77
+ timestamp: string;
78
+ attachments: Attachment[];
79
+ errors: string[];
80
+ }
81
+ ```
82
+
83
+ ## Programmatic Agent Creation
84
+
85
+ ```typescript
86
+ const jacs = require('@hai.ai/jacs/simple');
87
+
88
+ const agent = jacs.create({
89
+ name: 'my-agent',
90
+ password: process.env.JACS_PRIVATE_KEY_PASSWORD, // required
91
+ algorithm: 'pq2025', // default; also: "ring-Ed25519", "RSA-PSS"
92
+ dataDirectory: './jacs_data',
93
+ keyDirectory: './jacs_keys',
94
+ });
95
+ console.log(`Created: ${agent.agentId}`);
96
+ ```
97
+
98
+ ### Verify by Document ID
99
+
100
+ ```javascript
101
+ const result = jacs.verifyById('550e8400-e29b-41d4-a716-446655440000:1');
102
+ console.log(`Valid: ${result.valid}`);
103
+ ```
104
+
105
+ ### Re-encrypt Private Key
106
+
107
+ ```javascript
108
+ jacs.reencryptKey('old-password-123!', 'new-Str0ng-P@ss!');
109
+ ```
110
+
111
+ ### Password Requirements
112
+
113
+ Passwords must be at least 8 characters and include uppercase, lowercase, a digit, and a special character.
114
+
115
+ ### Algorithm Deprecation Notice
116
+
117
+ The `pq-dilithium` algorithm is deprecated. Use `pq2025` (ML-DSA-87, FIPS-204) instead. `pq-dilithium` still works but emits deprecation warnings.
118
+
119
+ ## Examples
120
+
121
+ ### Sign and Verify
122
+
123
+ ```javascript
124
+ const jacs = require('@hai.ai/jacs/simple');
125
+
126
+ jacs.load('./jacs.config.json');
127
+
128
+ // Sign data
129
+ const signed = jacs.signMessage({
130
+ action: 'transfer',
131
+ amount: 500,
132
+ to: 'agent-123'
133
+ });
134
+
135
+ // Later, verify received data
136
+ const result = jacs.verify(receivedJson);
137
+ if (result.valid) {
138
+ console.log(`Signed by: ${result.signerId}`);
139
+ console.log(`Data: ${JSON.stringify(result.data)}`);
140
+ }
141
+ ```
142
+
143
+ ### Update Agent
144
+
145
+ ```javascript
146
+ // Get current agent, modify, and update
147
+ const agentDoc = JSON.parse(jacs.exportAgent());
148
+ agentDoc.jacsAgentType = 'updated-service';
149
+ const updated = jacs.updateAgent(agentDoc);
150
+ console.log('Agent updated with new version');
151
+ ```
152
+
153
+ ### Update Document
154
+
155
+ ```javascript
156
+ // Create a document
157
+ const signed = jacs.signMessage({ status: 'pending', amount: 100 });
158
+
159
+ // Later, update it
160
+ const doc = JSON.parse(signed.raw);
161
+ doc.content.status = 'approved';
162
+ const updated = jacs.updateDocument(signed.documentId, doc);
163
+ console.log('Document updated with new version');
164
+ ```
165
+
166
+ ### File Signing
167
+
168
+ ```javascript
169
+ // Reference only (stores hash)
170
+ const signed = jacs.signFile('contract.pdf', false);
171
+
172
+ // Embed content (portable document)
173
+ const embedded = jacs.signFile('contract.pdf', true);
174
+ ```
175
+
176
+ ### MCP Integration
177
+
178
+ JACS provides a transport proxy that wraps any MCP transport with automatic signing and verification at the network boundary:
179
+
180
+ ```javascript
181
+ import { createJACSTransportProxy } from '@hai.ai/jacs/mcp';
182
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
183
+
184
+ // Wrap any MCP transport with JACS signing
185
+ const baseTransport = new StdioServerTransport();
186
+ const jacsTransport = createJACSTransportProxy(
187
+ baseTransport, './jacs.config.json', 'server'
188
+ );
189
+ ```
190
+
191
+ See `examples/mcp.simple.server.js` for a complete MCP server example with JACS-signed tools.
192
+
193
+ ## HAI Integration
194
+
195
+ The JACS package includes integration with HAI's key distribution service for fetching public keys without requiring local key storage.
196
+
197
+ ### Fetch Remote Keys
198
+
199
+ ```javascript
200
+ const { fetchRemoteKey } = require('@hai.ai/jacs');
201
+
202
+ // Fetch a public key from HAI's key service
203
+ const keyInfo = fetchRemoteKey('550e8400-e29b-41d4-a716-446655440000', 'latest');
204
+ console.log('Algorithm:', keyInfo.algorithm);
205
+ console.log('Public Key Hash:', keyInfo.publicKeyHash);
206
+ console.log('Agent ID:', keyInfo.agentId);
207
+ console.log('Version:', keyInfo.version);
208
+
209
+ // Use the public key for verification
210
+ const publicKeyBytes = keyInfo.publicKey; // Buffer containing DER-encoded key
211
+ ```
212
+
213
+ ### Environment Variables
214
+
215
+ | Variable | Description | Default |
216
+ |----------|-------------|---------|
217
+ | `HAI_KEYS_BASE_URL` | Base URL for the HAI key service | `https://keys.hai.ai` |
218
+
219
+ ### HAI Types
220
+
221
+ ```typescript
222
+ interface RemotePublicKeyInfo {
223
+ publicKey: Buffer; // DER-encoded public key bytes
224
+ algorithm: string; // e.g., "ed25519", "rsa-pss-sha256"
225
+ publicKeyHash: string; // SHA-256 hash of the public key
226
+ agentId: string; // The agent's unique identifier
227
+ version: string; // The key version
228
+ }
229
+ ```
230
+
231
+ ## See Also
232
+
233
+ - [JACS Book](https://humanassisted.github.io/JACS/) - Full documentation (published book)
234
+ - [Quick Start](https://humanassisted.github.io/JACS/getting-started/quick-start.html)
235
+ - [Source](https://github.com/HumanAssisted/JACS) - GitHub repository
236
+ - [HAI Developer Portal](https://hai.ai/dev)
237
+ - [Examples](./examples/)
package/http.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ // Define JacsOptions if not already defined elsewhere
2
+ interface JacsOptions {
3
+ configPath: string;
4
+ }
5
+
6
+ // For Koa
7
+ export function JACSKoaMiddleware(options: JacsOptions): (ctx: any, next: () => Promise<void>) => Promise<void>;
8
+
9
+ // For Express
10
+ export function JACSExpressMiddleware(options: JacsOptions): (req: any, res: any, next: () => Promise<void>) => Promise<void>;
11
+
12
+ // You can keep the old one if it's still used or remove it
13
+ // export function createJacsMiddleware(options?: JacsOptions): (ctx: any, next: () => Promise<void>) => Promise<void>;
package/http.js ADDED
@@ -0,0 +1,154 @@
1
+ import jacs from './index.js'; // Assuming JACS NAPI is here
2
+
3
+ /**
4
+ * JACS Middleware for Koa.js applications.
5
+ * Reads the raw request body, verifies JACS, makes payload available as ctx.jacsPayload.
6
+ * Signs the response object from ctx.body before sending.
7
+ * @param {Object} options
8
+ * @param {string} options.configPath - Path to JACS config file for the server.
9
+ */
10
+ export function JACSKoaMiddleware(options = {}) {
11
+ if (!options.configPath) {
12
+ throw new Error("JACSKoaMiddleware: options.configPath is required.");
13
+ }
14
+
15
+ return async (ctx, next) => {
16
+ // Ensure JACS NAPI is loaded with the server's config
17
+ // Consider loading this once when the middleware is initialized if jacs.load supports it,
18
+ // or ensure jacs instance is pre-configured. For simplicity, loading per request if not cached.
19
+ try {
20
+ await jacs.load(options.configPath);
21
+ } catch (loadError) {
22
+ console.error("JACSKoaMiddleware: Failed to load JACS config:", loadError);
23
+ ctx.status = 500;
24
+ ctx.body = "JACS configuration error on server.";
25
+ return;
26
+ }
27
+
28
+ // 1. Request Handling
29
+ if (ctx.request.method === 'POST' || ctx.request.method === 'PUT') { // Or any method with a body
30
+ let rawBody = '';
31
+ try {
32
+ const bodyBuffer = [];
33
+ for await (const chunk of ctx.req) { // ctx.req is the Node.js incoming message
34
+ bodyBuffer.push(chunk);
35
+ }
36
+ rawBody = Buffer.concat(bodyBuffer).toString();
37
+ } catch (err) {
38
+ console.error("JACSKoaMiddleware: Error reading raw request body:", err);
39
+ ctx.status = 400;
40
+ ctx.body = 'Failed to read request body.';
41
+ return;
42
+ }
43
+
44
+ if (rawBody) {
45
+ try {
46
+ console.log("JACSKoaMiddleware: Verifying incoming JACS string...");
47
+ const verificationResult = await jacs.verifyResponse(rawBody);
48
+ ctx.state.jacsPayload = verificationResult.payload; // Standard place for Koa state
49
+ ctx.jacsPayload = verificationResult.payload; // For convenience
50
+ console.log("JACSKoaMiddleware: JACS request verified. Payload in ctx.state.jacsPayload / ctx.jacsPayload.");
51
+ } catch (jacsError) {
52
+ console.error("JACSKoaMiddleware: JACS verification failed:", jacsError);
53
+ ctx.status = 400; // Bad Request - JACS validation failed
54
+ ctx.body = `Invalid JACS request: ${jacsError.message}`;
55
+ return;
56
+ }
57
+ } else {
58
+ console.log("JACSKoaMiddleware: No body found in POST/PUT request for JACS verification.");
59
+ // Depending on policy, might error or proceed if JACS is optional for this path
60
+ }
61
+ }
62
+
63
+ await next(); // Call the next middleware (e.g., your route handler)
64
+
65
+ // 2. Response Handling
66
+ // Check if ctx.body is an object intended for signing (and not already a string or buffer)
67
+ if (ctx.body && typeof ctx.body === 'object' && !(ctx.body instanceof String) && !Buffer.isBuffer(ctx.body) && !(typeof ctx.body.pipe === 'function')) {
68
+ try {
69
+ console.log("JACSKoaMiddleware: Signing outgoing response from ctx.body:", ctx.body);
70
+ const jacsStringResponse = await jacs.signRequest(ctx.body);
71
+ ctx.body = jacsStringResponse; // Replace object payload with JACS string
72
+ ctx.type = 'text/plain'; // Set Content-Type for the JACS string
73
+ console.log("JACSKoaMiddleware: JACS response signed.");
74
+ } catch (jacsError) {
75
+ console.error("JACSKoaMiddleware: Failed to sign JACS response:", jacsError);
76
+ // Potentially overwrite ctx.body with an error or re-throw
77
+ ctx.status = 500;
78
+ ctx.body = `Failed to sign JACS response: ${jacsError.message}`;
79
+ }
80
+ }
81
+ };
82
+ }
83
+
84
+ /**
85
+ * JACS Middleware for Express.js applications.
86
+ * Expects raw request body string in req.body (e.g., from express.text()).
87
+ * Verifies JACS, makes payload available as req.jacsPayload.
88
+ * Wraps res.send to sign the response object before sending.
89
+ * @param {Object} options
90
+ * @param {string} options.configPath - Path to JACS config file for the server.
91
+ */
92
+ export function JACSExpressMiddleware(options = {}) {
93
+ if (!options.configPath) {
94
+ throw new Error("JACSExpressMiddleware: options.configPath is required.");
95
+ }
96
+
97
+ return async (req, res, next) => {
98
+ // Ensure JACS NAPI is loaded
99
+ try {
100
+ await jacs.load(options.configPath);
101
+ } catch (loadError) {
102
+ console.error("JACSExpressMiddleware: Failed to load JACS config:", loadError);
103
+ res.status(500).send("JACS configuration error on server.");
104
+ return;
105
+ }
106
+
107
+ // 1. Request Handling
108
+ // Assumes prior middleware (like express.text()) has put raw string body into req.body
109
+ if ((req.method === 'POST' || req.method === 'PUT') && typeof req.body === 'string' && req.body.length > 0) {
110
+ try {
111
+ console.log("JACSExpressMiddleware: Verifying incoming JACS string from req.body...");
112
+ const verificationResult = await jacs.verifyResponse(req.body);
113
+ req.jacsPayload = verificationResult.payload;
114
+ console.log("JACSExpressMiddleware: JACS request verified. Payload in req.jacsPayload.");
115
+ } catch (jacsError) {
116
+ console.error("JACSExpressMiddleware: JACS verification failed:", jacsError);
117
+ res.status(400).send(`Invalid JACS request: ${jacsError.message}`);
118
+ return;
119
+ }
120
+ } else if ((req.method === 'POST' || req.method === 'PUT') && (!req.body || typeof req.body !== 'string')) {
121
+ console.log("JACSExpressMiddleware: req.body is not a JACS string. Ensure express.text() or similar is used before this middleware for POST/PUT.");
122
+ // Depending on policy, you might proceed or error if JACS is mandatory
123
+ }
124
+
125
+ // 2. Response Handling - Wrap res.send
126
+ const originalSend = res.send.bind(res);
127
+ res.send = async function (body) {
128
+ // 'this' is 'res'
129
+ if (body && typeof body === 'object' && !(body instanceof String) && !Buffer.isBuffer(body) && !(typeof body.pipe === 'function')) {
130
+ try {
131
+ console.log("JACSExpressMiddleware (res.send wrapper): Signing outgoing response object:", body);
132
+ const jacsStringResponse = await jacs.signRequest(body);
133
+ this.type('text/plain'); // Set Content-Type for the JACS string
134
+ console.log("JACSExpressMiddleware (res.send wrapper): JACS response signed.");
135
+ originalSend(jacsStringResponse);
136
+ } catch (jacsError) {
137
+ console.error("JACSExpressMiddleware (res.send wrapper): Failed to sign JACS response:", jacsError);
138
+ // Handle error - send an error response
139
+ if (!this.headersSent) {
140
+ this.status(500).type('text/plain').send(`Failed to sign JACS response: ${jacsError.message}`);
141
+ }
142
+ }
143
+ } else {
144
+ // Not an object to sign, or already a string/buffer, send as is
145
+ originalSend(body);
146
+ }
147
+ };
148
+
149
+ next(); // Call the next middleware (e.g., your route handler)
150
+ };
151
+ }
152
+
153
+ // The old generic middleware, can be removed or kept for other purposes.
154
+ // export function createJacsMiddleware(options = {}) { ... }
package/index.d.ts ADDED
@@ -0,0 +1,178 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ /** Hash a string using SHA-256. */
7
+ export declare function hashString(data: string): string
8
+ /** Create a JACS configuration object. */
9
+ export declare function createConfig(jacsUseSecurity?: string | undefined | null, jacsDataDirectory?: string | undefined | null, jacsKeyDirectory?: string | undefined | null, jacsAgentPrivateKeyFilename?: string | undefined | null, jacsAgentPublicKeyFilename?: string | undefined | null, jacsAgentKeyAlgorithm?: string | undefined | null, jacsPrivateKeyPassword?: string | undefined | null, jacsAgentIdAndVersion?: string | undefined | null, jacsDefaultStorage?: string | undefined | null): string
10
+ /** Create a JACS agent programmatically (non-interactive). */
11
+ export declare function createAgent(name: string, password: string, algorithm?: string | undefined | null, dataDirectory?: string | undefined | null, keyDirectory?: string | undefined | null, configPath?: string | undefined | null, agentType?: string | undefined | null, description?: string | undefined | null, domain?: string | undefined | null, defaultStorage?: string | undefined | null): string
12
+ /** Add an agent to the local trust store. */
13
+ export declare function trustAgent(agentJson: string): string
14
+ /** List all trusted agent IDs. */
15
+ export declare function listTrustedAgents(): Array<string>
16
+ /** Remove an agent from the trust store. */
17
+ export declare function untrustAgent(agentId: string): void
18
+ /** Check if an agent is in the trust store. */
19
+ export declare function isTrusted(agentId: string): boolean
20
+ /** Get a trusted agent's JSON document. */
21
+ export declare function getTrustedAgent(agentId: string): string
22
+ /**
23
+ * Run a read-only security audit and health checks.
24
+ * Returns the audit result as a JSON string (risks, health_checks, summary).
25
+ */
26
+ export declare function audit(configPath?: string | undefined | null, recentN?: number | undefined | null): string
27
+ /** @deprecated Use `new JacsAgent()` and `agent.load()` instead. */
28
+ export declare function load(configPath: string): string
29
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
30
+ export declare function signAgent(agentString: string, publicKey: Buffer, publicKeyEncType: string): string
31
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
32
+ export declare function verifyString(data: string, signatureBase64: string, publicKey: Buffer, publicKeyEncType: string): boolean
33
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
34
+ export declare function signString(data: string): string
35
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
36
+ export declare function verifyAgent(agentfile?: string | undefined | null): boolean
37
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
38
+ export declare function updateAgent(newAgentString: string): string
39
+ /** Result of verify_document_standalone. Exposed to JS as { valid, signerId }. */
40
+ export interface VerifyStandaloneResult {
41
+ valid: boolean
42
+ /** Signer agent ID; exposed to JS as signerId (camelCase). */
43
+ signerId: string
44
+ }
45
+ /**
46
+ * Verify a signed JACS document without loading an agent.
47
+ * Returns { valid, signerId }. Does not use global agent state.
48
+ */
49
+ export declare function verifyDocumentStandalone(signedDocument: string, keyResolution?: string | undefined | null, dataDirectory?: string | undefined | null, keyDirectory?: string | undefined | null): VerifyStandaloneResult
50
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
51
+ export declare function verifyDocument(documentString: string): boolean
52
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
53
+ export declare function updateDocument(documentKey: string, newDocumentString: string, attachments?: Array<string> | undefined | null, embed?: boolean | undefined | null): string
54
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
55
+ export declare function verifySignature(documentString: string, signatureField?: string | undefined | null): boolean
56
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
57
+ export declare function createAgreement(documentString: string, agentids: Array<string>, question?: string | undefined | null, context?: string | undefined | null, agreementFieldname?: string | undefined | null): string
58
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
59
+ export declare function signAgreement(documentString: string, agreementFieldname?: string | undefined | null): string
60
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
61
+ export declare function createDocument(documentString: string, customSchema?: string | undefined | null, outputfilename?: string | undefined | null, noSave?: boolean | undefined | null, attachments?: string | undefined | null, embed?: boolean | undefined | null): string
62
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
63
+ export declare function checkAgreement(documentString: string, agreementFieldname?: string | undefined | null): string
64
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
65
+ export declare function signRequest(params: any): string
66
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
67
+ export declare function verifyResponse(documentString: string): object
68
+ /** @deprecated Use `new JacsAgent()` and instance methods instead. */
69
+ export declare function verifyResponseWithAgentId(documentString: string): object
70
+ /**
71
+ * Information about a public key fetched from HAI key service.
72
+ *
73
+ * This struct contains the public key data and metadata returned by
74
+ * the HAI key distribution service.
75
+ */
76
+ export interface RemotePublicKeyInfo {
77
+ /** The raw public key bytes (DER encoded). */
78
+ publicKey: Buffer
79
+ /** The cryptographic algorithm (e.g., "ed25519", "rsa-pss-sha256"). */
80
+ algorithm: string
81
+ /** The hash of the public key (SHA-256). */
82
+ publicKeyHash: string
83
+ /** The agent ID the key belongs to. */
84
+ agentId: string
85
+ /** The version of the key. */
86
+ version: string
87
+ }
88
+ /**
89
+ * Fetch a public key from HAI's key distribution service.
90
+ *
91
+ * This function retrieves the public key for a specific agent and version
92
+ * from the HAI key distribution service. It is used to obtain trusted public
93
+ * keys for verifying agent signatures without requiring local key storage.
94
+ *
95
+ * # Arguments
96
+ *
97
+ * * `agent_id` - The unique identifier of the agent whose key to fetch.
98
+ * * `version` - The version of the agent's key to fetch. Use "latest" for
99
+ * the most recent version. If not provided, defaults to "latest".
100
+ *
101
+ * # Returns
102
+ *
103
+ * Returns a `RemotePublicKeyInfo` object containing the public key, algorithm, and hash.
104
+ *
105
+ * # Environment Variables
106
+ *
107
+ * * `HAI_KEYS_BASE_URL` - Base URL for the key service. Defaults to `https://keys.hai.ai`.
108
+ *
109
+ * # Example
110
+ *
111
+ * ```javascript
112
+ * const { fetchRemoteKey } = require('@hai.ai/jacs');
113
+ *
114
+ * const keyInfo = fetchRemoteKey('550e8400-e29b-41d4-a716-446655440000', 'latest');
115
+ * console.log('Algorithm:', keyInfo.algorithm);
116
+ * console.log('Hash:', keyInfo.publicKeyHash);
117
+ * ```
118
+ */
119
+ export declare function fetchRemoteKey(agentId: string, version?: string | undefined | null): RemotePublicKeyInfo
120
+ /**
121
+ * Build a verification URL for a signed JACS document.
122
+ *
123
+ * Encodes `document` as URL-safe base64 (no padding) and returns a full URL
124
+ * like `https://hai.ai/jacs/verify?s=...`. Throws if the URL would exceed 2048 chars.
125
+ */
126
+ export declare function generateVerifyLink(document: string, baseUrl: string): string
127
+ /**
128
+ * JacsAgent is a handle to a JACS agent instance.
129
+ * Each instance maintains its own state and can be used independently.
130
+ * This allows multiple agents to be used concurrently in the same process.
131
+ */
132
+ export declare class JacsAgent {
133
+ /**
134
+ * Create a new empty JacsAgent instance.
135
+ * Call `load()` to initialize it with a configuration.
136
+ */
137
+ constructor()
138
+ /** Load an agent from a configuration file. */
139
+ load(configPath: string): string
140
+ /** Sign an external agent's document with this agent's registration signature. */
141
+ signAgent(agentString: string, publicKey: Buffer, publicKeyEncType: string): string
142
+ /** Verify a signature on arbitrary string data. */
143
+ verifyString(data: string, signatureBase64: string, publicKey: Buffer, publicKeyEncType: string): boolean
144
+ /** Sign arbitrary string data with this agent's private key. */
145
+ signString(data: string): string
146
+ /** Verify this agent's signature and hash. */
147
+ verifyAgent(agentfile?: string | undefined | null): boolean
148
+ /** Update the agent document with new data. */
149
+ updateAgent(newAgentString: string): string
150
+ /** Verify a document's signature and hash. */
151
+ verifyDocument(documentString: string): boolean
152
+ /** Update an existing document. */
153
+ updateDocument(documentKey: string, newDocumentString: string, attachments?: Array<string> | undefined | null, embed?: boolean | undefined | null): string
154
+ /** Verify a document's signature with an optional custom signature field. */
155
+ verifySignature(documentString: string, signatureField?: string | undefined | null): boolean
156
+ /** Create an agreement on a document. */
157
+ createAgreement(documentString: string, agentids: Array<string>, question?: string | undefined | null, context?: string | undefined | null, agreementFieldname?: string | undefined | null): string
158
+ /** Sign an agreement on a document. */
159
+ signAgreement(documentString: string, agreementFieldname?: string | undefined | null): string
160
+ /** Create a new JACS document. */
161
+ createDocument(documentString: string, customSchema?: string | undefined | null, outputfilename?: string | undefined | null, noSave?: boolean | undefined | null, attachments?: string | undefined | null, embed?: boolean | undefined | null): string
162
+ /** Check an agreement on a document. */
163
+ checkAgreement(documentString: string, agreementFieldname?: string | undefined | null): string
164
+ /**
165
+ * Verify a document looked up by ID from storage.
166
+ *
167
+ * The document_id should be in "uuid:version" format.
168
+ */
169
+ verifyDocumentById(documentId: string): boolean
170
+ /** Re-encrypt the agent's private key with a new password. */
171
+ reencryptKey(oldPassword: string, newPassword: string): void
172
+ /** Sign a request payload (wraps in a JACS document). */
173
+ signRequest(params: any): string
174
+ /** Verify a response payload. */
175
+ verifyResponse(documentString: string): object
176
+ /** Verify a response payload and return the agent ID. */
177
+ verifyResponseWithAgentId(documentString: string): object
178
+ }