@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.
@@ -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 };
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/registration/index.ts
31
+ var registration_exports = {};
32
+ __export(registration_exports, {
33
+ AstraSync: () => AstraSync,
34
+ AstraSyncError: () => AstraSyncError,
35
+ AuthenticationError: () => AuthenticationError,
36
+ KYDRequiredError: () => KYDRequiredError
37
+ });
38
+ module.exports = __toCommonJS(registration_exports);
39
+
40
+ // src/registration/errors.ts
41
+ var AstraSyncError = class extends Error {
42
+ constructor(message, statusCode, code) {
43
+ super(message);
44
+ this.name = "AstraSyncError";
45
+ this.statusCode = statusCode;
46
+ this.code = code;
47
+ }
48
+ };
49
+ var KYDRequiredError = class extends AstraSyncError {
50
+ constructor(response) {
51
+ const kydUrl = response.kydUrl || "https://astrasync.ai/developer-profile";
52
+ super(
53
+ `KYD verification required before registering agents.
54
+ Complete your KYD profile at: ${kydUrl}`,
55
+ 403,
56
+ "KYD_REQUIRED"
57
+ );
58
+ this.name = "KYDRequiredError";
59
+ this.kydUrl = kydUrl;
60
+ this.ownerNotified = response.ownerNotified || false;
61
+ }
62
+ };
63
+ var AuthenticationError = class extends AstraSyncError {
64
+ constructor(message) {
65
+ super(message, 401, "AUTH_FAILED");
66
+ this.name = "AuthenticationError";
67
+ }
68
+ };
69
+
70
+ // src/registration/api.ts
71
+ var DEFAULT_BASE_URL = "https://astrasync.ai";
72
+ var AstraSync = class {
73
+ constructor(config = {}) {
74
+ this.baseUrl = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(
75
+ /\/+$/,
76
+ ""
77
+ );
78
+ this.apiKey = config.apiKey || process.env.ASTRASYNC_API_KEY;
79
+ this.email = config.email;
80
+ this.password = config.password;
81
+ this.privateKey = config.privateKey;
82
+ if (!this.apiKey && !this.email) {
83
+ throw new AuthenticationError(
84
+ "Authentication required. Provide apiKey, or email+password. Set ASTRASYNC_API_KEY env var or pass config to constructor."
85
+ );
86
+ }
87
+ if (this.email && !this.password) {
88
+ throw new AuthenticationError("Password is required when using email authentication.");
89
+ }
90
+ }
91
+ /**
92
+ * Register a new AI agent on the AstraSync KYA Platform.
93
+ * Sends full payload including model, framework, PDLSS, and metadata.
94
+ */
95
+ async register(options) {
96
+ const body = {
97
+ name: options.name,
98
+ ...options.description && { description: options.description },
99
+ ...options.agentType && { agentType: options.agentType },
100
+ ...options.apiEndpoint && { apiEndpoint: options.apiEndpoint },
101
+ ...options.model && { model: options.model },
102
+ ...options.framework && { framework: options.framework },
103
+ ...options.protocols && { protocols: options.protocols },
104
+ ...options.metadata && { metadata: options.metadata },
105
+ ...options.pdlss && { pdlss: options.pdlss }
106
+ };
107
+ return this.request("POST", "/api/agents/register", body);
108
+ }
109
+ /**
110
+ * Look up an agent's public profile by ASTRA ID or UUID.
111
+ */
112
+ async verify(agentId) {
113
+ return this.request("GET", `/api/agents/verify/${agentId}`);
114
+ }
115
+ /**
116
+ * Check API health.
117
+ */
118
+ async health() {
119
+ const res = await fetch(`${this.baseUrl}/api/health/`);
120
+ if (!res.ok) {
121
+ throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);
122
+ }
123
+ return res.json();
124
+ }
125
+ // ── Private helpers ──────────────────────────────────────────────
126
+ async request(method, endpoint, body) {
127
+ const url = `${this.baseUrl}${endpoint}`;
128
+ const headers = {
129
+ "Content-Type": "application/json"
130
+ };
131
+ const token = await this.getAuthToken();
132
+ headers["Authorization"] = `Bearer ${token}`;
133
+ if (this.privateKey) {
134
+ const signature = await this.signRequest(method, endpoint, body || {});
135
+ headers["X-AstraSync-Signature"] = signature;
136
+ }
137
+ const res = await fetch(url, {
138
+ method,
139
+ headers,
140
+ ...body ? { body: JSON.stringify(body) } : {}
141
+ });
142
+ if (!res.ok) {
143
+ const errorBody = await res.json().catch(() => ({ error: res.statusText }));
144
+ if (res.status === 403 && errorBody.code === "KYD_REQUIRED") {
145
+ throw new KYDRequiredError(errorBody);
146
+ }
147
+ throw new AstraSyncError(
148
+ errorBody.error || `Request failed: ${res.status}`,
149
+ res.status,
150
+ errorBody.code
151
+ );
152
+ }
153
+ return res.json();
154
+ }
155
+ async getAuthToken() {
156
+ if (this.apiKey) {
157
+ return this.apiKey;
158
+ }
159
+ if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {
160
+ return this.cachedJwt;
161
+ }
162
+ const res = await fetch(`${this.baseUrl}/api/auth/login`, {
163
+ method: "POST",
164
+ headers: { "Content-Type": "application/json" },
165
+ body: JSON.stringify({ email: this.email, password: this.password })
166
+ });
167
+ if (!res.ok) {
168
+ const errorBody = await res.json().catch(() => ({}));
169
+ throw new AuthenticationError(
170
+ errorBody.message || errorBody.error || "Login failed"
171
+ );
172
+ }
173
+ const data = await res.json();
174
+ this.cachedJwt = data.data.token;
175
+ this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1e3;
176
+ return this.cachedJwt;
177
+ }
178
+ /**
179
+ * Sign a request using secp256k1 (ethers.js).
180
+ * Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY
181
+ * Must match apps/backend/src/services/signature-verify.service.ts exactly.
182
+ */
183
+ async signRequest(method, endpoint, body) {
184
+ const { Wallet } = await import("ethers");
185
+ const sorted = this.sortObjectKeys(body);
186
+ const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;
187
+ const wallet = new Wallet(this.privateKey);
188
+ return wallet.signMessage(canonical);
189
+ }
190
+ /** Recursively sort object keys for canonical JSON representation. */
191
+ sortObjectKeys(obj) {
192
+ if (obj === null || typeof obj !== "object") {
193
+ return obj;
194
+ }
195
+ if (Array.isArray(obj)) {
196
+ return obj.map((item) => this.sortObjectKeys(item));
197
+ }
198
+ const sorted = {};
199
+ for (const key of Object.keys(obj).sort()) {
200
+ sorted[key] = this.sortObjectKeys(obj[key]);
201
+ }
202
+ return sorted;
203
+ }
204
+ };
205
+ // Annotate the CommonJS export names for ESM import in node:
206
+ 0 && (module.exports = {
207
+ AstraSync,
208
+ AstraSyncError,
209
+ AuthenticationError,
210
+ KYDRequiredError
211
+ });
212
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/registration/index.ts","../../src/registration/errors.ts","../../src/registration/api.ts"],"sourcesContent":["export { AstraSync } from './api';\nexport { AstraSyncError, KYDRequiredError, AuthenticationError } from './errors';\nexport type {\n AstraSyncConfig,\n RegisterOptions,\n RegistrationResponse,\n AgentRecord,\n VerifyResponse,\n HealthResponse,\n PDLSSConfig,\n PDLSSPurpose,\n PDLSSDuration,\n PDLSSLimits,\n PDLSSScope,\n PDLSSSelfInstantiation,\n ModelConfig,\n FrameworkConfig,\n AgentProtocol,\n} from './types';\n","import type { ApiErrorResponse } from './types';\n\n/** Base error class for AstraSync SDK errors. */\nexport class AstraSyncError extends Error {\n public readonly code?: string;\n public readonly statusCode: number;\n\n constructor(message: string, statusCode: number, code?: string) {\n super(message);\n this.name = 'AstraSyncError';\n this.statusCode = statusCode;\n this.code = code;\n }\n}\n\n/** Thrown when KYD verification is required before agent registration. */\nexport class KYDRequiredError extends AstraSyncError {\n public readonly kydUrl: string;\n public readonly ownerNotified: boolean;\n\n constructor(response: ApiErrorResponse) {\n const kydUrl = response.kydUrl || 'https://astrasync.ai/developer-profile';\n super(\n `KYD verification required before registering agents.\\nComplete your KYD profile at: ${kydUrl}`,\n 403,\n 'KYD_REQUIRED'\n );\n this.name = 'KYDRequiredError';\n this.kydUrl = kydUrl;\n this.ownerNotified = response.ownerNotified || false;\n }\n}\n\n/** Thrown when authentication fails. */\nexport class AuthenticationError extends AstraSyncError {\n constructor(message: string) {\n super(message, 401, 'AUTH_FAILED');\n this.name = 'AuthenticationError';\n }\n}\n","import type {\n AstraSyncConfig,\n RegisterOptions,\n RegistrationResponse,\n VerifyResponse,\n HealthResponse,\n ApiErrorResponse,\n} from './types';\nimport { AstraSyncError, KYDRequiredError, AuthenticationError } from './errors';\n\nconst DEFAULT_BASE_URL = 'https://astrasync.ai';\n\n/**\n * AstraSync SDK client for registering and managing AI agents.\n *\n * @example\n * ```typescript\n * const client = new AstraSync({ apiKey: 'kya_your_api_key' });\n * const result = await client.register({\n * name: 'My Agent',\n * model: { modelName: 'gpt-4o', modelProvider: 'openai', modelType: 'llm' },\n * });\n * ```\n *\n * For staging, pass `baseUrl: 'https://staging.astrasync.ai'`.\n */\nexport class AstraSync {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly email?: string;\n private readonly password?: string;\n private readonly privateKey?: string;\n private cachedJwt?: string;\n private jwtExpiresAt?: number;\n\n constructor(config: AstraSyncConfig = {}) {\n this.baseUrl = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(\n /\\/+$/,\n ''\n );\n\n this.apiKey = config.apiKey || process.env.ASTRASYNC_API_KEY;\n this.email = config.email;\n this.password = config.password;\n this.privateKey = config.privateKey;\n\n if (!this.apiKey && !this.email) {\n throw new AuthenticationError(\n 'Authentication required. Provide apiKey, or email+password. ' +\n 'Set ASTRASYNC_API_KEY env var or pass config to constructor.'\n );\n }\n\n if (this.email && !this.password) {\n throw new AuthenticationError('Password is required when using email authentication.');\n }\n }\n\n /**\n * Register a new AI agent on the AstraSync KYA Platform.\n * Sends full payload including model, framework, PDLSS, and metadata.\n */\n async register(options: RegisterOptions): Promise<RegistrationResponse> {\n const body: Record<string, unknown> = {\n name: options.name,\n ...(options.description && { description: options.description }),\n ...(options.agentType && { agentType: options.agentType }),\n ...(options.apiEndpoint && { apiEndpoint: options.apiEndpoint }),\n ...(options.model && { model: options.model }),\n ...(options.framework && { framework: options.framework }),\n ...(options.protocols && { protocols: options.protocols }),\n ...(options.metadata && { metadata: options.metadata }),\n ...(options.pdlss && { pdlss: options.pdlss }),\n };\n\n return this.request<RegistrationResponse>('POST', '/api/agents/register', body);\n }\n\n /**\n * Look up an agent's public profile by ASTRA ID or UUID.\n */\n async verify(agentId: string): Promise<VerifyResponse> {\n return this.request<VerifyResponse>('GET', `/api/agents/verify/${agentId}`);\n }\n\n /**\n * Check API health.\n */\n async health(): Promise<HealthResponse> {\n const res = await fetch(`${this.baseUrl}/api/health/`);\n if (!res.ok) {\n throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);\n }\n return res.json() as Promise<HealthResponse>;\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private async request<T>(method: string, endpoint: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Set auth header\n const token = await this.getAuthToken();\n headers['Authorization'] = `Bearer ${token}`;\n\n // Sign request if private key is configured\n if (this.privateKey) {\n const signature = await this.signRequest(method, endpoint, body || {});\n headers['X-AstraSync-Signature'] = signature;\n }\n\n const res = await fetch(url, {\n method,\n headers,\n ...(body ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const errorBody = (await res\n .json()\n .catch(() => ({ error: res.statusText }))) as ApiErrorResponse;\n\n // Handle KYD_REQUIRED specifically\n if (res.status === 403 && errorBody.code === 'KYD_REQUIRED') {\n throw new KYDRequiredError(errorBody);\n }\n\n throw new AstraSyncError(\n errorBody.error || `Request failed: ${res.status}`,\n res.status,\n errorBody.code\n );\n }\n\n return res.json() as Promise<T>;\n }\n\n private async getAuthToken(): Promise<string> {\n // API key auth — use directly\n if (this.apiKey) {\n return this.apiKey;\n }\n\n // Email+password — login and cache JWT\n if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {\n return this.cachedJwt;\n }\n\n const res = await fetch(`${this.baseUrl}/api/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email: this.email, password: this.password }),\n });\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n throw new AuthenticationError(\n (errorBody.message as string) || (errorBody.error as string) || 'Login failed'\n );\n }\n\n const data = (await res.json()) as { data: { token: string } };\n this.cachedJwt = data.data.token;\n // Cache for 6 days (tokens expire in 7)\n this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1000;\n\n return this.cachedJwt;\n }\n\n /**\n * Sign a request using secp256k1 (ethers.js).\n * Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY\n * Must match apps/backend/src/services/signature-verify.service.ts exactly.\n */\n private async signRequest(method: string, endpoint: string, body: unknown): Promise<string> {\n const { Wallet } = await import('ethers');\n const sorted = this.sortObjectKeys(body);\n const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;\n const wallet = new Wallet(this.privateKey!);\n return wallet.signMessage(canonical);\n }\n\n /** Recursively sort object keys for canonical JSON representation. */\n private sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => this.sortObjectKeys(item));\n }\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = this.sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,172 @@
1
+ // src/registration/errors.ts
2
+ var AstraSyncError = class extends Error {
3
+ constructor(message, statusCode, code) {
4
+ super(message);
5
+ this.name = "AstraSyncError";
6
+ this.statusCode = statusCode;
7
+ this.code = code;
8
+ }
9
+ };
10
+ var KYDRequiredError = class extends AstraSyncError {
11
+ constructor(response) {
12
+ const kydUrl = response.kydUrl || "https://astrasync.ai/developer-profile";
13
+ super(
14
+ `KYD verification required before registering agents.
15
+ Complete your KYD profile at: ${kydUrl}`,
16
+ 403,
17
+ "KYD_REQUIRED"
18
+ );
19
+ this.name = "KYDRequiredError";
20
+ this.kydUrl = kydUrl;
21
+ this.ownerNotified = response.ownerNotified || false;
22
+ }
23
+ };
24
+ var AuthenticationError = class extends AstraSyncError {
25
+ constructor(message) {
26
+ super(message, 401, "AUTH_FAILED");
27
+ this.name = "AuthenticationError";
28
+ }
29
+ };
30
+
31
+ // src/registration/api.ts
32
+ var DEFAULT_BASE_URL = "https://astrasync.ai";
33
+ var AstraSync = class {
34
+ constructor(config = {}) {
35
+ this.baseUrl = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(
36
+ /\/+$/,
37
+ ""
38
+ );
39
+ this.apiKey = config.apiKey || process.env.ASTRASYNC_API_KEY;
40
+ this.email = config.email;
41
+ this.password = config.password;
42
+ this.privateKey = config.privateKey;
43
+ if (!this.apiKey && !this.email) {
44
+ throw new AuthenticationError(
45
+ "Authentication required. Provide apiKey, or email+password. Set ASTRASYNC_API_KEY env var or pass config to constructor."
46
+ );
47
+ }
48
+ if (this.email && !this.password) {
49
+ throw new AuthenticationError("Password is required when using email authentication.");
50
+ }
51
+ }
52
+ /**
53
+ * Register a new AI agent on the AstraSync KYA Platform.
54
+ * Sends full payload including model, framework, PDLSS, and metadata.
55
+ */
56
+ async register(options) {
57
+ const body = {
58
+ name: options.name,
59
+ ...options.description && { description: options.description },
60
+ ...options.agentType && { agentType: options.agentType },
61
+ ...options.apiEndpoint && { apiEndpoint: options.apiEndpoint },
62
+ ...options.model && { model: options.model },
63
+ ...options.framework && { framework: options.framework },
64
+ ...options.protocols && { protocols: options.protocols },
65
+ ...options.metadata && { metadata: options.metadata },
66
+ ...options.pdlss && { pdlss: options.pdlss }
67
+ };
68
+ return this.request("POST", "/api/agents/register", body);
69
+ }
70
+ /**
71
+ * Look up an agent's public profile by ASTRA ID or UUID.
72
+ */
73
+ async verify(agentId) {
74
+ return this.request("GET", `/api/agents/verify/${agentId}`);
75
+ }
76
+ /**
77
+ * Check API health.
78
+ */
79
+ async health() {
80
+ const res = await fetch(`${this.baseUrl}/api/health/`);
81
+ if (!res.ok) {
82
+ throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);
83
+ }
84
+ return res.json();
85
+ }
86
+ // ── Private helpers ──────────────────────────────────────────────
87
+ async request(method, endpoint, body) {
88
+ const url = `${this.baseUrl}${endpoint}`;
89
+ const headers = {
90
+ "Content-Type": "application/json"
91
+ };
92
+ const token = await this.getAuthToken();
93
+ headers["Authorization"] = `Bearer ${token}`;
94
+ if (this.privateKey) {
95
+ const signature = await this.signRequest(method, endpoint, body || {});
96
+ headers["X-AstraSync-Signature"] = signature;
97
+ }
98
+ const res = await fetch(url, {
99
+ method,
100
+ headers,
101
+ ...body ? { body: JSON.stringify(body) } : {}
102
+ });
103
+ if (!res.ok) {
104
+ const errorBody = await res.json().catch(() => ({ error: res.statusText }));
105
+ if (res.status === 403 && errorBody.code === "KYD_REQUIRED") {
106
+ throw new KYDRequiredError(errorBody);
107
+ }
108
+ throw new AstraSyncError(
109
+ errorBody.error || `Request failed: ${res.status}`,
110
+ res.status,
111
+ errorBody.code
112
+ );
113
+ }
114
+ return res.json();
115
+ }
116
+ async getAuthToken() {
117
+ if (this.apiKey) {
118
+ return this.apiKey;
119
+ }
120
+ if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {
121
+ return this.cachedJwt;
122
+ }
123
+ const res = await fetch(`${this.baseUrl}/api/auth/login`, {
124
+ method: "POST",
125
+ headers: { "Content-Type": "application/json" },
126
+ body: JSON.stringify({ email: this.email, password: this.password })
127
+ });
128
+ if (!res.ok) {
129
+ const errorBody = await res.json().catch(() => ({}));
130
+ throw new AuthenticationError(
131
+ errorBody.message || errorBody.error || "Login failed"
132
+ );
133
+ }
134
+ const data = await res.json();
135
+ this.cachedJwt = data.data.token;
136
+ this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1e3;
137
+ return this.cachedJwt;
138
+ }
139
+ /**
140
+ * Sign a request using secp256k1 (ethers.js).
141
+ * Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY
142
+ * Must match apps/backend/src/services/signature-verify.service.ts exactly.
143
+ */
144
+ async signRequest(method, endpoint, body) {
145
+ const { Wallet } = await import("ethers");
146
+ const sorted = this.sortObjectKeys(body);
147
+ const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;
148
+ const wallet = new Wallet(this.privateKey);
149
+ return wallet.signMessage(canonical);
150
+ }
151
+ /** Recursively sort object keys for canonical JSON representation. */
152
+ sortObjectKeys(obj) {
153
+ if (obj === null || typeof obj !== "object") {
154
+ return obj;
155
+ }
156
+ if (Array.isArray(obj)) {
157
+ return obj.map((item) => this.sortObjectKeys(item));
158
+ }
159
+ const sorted = {};
160
+ for (const key of Object.keys(obj).sort()) {
161
+ sorted[key] = this.sortObjectKeys(obj[key]);
162
+ }
163
+ return sorted;
164
+ }
165
+ };
166
+ export {
167
+ AstraSync,
168
+ AstraSyncError,
169
+ AuthenticationError,
170
+ KYDRequiredError
171
+ };
172
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/registration/errors.ts","../../src/registration/api.ts"],"sourcesContent":["import type { ApiErrorResponse } from './types';\n\n/** Base error class for AstraSync SDK errors. */\nexport class AstraSyncError extends Error {\n public readonly code?: string;\n public readonly statusCode: number;\n\n constructor(message: string, statusCode: number, code?: string) {\n super(message);\n this.name = 'AstraSyncError';\n this.statusCode = statusCode;\n this.code = code;\n }\n}\n\n/** Thrown when KYD verification is required before agent registration. */\nexport class KYDRequiredError extends AstraSyncError {\n public readonly kydUrl: string;\n public readonly ownerNotified: boolean;\n\n constructor(response: ApiErrorResponse) {\n const kydUrl = response.kydUrl || 'https://astrasync.ai/developer-profile';\n super(\n `KYD verification required before registering agents.\\nComplete your KYD profile at: ${kydUrl}`,\n 403,\n 'KYD_REQUIRED'\n );\n this.name = 'KYDRequiredError';\n this.kydUrl = kydUrl;\n this.ownerNotified = response.ownerNotified || false;\n }\n}\n\n/** Thrown when authentication fails. */\nexport class AuthenticationError extends AstraSyncError {\n constructor(message: string) {\n super(message, 401, 'AUTH_FAILED');\n this.name = 'AuthenticationError';\n }\n}\n","import type {\n AstraSyncConfig,\n RegisterOptions,\n RegistrationResponse,\n VerifyResponse,\n HealthResponse,\n ApiErrorResponse,\n} from './types';\nimport { AstraSyncError, KYDRequiredError, AuthenticationError } from './errors';\n\nconst DEFAULT_BASE_URL = 'https://astrasync.ai';\n\n/**\n * AstraSync SDK client for registering and managing AI agents.\n *\n * @example\n * ```typescript\n * const client = new AstraSync({ apiKey: 'kya_your_api_key' });\n * const result = await client.register({\n * name: 'My Agent',\n * model: { modelName: 'gpt-4o', modelProvider: 'openai', modelType: 'llm' },\n * });\n * ```\n *\n * For staging, pass `baseUrl: 'https://staging.astrasync.ai'`.\n */\nexport class AstraSync {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly email?: string;\n private readonly password?: string;\n private readonly privateKey?: string;\n private cachedJwt?: string;\n private jwtExpiresAt?: number;\n\n constructor(config: AstraSyncConfig = {}) {\n this.baseUrl = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(\n /\\/+$/,\n ''\n );\n\n this.apiKey = config.apiKey || process.env.ASTRASYNC_API_KEY;\n this.email = config.email;\n this.password = config.password;\n this.privateKey = config.privateKey;\n\n if (!this.apiKey && !this.email) {\n throw new AuthenticationError(\n 'Authentication required. Provide apiKey, or email+password. ' +\n 'Set ASTRASYNC_API_KEY env var or pass config to constructor.'\n );\n }\n\n if (this.email && !this.password) {\n throw new AuthenticationError('Password is required when using email authentication.');\n }\n }\n\n /**\n * Register a new AI agent on the AstraSync KYA Platform.\n * Sends full payload including model, framework, PDLSS, and metadata.\n */\n async register(options: RegisterOptions): Promise<RegistrationResponse> {\n const body: Record<string, unknown> = {\n name: options.name,\n ...(options.description && { description: options.description }),\n ...(options.agentType && { agentType: options.agentType }),\n ...(options.apiEndpoint && { apiEndpoint: options.apiEndpoint }),\n ...(options.model && { model: options.model }),\n ...(options.framework && { framework: options.framework }),\n ...(options.protocols && { protocols: options.protocols }),\n ...(options.metadata && { metadata: options.metadata }),\n ...(options.pdlss && { pdlss: options.pdlss }),\n };\n\n return this.request<RegistrationResponse>('POST', '/api/agents/register', body);\n }\n\n /**\n * Look up an agent's public profile by ASTRA ID or UUID.\n */\n async verify(agentId: string): Promise<VerifyResponse> {\n return this.request<VerifyResponse>('GET', `/api/agents/verify/${agentId}`);\n }\n\n /**\n * Check API health.\n */\n async health(): Promise<HealthResponse> {\n const res = await fetch(`${this.baseUrl}/api/health/`);\n if (!res.ok) {\n throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);\n }\n return res.json() as Promise<HealthResponse>;\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n private async request<T>(method: string, endpoint: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n // Set auth header\n const token = await this.getAuthToken();\n headers['Authorization'] = `Bearer ${token}`;\n\n // Sign request if private key is configured\n if (this.privateKey) {\n const signature = await this.signRequest(method, endpoint, body || {});\n headers['X-AstraSync-Signature'] = signature;\n }\n\n const res = await fetch(url, {\n method,\n headers,\n ...(body ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const errorBody = (await res\n .json()\n .catch(() => ({ error: res.statusText }))) as ApiErrorResponse;\n\n // Handle KYD_REQUIRED specifically\n if (res.status === 403 && errorBody.code === 'KYD_REQUIRED') {\n throw new KYDRequiredError(errorBody);\n }\n\n throw new AstraSyncError(\n errorBody.error || `Request failed: ${res.status}`,\n res.status,\n errorBody.code\n );\n }\n\n return res.json() as Promise<T>;\n }\n\n private async getAuthToken(): Promise<string> {\n // API key auth — use directly\n if (this.apiKey) {\n return this.apiKey;\n }\n\n // Email+password — login and cache JWT\n if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {\n return this.cachedJwt;\n }\n\n const res = await fetch(`${this.baseUrl}/api/auth/login`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email: this.email, password: this.password }),\n });\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n throw new AuthenticationError(\n (errorBody.message as string) || (errorBody.error as string) || 'Login failed'\n );\n }\n\n const data = (await res.json()) as { data: { token: string } };\n this.cachedJwt = data.data.token;\n // Cache for 6 days (tokens expire in 7)\n this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1000;\n\n return this.cachedJwt;\n }\n\n /**\n * Sign a request using secp256k1 (ethers.js).\n * Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY\n * Must match apps/backend/src/services/signature-verify.service.ts exactly.\n */\n private async signRequest(method: string, endpoint: string, body: unknown): Promise<string> {\n const { Wallet } = await import('ethers');\n const sorted = this.sortObjectKeys(body);\n const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;\n const wallet = new Wallet(this.privateKey!);\n return wallet.signMessage(canonical);\n }\n\n /** Recursively sort object keys for canonical JSON representation. */\n private sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (Array.isArray(obj)) {\n return obj.map((item) => this.sortObjectKeys(item));\n }\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = this.sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n}\n"],"mappings":"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","names":[]}