From cb7a6320d55e04c5344608167ce115cce737798b Mon Sep 17 00:00:00 2001 From: Zachary Date: Sun, 1 Mar 2026 15:53:50 -0500 Subject: [PATCH] Add 7 missing SDK methods and document all exports - Add listAgents, unfreezeAgent, deleteAgent, getMe, issueApiToken, downloadExport, health methods - Add corresponding response types to types.ts - Export new types from index.ts - Document all previously undocumented exports in README Co-Authored-By: Claude Opus 4.6 --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++ src/client.ts | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 6 ++++++ src/types.ts | 28 ++++++++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/README.md b/README.md index bf506b0..bbfeca6 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,12 @@ const auth = await ElydoraClient.login(baseUrl, email, password); // Set token on client client.setToken(auth.token); + +// Get current authenticated user profile +const { user } = await client.getMe(); + +// Issue a new API token (with optional TTL in seconds) +const { token, expires_at } = await client.issueApiToken(3600); ``` ### Operations @@ -141,6 +147,15 @@ await client.freezeAgent(agentId, 'security review'); // Revoke a key await client.revokeKey(agentId, kid, 'key rotation'); + +// List all agents in the organization +const { agents } = await client.listAgents(); + +// Unfreeze a previously frozen agent +await client.unfreezeAgent(agentId, 'review complete'); + +// Delete an agent permanently +const { deleted } = await client.deleteAgent(agentId); ``` ### Audit @@ -173,6 +188,9 @@ const { export: exp } = await client.createExport({ const { exports } = await client.listExports(); const { export: detail, download_url } = await client.getExport(exportId); + +// Download export file data +const data = await client.downloadExport(exportId); ``` ### JWKS @@ -181,6 +199,24 @@ const { export: detail, download_url } = await client.getExport(exportId); const { keys } = await client.getJWKS(); ``` +### Health + +```typescript +// Check API health (no authentication required) +const health = await client.health(); +// health.status, health.version, health.protocol_version, health.timestamp +``` + +### Client State + +```typescript +// Get the current chain hash (useful for debugging/inspection) +const chainHash = client.getChainHash(); + +// Get the Ed25519 public key derived from the configured private key +const publicKey = client.getPublicKey(); +``` + ### Crypto Utilities The SDK exports low-level cryptographic primitives for advanced use: @@ -197,6 +233,17 @@ import { } from '@elydora/sdk'; ``` +### Utility Functions + +```typescript +import { + uuidv7, // Generate a UUIDv7 (time-ordered, RFC 9562) + generateNonce, // Generate a 16-byte random nonce (base64url) + base64urlEncode, // Encode Buffer/Uint8Array to base64url (no padding) + base64urlDecode, // Decode base64url string to Buffer +} from '@elydora/sdk'; +``` + ## Error Handling ```typescript diff --git a/src/client.ts b/src/client.ts index 661c40b..205c875 100644 --- a/src/client.ts +++ b/src/client.ts @@ -5,6 +5,9 @@ import type { RegisterAgentRequest, RegisterAgentResponse, GetAgentResponse, + ListAgentsResponse, + UnfreezeAgentResponse, + DeleteAgentResponse, SubmitOperationResponse, GetOperationResponse, VerifyOperationResponse, @@ -16,7 +19,10 @@ import type { CreateExportResponse, ListExportsResponse, GetExportResponse, + GetMeResponse, + IssueApiTokenResponse, JWKSResponse, + HealthResponse, AuthRegisterResponse, AuthLoginResponse, ErrorResponse, @@ -119,6 +125,18 @@ export class ElydoraClient { return handleResponse(res); } + // ------------------------------------------------------------------------- + // Auth (instance methods — require token) + // ------------------------------------------------------------------------- + + async getMe(): Promise { + return this.request('GET', '/v1/auth/me'); + } + + async issueApiToken(ttlSeconds?: number | null): Promise { + return this.request('POST', '/v1/auth/token', { ttl_seconds: ttlSeconds ?? null }); + } + // ------------------------------------------------------------------------- // Agent management // ------------------------------------------------------------------------- @@ -135,6 +153,18 @@ export class ElydoraClient { await this.request('POST', `/v1/agents/${encodeURIComponent(agentId)}/freeze`, { reason }); } + async listAgents(): Promise { + return this.request('GET', '/v1/agents'); + } + + async unfreezeAgent(agentId: string, reason: string): Promise { + return this.request('POST', `/v1/agents/${encodeURIComponent(agentId)}/unfreeze`, { reason }); + } + + async deleteAgent(agentId: string): Promise { + return this.request('DELETE', `/v1/agents/${encodeURIComponent(agentId)}`); + } + async revokeKey(agentId: string, kid: string, reason: string): Promise { await this.request('POST', `/v1/agents/${encodeURIComponent(agentId)}/revoke`, { kid, reason }); } @@ -250,6 +280,23 @@ export class ElydoraClient { return this.request('GET', `/v1/exports/${encodeURIComponent(exportId)}`); } + async downloadExport(exportId: string): Promise { + const url = `${this.baseUrl}/v1/exports/${encodeURIComponent(exportId)}/download`; + const headers: Record = {}; + + if (this.token) { + headers['Authorization'] = `Bearer ${this.token}`; + } + + const res = await fetch(url, { method: 'GET', headers }); + + if (!res.ok) { + return handleResponse(res); + } + + return res.arrayBuffer(); + } + // ------------------------------------------------------------------------- // JWKS // ------------------------------------------------------------------------- @@ -263,6 +310,19 @@ export class ElydoraClient { return handleResponse(res); } + // ------------------------------------------------------------------------- + // Health + // ------------------------------------------------------------------------- + + async health(): Promise { + const url = `${this.baseUrl}/v1/health`; + const res = await fetch(url, { + method: 'GET', + headers: { 'Accept': 'application/json' }, + }); + return handleResponse(res); + } + // ------------------------------------------------------------------------- // Internal HTTP helpers // ------------------------------------------------------------------------- diff --git a/src/index.ts b/src/index.ts index 2cba65b..284ab9a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -46,6 +46,9 @@ export type { RegisterAgentRequest, RegisterAgentResponse, GetAgentResponse, + ListAgentsResponse, + UnfreezeAgentResponse, + DeleteAgentResponse, SubmitOperationResponse, GetOperationResponse, VerifyOperationResponse, @@ -57,8 +60,11 @@ export type { CreateExportResponse, GetExportResponse, ListExportsResponse, + GetMeResponse, + IssueApiTokenResponse, JWK, JWKSResponse, + HealthResponse, AuthRegisterResponse, AuthLoginResponse, ErrorResponse, diff --git a/src/types.ts b/src/types.ts index a009ba0..3cf230f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -247,6 +247,34 @@ export interface ListExportsResponse { readonly exports: Export[]; } +export interface ListAgentsResponse { + readonly agents: Agent[]; +} + +export interface UnfreezeAgentResponse { + readonly agent: Agent; +} + +export interface DeleteAgentResponse { + readonly deleted: boolean; +} + +export interface GetMeResponse { + readonly user: User; +} + +export interface IssueApiTokenResponse { + readonly token: string; + readonly expires_at: number | null; +} + +export interface HealthResponse { + readonly status: string; + readonly version: string; + readonly protocol_version: string; + readonly timestamp: number; +} + export interface JWK { readonly kty: string; readonly crv?: string;