@atbash/sdk 0.3.1 → 0.3.2

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.cjs CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  DEFAULT_BLOCKCHAIN_RID: () => DEFAULT_BLOCKCHAIN_RID,
34
34
  DEFAULT_CHROMIA_NODE_URLS: () => DEFAULT_CHROMIA_NODE_URLS,
35
35
  DEFAULT_ENDPOINT: () => DEFAULT_ENDPOINT,
36
+ checkAgentExists: () => checkAgentExists,
36
37
  derivePublicKey: () => derivePublicKey,
37
38
  generateKeyPair: () => generateKeyPair,
38
39
  getAgentDetail: () => getAgentDetail,
@@ -59,7 +60,7 @@ module.exports = __toCommonJS(index_exports);
59
60
  var import_crypto = require("crypto");
60
61
  var import_postchain_client = __toESM(require("postchain-client"), 1);
61
62
  var { createClient, encryption, newSignatureProvider } = import_postchain_client.default;
62
- var DEFAULT_ENDPOINT = "https://atbash.ai";
63
+ var DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
63
64
  var DEFAULT_CHROMIA_NODE_URLS = [
64
65
  "https://node6.testnet.chromia.com:7740",
65
66
  "https://node7.testnet.chromia.com:7740",
@@ -109,41 +110,67 @@ function generateToolCallId() {
109
110
  const rand = (0, import_crypto.randomBytes)(4).toString("hex");
110
111
  return `tc-${ts}-${rand}`;
111
112
  }
112
- async function logToolCall(action, context, auth, chainOpts, extra) {
113
- const nodeUrls = chainOpts?.nodeUrls ?? DEFAULT_CHROMIA_NODE_URLS;
114
- const blockchainRid = chainOpts?.blockchainRid ?? DEFAULT_BLOCKCHAIN_RID;
115
- const client = await createClient({
116
- nodeUrlPool: nodeUrls,
117
- blockchainRid
118
- });
119
- const privKeyBuf = Buffer.from(auth.privkey, "hex");
120
- const keyPair = encryption.makeKeyPair(privKeyBuf);
121
- const sigProvider = newSignatureProvider({
122
- privKey: keyPair.privKey,
123
- pubKey: keyPair.pubKey
124
- });
125
- const toolCallId = generateToolCallId();
126
- await client.signAndSendUniqueTransaction(
127
- {
128
- name: "log_tool_call",
129
- args: [
130
- toolCallId,
131
- action,
132
- context || "",
133
- extra?.toolName || "",
134
- extra?.toolArgsJson || ""
135
- ]
136
- },
137
- sigProvider
138
- );
139
- return toolCallId;
113
+ async function checkAgentExists(pubkey, opts) {
114
+ try {
115
+ const url = `${baseUrl(opts)}/api/ai/exists?pubkey=${encodeURIComponent(pubkey)}`;
116
+ const data = await getJson(url, opts);
117
+ return Boolean(data.registered);
118
+ } catch {
119
+ return false;
120
+ }
121
+ }
122
+ async function logToolCall(action, context, auth, chainOpts, extra, clientOpts) {
123
+ const exists = await checkAgentExists(auth.pubkey, clientOpts);
124
+ if (!exists) {
125
+ return {
126
+ success: false,
127
+ toolCallId: null,
128
+ error: "Agent not registered. Onboard the agent at the dashboard before submitting actions."
129
+ };
130
+ }
131
+ try {
132
+ const nodeUrls = chainOpts?.nodeUrls ?? DEFAULT_CHROMIA_NODE_URLS;
133
+ const blockchainRid = chainOpts?.blockchainRid ?? DEFAULT_BLOCKCHAIN_RID;
134
+ const client = await createClient({
135
+ nodeUrlPool: nodeUrls,
136
+ blockchainRid
137
+ });
138
+ const privKeyBuf = Buffer.from(auth.privkey, "hex");
139
+ const keyPair = encryption.makeKeyPair(privKeyBuf);
140
+ const sigProvider = newSignatureProvider({
141
+ privKey: keyPair.privKey,
142
+ pubKey: keyPair.pubKey
143
+ });
144
+ const toolCallId = generateToolCallId();
145
+ await client.signAndSendUniqueTransaction(
146
+ {
147
+ name: "log_tool_call",
148
+ args: [
149
+ toolCallId,
150
+ action,
151
+ context || "",
152
+ extra?.toolName || "",
153
+ extra?.toolArgsJson || ""
154
+ ]
155
+ },
156
+ sigProvider
157
+ );
158
+ return { success: true, toolCallId };
159
+ } catch (err) {
160
+ return {
161
+ success: false,
162
+ toolCallId: null,
163
+ error: err instanceof Error ? err.message : "Failed to log tool call on-chain"
164
+ };
165
+ }
140
166
  }
141
167
  function normalizeVerdict(raw) {
142
- const v = String(raw || "").toUpperCase();
168
+ if (raw === null || raw === void 0) return "LOGGED";
169
+ const v = String(raw).toUpperCase();
143
170
  if (v === "ALLOW" || v === "GREEN") return "ALLOW";
144
171
  if (v === "HOLD" || v === "YELLOW") return "HOLD";
145
172
  if (v === "BLOCK" || v === "RED") return "BLOCK";
146
- return "BLOCK";
173
+ return "HOLD";
147
174
  }
148
175
  function normalizeStatus(raw) {
149
176
  const s = String(raw || "").toLowerCase();
@@ -197,26 +224,30 @@ async function getJson(url, opts) {
197
224
  return resp.json();
198
225
  }
199
226
  async function judgeAction(action, context, auth, opts) {
200
- const toolCallId = await logToolCall(
227
+ const logResult = await logToolCall(
201
228
  action,
202
229
  context,
203
230
  auth,
204
231
  opts?.chainOpts,
205
- { toolName: opts?.toolName, toolArgsJson: opts?.toolArgsJson }
232
+ { toolName: opts?.toolName, toolArgsJson: opts?.toolArgsJson },
233
+ opts
206
234
  );
235
+ if (!logResult.success || !logResult.toolCallId) {
236
+ throw new Error(logResult.error || "Failed to log tool call on-chain");
237
+ }
207
238
  const url = `${baseUrl(opts)}/api/v1/judge`;
208
239
  const data = await postJson(
209
240
  url,
210
241
  {
211
- tool_call_id: toolCallId,
242
+ tool_call_id: logResult.toolCallId,
212
243
  agent_pubkey: auth.pubkey,
213
244
  action,
214
- context: context || "",
215
- provider: opts?.provider || "",
216
- tool_name: opts?.toolName || "",
217
- api_key: opts?.apiKey || "",
218
- endpoint_url: opts?.providerEndpoint || "",
219
- model: opts?.model || ""
245
+ ...context && { context },
246
+ ...opts?.provider && { provider: opts.provider },
247
+ ...opts?.toolName && { tool_name: opts.toolName },
248
+ ...opts?.apiKey && { api_key: opts.apiKey },
249
+ ...opts?.providerEndpoint && { endpoint_url: opts.providerEndpoint },
250
+ ...opts?.model && { model: opts.model }
220
251
  },
221
252
  opts
222
253
  );
@@ -227,7 +258,7 @@ async function judgeAction(action, context, auth, opts) {
227
258
  confidence: Number(data.confidence ?? 0),
228
259
  provider: String(data.provider || ""),
229
260
  latency_ms: Number(data.latency_ms ?? 0),
230
- tool_call_id: String(data.tool_call_id || toolCallId),
261
+ tool_call_id: String(data.tool_call_id || logResult.toolCallId),
231
262
  on_chain: Boolean(data.on_chain)
232
263
  };
233
264
  }
@@ -351,6 +382,7 @@ async function getSafetyStats(opts) {
351
382
  DEFAULT_BLOCKCHAIN_RID,
352
383
  DEFAULT_CHROMIA_NODE_URLS,
353
384
  DEFAULT_ENDPOINT,
385
+ checkAgentExists,
354
386
  derivePublicKey,
355
387
  generateKeyPair,
356
388
  getAgentDetail,
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- declare const DEFAULT_ENDPOINT = "https://atbash.ai";
1
+ declare const DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
2
2
  declare const DEFAULT_CHROMIA_NODE_URLS: string[];
3
3
  declare const DEFAULT_BLOCKCHAIN_RID = "25B41DF620C489349C54944496FF5C6E58CFCEFED0C51658780B67299D40E8ED";
4
- type Verdict = "ALLOW" | "HOLD" | "BLOCK";
4
+ type Verdict = "ALLOW" | "HOLD" | "BLOCK" | "LOGGED";
5
5
  type Provider = "atbash" | "openai" | "google" | "microsoft" | "custom" | (string & {});
6
6
  type Tier = "audit" | "audit_plus" | "enforcement" | (string & {});
7
7
  type ActionType = "allow" | "hold_for_user_confirm" | "block" | (string & {});
@@ -29,16 +29,26 @@ interface ChainOpts {
29
29
  nodeUrls?: string[];
30
30
  blockchainRid?: string;
31
31
  }
32
+ interface LogToolCallResult {
33
+ success: boolean;
34
+ toolCallId: string | null;
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Check if an agent is onboarded before signing anything.
39
+ * Calls GET /api/ai/exists?pubkey=<66-hex>
40
+ */
41
+ declare function checkAgentExists(pubkey: string, opts?: ClientOpts): Promise<boolean>;
32
42
  /**
33
43
  * Sign and broadcast `log_tool_call` to the Chromia chain.
34
44
  *
35
- * The agent's private key is used to sign the transaction locally —
36
- * it is never sent over the network. Returns the tool_call_id.
45
+ * Checks that the agent is onboarded before signing. The agent's private
46
+ * key is used to sign the transaction locally — never sent over the network.
37
47
  */
38
48
  declare function logToolCall(action: string, context: string, auth: AgentAuth, chainOpts?: ChainOpts, extra?: {
39
49
  toolName?: string;
40
50
  toolArgsJson?: string;
41
- }): Promise<string>;
51
+ }, clientOpts?: ClientOpts): Promise<LogToolCallResult>;
42
52
  interface JudgeResult {
43
53
  verdict: Verdict;
44
54
  action_type: ActionType;
@@ -137,4 +147,4 @@ declare function getAgentDetail(agentPubkey: string, opts?: ClientOpts): Promise
137
147
  declare function getAgentPolicy(agentPubkey: string, opts?: ClientOpts): Promise<AgentPolicy>;
138
148
  declare function getSafetyStats(opts?: ClientOpts): Promise<Record<string, unknown>>;
139
149
 
140
- export { type AgentAuth, type ChainOpts, type ClientOpts, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, type HeldAction, type HeldActionReview, type JudgeOptions, type JudgeResult, type JudgmentStatus, type TierInfo, type ToolCallFull, type ToolCallRecord, type Verdict, derivePublicKey, generateKeyPair, getAgentDetail, getAgentPolicy, getAgentToolCalls, getHeldActionReviews, getJudgmentStatus, getOrgTierInfo, getOrgToolCalls, getPendingHeldActions, getSafetyStats, getToolCallCount, getToolCallFull, getToolCalls, isValidPrivateKey, judgeAction, loadAgent, logToolCall, toPubkeyHex };
150
+ export { type AgentAuth, type ChainOpts, type ClientOpts, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, type HeldAction, type HeldActionReview, type JudgeOptions, type JudgeResult, type JudgmentStatus, type LogToolCallResult, type TierInfo, type ToolCallFull, type ToolCallRecord, type Verdict, checkAgentExists, derivePublicKey, generateKeyPair, getAgentDetail, getAgentPolicy, getAgentToolCalls, getHeldActionReviews, getJudgmentStatus, getOrgTierInfo, getOrgToolCalls, getPendingHeldActions, getSafetyStats, getToolCallCount, getToolCallFull, getToolCalls, isValidPrivateKey, judgeAction, loadAgent, logToolCall, toPubkeyHex };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- declare const DEFAULT_ENDPOINT = "https://atbash.ai";
1
+ declare const DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
2
2
  declare const DEFAULT_CHROMIA_NODE_URLS: string[];
3
3
  declare const DEFAULT_BLOCKCHAIN_RID = "25B41DF620C489349C54944496FF5C6E58CFCEFED0C51658780B67299D40E8ED";
4
- type Verdict = "ALLOW" | "HOLD" | "BLOCK";
4
+ type Verdict = "ALLOW" | "HOLD" | "BLOCK" | "LOGGED";
5
5
  type Provider = "atbash" | "openai" | "google" | "microsoft" | "custom" | (string & {});
6
6
  type Tier = "audit" | "audit_plus" | "enforcement" | (string & {});
7
7
  type ActionType = "allow" | "hold_for_user_confirm" | "block" | (string & {});
@@ -29,16 +29,26 @@ interface ChainOpts {
29
29
  nodeUrls?: string[];
30
30
  blockchainRid?: string;
31
31
  }
32
+ interface LogToolCallResult {
33
+ success: boolean;
34
+ toolCallId: string | null;
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Check if an agent is onboarded before signing anything.
39
+ * Calls GET /api/ai/exists?pubkey=<66-hex>
40
+ */
41
+ declare function checkAgentExists(pubkey: string, opts?: ClientOpts): Promise<boolean>;
32
42
  /**
33
43
  * Sign and broadcast `log_tool_call` to the Chromia chain.
34
44
  *
35
- * The agent's private key is used to sign the transaction locally —
36
- * it is never sent over the network. Returns the tool_call_id.
45
+ * Checks that the agent is onboarded before signing. The agent's private
46
+ * key is used to sign the transaction locally — never sent over the network.
37
47
  */
38
48
  declare function logToolCall(action: string, context: string, auth: AgentAuth, chainOpts?: ChainOpts, extra?: {
39
49
  toolName?: string;
40
50
  toolArgsJson?: string;
41
- }): Promise<string>;
51
+ }, clientOpts?: ClientOpts): Promise<LogToolCallResult>;
42
52
  interface JudgeResult {
43
53
  verdict: Verdict;
44
54
  action_type: ActionType;
@@ -137,4 +147,4 @@ declare function getAgentDetail(agentPubkey: string, opts?: ClientOpts): Promise
137
147
  declare function getAgentPolicy(agentPubkey: string, opts?: ClientOpts): Promise<AgentPolicy>;
138
148
  declare function getSafetyStats(opts?: ClientOpts): Promise<Record<string, unknown>>;
139
149
 
140
- export { type AgentAuth, type ChainOpts, type ClientOpts, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, type HeldAction, type HeldActionReview, type JudgeOptions, type JudgeResult, type JudgmentStatus, type TierInfo, type ToolCallFull, type ToolCallRecord, type Verdict, derivePublicKey, generateKeyPair, getAgentDetail, getAgentPolicy, getAgentToolCalls, getHeldActionReviews, getJudgmentStatus, getOrgTierInfo, getOrgToolCalls, getPendingHeldActions, getSafetyStats, getToolCallCount, getToolCallFull, getToolCalls, isValidPrivateKey, judgeAction, loadAgent, logToolCall, toPubkeyHex };
150
+ export { type AgentAuth, type ChainOpts, type ClientOpts, DEFAULT_BLOCKCHAIN_RID, DEFAULT_CHROMIA_NODE_URLS, DEFAULT_ENDPOINT, type HeldAction, type HeldActionReview, type JudgeOptions, type JudgeResult, type JudgmentStatus, type LogToolCallResult, type TierInfo, type ToolCallFull, type ToolCallRecord, type Verdict, checkAgentExists, derivePublicKey, generateKeyPair, getAgentDetail, getAgentPolicy, getAgentToolCalls, getHeldActionReviews, getJudgmentStatus, getOrgTierInfo, getOrgToolCalls, getPendingHeldActions, getSafetyStats, getToolCallCount, getToolCallFull, getToolCalls, isValidPrivateKey, judgeAction, loadAgent, logToolCall, toPubkeyHex };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createECDH, randomBytes } from "crypto";
3
3
  import postchain from "postchain-client";
4
4
  var { createClient, encryption, newSignatureProvider } = postchain;
5
- var DEFAULT_ENDPOINT = "https://atbash.ai";
5
+ var DEFAULT_ENDPOINT = "https://chromia-verified-ai-dev-two.vercel.app";
6
6
  var DEFAULT_CHROMIA_NODE_URLS = [
7
7
  "https://node6.testnet.chromia.com:7740",
8
8
  "https://node7.testnet.chromia.com:7740",
@@ -52,41 +52,67 @@ function generateToolCallId() {
52
52
  const rand = randomBytes(4).toString("hex");
53
53
  return `tc-${ts}-${rand}`;
54
54
  }
55
- async function logToolCall(action, context, auth, chainOpts, extra) {
56
- const nodeUrls = chainOpts?.nodeUrls ?? DEFAULT_CHROMIA_NODE_URLS;
57
- const blockchainRid = chainOpts?.blockchainRid ?? DEFAULT_BLOCKCHAIN_RID;
58
- const client = await createClient({
59
- nodeUrlPool: nodeUrls,
60
- blockchainRid
61
- });
62
- const privKeyBuf = Buffer.from(auth.privkey, "hex");
63
- const keyPair = encryption.makeKeyPair(privKeyBuf);
64
- const sigProvider = newSignatureProvider({
65
- privKey: keyPair.privKey,
66
- pubKey: keyPair.pubKey
67
- });
68
- const toolCallId = generateToolCallId();
69
- await client.signAndSendUniqueTransaction(
70
- {
71
- name: "log_tool_call",
72
- args: [
73
- toolCallId,
74
- action,
75
- context || "",
76
- extra?.toolName || "",
77
- extra?.toolArgsJson || ""
78
- ]
79
- },
80
- sigProvider
81
- );
82
- return toolCallId;
55
+ async function checkAgentExists(pubkey, opts) {
56
+ try {
57
+ const url = `${baseUrl(opts)}/api/ai/exists?pubkey=${encodeURIComponent(pubkey)}`;
58
+ const data = await getJson(url, opts);
59
+ return Boolean(data.registered);
60
+ } catch {
61
+ return false;
62
+ }
63
+ }
64
+ async function logToolCall(action, context, auth, chainOpts, extra, clientOpts) {
65
+ const exists = await checkAgentExists(auth.pubkey, clientOpts);
66
+ if (!exists) {
67
+ return {
68
+ success: false,
69
+ toolCallId: null,
70
+ error: "Agent not registered. Onboard the agent at the dashboard before submitting actions."
71
+ };
72
+ }
73
+ try {
74
+ const nodeUrls = chainOpts?.nodeUrls ?? DEFAULT_CHROMIA_NODE_URLS;
75
+ const blockchainRid = chainOpts?.blockchainRid ?? DEFAULT_BLOCKCHAIN_RID;
76
+ const client = await createClient({
77
+ nodeUrlPool: nodeUrls,
78
+ blockchainRid
79
+ });
80
+ const privKeyBuf = Buffer.from(auth.privkey, "hex");
81
+ const keyPair = encryption.makeKeyPair(privKeyBuf);
82
+ const sigProvider = newSignatureProvider({
83
+ privKey: keyPair.privKey,
84
+ pubKey: keyPair.pubKey
85
+ });
86
+ const toolCallId = generateToolCallId();
87
+ await client.signAndSendUniqueTransaction(
88
+ {
89
+ name: "log_tool_call",
90
+ args: [
91
+ toolCallId,
92
+ action,
93
+ context || "",
94
+ extra?.toolName || "",
95
+ extra?.toolArgsJson || ""
96
+ ]
97
+ },
98
+ sigProvider
99
+ );
100
+ return { success: true, toolCallId };
101
+ } catch (err) {
102
+ return {
103
+ success: false,
104
+ toolCallId: null,
105
+ error: err instanceof Error ? err.message : "Failed to log tool call on-chain"
106
+ };
107
+ }
83
108
  }
84
109
  function normalizeVerdict(raw) {
85
- const v = String(raw || "").toUpperCase();
110
+ if (raw === null || raw === void 0) return "LOGGED";
111
+ const v = String(raw).toUpperCase();
86
112
  if (v === "ALLOW" || v === "GREEN") return "ALLOW";
87
113
  if (v === "HOLD" || v === "YELLOW") return "HOLD";
88
114
  if (v === "BLOCK" || v === "RED") return "BLOCK";
89
- return "BLOCK";
115
+ return "HOLD";
90
116
  }
91
117
  function normalizeStatus(raw) {
92
118
  const s = String(raw || "").toLowerCase();
@@ -140,26 +166,30 @@ async function getJson(url, opts) {
140
166
  return resp.json();
141
167
  }
142
168
  async function judgeAction(action, context, auth, opts) {
143
- const toolCallId = await logToolCall(
169
+ const logResult = await logToolCall(
144
170
  action,
145
171
  context,
146
172
  auth,
147
173
  opts?.chainOpts,
148
- { toolName: opts?.toolName, toolArgsJson: opts?.toolArgsJson }
174
+ { toolName: opts?.toolName, toolArgsJson: opts?.toolArgsJson },
175
+ opts
149
176
  );
177
+ if (!logResult.success || !logResult.toolCallId) {
178
+ throw new Error(logResult.error || "Failed to log tool call on-chain");
179
+ }
150
180
  const url = `${baseUrl(opts)}/api/v1/judge`;
151
181
  const data = await postJson(
152
182
  url,
153
183
  {
154
- tool_call_id: toolCallId,
184
+ tool_call_id: logResult.toolCallId,
155
185
  agent_pubkey: auth.pubkey,
156
186
  action,
157
- context: context || "",
158
- provider: opts?.provider || "",
159
- tool_name: opts?.toolName || "",
160
- api_key: opts?.apiKey || "",
161
- endpoint_url: opts?.providerEndpoint || "",
162
- model: opts?.model || ""
187
+ ...context && { context },
188
+ ...opts?.provider && { provider: opts.provider },
189
+ ...opts?.toolName && { tool_name: opts.toolName },
190
+ ...opts?.apiKey && { api_key: opts.apiKey },
191
+ ...opts?.providerEndpoint && { endpoint_url: opts.providerEndpoint },
192
+ ...opts?.model && { model: opts.model }
163
193
  },
164
194
  opts
165
195
  );
@@ -170,7 +200,7 @@ async function judgeAction(action, context, auth, opts) {
170
200
  confidence: Number(data.confidence ?? 0),
171
201
  provider: String(data.provider || ""),
172
202
  latency_ms: Number(data.latency_ms ?? 0),
173
- tool_call_id: String(data.tool_call_id || toolCallId),
203
+ tool_call_id: String(data.tool_call_id || logResult.toolCallId),
174
204
  on_chain: Boolean(data.on_chain)
175
205
  };
176
206
  }
@@ -293,6 +323,7 @@ export {
293
323
  DEFAULT_BLOCKCHAIN_RID,
294
324
  DEFAULT_CHROMIA_NODE_URLS,
295
325
  DEFAULT_ENDPOINT,
326
+ checkAgentExists,
296
327
  derivePublicKey,
297
328
  generateKeyPair,
298
329
  getAgentDetail,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atbash/sdk",
3
- "version": "0.3.1",
4
- "description": "TypeScript SDK for the Atbash risk-engine / judge API",
3
+ "version": "0.3.2",
4
+ "description": "Atbash SDK control boundary before the last irreversible step in an agent workflow",
5
5
  "homepage": "https://atbash.ai",
6
6
  "author": "Atbash",
7
7
  "license": "SEE LICENSE IN LICENSE",