@countersign/sdk 0.1.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2026 Simon Crean. All rights reserved.
2
+
3
+ This software and its source code (the "Software") are proprietary and
4
+ confidential. No license, right, or permission is granted to use, copy, modify,
5
+ merge, publish, distribute, sublicense, or sell copies of the Software, in whole
6
+ or in part, except with the prior written permission of the copyright holder.
7
+
8
+ Unauthorized copying, distribution, or use of the Software is strictly prohibited.
9
+
10
+ NOTE (intent): Countersign follows an open-core direction. Specific "front door"
11
+ components — the EnforcementProvider interface, the API contract, the SDK, and
12
+ the MCP server (packages: core interface, api-contract, sdk, mcp) — are expected
13
+ to be re-licensed under a permissive open-source license (e.g. MIT/Apache-2.0) to
14
+ drive adoption, while the control-plane "brain" (policy compiler, ledger, anomaly
15
+ engine, hosted Core) remains proprietary. Until that re-licensing is explicitly
16
+ published, all rights are reserved.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED. IT IS A TESTNET-ONLY PROOF AND HAS NOT BEEN SECURITY-AUDITED. DO NOT USE
20
+ WITH MAINNET FUNDS OR IN PRODUCTION CUSTODY OF REAL ASSETS.
package/dist/index.cjs ADDED
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ CountersignApiError: () => CountersignApiError,
24
+ CountersignClient: () => CountersignClient
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var import_api_contract = require("@countersign/api-contract");
28
+ var CountersignApiError = class extends Error {
29
+ constructor(status, body) {
30
+ super(`Countersign API ${status}: ${body}`);
31
+ this.status = status;
32
+ this.body = body;
33
+ this.name = "CountersignApiError";
34
+ }
35
+ status;
36
+ body;
37
+ };
38
+ var CountersignClient = class {
39
+ baseUrl;
40
+ doFetch;
41
+ constructor(opts) {
42
+ this.baseUrl = opts.baseUrl.replace(/\/$/, "");
43
+ this.doFetch = opts.fetch ?? fetch;
44
+ }
45
+ /** Liveness + per-backend health. */
46
+ health() {
47
+ return this.request("GET", "/health");
48
+ }
49
+ /** Every provisioned agent across all backends. */
50
+ agents() {
51
+ return this.request("GET", "/agents");
52
+ }
53
+ /** Compile + apply one unified policy across backends (fail-closed). */
54
+ applyPolicy(req) {
55
+ return this.request("POST", "/policy", req);
56
+ }
57
+ /** The kill switch — freeze every agent on every backend. */
58
+ freeze(req = {}) {
59
+ return this.request("POST", "/freeze", req);
60
+ }
61
+ /** Pre-flight guard: ask Countersign whether a spend is allowed BEFORE touching the wallet. */
62
+ evaluate(req) {
63
+ return this.request("POST", "/evaluate", req);
64
+ }
65
+ /** Spends currently held pending human approval. */
66
+ approvals() {
67
+ return this.request("GET", "/approvals");
68
+ }
69
+ /** Approve a pending spend (rejected if the system is frozen — fail-closed). */
70
+ approve(req) {
71
+ return this.request("POST", "/approve", req);
72
+ }
73
+ /** Deny a pending spend. */
74
+ deny(req) {
75
+ return this.request("POST", "/deny", req);
76
+ }
77
+ /** Lift a freeze (replay / recover). */
78
+ unfreeze() {
79
+ return this.request("POST", "/unfreeze", {});
80
+ }
81
+ /** The append-only, hash-chained ledger, re-verified at read time. */
82
+ ledger() {
83
+ return this.request("GET", "/ledger");
84
+ }
85
+ /**
86
+ * Subscribe to the live event stream (ledger appends, freeze reports). Returns an unsubscribe
87
+ * function. Uses the global WebSocket — available in browsers and Node 22+.
88
+ */
89
+ subscribe(onMessage) {
90
+ const url = this.baseUrl.replace(/^http/, "ws") + import_api_contract.WS_PATH;
91
+ const ws = new WebSocket(url);
92
+ ws.addEventListener("message", (ev) => {
93
+ try {
94
+ onMessage(JSON.parse(String(ev.data)));
95
+ } catch {
96
+ }
97
+ });
98
+ return () => ws.close();
99
+ }
100
+ async request(method, path, body) {
101
+ const init = { method };
102
+ if (body !== void 0) {
103
+ init.headers = { "content-type": "application/json" };
104
+ init.body = JSON.stringify(body);
105
+ }
106
+ const res = await this.doFetch(this.baseUrl + path, init);
107
+ if (!res.ok) throw new CountersignApiError(res.status, await res.text());
108
+ return await res.json();
109
+ }
110
+ };
111
+ // Annotate the CommonJS export names for ESM import in node:
112
+ 0 && (module.exports = {
113
+ CountersignApiError,
114
+ CountersignClient
115
+ });
@@ -0,0 +1,61 @@
1
+ import { CountersignApi, HealthResponse, AgentsResponse, ApplyPolicyRequest, ApplyPolicyResult, FreezeRequest, FreezeResponse, EvaluateRequest, EvaluateResponse, ApprovalsResponse, ApproveRequest, ApprovalResolution, DenyRequest, LedgerResponse, WsServerMessage } from '@countersign/api-contract';
2
+ export { AgentDTO, AgentsResponse, ApplyPolicyRequest, ApplyPolicyResult, ApprovalResolution, ApprovalsResponse, ApproveRequest, CountersignApi, DenyRequest, EvaluateRequest, EvaluateResponse, FreezeRequest, FreezeResponse, HealthResponse, LedgerRecordDTO, LedgerResponse, PendingApprovalDTO, ProviderHealth, WsServerMessage } from '@countersign/api-contract';
3
+
4
+ /**
5
+ * @countersign/sdk — the front door (roadmap Tier 0 #4). A tiny typed client over the Core API so an
6
+ * agent operator wires Countersign in trivially. Works in Node (22+) and the browser — uses only global
7
+ * fetch + WebSocket, no dependencies beyond the shared contract. The Flutter/Dart client is
8
+ * generated from the same api-contract; this is its TypeScript twin.
9
+ *
10
+ * const countersign = new CountersignClient({ baseUrl: "http://localhost:8080" });
11
+ * await countersign.applyPolicy({ policy }); // compile + apply across every backend
12
+ * const stop = countersign.subscribe((m) => ...); // live ledger stream
13
+ * await countersign.freeze({ reason: "kill switch" }); // one call, every vendor, < 1s
14
+ */
15
+
16
+ declare class CountersignApiError extends Error {
17
+ readonly status: number;
18
+ readonly body: string;
19
+ constructor(status: number, body: string);
20
+ }
21
+ interface CountersignClientOptions {
22
+ baseUrl: string;
23
+ /** Override fetch (tests / non-global environments). Defaults to the global fetch. */
24
+ fetch?: typeof fetch;
25
+ }
26
+ declare class CountersignClient implements CountersignApi {
27
+ private readonly baseUrl;
28
+ private readonly doFetch;
29
+ constructor(opts: CountersignClientOptions);
30
+ /** Liveness + per-backend health. */
31
+ health(): Promise<HealthResponse>;
32
+ /** Every provisioned agent across all backends. */
33
+ agents(): Promise<AgentsResponse>;
34
+ /** Compile + apply one unified policy across backends (fail-closed). */
35
+ applyPolicy(req: ApplyPolicyRequest): Promise<ApplyPolicyResult>;
36
+ /** The kill switch — freeze every agent on every backend. */
37
+ freeze(req?: FreezeRequest): Promise<FreezeResponse>;
38
+ /** Pre-flight guard: ask Countersign whether a spend is allowed BEFORE touching the wallet. */
39
+ evaluate(req: EvaluateRequest): Promise<EvaluateResponse>;
40
+ /** Spends currently held pending human approval. */
41
+ approvals(): Promise<ApprovalsResponse>;
42
+ /** Approve a pending spend (rejected if the system is frozen — fail-closed). */
43
+ approve(req: ApproveRequest): Promise<ApprovalResolution>;
44
+ /** Deny a pending spend. */
45
+ deny(req: DenyRequest): Promise<ApprovalResolution>;
46
+ /** Lift a freeze (replay / recover). */
47
+ unfreeze(): Promise<{
48
+ ok: boolean;
49
+ }>;
50
+ /** The append-only, hash-chained ledger, re-verified at read time. */
51
+ ledger(): Promise<LedgerResponse>;
52
+ /**
53
+ * Subscribe to the live event stream (ledger appends, freeze reports). Returns an unsubscribe
54
+ * function. Uses the global WebSocket — available in browsers and Node 22+.
55
+ */
56
+ subscribe(onMessage: (message: WsServerMessage) => void): () => void;
57
+ private request;
58
+ }
59
+
60
+ export { CountersignApiError, CountersignClient };
61
+ export type { CountersignClientOptions };
package/dist/index.js ADDED
@@ -0,0 +1,91 @@
1
+ // src/index.ts
2
+ import {
3
+ WS_PATH
4
+ } from "@countersign/api-contract";
5
+ var CountersignApiError = class extends Error {
6
+ constructor(status, body) {
7
+ super(`Countersign API ${status}: ${body}`);
8
+ this.status = status;
9
+ this.body = body;
10
+ this.name = "CountersignApiError";
11
+ }
12
+ status;
13
+ body;
14
+ };
15
+ var CountersignClient = class {
16
+ baseUrl;
17
+ doFetch;
18
+ constructor(opts) {
19
+ this.baseUrl = opts.baseUrl.replace(/\/$/, "");
20
+ this.doFetch = opts.fetch ?? fetch;
21
+ }
22
+ /** Liveness + per-backend health. */
23
+ health() {
24
+ return this.request("GET", "/health");
25
+ }
26
+ /** Every provisioned agent across all backends. */
27
+ agents() {
28
+ return this.request("GET", "/agents");
29
+ }
30
+ /** Compile + apply one unified policy across backends (fail-closed). */
31
+ applyPolicy(req) {
32
+ return this.request("POST", "/policy", req);
33
+ }
34
+ /** The kill switch — freeze every agent on every backend. */
35
+ freeze(req = {}) {
36
+ return this.request("POST", "/freeze", req);
37
+ }
38
+ /** Pre-flight guard: ask Countersign whether a spend is allowed BEFORE touching the wallet. */
39
+ evaluate(req) {
40
+ return this.request("POST", "/evaluate", req);
41
+ }
42
+ /** Spends currently held pending human approval. */
43
+ approvals() {
44
+ return this.request("GET", "/approvals");
45
+ }
46
+ /** Approve a pending spend (rejected if the system is frozen — fail-closed). */
47
+ approve(req) {
48
+ return this.request("POST", "/approve", req);
49
+ }
50
+ /** Deny a pending spend. */
51
+ deny(req) {
52
+ return this.request("POST", "/deny", req);
53
+ }
54
+ /** Lift a freeze (replay / recover). */
55
+ unfreeze() {
56
+ return this.request("POST", "/unfreeze", {});
57
+ }
58
+ /** The append-only, hash-chained ledger, re-verified at read time. */
59
+ ledger() {
60
+ return this.request("GET", "/ledger");
61
+ }
62
+ /**
63
+ * Subscribe to the live event stream (ledger appends, freeze reports). Returns an unsubscribe
64
+ * function. Uses the global WebSocket — available in browsers and Node 22+.
65
+ */
66
+ subscribe(onMessage) {
67
+ const url = this.baseUrl.replace(/^http/, "ws") + WS_PATH;
68
+ const ws = new WebSocket(url);
69
+ ws.addEventListener("message", (ev) => {
70
+ try {
71
+ onMessage(JSON.parse(String(ev.data)));
72
+ } catch {
73
+ }
74
+ });
75
+ return () => ws.close();
76
+ }
77
+ async request(method, path, body) {
78
+ const init = { method };
79
+ if (body !== void 0) {
80
+ init.headers = { "content-type": "application/json" };
81
+ init.body = JSON.stringify(body);
82
+ }
83
+ const res = await this.doFetch(this.baseUrl + path, init);
84
+ if (!res.ok) throw new CountersignApiError(res.status, await res.text());
85
+ return await res.json();
86
+ }
87
+ };
88
+ export {
89
+ CountersignApiError,
90
+ CountersignClient
91
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@countersign/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Countersign SDK — the typed client agents and operators use to wire in the cross-vendor freeze, spend-guard, and live audit ledger. Browser + Node.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/countersign-network/countersign.git",
25
+ "directory": "packages/sdk"
26
+ },
27
+ "homepage": "https://countersign.network",
28
+ "keywords": [
29
+ "countersign",
30
+ "ai-agents",
31
+ "agent-payments",
32
+ "sdk",
33
+ "kill-switch",
34
+ "x402"
35
+ ],
36
+ "dependencies": {
37
+ "@countersign/api-contract": "^0.1.0"
38
+ },
39
+ "devDependencies": {
40
+ "tsup": "^8.5.1",
41
+ "@countersign/core": "0.0.0",
42
+ "@countersign/api": "0.0.0",
43
+ "@countersign/policy": "0.0.0",
44
+ "@countersign/provider-mock": "0.0.0"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc -p ../../tsconfig.dts.json && tsup && rollup -c rollup.dts.config.mjs"
48
+ },
49
+ "module": "./dist/index.js"
50
+ }