@truststate/sdk 0.2.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.
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ /**
3
+ * TrustState middleware for Express and Next.js.
4
+ *
5
+ * @example Express
6
+ * ```typescript
7
+ * import express from "express";
8
+ * import { TrustStateClient, trustStateMiddleware } from "@truststate/sdk";
9
+ *
10
+ * const app = express();
11
+ * const client = new TrustStateClient({ apiKey: "your-key" });
12
+ * app.use(express.json());
13
+ * app.use(trustStateMiddleware(client));
14
+ * ```
15
+ *
16
+ * @example Next.js API route
17
+ * ```typescript
18
+ * import { withCompliance } from "@truststate/sdk";
19
+ * import { client } from "@/lib/truststate";
20
+ *
21
+ * export default withCompliance(client, "AgentResponse", async (req, res) => {
22
+ * res.json({ message: "Compliant response" });
23
+ * });
24
+ * ```
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.trustStateMiddleware = trustStateMiddleware;
28
+ exports.withCompliance = withCompliance;
29
+ // ---------------------------------------------------------------------------
30
+ // Express middleware
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * Express middleware that gates requests on TrustState compliance.
34
+ *
35
+ * Reads X-Compliance-Entity-Type and X-Compliance-Action headers.
36
+ * If X-Compliance-Entity-Type is present (or defaultEntityType is set),
37
+ * the request body is submitted to TrustState before the request proceeds.
38
+ *
39
+ * Failed checks return HTTP 422. Passed checks attach X-Compliance-Record-Id
40
+ * to the response headers.
41
+ */
42
+ function trustStateMiddleware(client, options = {}) {
43
+ const { defaultEntityType, defaultAction = "CREATE", entityIdHeader = "X-Compliance-Entity-Id", } = options;
44
+ return async function (req, res, next) {
45
+ const entityType = req.headers["x-compliance-entity-type"] ??
46
+ defaultEntityType;
47
+ // Pass through if no entity type configured
48
+ if (!entityType) {
49
+ next();
50
+ return;
51
+ }
52
+ const action = req.headers["x-compliance-action"] ?? defaultAction;
53
+ const entityId = req.headers[entityIdHeader.toLowerCase()];
54
+ const data = req.body ?? {};
55
+ try {
56
+ const result = await client.check(entityType, data, {
57
+ action,
58
+ entityId: entityId ?? undefined,
59
+ });
60
+ if (!result.passed) {
61
+ res.status(422).json({
62
+ error: "Compliance check failed",
63
+ failReason: result.failReason,
64
+ failedStep: result.failedStep,
65
+ entityId: result.entityId,
66
+ });
67
+ return;
68
+ }
69
+ // Attach record ID to response for downstream use
70
+ if (result.recordId) {
71
+ res.setHeader("X-Compliance-Record-Id", result.recordId);
72
+ }
73
+ next();
74
+ }
75
+ catch (err) {
76
+ res.status(503).json({
77
+ error: "Compliance service unavailable",
78
+ detail: err.message,
79
+ });
80
+ }
81
+ };
82
+ }
83
+ // ---------------------------------------------------------------------------
84
+ // Next.js route handler wrapper
85
+ // ---------------------------------------------------------------------------
86
+ /**
87
+ * Wraps a Next.js API route handler with TrustState compliance checking.
88
+ *
89
+ * The request body is submitted to TrustState before the handler runs.
90
+ * Returns 422 if the check fails.
91
+ *
92
+ * @param client - TrustStateClient instance.
93
+ * @param entityType - The TrustState entity type to validate against.
94
+ * @param handler - The Next.js route handler to wrap.
95
+ * @param options - Optional action and entityIdHeader overrides.
96
+ */
97
+ function withCompliance(client, entityType, handler, options = {}) {
98
+ const { action = "CREATE", entityIdHeader = "x-compliance-entity-id" } = options;
99
+ return async function (req, res) {
100
+ const entityId = req.headers[entityIdHeader];
101
+ const data = req.body ?? {};
102
+ try {
103
+ const result = await client.check(entityType, data, {
104
+ action,
105
+ entityId: entityId ?? undefined,
106
+ });
107
+ if (!result.passed) {
108
+ res.status(422).json({
109
+ error: "Compliance check failed",
110
+ failReason: result.failReason,
111
+ failedStep: result.failedStep,
112
+ entityId: result.entityId,
113
+ });
114
+ return;
115
+ }
116
+ if (result.recordId) {
117
+ res.setHeader("X-Compliance-Record-Id", result.recordId);
118
+ }
119
+ await handler(req, res);
120
+ }
121
+ catch (err) {
122
+ res.status(503).json({
123
+ error: "Compliance service unavailable",
124
+ detail: err.message,
125
+ });
126
+ }
127
+ };
128
+ }
129
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * TrustState SDK — TypeScript type definitions.
3
+ */
4
+ /** Result of a single compliance check. */
5
+ export interface ComplianceResult {
6
+ /** True if all compliance checks passed. */
7
+ passed: boolean;
8
+ /** Immutable ledger record ID — only present when passed=true. */
9
+ recordId?: string;
10
+ /** Unique API request identifier (useful for support/debugging). */
11
+ requestId: string;
12
+ /** The entity identifier submitted (caller-supplied or auto-generated). */
13
+ entityId: string;
14
+ /** Human-readable reason for failure — only present when passed=false. */
15
+ failReason?: string;
16
+ /** Numeric step that failed. 8 = schema validation, 9 = policy check. */
17
+ failedStep?: number;
18
+ /** Feed label from the batch request — useful for identifying source feeds. */
19
+ feedLabel?: string | null;
20
+ /** True when this result was synthesised locally in mock mode (no HTTP call). */
21
+ mock: boolean;
22
+ }
23
+ /** Aggregated result for a batch compliance submission. */
24
+ export interface BatchResult {
25
+ /** Unique identifier for this batch request. */
26
+ batchId: string;
27
+ /** Total number of items submitted. */
28
+ total: number;
29
+ /** Number of items that passed compliance checks. */
30
+ accepted: number;
31
+ /** Number of items that failed compliance checks. */
32
+ rejected: number;
33
+ /** Per-item results in the same order as the submitted items. */
34
+ results: ComplianceResult[];
35
+ /** Feed label echoed from the batch request. */
36
+ feedLabel?: string | null;
37
+ /** True when running in mock mode (no HTTP calls made). */
38
+ mock: boolean;
39
+ }
40
+ /** A single item in a batch submission. */
41
+ export interface CheckItem {
42
+ /** The TrustState entity type (e.g. "AgentResponse", "Transaction"). */
43
+ entityType: string;
44
+ /** The record payload to validate. */
45
+ data: Record<string, unknown>;
46
+ /** Action being performed. Defaults to "CREATE". */
47
+ action?: string;
48
+ /** Optional stable entity identifier. Auto-generated if omitted. */
49
+ entityId?: string;
50
+ /** Schema version to validate against. Uses client default if omitted. */
51
+ schemaVersion?: string;
52
+ /** Actor ID for the audit trail. Uses client default if omitted. */
53
+ actorId?: string;
54
+ }
55
+ /** A single oracle evidence item to submit alongside a compliance write. */
56
+ export interface EvidenceItem {
57
+ /** Unique ID for this evidence item. Auto-generated if not set. */
58
+ evidenceId: string;
59
+ /** Registered oracle provider ID (e.g. "reuters-fx"). */
60
+ providerId: string;
61
+ /** Oracle provider type (e.g. "fx_rate", "kyc_status"). */
62
+ providerType: string;
63
+ /** Key-value subject descriptor (e.g. { from: "MYR", to: "USD" }). */
64
+ subject: Record<string, unknown>;
65
+ /** The oracle-reported value. */
66
+ observedValue: string | number;
67
+ /** ISO-8601 timestamp when the value was observed by the oracle. */
68
+ observedAt: string;
69
+ /** ISO-8601 timestamp when you fetched this value. Defaults to now. */
70
+ retrievedAt: string;
71
+ /** Maximum acceptable age of this evidence in seconds. Default 300. */
72
+ maxAgeSeconds: number;
73
+ /** Optional sha256:<hex> hash of the raw proof document. */
74
+ proofHash?: string;
75
+ /** Optional URL for the raw proof document (background verified by TrustState). */
76
+ rawProofUri?: string;
77
+ /** Optional cryptographic attestation from the oracle provider. */
78
+ attestation?: {
79
+ type: string;
80
+ algorithm: string;
81
+ signature: string;
82
+ };
83
+ /** True when synthesised locally in mock mode. */
84
+ mock?: boolean;
85
+ }
86
+ /** Options for check_batch / checkBatch. */
87
+ export interface BatchOptions {
88
+ /** Optional label identifying this feed/source (e.g. "core-banking-feed"). */
89
+ feedLabel?: string;
90
+ /** Override default schema version for this batch. */
91
+ defaultSchemaVersion?: string;
92
+ /** Override default actor ID for this batch. */
93
+ defaultActorId?: string;
94
+ }
95
+ /** Constructor options for TrustStateClient. */
96
+ export interface TrustStateClientOptions {
97
+ /** Your TrustState API key (sent as X-API-Key header). */
98
+ apiKey: string;
99
+ /** Override the default API base URL. */
100
+ baseUrl?: string;
101
+ /**
102
+ * Default schema version applied when not specified per-call.
103
+ * If omitted, the server auto-resolves to the active schema for each entity type.
104
+ */
105
+ defaultSchemaVersion?: string;
106
+ /** Default actor ID for the audit trail. */
107
+ defaultActorId?: string;
108
+ /**
109
+ * Enable mock mode. When true, all HTTP calls are skipped and
110
+ * synthetic results are returned locally.
111
+ */
112
+ mock?: boolean;
113
+ /**
114
+ * Probability (0.0–1.0) that a mock check returns passed=true.
115
+ * 1.0 = always pass, 0.0 = always fail.
116
+ */
117
+ mockPassRate?: number;
118
+ /** HTTP request timeout in milliseconds. */
119
+ timeoutMs?: number;
120
+ }
121
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,MAAM,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iFAAiF;IACjF,IAAI,EAAE,OAAO,CAAC;CACf;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,2DAA2D;IAC3D,IAAI,EAAE,OAAO,CAAC;CACf;AAED,2CAA2C;AAC3C,MAAM,WAAW,SAAS;IACxB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,iCAAiC;IACjC,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,kDAAkD;IAClD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,gDAAgD;AAChD,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * TrustState SDK — TypeScript type definitions.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@truststate/sdk",
3
+ "version": "0.2.0",
4
+ "description": "TypeScript/JavaScript SDK for TrustState compliance validation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "commonjs",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": ["dist", "src", "README.md", "LICENSE"],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "test": "jest",
19
+ "test:watch": "jest --watch",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "keywords": ["truststate", "compliance", "AI governance", "audit", "fintech"],
23
+ "license": "MIT",
24
+ "dependencies": {},
25
+ "devDependencies": {
26
+ "typescript": "^5",
27
+ "@types/node": "^20",
28
+ "jest": "^29",
29
+ "@types/jest": "^29",
30
+ "ts-jest": "^29"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/MyreneBot/truststate-js"
35
+ },
36
+ "homepage": "https://trustchainlabs.com",
37
+ "jest": {
38
+ "preset": "ts-jest",
39
+ "testEnvironment": "node",
40
+ "moduleNameMapper": {
41
+ "^(\\.{1,2}/.*)\\.js$": "$1"
42
+ },
43
+ "testMatch": ["**/tests/**/*.test.ts"]
44
+ }
45
+ }