notaryos 1.0.0 → 2.0.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.mjs CHANGED
@@ -1,5 +1,25 @@
1
1
  // src/index.ts
2
- var SDK_VERSION = "1.0.0";
2
+ var SDK_VERSION = "2.0.0";
3
+ var NotaryErrorCode = {
4
+ // 4xx Client Errors
5
+ ERR_RECEIPT_NOT_FOUND: "ERR_RECEIPT_NOT_FOUND",
6
+ ERR_INVALID_SIGNATURE: "ERR_INVALID_SIGNATURE",
7
+ ERR_INVALID_STRUCTURE: "ERR_INVALID_STRUCTURE",
8
+ ERR_INVALID_TIMESTAMP: "ERR_INVALID_TIMESTAMP",
9
+ ERR_UNKNOWN_SIGNER: "ERR_UNKNOWN_SIGNER",
10
+ ERR_UNSUPPORTED_ALGORITHM: "ERR_UNSUPPORTED_ALGORITHM",
11
+ ERR_CHAIN_BROKEN: "ERR_CHAIN_BROKEN",
12
+ ERR_CHAIN_MISSING: "ERR_CHAIN_MISSING",
13
+ ERR_PAYLOAD_TOO_LARGE: "ERR_PAYLOAD_TOO_LARGE",
14
+ ERR_RATE_LIMIT_EXCEEDED: "ERR_RATE_LIMIT_EXCEEDED",
15
+ ERR_INVALID_API_KEY: "ERR_INVALID_API_KEY",
16
+ ERR_INSUFFICIENT_SCOPE: "ERR_INSUFFICIENT_SCOPE",
17
+ ERR_VALIDATION_FAILED: "ERR_VALIDATION_FAILED",
18
+ // 5xx Server Errors
19
+ ERR_INTERNAL_ERROR: "ERR_INTERNAL_ERROR",
20
+ ERR_DATABASE_ERROR: "ERR_DATABASE_ERROR",
21
+ ERR_SIGNING_ERROR: "ERR_SIGNING_ERROR"
22
+ };
3
23
  var NotaryError = class extends Error {
4
24
  constructor(message, code = "", status = 0, details = {}) {
5
25
  super(message);
@@ -28,6 +48,79 @@ var ValidationError = class extends NotaryError {
28
48
  this.name = "ValidationError";
29
49
  }
30
50
  };
51
+ var CounterfactualClient = class {
52
+ constructor(client) {
53
+ this.client = client;
54
+ }
55
+ /** Issue a v1 counterfactual receipt (proof of non-action). */
56
+ async issue(options) {
57
+ return this.client["request"]("POST", "/counterfactual/issue", {
58
+ action_not_taken: options.actionNotTaken,
59
+ capability_proof: options.capabilityProof,
60
+ opportunity_context: options.opportunityContext,
61
+ decision_reason: options.decisionReason,
62
+ declination_reason: options.declinationReason || "unknown",
63
+ provenance_refs: options.provenanceRefs,
64
+ validity_window_minutes: options.validityWindowMinutes || 60
65
+ });
66
+ }
67
+ /** Retrieve/verify a counterfactual receipt by hash (public). */
68
+ async get(receiptHash) {
69
+ return this.client["publicGet"](`/v1/notary/counterfactual/r/${receiptHash}`);
70
+ }
71
+ /** List counterfactual receipts for a specific agent (public). */
72
+ async listByAgent(agentId, limit = 50, offset = 0) {
73
+ return this.client["publicGet"](
74
+ `/v1/notary/counterfactual/agent/${agentId}?limit=${limit}&offset=${offset}`
75
+ );
76
+ }
77
+ /** Commit a v2 counterfactual receipt (Phase 1 of commit-reveal). */
78
+ async commit(options) {
79
+ return this.client["request"]("POST", "/counterfactual/commit", {
80
+ action_not_taken: options.actionNotTaken,
81
+ capability_proof: options.capabilityProof,
82
+ opportunity_context: options.opportunityContext,
83
+ decision_reason: options.decisionReason,
84
+ declination_reason: options.declinationReason || "unknown",
85
+ provenance_refs: options.provenanceRefs,
86
+ validity_window_minutes: options.validityWindowMinutes || 60,
87
+ min_reveal_delay_seconds: options.minRevealDelaySeconds || 300,
88
+ max_reveal_window_seconds: options.maxRevealWindowSeconds || 86400
89
+ });
90
+ }
91
+ /** Reveal a committed counterfactual receipt (Phase 2). */
92
+ async reveal(receiptHash, decisionReasonPlaintext) {
93
+ return this.client["request"]("POST", "/counterfactual/reveal", {
94
+ receipt_hash: receiptHash,
95
+ decision_reason_plaintext: decisionReasonPlaintext
96
+ });
97
+ }
98
+ /** Check commit-reveal lifecycle status (public). */
99
+ async commitStatus(receiptHash) {
100
+ return this.client["publicGet"](
101
+ `/v1/notary/counterfactual/commit-status/${receiptHash}`
102
+ );
103
+ }
104
+ /** Counter-sign a counterfactual receipt (corroboration). */
105
+ async corroborate(receiptHash, signals) {
106
+ return this.client["request"]("POST", "/counterfactual/corroborate", {
107
+ receipt_hash: receiptHash,
108
+ corroboration_signals: signals
109
+ });
110
+ }
111
+ /** Generate a compliance certificate for a counterfactual receipt (public). */
112
+ async certificate(receiptHash, format = "markdown") {
113
+ return this.client["publicGet"](
114
+ `/v1/notary/counterfactual/r/${receiptHash}/certificate?format=${format}`
115
+ );
116
+ }
117
+ /** Verify counterfactual chain continuity for an agent (public). */
118
+ async verifyChain(agentId) {
119
+ return this.client["publicGet"](
120
+ `/v1/notary/counterfactual/chain/${agentId}/verify`
121
+ );
122
+ }
123
+ };
31
124
  var _NotaryClient = class _NotaryClient {
32
125
  constructor(config) {
33
126
  const { apiKey, baseUrl, timeout, maxRetries } = config;
@@ -41,6 +134,13 @@ var _NotaryClient = class _NotaryClient {
41
134
  this.timeout = timeout || _NotaryClient.DEFAULT_TIMEOUT;
42
135
  this.maxRetries = maxRetries ?? 2;
43
136
  }
137
+ /** Access counterfactual receipt operations (enterprise premium). */
138
+ get counterfactual() {
139
+ if (!this._counterfactual) {
140
+ this._counterfactual = new CounterfactualClient(this);
141
+ }
142
+ return this._counterfactual;
143
+ }
44
144
  async request(method, path, body) {
45
145
  const url = `${this.baseUrl}/v1/notary${path}`;
46
146
  const headers = {
@@ -108,9 +208,40 @@ var _NotaryClient = class _NotaryClient {
108
208
  }
109
209
  throw lastError || new NotaryError("Request failed", "ERR_UNKNOWN");
110
210
  }
211
+ /** Public GET helper (no API key in headers). */
212
+ async publicGet(path) {
213
+ const url = `${this.baseUrl}${path}`;
214
+ const controller = new AbortController();
215
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
216
+ try {
217
+ const response = await fetch(url, {
218
+ method: "GET",
219
+ headers: {
220
+ "Content-Type": "application/json",
221
+ "User-Agent": `notary-typescript-sdk/${SDK_VERSION}`
222
+ },
223
+ signal: controller.signal
224
+ });
225
+ clearTimeout(timeoutId);
226
+ if (response.status === 404) {
227
+ return { found: false };
228
+ }
229
+ if (!response.ok) {
230
+ throw new NotaryError(response.statusText, "ERR_REQUEST", response.status);
231
+ }
232
+ return await response.json();
233
+ } catch (err) {
234
+ clearTimeout(timeoutId);
235
+ if (err instanceof NotaryError) throw err;
236
+ throw new NotaryError(`Connection failed: ${err.message}`, "ERR_CONNECTION");
237
+ }
238
+ }
111
239
  sleep(ms) {
112
240
  return new Promise((resolve) => setTimeout(resolve, ms));
113
241
  }
242
+ // =========================================================================
243
+ // Core API
244
+ // =========================================================================
114
245
  /**
115
246
  * Issue a signed receipt for an action.
116
247
  *
@@ -118,13 +249,6 @@ var _NotaryClient = class _NotaryClient {
118
249
  * @param payload - Action payload to be receipted
119
250
  * @param options - Optional chaining and metadata
120
251
  * @returns A signed Receipt
121
- *
122
- * @example
123
- * ```typescript
124
- * const receipt = await notary.issue('transfer', { amount: 100, to: 'agent-b' });
125
- * console.log(receipt.receipt_id);
126
- * console.log(receipt.verify_url); // https://...notary/r/abc123
127
- * ```
128
252
  */
129
253
  async issue(actionType, payload, options = {}) {
130
254
  const body = {
@@ -145,20 +269,7 @@ var _NotaryClient = class _NotaryClient {
145
269
  chain_sequence: response.chain_position
146
270
  };
147
271
  }
148
- /**
149
- * Verify a receipt's signature and integrity.
150
- *
151
- * @param receipt - Receipt object or raw receipt dict
152
- * @returns VerificationResult with validity details
153
- *
154
- * @example
155
- * ```typescript
156
- * const result = await notary.verify(receipt);
157
- * if (result.valid) {
158
- * console.log('Receipt is authentic');
159
- * }
160
- * ```
161
- */
272
+ /** Verify a receipt's signature and integrity. */
162
273
  async verify(receipt) {
163
274
  return this.request("POST", "/verify", { receipt });
164
275
  }
@@ -166,15 +277,7 @@ var _NotaryClient = class _NotaryClient {
166
277
  async verifyById(receiptId) {
167
278
  return this.request("POST", "/verify", { receipt_id: receiptId });
168
279
  }
169
- /**
170
- * Get Notary service status.
171
- *
172
- * @example
173
- * ```typescript
174
- * const status = await notary.status();
175
- * console.log(status.status); // "active"
176
- * ```
177
- */
280
+ /** Get Notary service status. */
178
281
  async status() {
179
282
  return this.request("GET", "/status");
180
283
  }
@@ -186,54 +289,150 @@ var _NotaryClient = class _NotaryClient {
186
289
  async me() {
187
290
  return this.request("GET", "/agents/me");
188
291
  }
292
+ /** Look up a receipt by hash (public endpoint). */
293
+ async lookup(receiptHash) {
294
+ return this.publicGet(`/v1/notary/r/${receiptHash}`);
295
+ }
296
+ // =========================================================================
297
+ // History & Provenance
298
+ // =========================================================================
189
299
  /**
190
- * Look up a receipt by hash (public endpoint, no API key required for lookup).
191
- *
192
- * @param receiptHash - Full or partial receipt hash (min 16 chars)
193
- * @returns Lookup result with receipt, verification, and meta
300
+ * Get paginated receipt history (requires Clerk JWT).
194
301
  *
195
- * @example
196
- * ```typescript
197
- * const result = await notary.lookup('abc123def456...');
198
- * if (result.found && result.verification?.valid) {
199
- * console.log('Receipt is valid!');
200
- * }
201
- * ```
302
+ * @param options - Pagination, filters, and Clerk token
303
+ * @returns Paginated history with items, total, totalPages
202
304
  */
203
- async lookup(receiptHash) {
204
- const url = `${this.baseUrl}/v1/notary/r/${receiptHash}`;
305
+ async history(options = {}) {
306
+ const params = new URLSearchParams();
307
+ params.set("page", String(options.page || 1));
308
+ params.set("page_size", String(options.pageSize || 10));
309
+ if (options.status) params.set("status", options.status);
310
+ if (options.search) params.set("search", options.search);
311
+ if (options.startDate) params.set("start_date", options.startDate);
312
+ if (options.endDate) params.set("end_date", options.endDate);
313
+ const url = `${this.baseUrl}/v1/notary/history?${params.toString()}`;
314
+ const headers = {
315
+ "Content-Type": "application/json",
316
+ "User-Agent": `notary-typescript-sdk/${SDK_VERSION}`
317
+ };
318
+ if (options.clerkToken) {
319
+ headers["Authorization"] = `Bearer ${options.clerkToken}`;
320
+ } else {
321
+ headers["X-API-Key"] = this.apiKey;
322
+ }
205
323
  const controller = new AbortController();
206
324
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
207
325
  try {
208
326
  const response = await fetch(url, {
209
327
  method: "GET",
210
- headers: {
211
- "Content-Type": "application/json",
212
- "User-Agent": `notary-typescript-sdk/${SDK_VERSION}`
213
- },
328
+ headers,
214
329
  signal: controller.signal
215
330
  });
216
331
  clearTimeout(timeoutId);
217
- if (response.status === 404) {
218
- return { found: false, receipt: null, verification: null, meta: null };
219
- }
220
332
  if (!response.ok) {
221
- throw new NotaryError(
222
- response.statusText,
223
- "ERR_LOOKUP",
224
- response.status
225
- );
333
+ throw new NotaryError(response.statusText, "ERR_HISTORY", response.status);
226
334
  }
227
335
  return await response.json();
228
336
  } catch (err) {
229
337
  clearTimeout(timeoutId);
230
338
  if (err instanceof NotaryError) throw err;
231
- throw new NotaryError(
232
- `Connection failed: ${err.message}`,
233
- "ERR_CONNECTION"
234
- );
339
+ throw new NotaryError(`Connection failed: ${err.message}`, "ERR_CONNECTION");
235
340
  }
236
341
  }
342
+ /**
343
+ * Get the provenance DAG report for a receipt (public).
344
+ *
345
+ * @param receiptHash - The receipt hash to check
346
+ * @returns Provenance report with grounding status, ancestors, paths
347
+ */
348
+ async provenance(receiptHash) {
349
+ return this.publicGet(`/v1/notary/r/${receiptHash}/provenance`);
350
+ }
351
+ // =========================================================================
352
+ // Auto-receipting (wrap)
353
+ // =========================================================================
354
+ /**
355
+ * Wrap an object so method calls are automatically receipted.
356
+ *
357
+ * Uses ES6 Proxy to intercept method calls. Receipts are issued
358
+ * in the background via fire-and-forget (won't slow down your agent).
359
+ *
360
+ * @param obj - The agent or object to wrap
361
+ * @param config - Optional auto-receipt configuration
362
+ * @returns A proxied version of the object
363
+ *
364
+ * @example
365
+ * ```typescript
366
+ * const agent = notary.wrap(myAgent, { mode: 'all', fireAndForget: true });
367
+ * await agent.processData(input); // auto-receipted!
368
+ * ```
369
+ */
370
+ wrap(obj, config = {}) {
371
+ const client = this;
372
+ const cfg = {
373
+ mode: config.mode || "all",
374
+ sampleRate: config.sampleRate ?? 1,
375
+ fireAndForget: config.fireAndForget ?? true,
376
+ maxPayloadBytes: config.maxPayloadBytes ?? 4096,
377
+ dryRun: config.dryRun ?? false
378
+ };
379
+ const className = obj.constructor?.name || "UnknownAgent";
380
+ let lastHash;
381
+ return new Proxy(obj, {
382
+ get(target, prop, receiver) {
383
+ const value = Reflect.get(target, prop, receiver);
384
+ if (typeof value !== "function" || typeof prop !== "string" || prop.startsWith("_")) {
385
+ return value;
386
+ }
387
+ return async function(...args) {
388
+ const start = performance.now();
389
+ let status = "success";
390
+ let errorType;
391
+ let result;
392
+ try {
393
+ result = await value.apply(target, args);
394
+ return result;
395
+ } catch (err) {
396
+ status = "error";
397
+ errorType = err.constructor?.name || "Error";
398
+ throw err;
399
+ } finally {
400
+ const shouldReceipt = cfg.mode === "all" || cfg.mode === "errors_only" && status === "error" || cfg.mode === "sample" && Math.random() < cfg.sampleRate;
401
+ if (shouldReceipt) {
402
+ const durationMs = Math.round((performance.now() - start) * 100) / 100;
403
+ const payload = {
404
+ agent: className,
405
+ auto_receipt: true,
406
+ function: prop,
407
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
408
+ duration_ms: durationMs,
409
+ status,
410
+ error_type: errorType,
411
+ arguments: _safeRepr(args),
412
+ result_summary: _safeRepr(result)
413
+ };
414
+ if (cfg.dryRun) {
415
+ console.error(`[NotaryOS DRY RUN] ${String(prop)}: ${JSON.stringify(payload)}`);
416
+ } else if (cfg.fireAndForget) {
417
+ client.issue(String(prop), payload, { previousReceiptHash: lastHash }).then((r) => {
418
+ if (r.receipt_hash) lastHash = r.receipt_hash;
419
+ }).catch(() => {
420
+ });
421
+ } else {
422
+ try {
423
+ const r = await client.issue(String(prop), payload, {
424
+ previousReceiptHash: lastHash
425
+ });
426
+ if (r.receipt_hash) lastHash = r.receipt_hash;
427
+ } catch {
428
+ }
429
+ }
430
+ }
431
+ }
432
+ };
433
+ }
434
+ });
435
+ }
237
436
  };
238
437
  _NotaryClient.DEFAULT_BASE_URL = "https://api.agenttownsquare.com";
239
438
  _NotaryClient.DEFAULT_TIMEOUT = 3e4;
@@ -263,10 +462,21 @@ async function computeHash(payload) {
263
462
  }
264
463
  return hex;
265
464
  }
465
+ function _safeRepr(value, depth = 3) {
466
+ if (depth <= 0) return value != null ? "..." : null;
467
+ if (value === null || value === void 0) return value;
468
+ if (typeof value === "boolean" || typeof value === "number") return value;
469
+ if (typeof value === "string") return value.length > 500 ? value.slice(0, 500) : value;
470
+ if (Array.isArray(value)) return `<array len=${value.length}>`;
471
+ if (typeof value === "object") return `<object keys=${Object.keys(value).length}>`;
472
+ return `<${typeof value}>`;
473
+ }
266
474
  export {
267
475
  AuthenticationError,
476
+ CounterfactualClient,
268
477
  NotaryClient,
269
478
  NotaryError,
479
+ NotaryErrorCode,
270
480
  RateLimitError,
271
481
  SDK_VERSION,
272
482
  ValidationError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notaryos",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "NotaryOS SDK - Cryptographic receipts for AI agent actions. Issue, verify, and audit agent behavior with Ed25519 signatures.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -38,10 +38,10 @@
38
38
  ],
39
39
  "author": {
40
40
  "name": "Agent Town Square",
41
- "email": "hello@agenttownsquare.com",
42
- "url": "https://agenttownsquare.com"
41
+ "email": "hello@notaryos.org",
42
+ "url": "https://notaryos.org"
43
43
  },
44
- "license": "MIT",
44
+ "license": "BUSL-1.1",
45
45
  "repository": {
46
46
  "type": "git",
47
47
  "url": "https://github.com/hellothere012/notaryos"