@astrasyncai/verification-gateway 2.3.10 → 2.4.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 +64 -9
- package/dist/bin/astrasync.js +348 -0
- package/dist/registration/index.d.mts +218 -0
- package/dist/registration/index.d.ts +218 -0
- package/dist/registration/index.js +212 -0
- package/dist/registration/index.js.map +1 -0
- package/dist/registration/index.mjs +172 -0
- package/dist/registration/index.mjs.map +1 -0
- package/package.json +14 -2
package/README.md
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
# @astrasyncai/verification-gateway
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The AstraSync KYA Platform SDK. One package, two roles: register agents with the KYA backend, and verify agents at any counterparty type (API / MCP / website / agent-to-agent).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## What's in this package?
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
As of v2.4.0 this is the only npm package you need for AstraSync integration. Pick the subpath that matches what you're doing:
|
|
8
8
|
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
| **
|
|
12
|
-
| **
|
|
13
|
-
| **
|
|
9
|
+
| If you're… | Import from | Get |
|
|
10
|
+
| ----------------------------------------------------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------- |
|
|
11
|
+
| **Registering an agent with the KYA backend** | `@astrasyncai/verification-gateway/registration` | `AstraSync` class — `register()`, `verify()`, `health()`. The `astrasync` CLI is bundled too. |
|
|
12
|
+
| **Building an agent that calls out to other services** (per-request credential injection) | `@astrasyncai/verification-gateway/agent` | `AgentClient`, `ChallengeHandler`, ownership validation, runtime PDLSS shape. |
|
|
13
|
+
| **Running an Express API that AI agents call into** | `@astrasyncai/verification-gateway/express` | `createMiddleware()` — protect routes, attach verification context. |
|
|
14
|
+
| **Running a Next.js app that AI agents call into** | `@astrasyncai/verification-gateway/nextjs` | `createMiddleware()`, Commerce Shield wiring. |
|
|
15
|
+
| **Running an MCP server that AI agents call into** | `@astrasyncai/verification-gateway/mcp` | MCP tool gates + inner-hop dedupe headers. |
|
|
16
|
+
| **Doing direct verification (no framework)** | `@astrasyncai/verification-gateway/sdk` | `VerificationGatewayClient` with retry / backoff / timeout. |
|
|
17
|
+
| **Parsing protocol-level credentials** (HTTP / A2A / MCP / x402 / AP2 / MPP) | `@astrasyncai/verification-gateway/transport` | Cross-protocol credential extraction + injection. |
|
|
18
|
+
| **Evaluating PDLSS offline** (local / hybrid mode) | `@astrasyncai/verification-gateway/gateway` | `AstraSyncGateway` (online / local / hybrid). |
|
|
19
|
+
| **Receiving webhook callbacks** | `@astrasyncai/verification-gateway/webhooks` | `verifyAstraSyncWebhook()`, `signAstraSyncWebhook()`. |
|
|
14
20
|
|
|
15
|
-
>
|
|
21
|
+
> All subpaths talk to the same backend — `POST /agents/verify-access` for verification, `POST /agents/register` for registration. The contract is shared; the role is just which side of the handshake you're sitting on.
|
|
22
|
+
|
|
23
|
+
Before v2.4.0 the agent-registration half shipped as a separate package (`@astrasyncai/agent-registration`, briefly; `@astrasyncai/sdk` before that). It was merged in to stop the two-package version drift and to give partners one install instead of two. The legacy `@astrasyncai/sdk` package on npm is deprecated with a pointer to this package; `@astrasyncai/agent-registration` was never published.
|
|
16
24
|
|
|
17
25
|
## Overview
|
|
18
26
|
|
|
@@ -95,6 +103,53 @@ if (result.verified && result.accessLevel !== 'none') {
|
|
|
95
103
|
}
|
|
96
104
|
```
|
|
97
105
|
|
|
106
|
+
### Agent Registration
|
|
107
|
+
|
|
108
|
+
Register an AI agent with the KYA backend in code (the `astrasync` CLI does the same thing from a shell).
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { AstraSync } from '@astrasyncai/verification-gateway/registration';
|
|
112
|
+
|
|
113
|
+
const astrasync = new AstraSync({
|
|
114
|
+
apiKey: process.env.ASTRASYNC_API_KEY, // or { email, password }
|
|
115
|
+
// Optional: privateKey for secp256k1 request signing
|
|
116
|
+
privateKey: process.env.ASTRASYNC_PRIVATE_KEY,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const result = await astrasync.register({
|
|
120
|
+
name: 'invoice-bot',
|
|
121
|
+
description: 'Reconciles AP/AR across accounting systems.',
|
|
122
|
+
agentType: 'autonomous',
|
|
123
|
+
model: { modelProvider: 'anthropic', modelName: 'claude-sonnet-4-5' },
|
|
124
|
+
framework: { frameworkName: 'langchain', frameworkVersion: '0.3.0' },
|
|
125
|
+
protocols: ['a2a', 'mcp'],
|
|
126
|
+
pdlss: {
|
|
127
|
+
purpose: { allowed: ['accounting.read', 'accounting.write'] },
|
|
128
|
+
duration: { requested: 'P30D' },
|
|
129
|
+
limits: { transactionValue: 5000, currency: 'USD' },
|
|
130
|
+
scope: { resources: ['xero.invoices', 'quickbooks.bills'] },
|
|
131
|
+
selfInstantiation: { allowed: false },
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
console.log(`Agent registered: ${result.agent.astraId}`);
|
|
136
|
+
console.log(`Trust score: ${result.agent.trustScore}`); // dynamic; recomputed on every verify-access call
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
CLI equivalent — same surface from a shell, also via `npx`:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx astrasync register --name invoice-bot --agent-type autonomous \
|
|
143
|
+
--model-provider anthropic --model-name claude-sonnet-4-5 \
|
|
144
|
+
--framework-name langchain --framework-version 0.3.0 \
|
|
145
|
+
--protocols a2a,mcp \
|
|
146
|
+
--pdlss '{"purpose":{"allowed":["accounting.read","accounting.write"]}, ...}'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> `/registration` is for **one-shot onboarding** — register an agent, look up its public profile, check API health. For **per-request credential injection** (attaching ASTRA-id, sessionId, PDLSS to outgoing HTTP / A2A / MCP calls from an already-registered agent), use `/agent` (`AgentClient`). The two roles are deliberately separate concerns: registration is identity, `/agent` is runtime.
|
|
150
|
+
|
|
151
|
+
> A `PDLSSConfig` type exists in both `/registration` and `/agent`, with **different shapes**. `/registration`'s `PDLSSConfig` is the boundary declaration submitted at register time; `/agent`'s `PDLSSConfig` is the per-request runtime request shape. Disambiguate via the import path — the root export deliberately does not re-export either.
|
|
152
|
+
|
|
98
153
|
### Inner-hop verification (MCP → REST dedupe with X-Astra-Verified-Hop)
|
|
99
154
|
|
|
100
155
|
When an MCP tool calls an inner REST endpoint that ALSO runs the
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/registration/errors.ts
|
|
27
|
+
var AstraSyncError = class extends Error {
|
|
28
|
+
constructor(message, statusCode, code) {
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = "AstraSyncError";
|
|
31
|
+
this.statusCode = statusCode;
|
|
32
|
+
this.code = code;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var KYDRequiredError = class extends AstraSyncError {
|
|
36
|
+
constructor(response) {
|
|
37
|
+
const kydUrl = response.kydUrl || "https://astrasync.ai/developer-profile";
|
|
38
|
+
super(
|
|
39
|
+
`KYD verification required before registering agents.
|
|
40
|
+
Complete your KYD profile at: ${kydUrl}`,
|
|
41
|
+
403,
|
|
42
|
+
"KYD_REQUIRED"
|
|
43
|
+
);
|
|
44
|
+
this.name = "KYDRequiredError";
|
|
45
|
+
this.kydUrl = kydUrl;
|
|
46
|
+
this.ownerNotified = response.ownerNotified || false;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var AuthenticationError = class extends AstraSyncError {
|
|
50
|
+
constructor(message) {
|
|
51
|
+
super(message, 401, "AUTH_FAILED");
|
|
52
|
+
this.name = "AuthenticationError";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/registration/api.ts
|
|
57
|
+
var DEFAULT_BASE_URL = "https://astrasync.ai";
|
|
58
|
+
var AstraSync = class {
|
|
59
|
+
constructor(config = {}) {
|
|
60
|
+
this.baseUrl = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(
|
|
61
|
+
/\/+$/,
|
|
62
|
+
""
|
|
63
|
+
);
|
|
64
|
+
this.apiKey = config.apiKey || process.env.ASTRASYNC_API_KEY;
|
|
65
|
+
this.email = config.email;
|
|
66
|
+
this.password = config.password;
|
|
67
|
+
this.privateKey = config.privateKey;
|
|
68
|
+
if (!this.apiKey && !this.email) {
|
|
69
|
+
throw new AuthenticationError(
|
|
70
|
+
"Authentication required. Provide apiKey, or email+password. Set ASTRASYNC_API_KEY env var or pass config to constructor."
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
if (this.email && !this.password) {
|
|
74
|
+
throw new AuthenticationError("Password is required when using email authentication.");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Register a new AI agent on the AstraSync KYA Platform.
|
|
79
|
+
* Sends full payload including model, framework, PDLSS, and metadata.
|
|
80
|
+
*/
|
|
81
|
+
async register(options) {
|
|
82
|
+
const body = {
|
|
83
|
+
name: options.name,
|
|
84
|
+
...options.description && { description: options.description },
|
|
85
|
+
...options.agentType && { agentType: options.agentType },
|
|
86
|
+
...options.apiEndpoint && { apiEndpoint: options.apiEndpoint },
|
|
87
|
+
...options.model && { model: options.model },
|
|
88
|
+
...options.framework && { framework: options.framework },
|
|
89
|
+
...options.protocols && { protocols: options.protocols },
|
|
90
|
+
...options.metadata && { metadata: options.metadata },
|
|
91
|
+
...options.pdlss && { pdlss: options.pdlss }
|
|
92
|
+
};
|
|
93
|
+
return this.request("POST", "/api/agents/register", body);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Look up an agent's public profile by ASTRA ID or UUID.
|
|
97
|
+
*/
|
|
98
|
+
async verify(agentId) {
|
|
99
|
+
return this.request("GET", `/api/agents/verify/${agentId}`);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check API health.
|
|
103
|
+
*/
|
|
104
|
+
async health() {
|
|
105
|
+
const res = await fetch(`${this.baseUrl}/api/health/`);
|
|
106
|
+
if (!res.ok) {
|
|
107
|
+
throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);
|
|
108
|
+
}
|
|
109
|
+
return res.json();
|
|
110
|
+
}
|
|
111
|
+
// ── Private helpers ──────────────────────────────────────────────
|
|
112
|
+
async request(method, endpoint, body) {
|
|
113
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
114
|
+
const headers = {
|
|
115
|
+
"Content-Type": "application/json"
|
|
116
|
+
};
|
|
117
|
+
const token = await this.getAuthToken();
|
|
118
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
119
|
+
if (this.privateKey) {
|
|
120
|
+
const signature = await this.signRequest(method, endpoint, body || {});
|
|
121
|
+
headers["X-AstraSync-Signature"] = signature;
|
|
122
|
+
}
|
|
123
|
+
const res = await fetch(url, {
|
|
124
|
+
method,
|
|
125
|
+
headers,
|
|
126
|
+
...body ? { body: JSON.stringify(body) } : {}
|
|
127
|
+
});
|
|
128
|
+
if (!res.ok) {
|
|
129
|
+
const errorBody = await res.json().catch(() => ({ error: res.statusText }));
|
|
130
|
+
if (res.status === 403 && errorBody.code === "KYD_REQUIRED") {
|
|
131
|
+
throw new KYDRequiredError(errorBody);
|
|
132
|
+
}
|
|
133
|
+
throw new AstraSyncError(
|
|
134
|
+
errorBody.error || `Request failed: ${res.status}`,
|
|
135
|
+
res.status,
|
|
136
|
+
errorBody.code
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return res.json();
|
|
140
|
+
}
|
|
141
|
+
async getAuthToken() {
|
|
142
|
+
if (this.apiKey) {
|
|
143
|
+
return this.apiKey;
|
|
144
|
+
}
|
|
145
|
+
if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {
|
|
146
|
+
return this.cachedJwt;
|
|
147
|
+
}
|
|
148
|
+
const res = await fetch(`${this.baseUrl}/api/auth/login`, {
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers: { "Content-Type": "application/json" },
|
|
151
|
+
body: JSON.stringify({ email: this.email, password: this.password })
|
|
152
|
+
});
|
|
153
|
+
if (!res.ok) {
|
|
154
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
155
|
+
throw new AuthenticationError(
|
|
156
|
+
errorBody.message || errorBody.error || "Login failed"
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const data = await res.json();
|
|
160
|
+
this.cachedJwt = data.data.token;
|
|
161
|
+
this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1e3;
|
|
162
|
+
return this.cachedJwt;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Sign a request using secp256k1 (ethers.js).
|
|
166
|
+
* Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY
|
|
167
|
+
* Must match apps/backend/src/services/signature-verify.service.ts exactly.
|
|
168
|
+
*/
|
|
169
|
+
async signRequest(method, endpoint, body) {
|
|
170
|
+
const { Wallet } = await import("ethers");
|
|
171
|
+
const sorted = this.sortObjectKeys(body);
|
|
172
|
+
const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;
|
|
173
|
+
const wallet = new Wallet(this.privateKey);
|
|
174
|
+
return wallet.signMessage(canonical);
|
|
175
|
+
}
|
|
176
|
+
/** Recursively sort object keys for canonical JSON representation. */
|
|
177
|
+
sortObjectKeys(obj) {
|
|
178
|
+
if (obj === null || typeof obj !== "object") {
|
|
179
|
+
return obj;
|
|
180
|
+
}
|
|
181
|
+
if (Array.isArray(obj)) {
|
|
182
|
+
return obj.map((item) => this.sortObjectKeys(item));
|
|
183
|
+
}
|
|
184
|
+
const sorted = {};
|
|
185
|
+
for (const key of Object.keys(obj).sort()) {
|
|
186
|
+
sorted[key] = this.sortObjectKeys(obj[key]);
|
|
187
|
+
}
|
|
188
|
+
return sorted;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// src/bin/astrasync.ts
|
|
193
|
+
function usage() {
|
|
194
|
+
console.log(`
|
|
195
|
+
astrasync - AstraSync KYA Platform CLI
|
|
196
|
+
|
|
197
|
+
USAGE:
|
|
198
|
+
astrasync [options] <command> [args]
|
|
199
|
+
|
|
200
|
+
GLOBAL OPTIONS:
|
|
201
|
+
--api-key <key> API key (kya_ prefixed). Also reads ASTRASYNC_API_KEY env.
|
|
202
|
+
--email <email> Email for login auth
|
|
203
|
+
--password <pass> Password for login auth
|
|
204
|
+
--private-key <key> secp256k1 private key for crypto signing
|
|
205
|
+
--base-url <url> API base URL (default: https://astrasync.ai; use https://staging.astrasync.ai for staging)
|
|
206
|
+
--help Show this help message
|
|
207
|
+
|
|
208
|
+
COMMANDS:
|
|
209
|
+
register Register a new AI agent
|
|
210
|
+
verify <id> Look up an agent by ASTRA ID or UUID
|
|
211
|
+
health Check API health
|
|
212
|
+
|
|
213
|
+
REGISTER OPTIONS:
|
|
214
|
+
--name <name> Agent name (required)
|
|
215
|
+
--description <desc> Agent description
|
|
216
|
+
--agent-type <type> Agent type (default: general)
|
|
217
|
+
--api-endpoint <url> Agent API endpoint URL
|
|
218
|
+
--model-name <name> LLM model name (e.g. claude-opus-4.6)
|
|
219
|
+
--model-provider <provider> Model provider (e.g. anthropic, openai)
|
|
220
|
+
--model-type <type> Model type (default: llm)
|
|
221
|
+
--framework-name <name> Framework name (e.g. langchain, crewai)
|
|
222
|
+
--framework-version <ver> Framework version
|
|
223
|
+
|
|
224
|
+
EXAMPLES:
|
|
225
|
+
astrasync --api-key kya_xxx register --name "My Agent"
|
|
226
|
+
astrasync register --name "My Agent" --model-name gpt-4o --model-provider openai
|
|
227
|
+
astrasync verify ASTRA-abc123
|
|
228
|
+
astrasync health
|
|
229
|
+
`);
|
|
230
|
+
}
|
|
231
|
+
function parseArgs(args) {
|
|
232
|
+
const globals = {};
|
|
233
|
+
const commandArgs = {};
|
|
234
|
+
let command = "";
|
|
235
|
+
let inCommand = false;
|
|
236
|
+
for (let i = 0; i < args.length; i++) {
|
|
237
|
+
const arg = args[i];
|
|
238
|
+
if (!inCommand && !arg.startsWith("--")) {
|
|
239
|
+
command = arg;
|
|
240
|
+
inCommand = true;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (arg === "--help" || arg === "-h") {
|
|
244
|
+
globals["help"] = "true";
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (arg.startsWith("--")) {
|
|
248
|
+
const key = arg.slice(2);
|
|
249
|
+
const value = args[++i] || "";
|
|
250
|
+
if (inCommand) {
|
|
251
|
+
commandArgs[key] = value;
|
|
252
|
+
} else {
|
|
253
|
+
globals[key] = value;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return { globals, command, commandArgs };
|
|
258
|
+
}
|
|
259
|
+
async function main() {
|
|
260
|
+
const { globals, command, commandArgs } = parseArgs(process.argv.slice(2));
|
|
261
|
+
if (globals["help"] || !command) {
|
|
262
|
+
usage();
|
|
263
|
+
process.exit(command ? 0 : 1);
|
|
264
|
+
}
|
|
265
|
+
const config = {
|
|
266
|
+
apiKey: globals["api-key"],
|
|
267
|
+
email: globals["email"],
|
|
268
|
+
password: globals["password"],
|
|
269
|
+
privateKey: globals["private-key"],
|
|
270
|
+
baseUrl: globals["base-url"]
|
|
271
|
+
};
|
|
272
|
+
try {
|
|
273
|
+
if (command === "health") {
|
|
274
|
+
const client2 = new AstraSync({
|
|
275
|
+
apiKey: config.apiKey || "health-check",
|
|
276
|
+
baseUrl: config.baseUrl
|
|
277
|
+
});
|
|
278
|
+
const result = await client2.health();
|
|
279
|
+
console.log(JSON.stringify(result, null, 2));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const client = new AstraSync({
|
|
283
|
+
apiKey: config.apiKey,
|
|
284
|
+
email: config.email,
|
|
285
|
+
password: config.password,
|
|
286
|
+
privateKey: config.privateKey,
|
|
287
|
+
baseUrl: config.baseUrl
|
|
288
|
+
});
|
|
289
|
+
if (command === "register") {
|
|
290
|
+
const name = commandArgs["name"];
|
|
291
|
+
if (!name) {
|
|
292
|
+
console.error("Error: --name is required for register command");
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
const options = {
|
|
296
|
+
name,
|
|
297
|
+
...commandArgs["description"] && { description: commandArgs["description"] },
|
|
298
|
+
...commandArgs["agent-type"] && { agentType: commandArgs["agent-type"] },
|
|
299
|
+
...commandArgs["api-endpoint"] && { apiEndpoint: commandArgs["api-endpoint"] }
|
|
300
|
+
};
|
|
301
|
+
if (commandArgs["model-name"] && commandArgs["model-provider"]) {
|
|
302
|
+
options.model = {
|
|
303
|
+
modelName: commandArgs["model-name"],
|
|
304
|
+
modelProvider: commandArgs["model-provider"],
|
|
305
|
+
...commandArgs["model-type"] && {
|
|
306
|
+
modelType: commandArgs["model-type"]
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
if (commandArgs["framework-name"] && commandArgs["framework-version"]) {
|
|
311
|
+
options.framework = {
|
|
312
|
+
frameworkName: commandArgs["framework-name"],
|
|
313
|
+
frameworkVersion: commandArgs["framework-version"]
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const result = await client.register(options);
|
|
317
|
+
console.log(JSON.stringify(result, null, 2));
|
|
318
|
+
} else if (command === "verify") {
|
|
319
|
+
const agentId = commandArgs["id"] || process.argv[process.argv.length - 1];
|
|
320
|
+
if (!agentId || agentId.startsWith("--")) {
|
|
321
|
+
console.error("Error: agent ID is required for verify command");
|
|
322
|
+
process.exit(1);
|
|
323
|
+
}
|
|
324
|
+
const result = await client.verify(agentId);
|
|
325
|
+
console.log(JSON.stringify(result, null, 2));
|
|
326
|
+
} else {
|
|
327
|
+
console.error(`Unknown command: ${command}`);
|
|
328
|
+
usage();
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
} catch (error) {
|
|
332
|
+
if (error instanceof KYDRequiredError) {
|
|
333
|
+
console.error(`
|
|
334
|
+
Error: ${error.message}`);
|
|
335
|
+
if (error.ownerNotified) {
|
|
336
|
+
console.error("A reminder email has been sent to your registered email address.");
|
|
337
|
+
}
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
340
|
+
if (error instanceof AstraSyncError) {
|
|
341
|
+
console.error(`
|
|
342
|
+
Error [${error.code || error.statusCode}]: ${error.message}`);
|
|
343
|
+
process.exit(1);
|
|
344
|
+
}
|
|
345
|
+
throw error;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
main();
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/** Configuration for the AstraSync SDK client. */
|
|
2
|
+
interface AstraSyncConfig {
|
|
3
|
+
/** API key (kya_ prefixed). Used as Bearer token. */
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
/** Email for email+password authentication. */
|
|
6
|
+
email?: string;
|
|
7
|
+
/** Password for email+password authentication. */
|
|
8
|
+
password?: string;
|
|
9
|
+
/** secp256k1 private key for crypto signing. Used WITH apiKey or email+password. */
|
|
10
|
+
privateKey?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Base URL for the AstraSync API.
|
|
13
|
+
* Defaults to ASTRASYNC_API_URL env or `https://astrasync.ai` (production).
|
|
14
|
+
* For staging, pass `https://staging.astrasync.ai`.
|
|
15
|
+
*/
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Multi-protocol declarations the agent participates in.
|
|
20
|
+
* Promoted from `metadata.protocols[]` to a first-class field in agent-registration v1.0.0.
|
|
21
|
+
*/
|
|
22
|
+
type AgentProtocol = 'a2a' | 'acp' | 'ap2' | 'ucp' | 'mpp' | 'x402' | 'erc8004' | 'vi' | 'agentpay' | 'tap' | 'other';
|
|
23
|
+
/** PDLSS purpose configuration. */
|
|
24
|
+
interface PDLSSPurpose {
|
|
25
|
+
categories: string[];
|
|
26
|
+
allowedActions?: string[];
|
|
27
|
+
deniedActions?: string[];
|
|
28
|
+
}
|
|
29
|
+
/** PDLSS duration configuration. */
|
|
30
|
+
interface PDLSSDuration {
|
|
31
|
+
startTime?: string | null;
|
|
32
|
+
endTime?: string | null;
|
|
33
|
+
timezone?: string | null;
|
|
34
|
+
maxSessionDuration?: number | null;
|
|
35
|
+
ttl?: number | null;
|
|
36
|
+
allowedDays?: number[] | null;
|
|
37
|
+
allowedHours?: {
|
|
38
|
+
start: number;
|
|
39
|
+
end: number;
|
|
40
|
+
} | null;
|
|
41
|
+
}
|
|
42
|
+
/** PDLSS limits configuration. */
|
|
43
|
+
interface PDLSSLimits {
|
|
44
|
+
autonomousThreshold?: number | null;
|
|
45
|
+
stepUpThreshold?: number | null;
|
|
46
|
+
approvalThreshold?: number | null;
|
|
47
|
+
maxTransactionsPerDay?: number | null;
|
|
48
|
+
maxTransactionsPerHour?: number | null;
|
|
49
|
+
maxTotalValue?: number | null;
|
|
50
|
+
currency?: string;
|
|
51
|
+
}
|
|
52
|
+
/** PDLSS scope configuration. */
|
|
53
|
+
interface PDLSSScope {
|
|
54
|
+
resources?: string[];
|
|
55
|
+
resourceTypes?: string[];
|
|
56
|
+
jurisdictions?: string[];
|
|
57
|
+
excludedResources?: string[];
|
|
58
|
+
counterparties?: string[];
|
|
59
|
+
excludedCounterparties?: string[];
|
|
60
|
+
}
|
|
61
|
+
/** PDLSS self-instantiation configuration. */
|
|
62
|
+
interface PDLSSSelfInstantiation {
|
|
63
|
+
allowed: boolean;
|
|
64
|
+
maxSubAgents?: number | null;
|
|
65
|
+
inheritPermissions?: boolean | null;
|
|
66
|
+
allowedPurposes?: string[] | null;
|
|
67
|
+
requireApproval?: boolean | null;
|
|
68
|
+
maxDepth?: number | null;
|
|
69
|
+
}
|
|
70
|
+
/** Full PDLSS configuration. */
|
|
71
|
+
interface PDLSSConfig {
|
|
72
|
+
purpose: PDLSSPurpose;
|
|
73
|
+
duration?: PDLSSDuration;
|
|
74
|
+
limits?: PDLSSLimits;
|
|
75
|
+
scope?: PDLSSScope;
|
|
76
|
+
selfInstantiation?: PDLSSSelfInstantiation;
|
|
77
|
+
}
|
|
78
|
+
/** Model metadata for registration. */
|
|
79
|
+
interface ModelConfig {
|
|
80
|
+
modelName: string;
|
|
81
|
+
modelProvider: string;
|
|
82
|
+
modelType?: 'llm' | 'embedding' | 'image' | 'audio' | 'multimodal' | 'code' | 'other';
|
|
83
|
+
contextWindow?: number;
|
|
84
|
+
maxTokens?: number;
|
|
85
|
+
}
|
|
86
|
+
/** Framework metadata for registration. */
|
|
87
|
+
interface FrameworkConfig {
|
|
88
|
+
frameworkName: string;
|
|
89
|
+
frameworkVersion: string;
|
|
90
|
+
}
|
|
91
|
+
/** Options for agent registration. */
|
|
92
|
+
interface RegisterOptions {
|
|
93
|
+
name: string;
|
|
94
|
+
description?: string;
|
|
95
|
+
agentType?: string;
|
|
96
|
+
apiEndpoint?: string;
|
|
97
|
+
model?: ModelConfig;
|
|
98
|
+
framework?: FrameworkConfig;
|
|
99
|
+
/** Multi-protocol declarations (e.g. ['acp', 'ap2', 'a2a']). First-class as of v1.0.0. */
|
|
100
|
+
protocols?: AgentProtocol[];
|
|
101
|
+
metadata?: Record<string, unknown>;
|
|
102
|
+
pdlss?: PDLSSConfig;
|
|
103
|
+
}
|
|
104
|
+
/** Response from agent registration. */
|
|
105
|
+
interface RegistrationResponse {
|
|
106
|
+
success: boolean;
|
|
107
|
+
message: string;
|
|
108
|
+
data: {
|
|
109
|
+
agent: AgentRecord;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/** Agent record from the API. */
|
|
113
|
+
interface AgentRecord {
|
|
114
|
+
kyaAgentId: string;
|
|
115
|
+
name: string;
|
|
116
|
+
description?: string;
|
|
117
|
+
agentType: string;
|
|
118
|
+
agentStatus: string;
|
|
119
|
+
trustScore: number;
|
|
120
|
+
astrasyncIdLevel1?: string | null;
|
|
121
|
+
tempId?: string | null;
|
|
122
|
+
metadata?: Record<string, unknown>;
|
|
123
|
+
createdAt: string;
|
|
124
|
+
updatedAt: string;
|
|
125
|
+
}
|
|
126
|
+
/** Public agent verification response. */
|
|
127
|
+
interface VerifyResponse {
|
|
128
|
+
success: boolean;
|
|
129
|
+
data: {
|
|
130
|
+
agentUuid: string;
|
|
131
|
+
agentName: string;
|
|
132
|
+
agentDescription: string;
|
|
133
|
+
agentTrustScore: number;
|
|
134
|
+
agentStatus: string;
|
|
135
|
+
ownerName?: string;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/** Health check response. */
|
|
139
|
+
interface HealthResponse {
|
|
140
|
+
status: string;
|
|
141
|
+
service: string;
|
|
142
|
+
version: string;
|
|
143
|
+
}
|
|
144
|
+
/** Error response from the API. */
|
|
145
|
+
interface ApiErrorResponse {
|
|
146
|
+
success: false;
|
|
147
|
+
error: string;
|
|
148
|
+
code?: string;
|
|
149
|
+
kydUrl?: string;
|
|
150
|
+
ownerNotified?: boolean;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* AstraSync SDK client for registering and managing AI agents.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const client = new AstraSync({ apiKey: 'kya_your_api_key' });
|
|
159
|
+
* const result = await client.register({
|
|
160
|
+
* name: 'My Agent',
|
|
161
|
+
* model: { modelName: 'gpt-4o', modelProvider: 'openai', modelType: 'llm' },
|
|
162
|
+
* });
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* For staging, pass `baseUrl: 'https://staging.astrasync.ai'`.
|
|
166
|
+
*/
|
|
167
|
+
declare class AstraSync {
|
|
168
|
+
private readonly baseUrl;
|
|
169
|
+
private readonly apiKey?;
|
|
170
|
+
private readonly email?;
|
|
171
|
+
private readonly password?;
|
|
172
|
+
private readonly privateKey?;
|
|
173
|
+
private cachedJwt?;
|
|
174
|
+
private jwtExpiresAt?;
|
|
175
|
+
constructor(config?: AstraSyncConfig);
|
|
176
|
+
/**
|
|
177
|
+
* Register a new AI agent on the AstraSync KYA Platform.
|
|
178
|
+
* Sends full payload including model, framework, PDLSS, and metadata.
|
|
179
|
+
*/
|
|
180
|
+
register(options: RegisterOptions): Promise<RegistrationResponse>;
|
|
181
|
+
/**
|
|
182
|
+
* Look up an agent's public profile by ASTRA ID or UUID.
|
|
183
|
+
*/
|
|
184
|
+
verify(agentId: string): Promise<VerifyResponse>;
|
|
185
|
+
/**
|
|
186
|
+
* Check API health.
|
|
187
|
+
*/
|
|
188
|
+
health(): Promise<HealthResponse>;
|
|
189
|
+
private request;
|
|
190
|
+
private getAuthToken;
|
|
191
|
+
/**
|
|
192
|
+
* Sign a request using secp256k1 (ethers.js).
|
|
193
|
+
* Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY
|
|
194
|
+
* Must match apps/backend/src/services/signature-verify.service.ts exactly.
|
|
195
|
+
*/
|
|
196
|
+
private signRequest;
|
|
197
|
+
/** Recursively sort object keys for canonical JSON representation. */
|
|
198
|
+
private sortObjectKeys;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Base error class for AstraSync SDK errors. */
|
|
202
|
+
declare class AstraSyncError extends Error {
|
|
203
|
+
readonly code?: string;
|
|
204
|
+
readonly statusCode: number;
|
|
205
|
+
constructor(message: string, statusCode: number, code?: string);
|
|
206
|
+
}
|
|
207
|
+
/** Thrown when KYD verification is required before agent registration. */
|
|
208
|
+
declare class KYDRequiredError extends AstraSyncError {
|
|
209
|
+
readonly kydUrl: string;
|
|
210
|
+
readonly ownerNotified: boolean;
|
|
211
|
+
constructor(response: ApiErrorResponse);
|
|
212
|
+
}
|
|
213
|
+
/** Thrown when authentication fails. */
|
|
214
|
+
declare class AuthenticationError extends AstraSyncError {
|
|
215
|
+
constructor(message: string);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export { type AgentProtocol, type AgentRecord, AstraSync, type AstraSyncConfig, AstraSyncError, AuthenticationError, type FrameworkConfig, type HealthResponse, KYDRequiredError, type ModelConfig, type PDLSSConfig, type PDLSSDuration, type PDLSSLimits, type PDLSSPurpose, type PDLSSScope, type PDLSSSelfInstantiation, type RegisterOptions, type RegistrationResponse, type VerifyResponse };
|