@tinycloud/sdk-services 2.3.0-beta.6 → 2.3.0-beta.8

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/types.schema.ts","../src/context.ts","../src/errors.ts","../src/base/BaseService.ts","../src/kv/PrefixedKVService.ts","../src/kv/types.ts","../src/kv/KVService.ts","../src/sql/DatabaseHandle.ts","../src/sql/types.ts","../src/sql/SQLService.ts","../src/duckdb/DuckDbDatabaseHandle.ts","../src/duckdb/types.ts","../src/duckdb/DuckDbService.ts","../src/hooks/HooksService.ts","../src/quota/TinyCloudQuota.ts","../src/vault/types.ts","../src/vault/SignatureCache.ts","../src/vault/DataVaultService.ts","../src/vault/createVaultCrypto.ts","../src/secrets/paths.ts","../src/secrets/SecretsService.ts","../src/encryption/canonical.ts","../src/encryption/networkId.ts","../src/encryption/types.ts","../src/encryption/discovery.ts","../src/encryption/envelope.ts","../src/encryption/invocation.ts","../src/encryption/receiverKey.ts","../src/encryption/response.ts","../src/encryption/EncryptionService.ts"],"sourcesContent":["/**\n * SDK Services - Core Types\n *\n * These types define the service architecture for TinyCloud SDK.\n * Services use dependency injection via IServiceContext for platform independence.\n */\n\n// =============================================================================\n// Result Type Pattern\n// =============================================================================\n\n/**\n * Result type for service operations.\n * Services return Result instead of throwing, making error handling explicit.\n *\n * @template T - The success data type\n * @template E - The error type (defaults to ServiceError)\n *\n * @example\n * ```typescript\n * const result = await kv.get('key');\n * if (result.ok) {\n * console.log(result.data);\n * } else {\n * console.error(result.error.code);\n * }\n * ```\n */\nexport type Result<T, E = ServiceError> =\n | { ok: true; data: T }\n | { ok: false; error: E };\n\n/**\n * Service error with structured information.\n */\nexport interface ServiceError {\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: string;\n /** Human-readable error message */\n message: string;\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: string;\n /** Original error if this wraps another error */\n cause?: Error;\n /** Additional metadata about the error */\n meta?: Record<string, unknown>;\n}\n\n/**\n * Storage quota information returned with quota-related errors.\n */\nexport interface StorageQuotaInfo {\n usedBytes: number;\n limitBytes: number;\n service: string;\n}\n\n/**\n * Standard error codes used across services.\n */\nexport const ErrorCodes = {\n // Common errors\n NOT_FOUND: \"NOT_FOUND\",\n AUTH_EXPIRED: \"AUTH_EXPIRED\",\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n AUTH_UNAUTHORIZED: \"AUTH_UNAUTHORIZED\",\n NETWORK_ERROR: \"NETWORK_ERROR\",\n TIMEOUT: \"TIMEOUT\",\n ABORTED: \"ABORTED\",\n INVALID_INPUT: \"INVALID_INPUT\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n\n // KV-specific errors\n KV_NOT_FOUND: \"KV_NOT_FOUND\",\n KV_WRITE_FAILED: \"KV_WRITE_FAILED\",\n\n // SQL-specific errors\n SQL_ERROR: \"SQL_ERROR\",\n SQL_PERMISSION_DENIED: \"SQL_PERMISSION_DENIED\",\n SQL_DATABASE_NOT_FOUND: \"SQL_DATABASE_NOT_FOUND\",\n SQL_RESPONSE_TOO_LARGE: \"SQL_RESPONSE_TOO_LARGE\",\n SQL_QUOTA_EXCEEDED: \"SQL_QUOTA_EXCEEDED\",\n SQL_INVALID_STATEMENT: \"SQL_INVALID_STATEMENT\",\n SQL_SCHEMA_ERROR: \"SQL_SCHEMA_ERROR\",\n SQL_READONLY_VIOLATION: \"SQL_READONLY_VIOLATION\",\n\n // Storage quota errors\n STORAGE_QUOTA_EXCEEDED: \"STORAGE_QUOTA_EXCEEDED\",\n STORAGE_LIMIT_REACHED: \"STORAGE_LIMIT_REACHED\",\n\n // DuckDB-specific errors\n DUCKDB_ERROR: \"DUCKDB_ERROR\",\n DUCKDB_PERMISSION_DENIED: \"DUCKDB_PERMISSION_DENIED\",\n DUCKDB_DATABASE_NOT_FOUND: \"DUCKDB_DATABASE_NOT_FOUND\",\n DUCKDB_RESPONSE_TOO_LARGE: \"DUCKDB_RESPONSE_TOO_LARGE\",\n DUCKDB_QUOTA_EXCEEDED: \"DUCKDB_QUOTA_EXCEEDED\",\n DUCKDB_INVALID_STATEMENT: \"DUCKDB_INVALID_STATEMENT\",\n DUCKDB_SCHEMA_ERROR: \"DUCKDB_SCHEMA_ERROR\",\n DUCKDB_READONLY_VIOLATION: \"DUCKDB_READONLY_VIOLATION\",\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\n// =============================================================================\n// Service Session\n// =============================================================================\n\n/**\n * Session data required for authenticated service operations.\n * Both TinyCloudSession and web-sdk Session can be cast to this interface.\n */\nexport interface ServiceSession {\n /** The delegation header containing the UCAN */\n delegationHeader: { Authorization: string };\n /** The delegation CID */\n delegationCid: string;\n /** The space ID for this session */\n spaceId: string;\n /** The verification method DID */\n verificationMethod: string;\n /** The session key JWK (required for invoke) */\n jwk: object;\n}\n\n// =============================================================================\n// Platform Dependencies (Injected)\n// =============================================================================\n\n/**\n * Headers type - compatible with both browser and Node.js.\n */\nexport type ServiceHeaders = Record<string, string> | [string, string][];\n\n/**\n * A single fact object to include in the UCAN invocation.\n * Facts are key-value objects that the server reads from the UCAN facts field.\n */\nexport interface InvocationFact {\n [key: string]: unknown;\n}\n\n/**\n * Facts to include in the UCAN invocation.\n * This is an array of fact objects per the UCAN spec.\n * Used to pass additional parameters that the server reads from the UCAN facts field.\n */\nexport type InvocationFacts = InvocationFact[];\n\n/**\n * Invoke function signature - platform-specific implementation injected via DI.\n * Both node-sdk-wasm and web-sdk-wasm export this with identical signature.\n *\n * @param session - The service session with delegation data\n * @param service - Service name (e.g., \"kv\")\n * @param path - Resource path or key\n * @param action - Action to perform (e.g., \"tinycloud.kv/get\")\n * @param facts - Optional facts to include in the UCAN (e.g., for capabilities/read params)\n * @returns Headers to include in the request\n */\nexport type InvokeFunction = (\n session: ServiceSession,\n service: string,\n path: string,\n action: string,\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Multi-resource invocation entry.\n */\nexport interface InvokeAnyEntry {\n /**\n * Legacy space-scoped resource. Optional when `resource` is provided.\n */\n spaceId?: string;\n service: string;\n path: string;\n action: string;\n /** Optional raw resource URI. When set, WASM signs this URI directly. */\n resource?: string;\n}\n\n/**\n * Invoke function for minting a single authorization header that covers\n * multiple capabilities across one effective invoker.\n */\nexport type InvokeAnyFunction = (\n session: ServiceSession,\n entries: InvokeAnyEntry[],\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Fetch request options - compatible with standard fetch API.\n */\nexport interface FetchRequestInit {\n method?: string;\n headers?: ServiceHeaders;\n body?: Blob | FormData | string;\n signal?: AbortSignal;\n}\n\n/**\n * Fetch response interface - compatible with standard Response.\n */\nexport interface FetchResponse {\n ok: boolean;\n status: number;\n statusText: string;\n body?: unknown;\n headers: {\n get(name: string): string | null;\n };\n json(): Promise<unknown>;\n text(): Promise<string>;\n arrayBuffer(): Promise<ArrayBuffer>;\n blob(): Promise<Blob>;\n}\n\n/**\n * Fetch function signature - allows for custom fetch implementations.\n * Compatible with both browser fetch and Node.js fetch.\n */\nexport type FetchFunction = (\n url: string,\n init?: FetchRequestInit,\n) => Promise<FetchResponse>;\n\n// =============================================================================\n// Retry Policy\n// =============================================================================\n\n/**\n * Configuration for automatic retry of failed requests.\n */\nexport interface RetryPolicy {\n /** Maximum number of attempts (including initial) */\n maxAttempts: number;\n /** Backoff strategy between retries */\n backoff: \"none\" | \"linear\" | \"exponential\";\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: number;\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: number;\n /** Error codes that should trigger a retry */\n retryableErrors: string[];\n}\n\n/**\n * Default retry policy.\n */\nexport const defaultRetryPolicy: RetryPolicy = {\n maxAttempts: 3,\n backoff: \"exponential\",\n baseDelayMs: 1000,\n maxDelayMs: 10000,\n retryableErrors: [ErrorCodes.NETWORK_ERROR, ErrorCodes.TIMEOUT],\n};\n\n// =============================================================================\n// Service Context\n// =============================================================================\n\n/**\n * Event handler function type.\n */\nexport type EventHandler = (data: unknown) => void;\n\n/**\n * Service interface - base contract for all services.\n */\nexport interface IService {\n /** Initialize service with context */\n initialize(context: IServiceContext): void;\n\n /** Called when session changes (sign-in, sign-out, refresh) */\n onSessionChange(session: ServiceSession | null): void;\n\n /** Called when SDK signs out - should abort pending operations */\n onSignOut(): void;\n\n /** Service-specific configuration */\n readonly config: Record<string, unknown>;\n}\n\n/**\n * Context provided to services for accessing platform dependencies.\n * The SDK creates this context and passes it to services during initialization.\n */\nexport interface IServiceContext {\n // Session management\n /** Current active session, or null if not authenticated */\n readonly session: ServiceSession | null;\n /** Whether there is an active authenticated session */\n readonly isAuthenticated: boolean;\n\n // Platform dependencies (injected by SDK)\n /** Platform-specific invoke function from WASM binding */\n readonly invoke: InvokeFunction;\n /** Optional multi-resource invoke function */\n readonly invokeAny?: InvokeAnyFunction;\n /** Fetch function (defaults to globalThis.fetch) */\n readonly fetch: FetchFunction;\n /** Available TinyCloud host URLs */\n readonly hosts: string[];\n\n // Cross-service access\n /** Get another registered service by name */\n getService<T extends IService>(name: string): T | undefined;\n\n // Telemetry/Events\n /** Emit a telemetry event */\n emit(event: string, data: unknown): void;\n /** Subscribe to events */\n on(event: string, handler: EventHandler): () => void;\n\n // Lifecycle\n /** Abort signal that fires when SDK signs out */\n readonly abortSignal: AbortSignal;\n\n // Retry policy\n /** Retry policy for failed requests */\n readonly retryPolicy: RetryPolicy;\n}\n\n// =============================================================================\n// Telemetry Events\n// =============================================================================\n\n/**\n * Event emitted before a service request.\n */\nexport interface ServiceRequestEvent {\n service: string;\n action: string;\n key?: string;\n timestamp: number;\n}\n\n/**\n * Event emitted after a service response.\n */\nexport interface ServiceResponseEvent {\n service: string;\n action: string;\n ok: boolean;\n duration: number;\n status?: number;\n}\n\n/**\n * Event emitted on service error.\n */\nexport interface ServiceErrorEvent {\n service: string;\n error: ServiceError;\n}\n\n/**\n * Event emitted on retry attempt.\n */\nexport interface ServiceRetryEvent {\n service: string;\n attempt: number;\n maxAttempts: number;\n error: ServiceError;\n}\n\n/**\n * Telemetry event names.\n */\nexport const TelemetryEvents = {\n SERVICE_REQUEST: \"service.request\",\n SERVICE_RESPONSE: \"service.response\",\n SERVICE_ERROR: \"service.error\",\n SERVICE_RETRY: \"service.retry\",\n SESSION_CHANGED: \"session.changed\",\n SESSION_EXPIRED: \"session.expired\",\n} as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Create a success result.\n */\nexport function ok<T>(data: T): Result<T> {\n return { ok: true, data };\n}\n\n/**\n * Create an error result.\n */\nexport function err<E = ServiceError>(error: E): Result<never, E> {\n return { ok: false, error };\n}\n\n/**\n * Create a ServiceError.\n */\nexport function serviceError(\n code: string,\n message: string,\n service: string,\n options?: { cause?: Error; meta?: Record<string, unknown> },\n): ServiceError {\n return {\n code,\n message,\n service,\n cause: options?.cause,\n meta: options?.meta,\n };\n}\n","/**\n * Zod schemas for SDK Services API response types.\n *\n * This is the source of truth for service response types. TypeScript types\n * are derived from these schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\n\n// =============================================================================\n// Validation Error Type\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError {\n code: \"VALIDATION_ERROR\";\n message: string;\n service: string;\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n// =============================================================================\n// Service Error Schema\n// =============================================================================\n\n/**\n * Schema for service error with structured information.\n */\nexport const ServiceErrorSchema = z.object({\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: z.string(),\n /** Human-readable error message */\n message: z.string(),\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: z.string(),\n /** Original error if this wraps another error - not validated since Error is a class */\n cause: z.unknown().optional(),\n /** Additional metadata about the error - passthrough allows any object properties */\n meta: z.object({}).passthrough().optional(),\n});\n\nexport type ServiceErrorType = z.infer<typeof ServiceErrorSchema>;\n\n// =============================================================================\n// Result Schema Factory\n// =============================================================================\n\n/**\n * Creates a Result schema for a given data type.\n * Result is a discriminated union: { ok: true, data: T } | { ok: false, error: E }\n *\n * @param dataSchema - Zod schema for the success data type\n * @param errorSchema - Zod schema for the error type (defaults to ServiceErrorSchema)\n * @returns A Zod schema for Result<T, E>\n *\n * @example\n * ```typescript\n * const KVGetResultSchema = createResultSchema(z.string());\n * type KVGetResult = z.infer<typeof KVGetResultSchema>;\n * ```\n */\nexport function createResultSchema<T extends z.ZodTypeAny, E extends z.ZodTypeAny>(\n dataSchema: T,\n errorSchema: E = ServiceErrorSchema as unknown as E\n) {\n return z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n data: dataSchema,\n }),\n z.object({\n ok: z.literal(false),\n error: errorSchema,\n }),\n ]);\n}\n\n/**\n * Pre-built Result schema with unknown data and ServiceError.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericResultSchema = createResultSchema(z.unknown(), ServiceErrorSchema);\n\n// =============================================================================\n// KV Response Schemas\n// =============================================================================\n\n/**\n * Schema for KV response headers metadata.\n * Note: The `get` method is a function and cannot be validated with Zod.\n * This schema validates the data properties only.\n */\nexport const KVResponseHeadersSchema = z.object({\n /** ETag for conditional requests */\n etag: z.string().optional(),\n /** Content type of the stored value */\n contentType: z.string().optional(),\n /** Last modification timestamp */\n lastModified: z.string().optional(),\n /** Content length in bytes */\n contentLength: z.number().optional(),\n});\n\nexport type KVResponseHeadersType = z.infer<typeof KVResponseHeadersSchema>;\n\n/**\n * Creates a KVResponse schema for a given data type.\n *\n * @param dataSchema - Zod schema for the data payload type\n * @returns A Zod schema for KVResponse<T>\n *\n * @example\n * ```typescript\n * const UserResponseSchema = createKVResponseSchema(UserSchema);\n * type UserResponse = z.infer<typeof UserResponseSchema>;\n * ```\n */\nexport function createKVResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n /** The data payload */\n data: dataSchema,\n /** Response headers with metadata */\n headers: KVResponseHeadersSchema,\n });\n}\n\n/**\n * Generic KVResponse schema with unknown data.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericKVResponseSchema = createKVResponseSchema(z.unknown());\n\nexport type GenericKVResponseType = z.infer<typeof GenericKVResponseSchema>;\n\n/**\n * Schema for KV list response.\n */\nexport const KVListResponseSchema = z.object({\n /** Array of keys matching the list criteria */\n keys: z.array(z.string()),\n});\n\nexport type KVListResponseType = z.infer<typeof KVListResponseSchema>;\n\n/**\n * Result schema for KV list operations.\n */\nexport const KVListResultSchema = createResultSchema(KVListResponseSchema);\n\nexport type KVListResultType = z.infer<typeof KVListResultSchema>;\n\n// =============================================================================\n// Telemetry Event Schemas\n// =============================================================================\n\n/**\n * Schema for service request event.\n */\nexport const ServiceRequestEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n key: z.string().optional(),\n timestamp: z.number(),\n});\n\nexport type ServiceRequestEventType = z.infer<typeof ServiceRequestEventSchema>;\n\n/**\n * Schema for service response event.\n */\nexport const ServiceResponseEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n ok: z.boolean(),\n duration: z.number(),\n status: z.number().optional(),\n});\n\nexport type ServiceResponseEventType = z.infer<typeof ServiceResponseEventSchema>;\n\n/**\n * Schema for service error event.\n */\nexport const ServiceErrorEventSchema = z.object({\n service: z.string(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceErrorEventType = z.infer<typeof ServiceErrorEventSchema>;\n\n/**\n * Schema for service retry event.\n */\nexport const ServiceRetryEventSchema = z.object({\n service: z.string(),\n attempt: z.number().int().positive(),\n maxAttempts: z.number().int().positive(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceRetryEventType = z.infer<typeof ServiceRetryEventSchema>;\n\n// =============================================================================\n// Retry Policy Schema\n// =============================================================================\n\n/**\n * Schema for retry policy configuration.\n */\nexport const RetryPolicySchema = z.object({\n /** Maximum number of attempts (including initial) */\n maxAttempts: z.number().int().positive(),\n /** Backoff strategy between retries */\n backoff: z.enum([\"none\", \"linear\", \"exponential\"]),\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: z.number().nonnegative(),\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: z.number().nonnegative(),\n /** Error codes that should trigger a retry */\n retryableErrors: z.array(z.string()),\n});\n\nexport type RetryPolicyType = z.infer<typeof RetryPolicySchema>;\n\n// =============================================================================\n// Service Session Schema\n// =============================================================================\n\n/**\n * Schema for service session data required for authenticated operations.\n */\nexport const ServiceSessionSchema = z.object({\n /** The delegation header containing the UCAN */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** The verification method DID */\n verificationMethod: z.string(),\n /** The session key JWK (required for invoke) */\n jwk: z.object({}).passthrough(),\n});\n\nexport type ServiceSessionType = z.infer<typeof ServiceSessionSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validate service error against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceError(\n data: unknown\n): { ok: true; data: ServiceErrorType } | { ok: false; error: ValidationError } {\n const result = ServiceErrorSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"validation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV list response against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVListResponse(\n data: unknown\n): { ok: true; data: KVListResponseType } | { ok: false; error: ValidationError } {\n const result = KVListResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV response headers against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVResponseHeaders(\n data: unknown\n): { ok: true; data: KVResponseHeadersType } | { ok: false; error: ValidationError } {\n const result = KVResponseHeadersSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceSession(\n data: unknown\n): { ok: true; data: ServiceSessionType } | { ok: false; error: ValidationError } {\n const result = ServiceSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate retry policy against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateRetryPolicy(\n data: unknown\n): { ok: true; data: RetryPolicyType } | { ok: false; error: ValidationError } {\n const result = RetryPolicySchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"config\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service request event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceRequestEvent(\n data: unknown\n): { ok: true; data: ServiceRequestEventType } | { ok: false; error: ValidationError } {\n const result = ServiceRequestEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service response event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceResponseEvent(\n data: unknown\n): { ok: true; data: ServiceResponseEventType } | { ok: false; error: ValidationError } {\n const result = ServiceResponseEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * ServiceContext implementation for TinyCloud SDK Services\n * @module @tinycloud/sdk-services\n */\n\nimport {\n IServiceContext,\n IService,\n ServiceSession,\n RetryPolicy,\n InvokeFunction,\n InvokeAnyFunction,\n FetchFunction,\n defaultRetryPolicy,\n} from \"./types\";\n\n/**\n * Event handler type for telemetry events.\n */\ntype EventHandler = (data: unknown) => void;\n\n/**\n * Configuration options for ServiceContext.\n */\nexport interface ServiceContextConfig {\n /** Function to invoke WASM operations */\n invoke: InvokeFunction;\n /** Optional function to mint a single authorization header for multiple capabilities */\n invokeAny?: InvokeAnyFunction;\n /** Function to make HTTP requests (defaults to globalThis.fetch) */\n fetch?: FetchFunction;\n /** List of TinyCloud host URLs */\n hosts: string[];\n /** Initial session (optional) */\n session?: ServiceSession | null;\n /** Retry policy configuration */\n retryPolicy?: Partial<RetryPolicy>;\n}\n\n/**\n * ServiceContext provides platform dependencies and cross-service access to services.\n * This is the primary interface services use to interact with the SDK runtime.\n *\n * @example\n * ```typescript\n * const context = new ServiceContext({\n * invoke: wasmInvoke,\n * hosts: ['https://node.tinycloud.xyz'],\n * retryPolicy: { maxAttempts: 5 },\n * });\n *\n * // Register a service\n * const kvService = new KVService({});\n * context.registerService('kv', kvService);\n * kvService.initialize(context);\n *\n * // Update session when user signs in\n * context.setSession(userSession);\n * ```\n */\nexport class ServiceContext implements IServiceContext {\n private _session: ServiceSession | null = null;\n private _services: Map<string, IService> = new Map();\n private _eventHandlers: Map<string, Set<EventHandler>> = new Map();\n private _abortController: AbortController = new AbortController();\n private readonly _invoke: InvokeFunction;\n private readonly _invokeAny?: InvokeAnyFunction;\n private readonly _fetch: FetchFunction;\n private readonly _hosts: string[];\n private readonly _retryPolicy: RetryPolicy;\n\n constructor(config: ServiceContextConfig) {\n this._invoke = config.invoke;\n this._invokeAny = config.invokeAny;\n this._fetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n this._hosts = config.hosts;\n this._session = config.session ?? null;\n this._retryPolicy = {\n ...defaultRetryPolicy,\n ...config.retryPolicy,\n };\n }\n\n // ============================================================\n // Session Management\n // ============================================================\n\n /**\n * Get the current session.\n */\n get session(): ServiceSession | null {\n return this._session;\n }\n\n /**\n * Check if the context has an authenticated session.\n */\n get isAuthenticated(): boolean {\n return this._session !== null;\n }\n\n /**\n * Update the session and notify all registered services.\n *\n * @param session - New session or null to clear\n */\n setSession(session: ServiceSession | null): void {\n this._session = session;\n this.emit('session.changed', { authenticated: session !== null });\n\n // Notify all services of session change\n for (const service of this._services.values()) {\n service.onSessionChange(session);\n }\n }\n\n // ============================================================\n // Platform Dependencies\n // ============================================================\n\n /**\n * Get the invoke function for WASM operations.\n */\n get invoke(): InvokeFunction {\n return this._invoke;\n }\n\n /**\n * Get the multi-resource invoke function when available.\n */\n get invokeAny(): InvokeAnyFunction | undefined {\n return this._invokeAny;\n }\n\n /**\n * Get the fetch function for HTTP requests.\n */\n get fetch(): FetchFunction {\n return this._fetch;\n }\n\n /**\n * Get the list of TinyCloud host URLs.\n */\n get hosts(): string[] {\n return this._hosts;\n }\n\n // ============================================================\n // Service Registry\n // ============================================================\n\n /**\n * Register a service with the context.\n *\n * @param name - Service name (e.g., 'kv')\n * @param service - Service instance\n */\n registerService(name: string, service: IService): void {\n this._services.set(name, service);\n }\n\n /**\n * Unregister a service from the context.\n *\n * @param name - Service name to remove\n */\n unregisterService(name: string): void {\n this._services.delete(name);\n }\n\n /**\n * Get a registered service by name.\n *\n * @param name - Service name\n * @returns The service instance or undefined if not registered\n */\n getService<T extends IService>(name: string): T | undefined {\n return this._services.get(name) as T | undefined;\n }\n\n // ============================================================\n // Event System (Telemetry)\n // ============================================================\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n emit(event: string, data: unknown): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n // Don't let event handler errors break the flow\n console.error(`Error in event handler for \"${event}\":`, error);\n }\n }\n }\n }\n\n /**\n * Subscribe to telemetry events.\n *\n * @param event - Event name to subscribe to\n * @param handler - Handler function\n * @returns Unsubscribe function\n */\n on(event: string, handler: EventHandler): () => void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this._eventHandlers.delete(event);\n }\n }\n };\n }\n\n /**\n * Remove all event handlers for an event.\n *\n * @param event - Event name (if omitted, clears all events)\n */\n clearEventHandlers(event?: string): void {\n if (event) {\n this._eventHandlers.delete(event);\n } else {\n this._eventHandlers.clear();\n }\n }\n\n // ============================================================\n // Lifecycle\n // ============================================================\n\n /**\n * Get the abort signal for cancelling operations.\n */\n get abortSignal(): AbortSignal {\n return this._abortController.signal;\n }\n\n /**\n * Abort all pending operations and notify services.\n * Creates a new AbortController for future operations.\n */\n abort(): void {\n this._abortController.abort();\n this._abortController = new AbortController();\n\n // Notify all services\n for (const service of this._services.values()) {\n service.onSignOut();\n }\n }\n\n /**\n * Sign out - abort operations and clear session.\n */\n signOut(): void {\n this.abort();\n this.setSession(null);\n this.emit('session.expired', {});\n }\n\n // ============================================================\n // Retry Policy\n // ============================================================\n\n /**\n * Get the retry policy configuration.\n */\n get retryPolicy(): RetryPolicy {\n return this._retryPolicy;\n }\n}\n","/**\n * SDK Services - Error Utilities\n *\n * Utilities for creating and handling service errors.\n */\n\nimport { ServiceError, ErrorCodes, err, serviceError } from \"./types\";\n\n/**\n * Create a service error for authentication required.\n */\nexport function authRequiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_REQUIRED,\n message: \"Authentication required. Please sign in first.\",\n service,\n };\n}\n\n/**\n * Create a service error for expired authentication.\n */\nexport function authExpiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_EXPIRED,\n message: \"Session has expired. Please sign in again.\",\n service,\n };\n}\n\n/**\n * Create a service error for network issues.\n */\nexport function networkError(\n service: string,\n message: string,\n cause?: Error\n): ServiceError {\n return {\n code: ErrorCodes.NETWORK_ERROR,\n message,\n service,\n cause,\n };\n}\n\n/**\n * Create a service error for timeouts.\n */\nexport function timeoutError(service: string): ServiceError {\n return {\n code: ErrorCodes.TIMEOUT,\n message: \"Request timed out.\",\n service,\n };\n}\n\n/**\n * Create a service error for aborted requests.\n */\nexport function abortedError(service: string): ServiceError {\n return {\n code: ErrorCodes.ABORTED,\n message: \"Request was aborted.\",\n service,\n };\n}\n\n/**\n * Create a service error for not found resources.\n */\nexport function notFoundError(\n service: string,\n resource: string\n): ServiceError {\n return {\n code: ErrorCodes.NOT_FOUND,\n message: `Resource not found: ${resource}`,\n service,\n };\n}\n\n/**\n * Create a service error for permission denied.\n */\nexport function permissionDeniedError(\n service: string,\n action: string\n): ServiceError {\n return {\n code: ErrorCodes.PERMISSION_DENIED,\n message: `Permission denied for action: ${action}`,\n service,\n };\n}\n\n/**\n * Parse the server's \"Unauthorized Action: {resource} / {ability}\" pattern.\n */\nexport function parseAuthError(responseText: string): { resource?: string; action?: string } {\n const match = responseText.match(/^Unauthorized Action:\\s*(.+?)\\s*\\/\\s*(tinycloud\\.\\S+)$/m);\n if (match) {\n return { resource: match[1].trim(), action: match[2].trim() };\n }\n return {};\n}\n\n/**\n * Create a service error for unauthorized action (missing capability).\n */\nexport function authUnauthorizedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return serviceError(ErrorCodes.AUTH_UNAUTHORIZED, message, service, { meta });\n}\n\n/**\n * Create a service error for storage quota exceeded (402 Payment Required).\n */\nexport function storageQuotaExceededError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_QUOTA_EXCEEDED,\n message,\n service,\n meta,\n };\n}\n\n/**\n * Create a service error for storage limit reached (413 Payload Too Large).\n */\nexport function storageLimitReachedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_LIMIT_REACHED,\n message,\n service,\n meta,\n };\n}\n\n/**\n * Wrap an unknown error in a ServiceError.\n */\nexport function wrapError(\n service: string,\n error: unknown,\n defaultCode: string = ErrorCodes.NETWORK_ERROR\n): ServiceError {\n if (error instanceof Error) {\n // Check for abort errors\n if (error.name === \"AbortError\") {\n return abortedError(service);\n }\n\n // Check for timeout errors (varies by platform)\n if (\n error.name === \"TimeoutError\" ||\n error.message.toLowerCase().includes(\"timeout\")\n ) {\n return timeoutError(service);\n }\n\n return {\n code: defaultCode,\n message: error.message,\n service,\n cause: error,\n };\n }\n\n return {\n code: defaultCode,\n message: String(error),\n service,\n };\n}\n\n/**\n * Create an error Result from a ServiceError.\n */\nexport function errorResult(error: ServiceError) {\n return err(error);\n}\n","/**\n * BaseService - Abstract base class for all TinyCloud services.\n *\n * Provides common functionality:\n * - Context management\n * - Session lifecycle hooks\n * - Abort signal handling\n * - Telemetry emission\n */\n\nimport {\n IService,\n IServiceContext,\n ServiceSession,\n ServiceError,\n TelemetryEvents,\n err,\n Result,\n} from \"../types\";\nimport { authRequiredError, wrapError } from \"../errors\";\n\n/**\n * Abstract base class for TinyCloud services.\n *\n * Services extend this class to get common functionality like\n * context management, session lifecycle, and abort handling.\n *\n * @example\n * ```typescript\n * class MyService extends BaseService implements IMyService {\n * static readonly serviceName = 'myservice';\n *\n * constructor(config: MyServiceConfig = {}) {\n * super();\n * this._config = config;\n * }\n *\n * async doSomething(): Promise<Result<Data>> {\n * if (!this.requireAuth()) {\n * return err(authRequiredError('myservice'));\n * }\n * // ... implementation\n * }\n * }\n * ```\n */\nexport abstract class BaseService implements IService {\n /**\n * Service identifier used for registration.\n * Must be overridden by subclasses.\n */\n static readonly serviceName: string;\n\n /**\n * Service context providing access to platform dependencies.\n * Set during initialize().\n */\n protected context!: IServiceContext;\n\n /**\n * Abort controller for this service's operations.\n * Reset on sign-out.\n */\n protected abortController: AbortController = new AbortController();\n\n /**\n * Service-specific configuration.\n */\n protected _config: Record<string, unknown> = {};\n\n /**\n * Get the service configuration.\n */\n get config(): Record<string, unknown> {\n return this._config;\n }\n\n /**\n * Initialize the service with context.\n * Called by the SDK after instantiation.\n *\n * @param context - The service context\n */\n initialize(context: IServiceContext): void {\n this.context = context;\n }\n\n /**\n * Called when session changes (sign-in, sign-out, refresh).\n * Override in subclasses to handle session changes.\n *\n * @param session - The new session, or null if signed out\n */\n onSessionChange(session: ServiceSession | null): void {\n // Override in subclass if needed\n }\n\n /**\n * Called when SDK signs out.\n * Aborts all pending operations.\n */\n onSignOut(): void {\n this.abortController.abort();\n this.abortController = new AbortController();\n }\n\n /**\n * Get the abort signal for this service.\n * Combines the service-level abort with context-level abort.\n */\n protected get abortSignal(): AbortSignal {\n return this.abortController.signal;\n }\n\n /**\n * Check if the service is authenticated.\n */\n protected get isAuthenticated(): boolean {\n return this.context?.isAuthenticated ?? false;\n }\n\n /**\n * Get the current session.\n * Throws if not authenticated.\n */\n protected get session(): ServiceSession {\n if (!this.context?.session) {\n throw new Error(\"Not authenticated\");\n }\n return this.context.session;\n }\n\n /**\n * Check authentication and return error result if not authenticated.\n * Use this at the start of methods that require authentication.\n *\n * @returns true if authenticated, false otherwise\n */\n protected requireAuth(): boolean {\n return this.isAuthenticated;\n }\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n protected emit(event: string, data: unknown): void {\n this.context?.emit(event, data);\n }\n\n /**\n * Emit a service request event.\n *\n * @param action - The action being performed\n * @param key - Optional key/path being accessed\n */\n protected emitRequest(action: string, key?: string): void {\n this.emit(TelemetryEvents.SERVICE_REQUEST, {\n service: this.getServiceName(),\n action,\n key,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Emit a service response event.\n *\n * @param action - The action that was performed\n * @param ok - Whether the request was successful\n * @param startTime - Start time for duration calculation\n * @param status - Optional HTTP status code\n */\n protected emitResponse(\n action: string,\n ok: boolean,\n startTime: number,\n status?: number\n ): void {\n this.emit(TelemetryEvents.SERVICE_RESPONSE, {\n service: this.getServiceName(),\n action,\n ok,\n duration: Date.now() - startTime,\n status,\n });\n }\n\n /**\n * Emit a service error event.\n *\n * @param error - The service error\n */\n protected emitError(error: ServiceError): void {\n this.emit(TelemetryEvents.SERVICE_ERROR, {\n service: this.getServiceName(),\n error,\n });\n }\n\n /**\n * Get the service name from the static property.\n * Subclasses must define static serviceName.\n */\n protected getServiceName(): string {\n return (this.constructor as typeof BaseService).serviceName;\n }\n\n /**\n * Create a combined abort signal from multiple sources.\n *\n * @param signals - Additional abort signals to combine\n * @returns A combined abort signal\n */\n protected combineSignals(...signals: (AbortSignal | undefined)[]): AbortSignal {\n const controller = new AbortController();\n const allSignals = [this.abortSignal, ...signals.filter(Boolean)] as AbortSignal[];\n\n for (const signal of allSignals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n signal.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n }\n\n /**\n * Wrap an operation with error handling and telemetry.\n *\n * @param action - The action name for telemetry\n * @param key - Optional key for telemetry\n * @param operation - The operation to execute\n * @returns Result of the operation\n */\n protected async withTelemetry<T>(\n action: string,\n key: string | undefined,\n operation: () => Promise<Result<T>>\n ): Promise<Result<T>> {\n const startTime = Date.now();\n this.emitRequest(action, key);\n\n try {\n const result = await operation();\n\n if (result.ok) {\n this.emitResponse(action, true, startTime);\n } else {\n this.emitResponse(action, false, startTime);\n this.emitError(result.error);\n }\n\n return result;\n } catch (error) {\n const serviceError = wrapError(this.getServiceName(), error);\n this.emitResponse(action, false, startTime);\n this.emitError(serviceError);\n return err(serviceError);\n }\n }\n}\n","/**\n * PrefixedKVService - A prefix-scoped view of KVService.\n *\n * Provides key-value operations scoped to a specific prefix.\n * All operations automatically prefix keys, enabling app data isolation\n * within a shared space.\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n\nimport { Result } from \"../types\";\nimport {\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVListOptions,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVSignedReadUrlResponse,\n} from \"./types\";\n\n/**\n * Interface for prefixed KV operations.\n *\n * Provides the same operations as IKVService but scoped to a prefix.\n * Supports nested prefixes via withPrefix().\n */\nexport interface IPrefixedKVService {\n /**\n * The current prefix for this scoped view.\n */\n readonly prefix: string;\n\n /**\n * Get a value by key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to retrieve (will be prefixed)\n * @param options - Optional get configuration\n * @returns Result with the stored value and headers\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.get('settings.json');\n * // -> Reads from: /app.myapp.com/settings.json\n * ```\n */\n get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>>;\n\n /**\n * Store a value at a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to store under (will be prefixed)\n * @param value - The value to store\n * @param options - Optional put configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Stores at: /app.myapp.com/settings.json\n * ```\n */\n put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>>;\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>>;\n\n /**\n * List keys within this prefix.\n *\n * Returns keys that match the prefix, with keys returned relative\n * to the prefix when removePrefix is true (default for prefixed service).\n *\n * @param options - Optional list configuration\n * @returns Result with array of matching keys\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.list();\n * // -> Lists keys under: /app.myapp.com/*\n * // Returns: ['settings.json', 'data/user.json', ...]\n * ```\n */\n list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;\n\n /**\n * Delete a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to delete (will be prefixed)\n * @param options - Optional delete configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.delete('old-settings.json');\n * // -> Deletes: /app.myapp.com/old-settings.json\n * ```\n */\n delete(key: string, options?: Omit<KVDeleteOptions, 'prefix'>): Promise<Result<void>>;\n\n /**\n * Get metadata for a key without retrieving the value.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to check (will be prefixed)\n * @param options - Optional head configuration\n * @returns Result with headers only\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.head('large-file.bin');\n * // -> Gets metadata for: /app.myapp.com/large-file.bin\n * ```\n */\n head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to expose via a signed read URL (will be prefixed)\n * @param options - Optional signed URL configuration\n * @returns Result with URL and expiry metadata\n */\n createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>>;\n\n /**\n * Create a nested prefix-scoped view.\n *\n * The subPrefix is appended to the current prefix.\n *\n * @param subPrefix - The sub-prefix to append\n * @returns A new PrefixedKVService with the combined prefix\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json');\n * // -> Reads from: /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(subPrefix: string): IPrefixedKVService;\n}\n\n/**\n * Interface for a KV service that supports prefix delegation.\n *\n * This is the subset of IKVService methods needed by PrefixedKVService.\n */\ninterface IKVServiceLike {\n get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>>;\n\n put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>>;\n\n batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>>;\n\n list(options?: KVListOptions): Promise<Result<KVListResponse>>;\n\n delete(key: string, options?: KVDeleteOptions): Promise<Result<void>>;\n\n head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;\n\n createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>>;\n}\n\n/**\n * PrefixedKVService - Implementation of prefix-scoped KV operations.\n *\n * This class wraps a KVService (or another PrefixedKVService) and\n * automatically prefixes all key operations with the configured prefix.\n *\n * ## Prefix Convention\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * // Create from KVService\n * const prefixed = new PrefixedKVService(kvService, '/app.myapp.com');\n *\n * // Or use the withPrefix factory method on KVService\n * const prefixed = kvService.withPrefix('/app.myapp.com');\n *\n * // All operations are automatically prefixed\n * await prefixed.put('settings.json', { theme: 'dark' });\n * await prefixed.get('settings.json');\n *\n * // Nested prefixes\n * const nested = prefixed.withPrefix('/settings');\n * await nested.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\nexport class PrefixedKVService implements IPrefixedKVService {\n /**\n * The underlying KV service.\n */\n private readonly _kv: IKVServiceLike;\n\n /**\n * The prefix for this scoped view.\n */\n private readonly _prefix: string;\n\n /**\n * Create a new PrefixedKVService.\n *\n * @param kv - The underlying KV service to delegate to\n * @param prefix - The prefix to apply to all operations\n */\n constructor(kv: IKVServiceLike, prefix: string) {\n this._kv = kv;\n // Normalize prefix: ensure it doesn't end with slash\n this._prefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n }\n\n /**\n * The current prefix for this scoped view.\n */\n get prefix(): string {\n return this._prefix;\n }\n\n /**\n * Compute the full key path by combining prefix and key.\n *\n * @param key - The key to prefix\n * @returns The full path including prefix\n */\n private getFullKey(key: string): string {\n // Handle keys that start with slash\n const normalizedKey = key.startsWith('/') ? key : `/${key}`;\n return `${this._prefix}${normalizedKey}`;\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>> {\n const fullKey = this.getFullKey(key);\n // Use empty prefix override to use the full key as-is\n return this._kv.get<T>(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.put(fullKey, value, { ...options, prefix: '' });\n }\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>> {\n return this._kv.batchPut(\n items.map((item) => ({\n ...item,\n key: this.getFullKey(item.key),\n })),\n { ...options, prefix: '' }\n );\n }\n\n /**\n * List keys within this prefix.\n */\n async list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>> {\n // List uses the prefix directly, and by default removes the prefix from results\n const removePrefix = options?.removePrefix ?? true;\n return this._kv.list({\n ...options,\n prefix: this._prefix,\n removePrefix,\n });\n }\n\n /**\n * Delete a key.\n */\n async delete(key: string, options?: Omit<KVDeleteOptions, 'prefix'>): Promise<Result<void>> {\n const fullKey = this.getFullKey(key);\n return this._kv.delete(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.head(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>> {\n const fullKey = this.getFullKey(key);\n return this._kv.createSignedReadUrl(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Create a nested prefix-scoped view.\n */\n withPrefix(subPrefix: string): IPrefixedKVService {\n // Normalize subPrefix\n const normalizedSubPrefix = subPrefix.startsWith('/')\n ? subPrefix\n : `/${subPrefix}`;\n const combinedPrefix = `${this._prefix}${normalizedSubPrefix}`;\n return new PrefixedKVService(this._kv, combinedPrefix);\n }\n}\n","/**\n * KV Service Types\n *\n * Type definitions for the KV (Key-Value) service operations.\n */\n\n/**\n * Configuration for KVService.\n */\nexport interface KVServiceConfig {\n /**\n * Default prefix for all keys.\n * Useful for namespacing data within a space.\n *\n * @example\n * ```typescript\n * const kv = new KVService({ prefix: 'myapp/settings' });\n * await kv.put('theme', 'dark'); // Stores at 'myapp/settings/theme'\n * ```\n */\n prefix?: string;\n\n /**\n * Default timeout in milliseconds for KV operations.\n * Overrides the context-level timeout if set.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for KV get operations.\n */\nexport interface KVGetOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Return raw response instead of parsed JSON.\n * When true, data will be the raw response text.\n */\n raw?: boolean;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV put operations.\n */\nexport interface KVPutOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Content type for the value.\n * Defaults to 'application/json' for objects.\n */\n contentType?: string;\n\n /**\n * Custom metadata headers to store with the value.\n */\n metadata?: Record<string, string>;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * One entry in a KV batch put request.\n */\nexport interface KVBatchPutItem {\n /**\n * The key to store under.\n */\n key: string;\n\n /**\n * The value to store.\n *\n * Objects are JSON stringified. Strings are stored as text. Binary values\n * should be supplied as Blob, ArrayBuffer, or Uint8Array.\n */\n value: unknown;\n\n /**\n * Content type for this item. Defaults to application/json for objects and\n * application/octet-stream for binary values.\n */\n contentType?: string;\n}\n\n/**\n * Options for KV batch put operations.\n */\nexport interface KVBatchPutOptions {\n /**\n * Override the default prefix for all entries in this batch.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response from KV batch put operations.\n */\nexport interface KVBatchPutResponse {\n /**\n * Keys successfully written by the batch.\n */\n written: string[];\n\n /**\n * Number of written keys.\n */\n count: number;\n}\n\n/**\n * Options for KV list operations.\n */\nexport interface KVListOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Additional path to append to the prefix.\n */\n path?: string;\n\n /**\n * Whether to remove the prefix from returned keys.\n * When true, keys are returned relative to the prefix.\n */\n removePrefix?: boolean;\n\n /**\n * Return raw response instead of parsed JSON.\n */\n raw?: boolean;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV delete operations.\n */\nexport interface KVDeleteOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV head (metadata) operations.\n */\nexport interface KVHeadOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Default lifetime for signed KV read URLs when a caller omits expiresInSeconds.\n * SDK duration defaults are stored in milliseconds; createSignedReadUrl converts\n * this to the node endpoint's ttl_seconds field.\n *\n * Keep this in sync with EXPIRY.SIGNED_READ_URL_MS in @tinycloud/sdk-core.\n * sdk-services cannot import sdk-core because sdk-core depends on sdk-services.\n */\nexport const DEFAULT_SIGNED_READ_URL_EXPIRY_MS = 5 * 60 * 1000;\n\n/**\n * Options for creating a signed KV read URL.\n */\nexport interface KVCreateSignedReadUrlOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Requested URL lifetime in seconds.\n * Defaults to {@link DEFAULT_SIGNED_READ_URL_EXPIRY_MS} converted to seconds.\n * The node may cap this by its configured maximum, the invocation expiry,\n * or the parent delegation expiry.\n */\n expiresInSeconds?: number;\n\n /**\n * Optional blake3 content hash to bind the signed URL to a specific object.\n */\n contentHash?: string;\n\n /**\n * Optional ETag to bind the signed URL to a specific object version.\n */\n etag?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response headers from KV operations.\n */\nexport interface KVResponseHeaders {\n /**\n * ETag for conditional requests.\n */\n etag?: string;\n\n /**\n * Content type of the stored value.\n */\n contentType?: string;\n\n /**\n * Last modification timestamp.\n */\n lastModified?: string;\n\n /**\n * Content length in bytes.\n */\n contentLength?: number;\n\n /**\n * Get a header value by name.\n * @param name - Header name (case-insensitive)\n */\n get(name: string): string | null;\n}\n\n/**\n * Response from KV get/put operations.\n *\n * @template T - Type of the data payload\n */\nexport interface KVResponse<T = unknown> {\n /**\n * The data payload.\n * For get: the stored value.\n * For put: undefined.\n */\n data: T;\n\n /**\n * Response headers with metadata.\n */\n headers: KVResponseHeaders;\n}\n\n/**\n * Response from KV list operations.\n */\nexport interface KVListResponse {\n /**\n * Array of keys matching the list criteria.\n */\n keys: string[];\n}\n\n/**\n * Response from signed KV read URL creation.\n */\nexport interface KVSignedReadUrlResponse {\n /**\n * Absolute URL suitable for passing to external readers.\n */\n url: string;\n\n /**\n * Opaque URL returned by tinycloud-node, usually relative to the node host.\n */\n relativeUrl: string;\n\n /**\n * Opaque signed KV ticket identifier.\n */\n ticketId: string;\n\n /**\n * Expiry timestamp as returned by tinycloud-node.\n */\n expiresAt: string;\n}\n\n/**\n * KV service action types.\n */\nexport const KVAction = {\n GET: \"tinycloud.kv/get\",\n PUT: \"tinycloud.kv/put\",\n LIST: \"tinycloud.kv/list\",\n DELETE: \"tinycloud.kv/del\",\n HEAD: \"tinycloud.kv/metadata\",\n} as const;\n\nexport type KVActionType = (typeof KVAction)[keyof typeof KVAction];\n","/**\n * KVService - Key-Value storage service implementation.\n *\n * Platform-agnostic KV service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n FetchResponse,\n ServiceHeaders,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n storageQuotaExceededError,\n storageLimitReachedError,\n parseAuthError,\n authUnauthorizedError,\n} from \"../errors\";\nimport { IKVService } from \"./IKVService\";\nimport { PrefixedKVService, IPrefixedKVService } from \"./PrefixedKVService\";\nimport {\n DEFAULT_SIGNED_READ_URL_EXPIRY_MS,\n KVServiceConfig,\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVListOptions,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVResponseHeaders,\n KVSignedReadUrlResponse,\n KVAction,\n} from \"./types\";\n\ninterface SignedKvUrlNodeResponse {\n url: string;\n ticketId: string;\n expiresAt: string;\n}\n\nfunction encodeKvBatchPartName(path: string): string {\n return encodeURIComponent(path).replace(/[!'()*]/g, (char) =>\n `%${char.charCodeAt(0).toString(16).toUpperCase()}`\n );\n}\n\n/**\n * KV service implementation.\n *\n * Provides key-value storage operations using TinyCloud's KV API.\n * Uses the Result type pattern for explicit error handling.\n *\n * @example\n * ```typescript\n * // Register with SDK\n * const sdk = new TinyCloud({\n * services: { kv: KVService },\n * serviceConfigs: { kv: { prefix: 'myapp' } },\n * });\n *\n * // Use the service\n * const result = await sdk.kv.get('settings');\n * if (result.ok) {\n * console.log(result.data.data);\n * }\n * ```\n */\nexport class KVService extends BaseService implements IKVService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"kv\";\n\n /**\n * Service configuration.\n */\n declare protected _config: KVServiceConfig;\n\n /**\n * Create a new KVService instance.\n *\n * @param config - Service configuration\n */\n constructor(config: KVServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): KVServiceConfig {\n return this._config;\n }\n\n // Parses \"Used: X bytes, Limit: Y bytes\" from tinycloud-node error responses\n private parseQuotaInfo(\n errorText: string\n ): { usedBytes: number; limitBytes: number } | undefined {\n const match = errorText.match(\n /Used:\\s*(\\d+)\\s*bytes,\\s*Limit:\\s*(\\d+)\\s*bytes/i\n );\n if (match) {\n return {\n usedBytes: parseInt(match[1], 10),\n limitBytes: parseInt(match[2], 10),\n };\n }\n return undefined;\n }\n\n private handleQuotaErrorResponse(\n response: FetchResponse,\n errorText: string,\n key: string\n ): Result<never> | undefined {\n if (response.status === 402) {\n const quotaInfo = this.parseQuotaInfo(errorText);\n return err(\n storageQuotaExceededError(\n \"kv\",\n `Storage quota exceeded for key \"${key}\": ${errorText}`,\n {\n status: response.status,\n ...(quotaInfo\n ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes }\n : {}),\n }\n )\n );\n }\n\n if (response.status === 413) {\n const quotaInfo = this.parseQuotaInfo(errorText);\n return err(\n storageLimitReachedError(\n \"kv\",\n `Storage limit reached for key \"${key}\": ${errorText}`,\n {\n status: response.status,\n ...(quotaInfo\n ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes }\n : {}),\n }\n )\n );\n }\n\n return undefined;\n }\n\n /**\n * Get the full path with optional prefix.\n *\n * @param key - The key\n * @param prefixOverride - Optional prefix override\n * @returns The full path\n */\n private getFullPath(key: string, prefixOverride?: string): string {\n const prefix = prefixOverride ?? this._config.prefix ?? \"\";\n return prefix ? `${prefix}/${key}` : key;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.context.hosts[0];\n }\n\n private withJsonContentType(headers: ServiceHeaders): ServiceHeaders {\n if (Array.isArray(headers)) {\n return [...headers, [\"content-type\", \"application/json\"]];\n }\n\n return {\n ...headers,\n \"content-type\": \"application/json\",\n };\n }\n\n /**\n * Execute an invoke operation.\n *\n * @param path - Resource path\n * @param action - KV action\n * @param body - Optional request body\n * @param signal - Optional abort signal\n * @returns Fetch response\n */\n private async invokeOperation(\n path: string,\n action: string,\n body?: Blob | string,\n signal?: AbortSignal\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n action\n );\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body,\n signal: this.combineSignals(signal),\n });\n }\n\n private serializeBatchPutValue(item: KVBatchPutItem): Blob {\n const contentType = item.contentType;\n\n if (item.value instanceof Blob) {\n if (!contentType || item.value.type === contentType) {\n return item.value;\n }\n return new Blob([item.value], { type: contentType });\n }\n\n if (item.value instanceof ArrayBuffer) {\n return new Blob([item.value], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (ArrayBuffer.isView(item.value)) {\n const value = item.value;\n const bytes = new Uint8Array(value.byteLength);\n bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n return new Blob([bytes], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (typeof item.value === \"string\") {\n return new Blob([item.value], {\n type: contentType ?? \"text/plain;charset=UTF-8\",\n });\n }\n\n const json = JSON.stringify(item.value);\n if (json === undefined) {\n throw new Error(`Cannot JSON serialize KV batch value for key \"${item.key}\"`);\n }\n\n return new Blob([json], {\n type: contentType ?? \"application/json\",\n });\n }\n\n private normalizeBatchPutResponse(data: unknown): KVBatchPutResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<KVBatchPutResponse>;\n if (\n !Array.isArray(response.written) ||\n !response.written.every((key) => typeof key === \"string\") ||\n typeof response.count !== \"number\"\n ) {\n return undefined;\n }\n\n return {\n written: response.written,\n count: response.count,\n };\n }\n\n /**\n * Create KVResponseHeaders from fetch response headers.\n *\n * @param headers - Fetch response headers\n * @returns KVResponseHeaders object\n */\n private createResponseHeaders(headers: {\n get(name: string): string | null;\n }): KVResponseHeaders {\n return {\n etag: headers.get(\"etag\") ?? undefined,\n contentType: headers.get(\"content-type\") ?? undefined,\n lastModified: headers.get(\"last-modified\") ?? undefined,\n contentLength: headers.get(\"content-length\")\n ? parseInt(headers.get(\"content-length\")!, 10)\n : undefined,\n get: (name: string) => headers.get(name),\n };\n }\n\n /**\n * Parse response body based on content type.\n *\n * @param response - Fetch response\n * @param raw - Whether to return raw text\n * @returns Parsed data\n */\n private async parseResponse<T>(\n response: FetchResponse,\n raw: boolean = false\n ): Promise<T | undefined> {\n if (!response.ok) {\n return undefined;\n }\n\n if (raw) {\n return (await response.text()) as unknown as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return (await response.json()) as T;\n } else if (contentType?.startsWith(\"text/\")) {\n return (await response.text()) as unknown as T;\n }\n\n // No content-type header - try to parse as JSON, fall back to text\n const text = await response.text();\n if (!text) {\n return undefined;\n }\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n }\n\n private async createSignedReadUrlError(\n response: FetchResponse,\n key: string\n ): Promise<Result<never>> {\n let errorText = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n errorText = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n\n if (response.status === 401 || response.status === 403) {\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const code =\n response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;\n return err(\n serviceError(\n code,\n `Failed to create signed read URL for key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n private normalizeSignedReadUrlResponse(\n data: unknown\n ): KVSignedReadUrlResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<SignedKvUrlNodeResponse>;\n if (\n typeof response.url !== \"string\" ||\n typeof response.ticketId !== \"string\" ||\n typeof response.expiresAt !== \"string\"\n ) {\n return undefined;\n }\n\n return {\n url: new URL(response.url, this.host).toString(),\n relativeUrl: response.url,\n ticketId: response.ticketId,\n expiresAt: response.expiresAt,\n };\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.GET,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `Key not found: ${key}`,\n \"kv\"\n )\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n const data = await this.parseResponse<T>(response, options?.raw);\n return ok({\n data: data as T,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n // Serialize value to string\n let body: string;\n if (typeof value === \"string\") {\n body = value;\n } else {\n body = JSON.stringify(value);\n }\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.PUT,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const errorText = await response.text();\n\n // Check for storage quota errors (402, 413)\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n key\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to put key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Store multiple values in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>> {\n return this.withTelemetry(\"batchPut\", String(items.length), async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (items.length === 0) {\n return ok({ written: [], count: 0 });\n }\n\n if (!this.context.invokeAny) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batchPut requires SDK runtime support for multi-resource invocations\",\n \"kv\"\n )\n );\n }\n\n const session = this.context.session!;\n const paths = items.map((item) => this.getFullPath(item.key, options?.prefix));\n const seen = new Set<string>();\n for (const path of paths) {\n if (seen.has(path)) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n `KV batchPut received duplicate key after prefix resolution: ${path}`,\n \"kv\"\n )\n );\n }\n seen.add(path);\n }\n\n try {\n const body = new FormData();\n for (let index = 0; index < items.length; index++) {\n body.append(\n encodeKvBatchPartName(paths[index]!),\n this.serializeBatchPutValue(items[index]!)\n );\n }\n\n const headers = this.context.invokeAny(\n session,\n paths.map((path) => ({\n spaceId: session.spaceId,\n service: \"kv\",\n path,\n action: KVAction.PUT,\n }))\n );\n\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body,\n signal: this.combineSignals(options?.signal),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 401 || response.status === 403) {\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n \"batch\"\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to batch put ${items.length} key(s): ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n const batchResponse = this.normalizeBatchPutResponse(await response.json());\n if (!batchResponse || batchResponse.count !== batchResponse.written.length) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV batchPut response did not include matching written keys and count\",\n \"kv\"\n )\n );\n }\n\n return ok(batchResponse);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * List keys with optional prefix filtering.\n */\n async list(options?: KVListOptions): Promise<Result<KVListResponse>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n // Build the path from prefix and optional path\n let listPath = options?.prefix ?? this._config.prefix ?? \"\";\n if (options?.path) {\n listPath = listPath ? `${listPath}/${options.path}` : options.path;\n }\n\n try {\n const response = await this.invokeOperation(\n listPath,\n KVAction.LIST,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to list keys: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n let keys = await this.parseResponse<string[]>(response, options?.raw);\n keys = keys ?? [];\n\n // Optionally remove prefix from keys\n if (options?.removePrefix && listPath) {\n const prefixWithSlash = listPath.endsWith(\"/\")\n ? listPath\n : `${listPath}/`;\n keys = keys.map((key) =>\n key.startsWith(prefixWithSlash)\n ? key.slice(prefixWithSlash.length)\n : key\n );\n }\n\n return ok({ keys });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Delete a key.\n */\n async delete(key: string, options?: KVDeleteOptions): Promise<Result<void>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.DELETE,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `Key not found: ${key}`,\n \"kv\"\n )\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to delete key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: KVHeadOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.HEAD,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `Key not found: ${key}`,\n \"kv\"\n )\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get metadata for key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>> {\n return this.withTelemetry(\"createSignedReadUrl\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n KVAction.GET\n );\n\n const body: {\n space: string;\n path: string;\n ttl_seconds: number;\n content_hash?: string;\n etag?: string;\n } = {\n space: session.spaceId,\n path,\n ttl_seconds:\n options?.expiresInSeconds ??\n Math.ceil(DEFAULT_SIGNED_READ_URL_EXPIRY_MS / 1000),\n };\n\n if (options?.contentHash !== undefined) {\n body.content_hash = options.contentHash;\n }\n if (options?.etag !== undefined) {\n body.etag = options.etag;\n }\n\n try {\n const response = await this.context.fetch(`${this.host}/signed/kv`, {\n method: \"POST\",\n headers: this.withJsonContentType(headers),\n body: JSON.stringify(body),\n signal: this.combineSignals(options?.signal),\n });\n\n if (!response.ok) {\n return this.createSignedReadUrlError(response, key);\n }\n\n const signedUrl = this.normalizeSignedReadUrlResponse(\n await response.json()\n );\n if (!signedUrl) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"Signed read URL response did not include url, ticketId, and expiresAt\",\n \"kv\"\n )\n );\n }\n\n return ok(signedUrl);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Create a prefix-scoped view of this KV service.\n *\n * Returns a PrefixedKVService that automatically prefixes all\n * key operations with the specified prefix. This enables apps\n * to isolate their data within a shared space.\n *\n * @param prefix - The prefix to apply to all operations\n * @returns A PrefixedKVService scoped to the prefix\n *\n * ## Prefix Conventions\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(prefix: string): IPrefixedKVService {\n return new PrefixedKVService(this, prefix);\n }\n}\n","/**\n * DatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent SQLService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDatabaseHandle } from \"./ISQLService\";\nimport type { SQLService } from \"./SQLService\";\nimport type {\n SqlValue,\n SqlStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n} from \"./types\";\n\nexport class DatabaseHandle implements IDatabaseHandle {\n private service: SQLService;\n public readonly name: string;\n\n constructor(service: SQLService, name: string) {\n this.service = service;\n this.name = name;\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async export(options?: QueryOptions): Promise<Result<Blob>> {\n return this.service.exportDb(this.name, options);\n }\n}\n","/**\n * SQL Service Types\n *\n * Type definitions for the SQL service operations.\n */\n\n/**\n * Configuration for SQLService.\n */\nexport interface SQLServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Default timeout in milliseconds for SQL operations.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for SQL query operations.\n */\nexport interface QueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for SQL execute operations.\n */\nexport interface ExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for SQL batch operations.\n */\nexport interface BatchOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A SQL value: null, number, string, or binary data.\n */\nexport type SqlValue = null | number | string | Uint8Array;\n\n/**\n * A SQL statement with optional parameters.\n */\nexport interface SqlStatement {\n sql: string;\n params?: SqlValue[];\n}\n\n/**\n * Response from SQL query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from SQL execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n lastInsertRowId: number;\n}\n\n/**\n * Response from SQL batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * SQL service action types.\n */\nexport const SQLAction = {\n READ: \"tinycloud.sql/read\",\n WRITE: \"tinycloud.sql/write\",\n ADMIN: \"tinycloud.sql/admin\",\n SELECT: \"tinycloud.sql/select\",\n INSERT: \"tinycloud.sql/insert\",\n UPDATE: \"tinycloud.sql/update\",\n DELETE: \"tinycloud.sql/delete\",\n EXECUTE: \"tinycloud.sql/execute\",\n EXPORT: \"tinycloud.sql/export\",\n ALL: \"tinycloud.sql/*\",\n} as const;\n\nexport type SQLActionType = (typeof SQLAction)[keyof typeof SQLAction];\n","/**\n * SQLService - SQL database service implementation.\n *\n * Platform-agnostic SQL service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n} from \"../types\";\nimport { authRequiredError, wrapError, parseAuthError } from \"../errors\";\nimport type { ISQLService } from \"./ISQLService\";\nimport type { IDatabaseHandle } from \"./ISQLService\";\nimport { DatabaseHandle } from \"./DatabaseHandle\";\nimport {\n type SQLServiceConfig,\n type QueryOptions,\n type ExecuteOptions,\n type BatchOptions,\n type SqlValue,\n type SqlStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n SQLAction,\n} from \"./types\";\n\nexport class SQLService extends BaseService implements ISQLService {\n static readonly serviceName = \"sql\";\n\n declare protected _config: SQLServiceConfig;\n\n constructor(config: SQLServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): SQLServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDatabaseHandle {\n return new DatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database.\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n // === Internal methods called by DatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n SQLAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\");\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: params ?? [],\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const response = await this.invokeSQL(\n dbName,\n SQLAction.WRITE,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\");\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n SQLAction.WRITE,\n { action: \"batch\", statements },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\");\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n SQLAction.EXECUTE,\n { action: \"execute_statement\", name, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\");\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async exportDb(\n dbName: string,\n options?: QueryOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n SQLAction.EXPORT,\n { action: \"export\" },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\");\n }\n\n // FetchResponse doesn't expose blob(), so access it from the\n // underlying response which is a standard fetch Response at runtime\n const resp = response as any;\n if (typeof resp.blob === \"function\") {\n const blob = await resp.blob();\n return ok(blob as Blob);\n }\n // If blob() is not available, return the raw text as a Blob-like\n const text = await response.text();\n return ok(text as unknown as Blob);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n // === Private helpers ===\n\n private async invokeSQL(\n dbName: string,\n action: string,\n body: Record<string, unknown>,\n signal?: AbortSignal\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(session, \"sql\", dbName, action);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body) as any,\n signal: this.combineSignals(signal),\n });\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n\n let errorBody: { error?: string; message?: string; code?: string } = {};\n try {\n errorBody = JSON.parse(errorText);\n } catch {\n // Not JSON\n }\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message =\n errorBody.message ||\n `SQL ${operation} failed: ${response.status} - ${errorText}`;\n\n const meta: Record<string, unknown> = { status: response.status, statusText: response.statusText };\n\n if (response.status === 401) {\n const { resource, action } = parseAuthError(errorText);\n if (action) meta.requiredAction = action;\n if (resource) meta.resource = resource;\n }\n\n return err(\n serviceError(errorCode, message, \"sql\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.SQL_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"sql_readonly_violation\") {\n return ErrorCodes.SQL_READONLY_VIOLATION;\n }\n return ErrorCodes.SQL_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.SQL_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.SQL_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.SQL_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n","/**\n * DuckDbDatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent DuckDbService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport type { DuckDbService } from \"./DuckDbService\";\nimport type {\n DuckDbValue,\n DuckDbStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SchemaInfo,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n} from \"./types\";\n\nexport class DuckDbDatabaseHandle implements IDuckDbDatabaseHandle {\n private service: DuckDbService;\n public readonly name: string;\n\n constructor(service: DuckDbService, name: string) {\n this.service = service;\n this.name = name;\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.service.queryArrowOnDb(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async describe(options?: DuckDbOptions): Promise<Result<SchemaInfo>> {\n return this.service.describeDb(this.name, options);\n }\n\n async export(options?: DuckDbOptions): Promise<Result<Blob>> {\n return this.service.exportOnDb(this.name, options);\n }\n\n async import(data: Uint8Array, options?: DuckDbOptions): Promise<Result<void>> {\n return this.service.importOnDb(this.name, data, options);\n }\n}\n","/**\n * DuckDB Service Types\n *\n * Type definitions for the DuckDB service operations.\n */\n\n/**\n * Configuration for DuckDbService.\n */\nexport interface DuckDbServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Default timeout in milliseconds for DuckDB operations.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for DuckDB query operations.\n */\nexport interface DuckDbQueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB execute operations.\n */\nexport interface DuckDbExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB batch operations.\n */\nexport interface DuckDbBatchOptions {\n /**\n * Whether to run statements in a transaction.\n */\n transactional?: boolean;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB operations that only need an abort signal.\n */\nexport interface DuckDbOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A DuckDB value: null, boolean, number, string, binary, array, or object.\n */\nexport type DuckDbValue =\n | null\n | boolean\n | number\n | string\n | Uint8Array\n | DuckDbValueArray\n | DuckDbValueRecord;\n\n/** Array of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueArray extends Array<DuckDbValue> {}\n\n/** Record of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueRecord {\n [key: string]: DuckDbValue;\n}\n\n/**\n * A DuckDB statement with optional parameters.\n */\nexport interface DuckDbStatement {\n sql: string;\n params?: DuckDbValue[];\n}\n\n/**\n * Response from DuckDB query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from DuckDB execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n}\n\n/**\n * Response from DuckDB batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * Schema information for a DuckDB database.\n */\nexport interface SchemaInfo {\n tables: TableInfo[];\n views: ViewInfo[];\n}\n\n/**\n * Information about a table.\n */\nexport interface TableInfo {\n name: string;\n columns: ColumnInfo[];\n}\n\n/**\n * Information about a column.\n */\nexport interface ColumnInfo {\n name: string;\n type: string;\n nullable: boolean;\n}\n\n/**\n * Information about a view.\n */\nexport interface ViewInfo {\n name: string;\n sql: string;\n}\n\n/**\n * DuckDB service action types.\n */\nexport const DuckDbAction = {\n READ: \"tinycloud.duckdb/read\",\n WRITE: \"tinycloud.duckdb/write\",\n ADMIN: \"tinycloud.duckdb/admin\",\n DESCRIBE: \"tinycloud.duckdb/describe\",\n EXPORT: \"tinycloud.duckdb/export\",\n IMPORT: \"tinycloud.duckdb/import\",\n EXECUTE: \"tinycloud.duckdb/execute\",\n ALL: \"tinycloud.duckdb/*\",\n} as const;\n\nexport type DuckDbActionType = (typeof DuckDbAction)[keyof typeof DuckDbAction];\n","/**\n * DuckDbService - DuckDB database service implementation.\n *\n * Platform-agnostic DuckDB service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n} from \"../types\";\nimport { authRequiredError, wrapError, parseAuthError } from \"../errors\";\nimport type { IDuckDbService, IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport { DuckDbDatabaseHandle } from \"./DuckDbDatabaseHandle\";\nimport {\n type DuckDbServiceConfig,\n type DuckDbQueryOptions,\n type DuckDbExecuteOptions,\n type DuckDbBatchOptions,\n type DuckDbOptions,\n type DuckDbValue,\n type DuckDbStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SchemaInfo,\n DuckDbAction,\n} from \"./types\";\n\nexport class DuckDbService extends BaseService implements IDuckDbService {\n static readonly serviceName = \"duckdb\";\n\n declare protected _config: DuckDbServiceConfig;\n\n constructor(config: DuckDbServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): DuckDbServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDuckDbDatabaseHandle {\n return new DuckDbDatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database (JSON format).\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: query the default database (Arrow IPC format).\n */\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.queryArrowOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n // === Internal methods called by DuckDbDatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry<QueryResponse<T>>(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\");\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async queryArrowOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.withTelemetry<ArrayBuffer>(\"queryArrow\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n options?.signal,\n { Accept: \"application/vnd.apache.arrow.stream\" }\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"queryArrow\");\n }\n\n const buffer = await response.arrayBuffer();\n return ok(buffer);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: params ?? [],\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\");\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const body: Record<string, unknown> = {\n action: \"batch\",\n statements,\n };\n if (options?.transactional !== undefined) {\n body.transactional = options.transactional;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\");\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.EXECUTE,\n { action: \"executeStatement\", name, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\");\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async describeDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<SchemaInfo>> {\n return this.withTelemetry(\"describe\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.DESCRIBE,\n { action: \"describe\" },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"describe\");\n }\n\n const data = (await response.json()) as SchemaInfo;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async exportOnDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.EXPORT,\n { action: \"export\" },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\");\n }\n\n const blob = await response.blob();\n return ok(blob);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async importOnDb(\n dbName: string,\n data: Uint8Array,\n options?: DuckDbOptions\n ): Promise<Result<void>> {\n return this.withTelemetry(\"import\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"duckdb\",\n dbName,\n DuckDbAction.IMPORT\n );\n\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/x-duckdb\",\n },\n body: new Blob([data]),\n signal: this.combineSignals(options?.signal),\n });\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"import\");\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n // === Private helpers ===\n\n private async invokeDuckDb(\n dbName: string,\n action: string,\n body: Record<string, unknown>,\n signal?: AbortSignal,\n extraHeaders?: Record<string, string>\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(session, \"duckdb\", dbName, action);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n signal: this.combineSignals(signal),\n });\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n\n let errorBody: { error?: string; message?: string; code?: string } = {};\n try {\n errorBody = JSON.parse(errorText);\n } catch {\n // Not JSON\n }\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message =\n errorBody.message ||\n `DuckDB ${operation} failed: ${response.status} - ${errorText}`;\n\n const meta: Record<string, unknown> = { status: response.status, statusText: response.statusText };\n\n if (response.status === 401) {\n const { resource, action } = parseAuthError(errorText);\n if (action) meta.requiredAction = action;\n if (resource) meta.resource = resource;\n }\n\n return err(\n serviceError(errorCode, message, \"duckdb\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.DUCKDB_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"duckdb_readonly_violation\") {\n return ErrorCodes.DUCKDB_READONLY_VIOLATION;\n }\n return ErrorCodes.DUCKDB_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.DUCKDB_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.DUCKDB_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.DUCKDB_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n","import { BaseService } from \"../base/BaseService\";\nimport type {\n FetchResponse,\n InvokeAnyEntry,\n ServiceHeaders,\n Result,\n} from \"../types\";\nimport { ErrorCodes, err, ok, serviceError } from \"../types\";\nimport { authRequiredError, wrapError } from \"../errors\";\nimport type { IHooksService } from \"./IHooksService\";\nimport type {\n HookEvent,\n HookStreamEvent,\n HookSubscription,\n HooksServiceConfig,\n SubscribeOptions,\n HookWebhookListOptions,\n HookWebhookRecord,\n HookWebhookRegistration,\n HookWebhookUnregisterOptions,\n} from \"./types\";\n\ninterface HookTicketResponse {\n ticket: string;\n expiresAt: string;\n}\n\ninterface HookSubscriber {\n requested: HookSubscription[];\n ttlSeconds?: number;\n queue: AsyncQueue<HookEvent>;\n}\n\nclass AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this;\n }\n\n push(value: T): void {\n if (this.closed) {\n return;\n }\n\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter({ value, done: false });\n return;\n }\n\n this.values.push(value);\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n while (this.waiters.length > 0) {\n const waiter = this.waiters.shift();\n waiter?.({ value: undefined as never, done: true });\n }\n }\n\n next(): Promise<IteratorResult<T>> {\n if (this.values.length > 0) {\n const value = this.values.shift()!;\n return Promise.resolve({ value, done: false });\n }\n\n if (this.closed) {\n return Promise.resolve({ value: undefined as never, done: true });\n }\n\n return new Promise<IteratorResult<T>>((resolve) => {\n this.waiters.push(resolve);\n });\n }\n}\n\nexport class HooksService extends BaseService implements IHooksService {\n static readonly serviceName = \"hooks\";\n\n declare protected _config: HooksServiceConfig;\n private readonly _subscribers: Set<HookSubscriber> = new Set();\n private _sharedStreamTask?: Promise<void>;\n private _sharedStreamAbort?: AbortController;\n private _refreshChain: Promise<void> = Promise.resolve();\n private _activeSignature = \"\";\n\n constructor(config: HooksServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): HooksServiceConfig {\n return this._config;\n }\n\n private get host(): string {\n return this._config.host ?? this.context.hosts[0];\n }\n\n async *subscribe(\n subscriptions: HookSubscription[],\n options: SubscribeOptions = {},\n ): AsyncIterable<HookEvent> {\n if (!this.requireAuth()) {\n throw new Error(\"Authentication required for hooks subscription\");\n }\n if (subscriptions.length === 0) {\n throw new Error(\"At least one hook subscription is required\");\n }\n\n const normalized = subscriptions.map(normalizeSubscription);\n const subscriber: HookSubscriber = {\n requested: normalized,\n ttlSeconds: options.ttlSeconds,\n queue: new AsyncQueue<HookEvent>(),\n };\n\n this._subscribers.add(subscriber);\n const abortHandler = () => {\n this._subscribers.delete(subscriber);\n subscriber.queue.close();\n void this.scheduleSharedStreamRefresh();\n };\n\n if (options.signal) {\n if (options.signal.aborted) {\n abortHandler();\n } else {\n options.signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n }\n\n void this.scheduleSharedStreamRefresh();\n\n try {\n for await (const event of subscriber.queue) {\n yield event;\n }\n } finally {\n if (options.signal) {\n options.signal.removeEventListener(\"abort\", abortHandler);\n }\n abortHandler();\n }\n }\n\n async register(\n webhook: HookWebhookRegistration,\n ): Promise<Result<HookWebhookRecord>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n if (typeof webhook.secret !== \"string\" || webhook.secret.trim().length === 0) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"Webhook secret is required\",\n \"hooks\",\n { meta: { field: \"secret\" } },\n ),\n );\n }\n\n try {\n const response = await this.context.fetch(`${this.host}/hooks/webhooks`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/register\",\n buildScopePath(webhook.service, webhook.pathPrefix),\n ),\n ),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n space: webhook.space,\n service: webhook.service,\n pathPrefix: normalizePathPrefix(webhook.pathPrefix),\n abilities: webhook.abilities ?? [],\n callbackUrl: webhook.callbackUrl,\n secret: webhook.secret,\n }),\n });\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to register webhook\", response),\n );\n }\n\n const data = normalizeWebhookRecord(await response.json());\n if (!data) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook registration response did not include a record\"),\n ),\n );\n }\n\n return ok(data);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async list(\n options: HookWebhookListOptions = {},\n ): Promise<Result<HookWebhookRecord[]>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const query = new URLSearchParams();\n if (options.space) {\n query.set(\"space\", options.space);\n }\n if (options.service) {\n query.set(\"service\", options.service);\n }\n if (options.pathPrefix) {\n const normalizedPrefix = normalizePathPrefix(options.pathPrefix);\n if (normalizedPrefix) {\n query.set(\"prefix\", normalizedPrefix);\n }\n }\n\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n {\n method: \"GET\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/list\",\n options.service\n ? buildScopePath(options.service, options.pathPrefix)\n : \"webhooks\",\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to list webhooks\", response),\n );\n }\n\n const payload = await response.json();\n const records = normalizeWebhookRecordList(payload);\n if (!records) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook list response did not include records\"),\n ),\n );\n }\n\n return ok(records);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async unregister(\n id: string,\n options: HookWebhookUnregisterOptions = {},\n ): Promise<Result<void>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks/${encodeURIComponent(id)}`,\n {\n method: \"DELETE\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/unregister\",\n options.target\n ? buildScopePath(\n options.target.service,\n options.target.pathPrefix,\n )\n : `webhooks/${id}`,\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\n \"hooks\",\n \"failed to unregister webhook\",\n response,\n ),\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n private async scheduleSharedStreamRefresh(): Promise<void> {\n this._refreshChain = this._refreshChain\n .then(() => this.refreshSharedStream())\n .catch(() => undefined);\n await this._refreshChain;\n }\n\n private async refreshSharedStream(): Promise<void> {\n if (!this.requireAuth() || this._subscribers.size === 0) {\n this.abortSharedStream();\n this._activeSignature = \"\";\n return;\n }\n\n const state = this.collectSharedStreamState();\n if (state.signature !== this._activeSignature) {\n this._activeSignature = state.signature;\n this.abortSharedStream();\n }\n\n if (!this._sharedStreamTask) {\n this._sharedStreamTask = this.runSharedStream(state)\n .catch((error: unknown) => {\n if (!isAbortError(error)) {\n throw error;\n }\n })\n .finally(() => {\n this._sharedStreamTask = undefined;\n this._sharedStreamAbort = undefined;\n if (this._subscribers.size > 0) {\n void this.scheduleSharedStreamRefresh();\n }\n });\n }\n }\n\n private collectSharedStreamState(): {\n subscriptions: HookSubscription[];\n ttlSeconds?: number;\n signature: string;\n } {\n const merged = new Map<string, HookSubscription>();\n const ttlCandidates: number[] = [];\n\n for (const subscriber of this._subscribers) {\n if (typeof subscriber.ttlSeconds === \"number\") {\n ttlCandidates.push(subscriber.ttlSeconds);\n }\n for (const subscription of subscriber.requested) {\n merged.set(subscriptionSignature(subscription), subscription);\n }\n }\n\n const subscriptions = [...merged.values()].sort((left, right) =>\n subscriptionSignature(left).localeCompare(subscriptionSignature(right)),\n );\n const ttlSeconds =\n ttlCandidates.length > 0 ? Math.min(...ttlCandidates) : undefined;\n const signature = JSON.stringify({\n subscriptions: subscriptions.map(subscriptionSignature),\n ttlSeconds,\n });\n\n return {\n subscriptions,\n ttlSeconds,\n signature,\n };\n }\n\n private async runSharedStream(state: {\n subscriptions: HookSubscription[];\n ttlSeconds?: number;\n }): Promise<void> {\n const abortController = new AbortController();\n this._sharedStreamAbort = abortController;\n\n try {\n const host = this._config.host ?? this.context.hosts[0];\n const ticketResponse = await this.mintHookTicket(\n state.subscriptions,\n state.ttlSeconds,\n abortController.signal,\n );\n const streamResponse = await this.openHookStream(\n host,\n ticketResponse.ticket,\n abortController.signal,\n );\n\n for await (const message of parseSseStream(\n streamResponse.body,\n abortController.signal,\n )) {\n if (!message.data) {\n continue;\n }\n const event = parseHookEvent(message);\n for (const subscriber of this._subscribers) {\n if (matchesAnySubscription(event, subscriber.requested)) {\n subscriber.queue.push(event);\n }\n }\n }\n } finally {\n if (this._sharedStreamAbort === abortController) {\n this._sharedStreamAbort = undefined;\n }\n }\n }\n\n private abortSharedStream(): void {\n this._sharedStreamAbort?.abort();\n }\n\n private createHookHeaders(action: string, path: string): ServiceHeaders {\n return this.context.invoke(this.session, \"hooks\", path, action);\n }\n\n private async mintHookTicket(\n subscriptions: HookSubscription[],\n ttlSeconds: number | undefined,\n signal?: AbortSignal,\n ): Promise<HookTicketResponse> {\n const host = this._config.host ?? this.context.hosts[0];\n const headers = this.createInvokeHeaders(subscriptions);\n const ticketResponse = await this.context.fetch(`${host}/hooks/tickets`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(headers),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n subscriptions,\n ttlSeconds,\n }),\n signal,\n });\n\n if (!ticketResponse.ok) {\n throw await responseError(\n \"hooks\",\n \"failed to mint hook ticket\",\n ticketResponse,\n );\n }\n\n const ticketJson = (await ticketResponse.json()) as HookTicketResponse;\n if (!ticketJson?.ticket) {\n throw new Error(\"Hook ticket response did not include a ticket\");\n }\n\n return ticketJson;\n }\n\n private async openHookStream(\n host: string,\n ticket: string,\n signal?: AbortSignal,\n ): Promise<FetchResponse> {\n const streamResponse = await this.context.fetch(\n `${host}/hooks/events?ticket=${encodeURIComponent(ticket)}`,\n {\n method: \"GET\",\n headers: { accept: \"text/event-stream\" },\n signal,\n },\n );\n\n if (!streamResponse.ok) {\n throw await responseError(\n \"hooks\",\n \"failed to open hook stream\",\n streamResponse,\n );\n }\n\n return streamResponse;\n }\n\n private createInvokeHeaders(\n subscriptions: HookSubscription[],\n ): ServiceHeaders {\n const entries: InvokeAnyEntry[] = subscriptions.map((subscription) => ({\n spaceId: subscription.space,\n service: \"hooks\",\n path: subscription.pathPrefix\n ? `${subscription.service}/${subscription.pathPrefix}`\n : subscription.service,\n action: \"tinycloud.hooks/subscribe\",\n }));\n\n if (this.context.invokeAny) {\n return this.context.invokeAny(this.session, entries);\n }\n\n if (entries.length === 1) {\n const entry = entries[0];\n return this.context.invoke(\n this.session,\n entry.service,\n entry.path,\n entry.action,\n );\n }\n\n throw new Error(\n \"This SDK runtime does not support multi-scope hook invocations\",\n );\n }\n}\n\nfunction buildScopePath(\n service: HookSubscription[\"service\"],\n pathPrefix?: string,\n): string {\n const normalized = normalizePathPrefix(pathPrefix);\n return normalized ? `${service}/${normalized}` : service;\n}\n\nfunction normalizeSubscription(\n subscription: HookSubscription,\n): HookSubscription {\n return {\n ...subscription,\n pathPrefix: normalizePathPrefix(subscription.pathPrefix),\n abilities: subscription.abilities ?? [],\n };\n}\n\nfunction subscriptionSignature(subscription: HookSubscription): string {\n return JSON.stringify({\n space: subscription.space,\n service: subscription.service,\n pathPrefix: subscription.pathPrefix ?? \"\",\n abilities: [...(subscription.abilities ?? [])].sort(),\n });\n}\n\nfunction matchesAnySubscription(\n event: HookEvent,\n subscriptions: HookSubscription[],\n): boolean {\n return subscriptions.some((subscription) =>\n matchesSubscription(event, subscription),\n );\n}\n\nfunction matchesSubscription(\n event: HookEvent,\n subscription: HookSubscription,\n): boolean {\n if (event.space !== subscription.space) {\n return false;\n }\n if (event.service !== subscription.service) {\n return false;\n }\n if (subscription.pathPrefix) {\n const prefix = subscription.pathPrefix.endsWith(\"/\")\n ? subscription.pathPrefix\n : `${subscription.pathPrefix}/`;\n if (\n event.path &&\n event.path !== subscription.pathPrefix &&\n !event.path.startsWith(prefix)\n ) {\n return false;\n }\n }\n const abilities = subscription.abilities ?? [];\n if (abilities.length > 0 && !abilities.includes(event.ability)) {\n return false;\n }\n return true;\n}\n\nfunction normalizePathPrefix(pathPrefix?: string): string | undefined {\n if (!pathPrefix) {\n return undefined;\n }\n const trimmed = pathPrefix.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction serviceHeadersToRecord(\n headers: ServiceHeaders,\n): Record<string, string> {\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers);\n }\n return { ...headers };\n}\n\nasync function responseError(\n service: string,\n message: string,\n response: FetchResponse,\n): Promise<ReturnType<typeof wrapError>> {\n let detail = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n detail = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n return wrapError(\n service,\n new Error(`${message}: ${response.status} ${detail}`),\n );\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n\nasync function* parseSseStream(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<HookStreamEvent> {\n if (!body) {\n throw new Error(\"Hook stream response does not expose a readable body\");\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n for await (const chunk of readBodyChunks(body, signal)) {\n buffer += decoder.decode(chunk, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\");\n while (separatorIndex >= 0) {\n const rawEvent = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + 2);\n const parsed = parseSseEvent(rawEvent);\n if (parsed) {\n yield parsed;\n }\n separatorIndex = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n buffer += decoder.decode();\n const trailing = parseSseEvent(buffer.trim());\n if (trailing) {\n yield trailing;\n }\n}\n\nasync function* readBodyChunks(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<Uint8Array> {\n const asyncIterable = body as AsyncIterable<Uint8Array>;\n if (typeof asyncIterable?.[Symbol.asyncIterator] === \"function\") {\n for await (const chunk of asyncIterable) {\n if (signal?.aborted) {\n break;\n }\n yield chunk;\n }\n return;\n }\n\n const stream = body as {\n getReader?: () => {\n read: () => Promise<{ done: boolean; value?: Uint8Array }>;\n releaseLock?: () => void;\n cancel?: () => Promise<void>;\n };\n };\n\n if (typeof stream.getReader !== \"function\") {\n throw new Error(\"Unsupported hook stream body type\");\n }\n\n const reader = stream.getReader();\n try {\n while (!signal?.aborted) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value) {\n yield value;\n }\n }\n } finally {\n try {\n await reader.cancel?.();\n } catch {\n // Ignore cancellation failures.\n }\n reader.releaseLock?.();\n }\n}\n\nfunction parseSseEvent(rawEvent: string): HookStreamEvent | null {\n if (!rawEvent) {\n return null;\n }\n\n let event = \"message\";\n let id: string | undefined;\n const dataLines: string[] = [];\n\n for (const line of rawEvent.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) {\n continue;\n }\n const [field, ...rest] = line.split(\":\");\n const value = rest.join(\":\").replace(/^ /, \"\");\n switch (field) {\n case \"event\":\n event = value;\n break;\n case \"id\":\n id = value;\n break;\n case \"data\":\n dataLines.push(value);\n break;\n default:\n break;\n }\n }\n\n if (dataLines.length === 0) {\n return null;\n }\n\n return {\n event,\n id,\n data: dataLines.join(\"\\n\"),\n };\n}\n\nfunction parseHookEvent(message: HookStreamEvent): HookEvent {\n const parsed = JSON.parse(message.data) as Partial<HookEvent>;\n return {\n type: \"write\",\n id: parsed.id ?? message.id ?? \"\",\n space: parsed.space ?? \"\",\n service: parsed.service ?? \"\",\n ability: parsed.ability ?? \"\",\n path: parsed.path,\n actor: parsed.actor ?? \"\",\n epoch: parsed.epoch ?? \"\",\n eventIndex: parsed.eventIndex ?? 0,\n timestamp: parsed.timestamp ?? \"\",\n };\n}\n\nfunction normalizeWebhookRecord(data: unknown): HookWebhookRecord | null {\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const candidate =\n pickWebhookRecord(record) ??\n normalizeWebhookRecord(record.webhook) ??\n normalizeWebhookRecord(record.hook) ??\n normalizeWebhookRecord(record.subscription) ??\n normalizeWebhookRecord(record.data);\n return candidate ?? null;\n}\n\nfunction normalizeWebhookRecordList(data: unknown): HookWebhookRecord[] | null {\n if (Array.isArray(data)) {\n const records = data\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n }\n\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const nested =\n maybeRecordArray(record.webhooks) ??\n maybeRecordArray(record.subscriptions) ??\n maybeRecordArray(record.hooks) ??\n maybeRecordArray(record.data);\n if (nested) {\n return nested;\n }\n\n const single = pickWebhookRecord(record);\n return single ? [single] : null;\n}\n\nfunction maybeRecordArray(value: unknown): HookWebhookRecord[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n\n const records = value\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n}\n\nfunction pickWebhookRecord(\n value: Record<string, unknown>,\n): HookWebhookRecord | null {\n const id = stringField(value, \"id\");\n const space = stringField(value, \"space\") ?? stringField(value, \"spaceId\");\n const service = stringField(value, \"service\");\n const callbackUrl =\n stringField(value, \"callbackUrl\") ?? stringField(value, \"callback_url\");\n if (!id || !space || !service || !callbackUrl) {\n return null;\n }\n\n return {\n id,\n space,\n service: service as HookWebhookRecord[\"service\"],\n pathPrefix:\n optionalStringField(value, \"pathPrefix\") ??\n optionalStringField(value, \"path_prefix\"),\n abilities:\n stringArrayField(value, \"abilities\") ??\n parsedStringArrayField(value, \"abilitiesJson\") ??\n parsedStringArrayField(value, \"abilities_json\"),\n callbackUrl,\n active: booleanField(value, \"active\") ?? true,\n createdAt:\n stringField(value, \"createdAt\") ??\n stringField(value, \"created_at\") ??\n new Date().toISOString(),\n subscriberDid:\n optionalStringField(value, \"subscriberDid\") ??\n optionalStringField(value, \"subscriber_did\"),\n };\n}\n\nfunction isRecordContainer(value: object): Record<string, unknown> {\n return value as Record<string, unknown>;\n}\n\nfunction stringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n const field = value[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction optionalStringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n return stringField(value, key);\n}\n\nfunction booleanField(\n value: Record<string, unknown>,\n key: string,\n): boolean | undefined {\n const field = value[key];\n return typeof field === \"boolean\" ? field : undefined;\n}\n\nfunction stringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (!Array.isArray(field)) {\n return undefined;\n }\n const strings = field.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === field.length ? strings : undefined;\n}\n\nfunction parsedStringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (typeof field !== \"string\") {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(field) as unknown;\n if (!Array.isArray(parsed)) {\n return undefined;\n }\n const strings = parsed.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === parsed.length ? strings : undefined;\n } catch {\n return undefined;\n }\n}\n","import type { StorageQuotaInfo } from \"../types\";\n\nexport interface QuotaConfig {\n /** Called when a storage quota error is detected (402/413) */\n onUpgradeRequired?: (info: StorageQuotaInfo) => void;\n}\n\nexport interface QuotaStatus {\n /** Storage limit in bytes for this space */\n limitBytes: number;\n /** Storage used in bytes for this space */\n usedBytes?: number;\n /** Remaining storage in bytes */\n remainingBytes?: number;\n}\n\nexport class TinyCloudQuota {\n private config: QuotaConfig;\n private quotaUrl: string | null = null;\n\n constructor(config: QuotaConfig = {}) {\n this.config = config;\n }\n\n /** Set the quota URL discovered from the /info endpoint */\n setQuotaUrl(url: string | null): void {\n this.quotaUrl = url;\n }\n\n /** Whether a quota service is available */\n get available(): boolean {\n return this.quotaUrl !== null;\n }\n\n /** Query quota status for a space from the quota URL */\n async getQuota(spaceId: string): Promise<QuotaStatus | null> {\n if (!this.quotaUrl) return null;\n\n const resp = await fetch(\n `${this.quotaUrl}/api/quota/${encodeURIComponent(spaceId)}`\n );\n if (!resp.ok) return null;\n\n const data = (await resp.json()) as { storage_limit_bytes?: number };\n return {\n limitBytes: data.storage_limit_bytes ?? 0,\n };\n }\n\n /** Trigger the upgrade callback when a quota error is encountered */\n handleQuotaError(info: StorageQuotaInfo): void {\n this.config.onUpgradeRequired?.(info);\n }\n}\n","/**\n * Data Vault Service Types\n *\n * Type definitions for the Data Vault (encrypted KV) service operations.\n */\n\nimport type {\n DecryptCapabilityProof,\n IEncryptionService,\n} from \"../encryption\";\n\nexport interface VaultNetworkEncryptionConfig {\n /** Default encryption network used for inline vault envelopes. */\n networkId: string;\n /** TinyCloud encryption module used for local encrypt and node-mediated decrypt. */\n service: IEncryptionService;\n /** Proof material presented to the encryption module for decrypt requests. */\n decryptCapabilityProof?:\n | DecryptCapabilityProof\n | (() => DecryptCapabilityProof | Promise<DecryptCapabilityProof>);\n}\n\n/**\n * Configuration for DataVaultService.\n */\nexport interface DataVaultConfig {\n /** Space ID for encrypted data storage */\n spaceId: string;\n /** Key rotation policy */\n keyRotation?: \"per-write\" | \"per-key\"; // default: \"per-write\"\n /** Network-envelope encryption mode. When set, vault.unlock/key grants are not used. */\n encryption?: VaultNetworkEncryptionConfig;\n}\n\n/**\n * Options for vault put operations.\n */\nexport interface VaultPutOptions {\n /** Custom metadata tags appended to the envelope */\n metadata?: Record<string, string>;\n /** Content type hint for deserialization (default: auto-detect) */\n contentType?: string;\n /** Custom serializer (default: JSON.stringify for objects) */\n serialize?: (value: unknown) => Uint8Array;\n}\n\n/**\n * Options for vault get operations.\n */\nexport interface VaultGetOptions<T = unknown> {\n /** Custom deserializer (default: JSON.parse if content-type is JSON) */\n deserialize?: (data: Uint8Array) => T;\n /** Return raw decrypted bytes without deserialization */\n raw?: boolean;\n /** Delegated KV service for reading from the grantor's space (used by getShared) */\n kv?: { get<V>(key: string, options?: { raw?: boolean }): Promise<{ ok: boolean; data?: { data: V }; error?: { message: string } }> };\n}\n\n/**\n * Options for vault list operations.\n */\nexport interface VaultListOptions {\n /** Prefix filter for key names */\n prefix?: string;\n /** Remove prefix from returned keys */\n removePrefix?: boolean;\n}\n\n/**\n * Options for vault grant (sharing) operations.\n */\nexport interface VaultGrantOptions {\n /** Additional metadata on the grant */\n metadata?: Record<string, string>;\n}\n\n/**\n * A decrypted vault entry returned by get operations.\n *\n * @template T - Type of the decrypted value\n */\nexport interface VaultEntry<T> {\n /** Decrypted value */\n value: T;\n /** Envelope metadata */\n metadata: Record<string, string>;\n /** Key ID used for encryption */\n keyId: string;\n}\n\n/**\n * Structured error codes for vault operations.\n */\n/**\n * Input types for creating vault errors (service field added automatically).\n */\nexport type VaultErrorInput =\n | { code: \"DECRYPTION_FAILED\"; message?: string; cause?: Error }\n | { code: \"KEY_NOT_FOUND\"; key: string; message?: string }\n | { code: \"INTEGRITY_ERROR\"; message?: string; cause?: Error }\n | { code: \"GRANT_NOT_FOUND\"; grantor: string; key: string; message?: string }\n | { code: \"VAULT_LOCKED\"; message?: string }\n | { code: \"PUBLIC_KEY_NOT_FOUND\"; did: string; message?: string }\n | { code: \"STORAGE_ERROR\"; cause: Error; message?: string };\n\n/**\n * Vault error with service field (compatible with ServiceError).\n */\nexport type VaultError = VaultErrorInput & { service: \"vault\"; message: string };\n\n\n/** KV actions the vault needs on the public space for key publishing. */\nexport const VaultPublicSpaceKVActions = [\n \"tinycloud.kv/get\",\n \"tinycloud.kv/put\",\n \"tinycloud.kv/metadata\",\n] as const;\n\n/** Version-keyed signing message configuration for vault key derivation. */\nexport const VaultVersionConfig = {\n \"1\": {\n masterMessage: (spaceId: string) => `tinycloud-vault-master-v1:${spaceId}`,\n identityMessage: \"tinycloud-encryption-identity-v1\",\n },\n} as const;\n\nexport const CURRENT_VAULT_VERSION = \"1\" as const;\n\n/** Metadata header keys used in vault envelopes */\nexport const VaultHeaders = {\n VERSION: \"x-vault-version\",\n CIPHER: \"x-vault-cipher\",\n KEY_ID: \"x-vault-key-id\",\n CONTENT_TYPE: \"x-vault-content-type\",\n KDF: \"x-vault-kdf\",\n KEY_ROTATION: \"x-vault-key-rotation\",\n GRANT_VERSION: \"x-vault-grant-version\",\n GRANTOR: \"x-vault-grantor\",\n} as const;\n","/**\n * Caches vault signatures in IndexedDB, encrypted with a\n * non-extractable CryptoKey. Browser-only — no-ops in Node.\n */\n\n// Minimal type declarations for browser APIs used below.\n// The sdk-services tsconfig targets ES2020 without DOM lib;\n// these declarations let the file compile while the runtime\n// guards (isBrowser()) ensure we never call them in Node.\ndeclare const indexedDB: {\n open(name: string, version?: number): IDBOpenDBRequest;\n};\ninterface IDBOpenDBRequest {\n result: IDBDatabase;\n error: DOMException | null;\n onupgradeneeded: ((this: IDBOpenDBRequest) => void) | null;\n onsuccess: ((this: IDBOpenDBRequest) => void) | null;\n onerror: ((this: IDBOpenDBRequest) => void) | null;\n}\ninterface IDBDatabase {\n objectStoreNames: { contains(name: string): boolean };\n createObjectStore(name: string): void;\n transaction(storeNames: string | string[], mode?: string): IDBTransaction;\n}\ninterface IDBTransaction {\n objectStore(name: string): IDBObjectStore;\n}\ninterface IDBObjectStore {\n get(key: string): IDBRequest;\n put(value: unknown, key: string): IDBRequest;\n delete(key: string): IDBRequest;\n getAllKeys(): IDBRequest;\n}\ninterface IDBRequest<T = unknown> {\n result: T;\n error: DOMException | null;\n onsuccess: ((this: IDBRequest<T>) => void) | null;\n onerror: ((this: IDBRequest<T>) => void) | null;\n}\ntype IDBValidKey = string | number | Date | ArrayBuffer | Uint8Array | IDBValidKey[];\n\nconst DB_NAME = \"tinycloud-vault-cache\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"signatures\";\nconst WRAP_KEY_ID = \"__wrap_key__\";\n\n/** Check whether we're in a browser with IndexedDB + SubtleCrypto support. */\nfunction isBrowser(): boolean {\n try {\n return (\n typeof indexedDB !== \"undefined\" &&\n typeof crypto !== \"undefined\" &&\n typeof crypto.subtle !== \"undefined\"\n );\n } catch {\n return false;\n }\n}\n\n/** Open (or create) the IndexedDB database. */\nfunction openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\n/** Generic IDB get helper. */\nfunction idbGet<T>(db: IDBDatabase, key: string): Promise<T | undefined> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.get(key);\n req.onsuccess = () => resolve(req.result as T | undefined);\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB put helper. */\nfunction idbPut(db: IDBDatabase, key: string, value: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.put(value, key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB delete helper. */\nfunction idbDelete(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.delete(key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** List all keys in the store. */\nfunction idbKeys(db: IDBDatabase): Promise<string[]> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.getAllKeys();\n req.onsuccess = () =>\n resolve((req.result as IDBValidKey[]).filter((k) => typeof k === \"string\") as string[]);\n req.onerror = () => reject(req.error);\n });\n}\n\ninterface EncryptedEntry {\n iv: Uint8Array;\n ciphertext: Uint8Array;\n}\n\n/**\n * Get or create the non-extractable AES-GCM wrapping key.\n * The key is stored directly in IndexedDB (structured-clone preserves CryptoKey).\n */\nasync function getWrapKey(db: IDBDatabase): Promise<CryptoKey> {\n const existing = await idbGet<CryptoKey>(db, WRAP_KEY_ID);\n if (existing) return existing;\n\n const key = await crypto.subtle.generateKey(\n { name: \"AES-GCM\", length: 256 },\n false, // non-extractable\n [\"encrypt\", \"decrypt\"]\n );\n await idbPut(db, WRAP_KEY_ID, key);\n return key;\n}\n\n/** Encrypt signature bytes with the wrap key. */\nasync function encryptSig(\n wrapKey: CryptoKey,\n sigBytes: Uint8Array\n): Promise<EncryptedEntry> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = new Uint8Array(\n await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, wrapKey, sigBytes)\n );\n return { iv, ciphertext };\n}\n\n/** Decrypt an encrypted entry back to signature bytes. */\nasync function decryptSig(\n wrapKey: CryptoKey,\n entry: EncryptedEntry\n): Promise<Uint8Array> {\n const plaintext = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: entry.iv },\n wrapKey,\n entry.ciphertext\n );\n return new Uint8Array(plaintext);\n}\n\n/** Cache key for a given spaceId. */\nfunction cacheKey(spaceId: string): string {\n return `sig:${spaceId}`;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Load a cached signature for the given spaceId.\n * Returns null on cache miss or in non-browser environments.\n */\nexport async function loadCachedSignature(\n spaceId: string\n): Promise<Uint8Array | null> {\n if (!isBrowser()) return null;\n try {\n const db = await openDB();\n const entry = await idbGet<EncryptedEntry>(db, cacheKey(spaceId));\n if (!entry) return null;\n const wrapKey = await getWrapKey(db);\n return await decryptSig(wrapKey, entry);\n } catch {\n return null;\n }\n}\n\n/**\n * Cache a signature for the given spaceId.\n * No-ops in non-browser environments.\n */\nexport async function cacheSignature(\n spaceId: string,\n sigBytes: Uint8Array\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n const wrapKey = await getWrapKey(db);\n const encrypted = await encryptSig(wrapKey, sigBytes);\n await idbPut(db, cacheKey(spaceId), encrypted);\n } catch {\n // Best-effort — swallow errors\n }\n}\n\n/**\n * Clear cached signature(s).\n * If spaceId is provided, clears only that entry; otherwise clears all.\n */\nexport async function clearSignatureCache(\n spaceId?: string\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n if (spaceId) {\n await idbDelete(db, cacheKey(spaceId));\n } else {\n // Clear all sig entries but keep the wrap key\n const keys = await idbKeys(db);\n for (const k of keys) {\n if (k.startsWith(\"sig:\")) {\n await idbDelete(db, k);\n }\n }\n }\n } catch {\n // Best-effort\n }\n}\n","/**\n * DataVaultService - Encrypted key-value storage service implementation.\n *\n * Platform-agnostic encrypted KV service that wraps KVService internally.\n * Uses dependency injection via VaultCrypto for WASM crypto operations\n * and DataVaultServiceConfig for platform dependencies.\n *\n * Architecture:\n * - Extends BaseService (not KVService)\n * - Wraps two KV instances: dataKV (prefix \"vault/\") and keyKV (prefix \"keys/\")\n * - Master key and encryption identity live in memory only (cleared on lock)\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n serviceError,\n IServiceContext,\n ServiceSession,\n} from \"../types\";\nimport { wrapError } from \"../errors\";\nimport type { IKVService } from \"../kv/IKVService\";\nimport type { KVService } from \"../kv/KVService\";\nimport type {\n DecryptCapabilityProof,\n InlineEncryptedEnvelope,\n} from \"../encryption\";\nimport type { IDataVaultService } from \"./IDataVaultService\";\nimport {\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultGrantOptions,\n VaultEntry,\n VaultError,\n VaultErrorInput,\n VaultHeaders,\n VaultVersionConfig,\n CURRENT_VAULT_VERSION,\n} from \"./types\";\nimport {\n loadCachedSignature,\n cacheSignature,\n clearSignatureCache,\n} from \"./SignatureCache\";\n\n// =============================================================================\n// Crypto Interface\n// =============================================================================\n\n/**\n * Crypto operations interface - implementations provided by WASM bindings.\n * Passed via DataVaultServiceConfig to keep the service platform-agnostic.\n */\nexport interface VaultCrypto {\n encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n deriveKey(\n signature: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array\n ): Uint8Array;\n x25519FromSeed(\n seed: Uint8Array\n ): { publicKey: Uint8Array; privateKey: Uint8Array };\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n randomBytes(length: number): Uint8Array;\n sha256(data: Uint8Array): Uint8Array;\n}\n\n// =============================================================================\n// Extended Config\n// =============================================================================\n\n/**\n * Extended config used internally by DataVaultService.\n * Includes crypto operations and TinyCloud instance references.\n */\ninterface DataVaultServiceConfig extends DataVaultConfig {\n [key: string]: unknown;\n /** Crypto operations (WASM bindings) */\n crypto: VaultCrypto;\n /** TinyCloud instance for space/kv/delegation operations */\n tc: {\n kv: IKVService;\n ensurePublicSpace(): Promise<Result<void>>;\n publicKV: IKVService;\n readPublicSpace<T>(\n host: string,\n spaceId: string,\n key: string\n ): Promise<Result<T>>;\n makePublicSpaceId(address: string, chainId: number): string;\n did: string;\n address: string;\n chainId: number;\n hosts: string[];\n };\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/** Convert a caught value to an Error. WASM throws plain objects, not Error instances. */\nfunction toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\nfunction toBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nfunction fromBytes(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((acc, arr) => acc + arr.length, 0);\n const result = new Uint8Array(total);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction base64Encode(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64Decode(str: string): Uint8Array {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction unwrapKVData<T = unknown>(value: unknown): T {\n if (value !== null && typeof value === \"object\" && \"data\" in value) {\n return (value as { data: T }).data;\n }\n return value as T;\n}\n\nfunction isUnlockSigner(\n signer: unknown\n): signer is { signMessage(message: string): Promise<string> } {\n return (\n typeof signer === \"object\" &&\n signer !== null &&\n typeof (signer as { signMessage?: unknown }).signMessage === \"function\"\n );\n}\n\nfunction defaultVaultMessage(input: VaultErrorInput): string {\n switch (input.code) {\n case \"DECRYPTION_FAILED\": return input.message ?? \"Decryption failed\";\n case \"KEY_NOT_FOUND\": return input.message ?? `Key not found: ${input.key}`;\n case \"INTEGRITY_ERROR\": return input.message ?? \"Integrity check failed\";\n case \"GRANT_NOT_FOUND\": return input.message ?? `Grant not found: ${input.grantor} / ${input.key}`;\n case \"VAULT_LOCKED\": return input.message ?? \"Vault is locked\";\n case \"PUBLIC_KEY_NOT_FOUND\": return input.message ?? `Public key not found for ${input.did}`;\n case \"STORAGE_ERROR\": return input.message ?? input.cause.message;\n }\n}\n\nfunction vaultError(input: VaultErrorInput): Result<never, VaultError> {\n const error: VaultError = {\n ...input,\n service: \"vault\",\n message: defaultVaultMessage(input),\n };\n return { ok: false, error };\n}\n\n// =============================================================================\n// DataVaultService\n// =============================================================================\n\n/**\n * Data Vault service implementation.\n *\n * Provides encrypted key-value storage with client-side encryption,\n * key management, and sharing via X25519 grants.\n *\n * @example\n * ```typescript\n * // Unlock the vault\n * await vault.unlock(signer);\n *\n * // Store encrypted data\n * await vault.put('secret/notes', { content: 'Hello' });\n *\n * // Retrieve and decrypt\n * const entry = await vault.get<{ content: string }>('secret/notes');\n * if (entry.ok) {\n * console.log(entry.data.value.content); // 'Hello'\n * }\n *\n * // Share with another user\n * await vault.grant('secret/notes', recipientDID);\n * ```\n */\nexport class DataVaultService extends BaseService implements IDataVaultService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"vault\";\n\n /**\n * Service configuration.\n */\n declare protected _config: DataVaultServiceConfig;\n\n private masterKey: Uint8Array | null = null;\n private encryptionIdentity: {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n } | null = null;\n private _isUnlocked = false;\n private vaultConfig: DataVaultServiceConfig;\n private unlockInFlight: Promise<Result<void, VaultError>> | null = null;\n\n /**\n * Create a new DataVaultService instance.\n *\n * @param config - Service configuration including crypto and tc references\n */\n constructor(config: DataVaultServiceConfig) {\n super();\n this.vaultConfig = config;\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): DataVaultServiceConfig {\n return this._config;\n }\n\n /**\n * Whether the vault is currently unlocked.\n */\n get isUnlocked(): boolean {\n return this.usesNetworkEncryption || this._isUnlocked;\n }\n\n /**\n * The vault's public encryption key (X25519).\n * Throws if vault is locked.\n */\n get publicKey(): Uint8Array {\n if (this.usesNetworkEncryption) {\n throw new Error(\"Network-encrypted vaults do not expose a local public key\");\n }\n if (!this.encryptionIdentity) {\n throw new Error(\"Vault is locked\");\n }\n return this.encryptionIdentity.publicKey;\n }\n\n /**\n * Convenience accessor for crypto operations.\n */\n private get crypto(): VaultCrypto {\n return this.vaultConfig.crypto;\n }\n\n /**\n * Convenience accessor for TinyCloud instance.\n */\n private get tc() {\n return this.vaultConfig.tc;\n }\n\n private get networkEncryption() {\n return this.vaultConfig.encryption;\n }\n\n private get usesNetworkEncryption(): boolean {\n return this.networkEncryption !== undefined;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.tc.hosts[0];\n }\n\n private async decryptCapabilityProof(): Promise<DecryptCapabilityProof> {\n const proof = this.networkEncryption?.decryptCapabilityProof;\n if (typeof proof === \"function\") {\n return await proof();\n }\n return proof ?? { proofs: [] };\n }\n\n private serializeValue(\n value: unknown,\n options?: VaultPutOptions,\n ): { plaintext: Uint8Array; contentType: string } {\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array ? \"application/octet-stream\" : \"application/json\");\n return { plaintext, contentType };\n }\n\n private deserializeValue<T>(\n plaintext: Uint8Array,\n contentType: string,\n options?: VaultGetOptions<T>,\n ): T {\n if (options?.raw) {\n return plaintext as unknown as T;\n }\n if (options?.deserialize) {\n return options.deserialize(plaintext);\n }\n if (contentType === \"application/json\") {\n return JSON.parse(fromBytes(plaintext)) as T;\n }\n return plaintext as unknown as T;\n }\n\n // =========================================================================\n // Phase 1: Core Operations\n // =========================================================================\n\n /**\n * Unlock the vault. Derives keys from two wallet signatures:\n * 1. Master signature (per-space) — used to derive the master encryption key\n * 2. Identity signature (per-address) — used to derive X25519 encryption identity\n *\n * If the identity public key already exists in the public space, the identity\n * signature is skipped entirely (no wallet popup). The identity private key is\n * only needed for sharing operations.\n *\n * @param signer - Object with signMessage method. Optional when cached\n * signatures exist (browser only).\n */\n async unlock(\n signer?: { signMessage(message: string): Promise<string> } | unknown\n ): Promise<Result<void, VaultError>> {\n if (this.usesNetworkEncryption) {\n this._isUnlocked = true;\n return { ok: true, data: undefined };\n }\n\n const unlockSigner = isUnlockSigner(signer) ? signer : undefined;\n if (\n this._isUnlocked &&\n this.masterKey &&\n (this.encryptionIdentity || !unlockSigner)\n ) {\n return { ok: true, data: undefined };\n }\n\n if (this.unlockInFlight) {\n return this.unlockInFlight;\n }\n\n this.unlockInFlight = this.withTelemetry(\"unlock\", undefined, async () => {\n const spaceId = this.vaultConfig.spaceId;\n const versionConfig = VaultVersionConfig[CURRENT_VAULT_VERSION];\n const masterCacheKey = `vault-master:${spaceId}`;\n const identityCacheKey = `vault-identity:${this.tc.address}`;\n\n try {\n // -----------------------------------------------------------------\n // Step 1: Master signature → master key\n // -----------------------------------------------------------------\n if (!this.masterKey) {\n let masterSigBytes = await loadCachedSignature(masterCacheKey);\n\n if (!masterSigBytes) {\n if (!unlockSigner) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Signer is required when no cached master signature exists\",\n });\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.masterMessage(spaceId)\n );\n masterSigBytes = toBytes(sig);\n await cacheSignature(masterCacheKey, masterSigBytes);\n }\n\n // Derive master key: deriveKey(sigBytes, sha256(spaceId), \"vault-master\")\n this.masterKey = this.crypto.deriveKey(\n masterSigBytes,\n this.crypto.sha256(toBytes(spaceId)),\n toBytes(\"vault-master\")\n );\n }\n\n // -----------------------------------------------------------------\n // Step 2: Identity — check public space first, then sign if needed\n // -----------------------------------------------------------------\n const publicSpaceId = this.tc.makePublicSpaceId(this.tc.address, this.tc.chainId);\n\n // Check public space for existing vault pubkey\n let existingPubKey: string | null = null;\n try {\n const existing = await this.tc.readPublicSpace<string>(\n this.host, publicSpaceId, \".well-known/vault-pubkey\"\n );\n if (existing.ok && existing.data) {\n existingPubKey = existing.data as string;\n }\n } catch {\n // Read failed — treat as missing\n }\n\n if (existingPubKey) {\n // Public key exists — trust it, skip identity signing entirely\n this.encryptionIdentity = {\n publicKey: base64Decode(existingPubKey),\n privateKey: new Uint8Array(0), // private key not available without signing\n };\n } else {\n // Public key missing — need identity signature to derive keypair\n let identitySigBytes = await loadCachedSignature(identityCacheKey);\n\n if (!identitySigBytes) {\n if (!unlockSigner) {\n // No signer available — skip identity derivation.\n // Vault still works for get/put (only needs master key).\n this.encryptionIdentity = null;\n this._isUnlocked = true;\n return ok(undefined);\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.identityMessage\n );\n identitySigBytes = toBytes(sig);\n await cacheSignature(identityCacheKey, identitySigBytes);\n }\n\n // Derive X25519 keypair from identity signature\n const seed = this.crypto.deriveKey(\n identitySigBytes,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"encryption-identity\")\n );\n this.encryptionIdentity = this.crypto.x25519FromSeed(seed);\n\n // Publish public key to public space\n try {\n const pubKeyB64 = base64Encode(this.encryptionIdentity.publicKey);\n await this.tc.ensurePublicSpace();\n await this.tc.publicKV.put(\".well-known/vault-pubkey\", pubKeyB64);\n await this.tc.publicKV.put(\".well-known/vault-version\", CURRENT_VAULT_VERSION);\n await this.tc.publicKV.put(\".well-known/vault-space\", this.vaultConfig.spaceId);\n } catch {\n // Publishing failed — vault still usable\n }\n }\n\n this._isUnlocked = true;\n return ok(undefined);\n } catch (error) {\n // Clear key material on failure\n this.masterKey = null;\n this.encryptionIdentity = null;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n\n try {\n return await this.unlockInFlight;\n } finally {\n this.unlockInFlight = null;\n }\n }\n\n /**\n * Clear the cached vault signatures.\n *\n * @param spaceId - Clear only this space's master cache. If omitted, clears all.\n */\n async clearCache(spaceId?: string): Promise<void> {\n if (spaceId) {\n await clearSignatureCache(`vault-master:${spaceId}`);\n } else {\n await clearSignatureCache();\n }\n }\n\n /**\n * Lock the vault, clearing all key material from memory.\n */\n lock(): void {\n this.masterKey = null;\n this.encryptionIdentity = null;\n this._isUnlocked = false;\n }\n\n /**\n * Called when SDK signs out. Locks the vault and aborts operations.\n */\n onSignOut(): void {\n this.lock();\n super.onSignOut();\n }\n\n private async putNetworkEncrypted(\n key: string,\n value: unknown,\n options?: VaultPutOptions,\n ): Promise<Result<void, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const { plaintext, contentType } = this.serializeValue(value, options);\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"2\",\n [VaultHeaders.CIPHER]: \"tinycloud-network-envelope\",\n [VaultHeaders.CONTENT_TYPE]: contentType,\n ...(options?.metadata ?? {}),\n };\n const aad = toBytes(`tinycloud.vault:${this.vaultConfig.spaceId}:${key}`);\n const envelopeResult = await config.service.encryptToNetwork(\n config.networkId,\n plaintext,\n { aad, metadata },\n );\n if (!envelopeResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(envelopeResult.error.message),\n });\n }\n\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n JSON.stringify(envelopeResult.data),\n );\n if (!valuePutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store encrypted value: ${valuePutResult.error.message}`,\n ),\n });\n }\n\n return { ok: true, data: undefined };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n private async getNetworkEncrypted<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>,\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(envelope, proof);\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n private async headNetworkEncrypted(\n key: string,\n ): Promise<Result<Record<string, string>, VaultError>> {\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n return { ok: true, data: envelope.metadata ?? {} };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n /**\n * Encrypt and store a value at the given key.\n *\n * @param key - The key to store under\n * @param value - The value to encrypt and store\n * @param options - Optional put configuration\n */\n async put(\n key: string,\n value: unknown,\n options?: VaultPutOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.putNetworkEncrypted(key, value, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before storing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Serialize value\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array\n ? \"application/octet-stream\"\n : \"application/json\");\n\n // Generate per-entry key\n const entryKey = this.crypto.randomBytes(32);\n const keyId = hexEncode(this.crypto.sha256(entryKey)).slice(0, 16);\n\n // Encrypt value with entry key\n const encrypted = this.crypto.encrypt(entryKey, plaintext);\n\n // Encrypt entry key with master key\n const keyBlob = this.crypto.encrypt(this.masterKey, entryKey);\n\n // Build metadata\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"1\",\n [VaultHeaders.CIPHER]: \"aes-256-gcm\",\n [VaultHeaders.KEY_ID]: keyId,\n [VaultHeaders.CONTENT_TYPE]: contentType,\n [VaultHeaders.KDF]: \"hkdf-sha256\",\n [VaultHeaders.KEY_ROTATION]:\n this.vaultConfig.keyRotation ?? \"per-write\",\n ...(options?.metadata ?? {}),\n };\n\n // Store encrypted entry key in key space\n const keyMetadata = JSON.stringify({\n keyId,\n contentType,\n ...metadata,\n });\n const keyPayload = JSON.stringify({\n key: base64Encode(keyBlob),\n metadata: keyMetadata,\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store key blob: ${keyPutResult.error.message}`\n ),\n });\n }\n\n // Store encrypted value in data space\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store encrypted value: ${valuePutResult.error.message}`\n ),\n });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * Retrieve and decrypt a value by key.\n *\n * @param key - The key to retrieve\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async get<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.getNetworkEncrypted<T>(key, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch encrypted entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Fetch encrypted value from data space\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const encryptedBytes = base64Decode(valueEnvelope.data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Delete an encrypted key.\n * Removes both the encrypted value and the key blob.\n *\n * @param key - The key to delete\n */\n async delete(key: string): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before deleting data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n if (this.usesNetworkEncryption) {\n const valueDelResult = await this.tc.kv.delete(`vault/${key}`);\n if (!valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n return ok(undefined);\n }\n\n // Delete from both key space and data space\n const [keyDelResult, valueDelResult] = await Promise.all([\n this.tc.kv.delete(`keys/${key}`),\n this.tc.kv.delete(`vault/${key}`),\n ]);\n\n if (!keyDelResult.ok && !valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * List vault keys with optional prefix filtering.\n *\n * @param options - Optional list configuration\n * @returns Result with array of key names (vault/ prefix stripped)\n */\n async list(\n options?: VaultListOptions\n ): Promise<Result<string[], VaultError>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listPrefix = options?.prefix\n ? `vault/${options.prefix}`\n : \"vault/\";\n\n const listResult = await this.tc.kv.list({\n prefix: listPrefix,\n removePrefix: true,\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list vault keys: ${listResult.error.message}`\n ),\n });\n }\n\n // Keys are already stripped of the \"vault/\" prefix by removePrefix\n let keys = listResult.data.keys;\n\n // If a user prefix was provided, strip it too if requested\n if (options?.removePrefix && options.prefix) {\n const userPrefix = options.prefix.endsWith(\"/\")\n ? options.prefix\n : `${options.prefix}/`;\n keys = keys.map((k) =>\n k.startsWith(userPrefix) ? k.slice(userPrefix.length) : k\n );\n }\n\n return ok(keys);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<string[], VaultError>>;\n }\n\n /**\n * Get envelope metadata for a key without decrypting the value.\n *\n * @param key - The key to inspect\n * @returns Result with metadata headers\n */\n async head(\n key: string\n ): Promise<Result<Record<string, string>, VaultError>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.headNetworkEncrypted(key);\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading metadata\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch envelope without decrypting\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n return ok(metadata);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<Record<string, string>, VaultError>>;\n }\n\n // =========================================================================\n // Batch Operations\n // =========================================================================\n\n /**\n * Encrypt and store multiple entries.\n *\n * @param entries - Array of key/value pairs with optional per-entry options\n * @returns Array of results, one per entry\n */\n async putMany(\n entries: Array<{ key: string; value: unknown; options?: VaultPutOptions }>\n ): Promise<Result<void, VaultError>[]> {\n return Promise.all(\n entries.map((entry) => this.put(entry.key, entry.value, entry.options))\n );\n }\n\n /**\n * Retrieve and decrypt multiple keys.\n *\n * @param keys - Array of keys to retrieve\n * @param options - Optional get configuration applied to all entries\n * @returns Array of results, one per key\n */\n async getMany<T = unknown>(\n keys: string[],\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>[]> {\n return Promise.all(keys.map((key) => this.get<T>(key, options)));\n }\n\n // =========================================================================\n // Phase 2: Sharing\n // =========================================================================\n\n /**\n * Re-encrypt a vault key for another user (renamed from grant).\n * Re-encrypts the data key to the recipient's public key via X25519 DH.\n *\n * @param key - The key to share\n * @param recipientDID - The recipient's primary DID (did:pkh:...)\n * @param options - Optional grant configuration\n */\n async reencrypt(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"reencrypt\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n void options;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; grant tinycloud.encryption/decrypt on the network plus KV access to vault data.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before granting access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: Resolve recipient's public key\n const pubKeyResult = await this.resolvePublicKey(recipientDID);\n if (!pubKeyResult.ok) {\n return pubKeyResult;\n }\n const bobPubKey = pubKeyResult.data;\n\n // Step 2: Fetch and decrypt entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Step 3: Create ephemeral X25519 key pair\n const ephemeralSeed = this.crypto.randomBytes(32);\n const ephemeralKeyPair = this.crypto.x25519FromSeed(ephemeralSeed);\n\n // Step 4: Compute shared secret via DH\n const sharedSecret = this.crypto.x25519Dh(\n ephemeralKeyPair.privateKey,\n bobPubKey\n );\n\n // Step 5: Derive encryption key from shared secret\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 6: Encrypt entry key with derived key\n const encryptedGrant = this.crypto.encrypt(encryptionKey, entryKey);\n\n // Step 7: Concatenate ephemeral public key + encrypted grant\n const grantBlob = concatBytes(\n ephemeralKeyPair.publicKey,\n encryptedGrant\n );\n\n // Step 8: Store grant in key space\n const grantPayload = JSON.stringify({\n grant: base64Encode(grantBlob),\n spaceId: this.vaultConfig.spaceId,\n metadata: {\n [VaultHeaders.GRANT_VERSION]: \"1\",\n [VaultHeaders.GRANTOR]: this.tc.did,\n ...(options?.metadata ?? {}),\n },\n });\n // Store grant in the vault's space (main space)\n const grantPutResult = await this.tc.kv.put(\n `grants/${recipientDID}/${key}`,\n grantPayload\n );\n if (!grantPutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store grant: ${grantPutResult.error.message}`\n ),\n });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * @deprecated Use reencrypt() instead.\n */\n async grant(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.reencrypt(key, recipientDID, options);\n }\n\n /**\n * Retrieve and decrypt a value shared by another user.\n *\n * @param grantorDID - The DID of the user who shared the data\n * @param key - The key that was shared\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async getShared<T = unknown>(\n grantorDID: string,\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"getShared\", key, async () => {\n if (this.usesNetworkEncryption) {\n const grantorKV = options?.kv;\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv.\",\n ),\n });\n }\n\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(\n envelope,\n proof,\n );\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n void grantorDID;\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n if (\n !this._isUnlocked ||\n !this.masterKey ||\n !this.encryptionIdentity\n ) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading shared data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const myDID = this.tc.did;\n const grantorKV = options?.kv;\n\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv. \" +\n \"Use useDelegation() to get delegated access, then pass { kv: access.kv }.\"\n ),\n });\n }\n\n // Step 1: Fetch grant from grantor's space via delegated KV\n const grantResult = await grantorKV.get<string>(`grants/${myDID}/${key}`, {\n raw: true,\n });\n if (!grantResult.ok) {\n return vaultError({\n code: \"GRANT_NOT_FOUND\",\n grantor: grantorDID,\n key,\n });\n }\n\n const grantEnvelope = typeof grantResult.data?.data === \"string\"\n ? JSON.parse(grantResult.data.data as string)\n : grantResult.data?.data;\n const grantBlobBytes = base64Decode((grantEnvelope as any).grant);\n\n // Step 2: Extract ephemeral public key and encrypted grant\n const ephemeralPubKey = grantBlobBytes.slice(0, 32);\n const encryptedGrant = grantBlobBytes.slice(32);\n\n // Step 3: Compute shared secret using our private key\n const sharedSecret = this.crypto.x25519Dh(\n this.encryptionIdentity.privateKey,\n ephemeralPubKey\n );\n\n // Step 4: Derive decryption key\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 5: Decrypt entry key\n const entryKey = this.crypto.decrypt(encryptionKey, encryptedGrant);\n\n // Step 6: Fetch encrypted value from grantor's space via delegated KV\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({\n code: \"KEY_NOT_FOUND\",\n key,\n });\n }\n\n const valueEnvelope = typeof valueResult.data?.data === \"string\"\n ? JSON.parse(valueResult.data.data as string)\n : valueResult.data?.data;\n const encryptedBytes = base64Decode((valueEnvelope as any).data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = (valueEnvelope as any).metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Resolve another user's public encryption key from their DID.\n *\n * @param did - The DID to resolve (did:pkh:eip155:{chainId}:{address})\n * @returns Result with the public key bytes\n */\n async resolvePublicKey(\n did: string\n ): Promise<Result<Uint8Array, VaultError>> {\n try {\n const parts = this.parseDID(did);\n if (!parts) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const spaceId = this.tc.makePublicSpaceId(\n parts.address,\n parts.chainId\n );\n\n const result = await this.tc.readPublicSpace<string>(\n this.host,\n spaceId,\n \".well-known/vault-pubkey\"\n );\n\n if (!result.ok) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const pubKeyBytes = base64Decode(result.data as string);\n return { ok: true, data: pubKeyBytes } as Result<Uint8Array, VaultError>;\n } catch (error) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n }\n\n /**\n * List DIDs that have been granted access to a key.\n *\n * @param key - The key to list grants for\n * @returns Result with array of recipient DIDs\n */\n async listGrants(\n key: string\n ): Promise<Result<string[], VaultError>> {\n return this.withTelemetry(\"listGrants\", key, async () => {\n if (this.usesNetworkEncryption) {\n void key;\n return { ok: true, data: [] };\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing grants\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listResult = await this.tc.kv.list({\n prefix: \"grants/\",\n removePrefix: true,\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list grants: ${listResult.error.message}`\n ),\n });\n }\n\n // Grant paths are: {recipientDID}/{key}\n // Filter for the specific key and extract DIDs\n const dids: string[] = [];\n for (const grantPath of listResult.data.keys) {\n // Path format: {recipientDID}/{key}\n // The key may contain slashes, so we need to match the suffix\n if (grantPath.endsWith(`/${key}`)) {\n const did = grantPath.slice(\n 0,\n grantPath.length - key.length - 1\n );\n if (did) {\n dids.push(did);\n }\n }\n }\n\n return ok(dids);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<string[], VaultError>>;\n }\n\n // =========================================================================\n // Phase 3: Key Rotation / Revocation\n // =========================================================================\n\n /**\n * Revoke a previously issued grant.\n *\n * This performs a full key rotation:\n * 1. Lists current grantees\n * 2. Removes the revoked recipient\n * 3. Re-encrypts the value with a new entry key\n * 4. Re-issues grants to remaining recipients\n *\n * @param key - The key to revoke access to\n * @param recipientDID - The recipient whose access to revoke\n */\n async revoke(\n key: string,\n recipientDID: string\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"revoke\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; revoke KV and tinycloud.encryption/decrypt grants instead.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before revoking access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: List all current grantees\n const granteesResult = await this.listGrants(key);\n if (!granteesResult.ok) {\n return granteesResult;\n }\n\n const remainingGrantees = granteesResult.data.filter(\n (did) => did !== recipientDID\n );\n\n // Step 2: Delete the grant for the revoked recipient\n const deleteGrantResult = await this.tc.kv.delete(\n `grants/${recipientDID}/${key}`\n );\n // Grant may already be deleted, that's fine\n\n // Step 3: Fetch and decrypt current value\n const getResult = await this.get(key);\n if (!getResult.ok) {\n return getResult as Result<never, VaultError>;\n }\n\n const currentEntry = getResult.data;\n\n // Step 4: Generate new entry key\n const newEntryKey = this.crypto.randomBytes(32);\n const newKeyId = hexEncode(this.crypto.sha256(newEntryKey)).slice(\n 0,\n 16\n );\n\n // Step 5: Re-serialize and re-encrypt value with new key\n let plaintext: Uint8Array;\n if (currentEntry.value instanceof Uint8Array) {\n plaintext = currentEntry.value;\n } else {\n plaintext = toBytes(JSON.stringify(currentEntry.value));\n }\n\n const encrypted = this.crypto.encrypt(newEntryKey, plaintext);\n\n // Step 6: Encrypt new entry key with master key\n const newKeyBlob = this.crypto.encrypt(this.masterKey, newEntryKey);\n\n // Step 7: Update metadata with new key ID\n const metadata: Record<string, string> = {\n ...currentEntry.metadata,\n [VaultHeaders.KEY_ID]: newKeyId,\n };\n\n // Step 8: Store updated key blob\n const keyPayload = JSON.stringify({\n key: base64Encode(newKeyBlob),\n metadata: JSON.stringify({\n keyId: newKeyId,\n ...metadata,\n }),\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store rotated key blob: ${keyPutResult.error.message}`\n ),\n });\n }\n\n // Step 9: Store re-encrypted value\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store re-encrypted value: ${valuePutResult.error.message}`\n ),\n });\n }\n\n // Step 10: Re-issue grants to remaining recipients\n for (const did of remainingGrantees) {\n const grantResult = await this.reencrypt(key, did);\n if (!grantResult.ok) {\n // Continue re-issuing to other recipients even if one fails\n // The failed grant can be re-issued manually\n }\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n // =========================================================================\n // Internal Helpers\n // =========================================================================\n\n /**\n * Parse a DID string to extract address and chainId.\n * Expected format: did:pkh:eip155:{chainId}:{address}\n *\n * @param did - The DID to parse\n * @returns Parsed address and chainId, or null if invalid\n */\n private parseDID(\n did: string\n ): { address: string; chainId: number } | null {\n // did:pkh:eip155:{chainId}:{address}\n const parts = did.split(\":\");\n if (\n parts.length !== 5 ||\n parts[0] !== \"did\" ||\n parts[1] !== \"pkh\" ||\n parts[2] !== \"eip155\"\n ) {\n return null;\n }\n\n const chainId = parseInt(parts[3], 10);\n const address = parts[4];\n if (isNaN(chainId) || !address) {\n return null;\n }\n\n return { address, chainId };\n }\n}\n","import type { VaultCrypto } from \"./DataVaultService\";\n\nexport interface WasmVaultFunctions {\n vault_encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n vault_decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n /** WASM order: (salt, signature, info) — NOT (signature, salt, info) */\n vault_derive_key(salt: Uint8Array, signature: Uint8Array, info: Uint8Array): Uint8Array;\n vault_x25519_from_seed(seed: Uint8Array): { publicKey: Uint8Array; privateKey: Uint8Array };\n vault_x25519_dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n vault_random_bytes(length: number): Uint8Array;\n vault_sha256(data: Uint8Array): Uint8Array;\n}\n\nexport function createVaultCrypto(wasm: WasmVaultFunctions): VaultCrypto {\n return {\n encrypt: (key, plaintext) => wasm.vault_encrypt(key, plaintext),\n decrypt: (key, blob) => wasm.vault_decrypt(key, blob),\n deriveKey: (signature, salt, info) => wasm.vault_derive_key(salt, signature, info),\n x25519FromSeed: (seed) => wasm.vault_x25519_from_seed(seed),\n x25519Dh: (privateKey, publicKey) => wasm.vault_x25519_dh(privateKey, publicKey),\n randomBytes: (length) => wasm.vault_random_bytes(length),\n sha256: (data) => wasm.vault_sha256(data),\n };\n}\n","export const SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;\n\nconst SECRET_PREFIX = \"secrets/\";\nconst SCOPED_SECRET_PREFIX = \"secrets/scoped/\";\nconst RESERVED_SECRET_SCOPES = new Set([\"default\", \"global\"]);\n\nexport interface SecretScopeOptions {\n /** Optional logical scope. Omit for the global secret namespace. */\n scope?: string;\n}\n\nexport interface ResolvedSecretPath {\n /** Canonical env-style secret name. */\n name: string;\n /** Canonical scope. Undefined means global. */\n scope?: string;\n /** Key passed to the data vault service. */\n vaultKey: string;\n /** KV permission path that backs the encrypted vault entry. */\n permissionPaths: {\n vault: string;\n };\n}\n\nexport function canonicalizeSecretScope(scope: string | undefined): string | undefined {\n if (scope === undefined) {\n return undefined;\n }\n\n const trimmed = scope.trim();\n if (trimmed === \"\") {\n throw new Error(\"Secret scope must be non-empty; omit scope for global secrets.\");\n }\n\n const canonical = trimmed\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n if (canonical === \"\") {\n throw new Error(\"Secret scope must contain at least one letter or number.\");\n }\n if (RESERVED_SECRET_SCOPES.has(canonical)) {\n throw new Error(\n `Secret scope ${JSON.stringify(scope)} is reserved; omit scope for global secrets.`,\n );\n }\n\n return canonical;\n}\n\nexport function resolveSecretPath(\n name: string,\n options: SecretScopeOptions = {},\n): ResolvedSecretPath {\n const normalizedName = name.trim();\n if (!SECRET_NAME_RE.test(normalizedName)) {\n throw new Error(\n `Invalid secret name ${JSON.stringify(name)}. Secret names must match ${SECRET_NAME_RE.source}.`,\n );\n }\n\n const scope = canonicalizeSecretScope(options.scope);\n const vaultKey = scope === undefined\n ? `${SECRET_PREFIX}${normalizedName}`\n : `${SCOPED_SECRET_PREFIX}${scope}/${normalizedName}`;\n\n return {\n name: normalizedName,\n ...(scope !== undefined ? { scope } : {}),\n vaultKey,\n permissionPaths: {\n vault: `vault/${vaultKey}`,\n },\n };\n}\n\nexport function resolveSecretListPrefix(\n options: SecretScopeOptions = {},\n): string {\n const scope = canonicalizeSecretScope(options.scope);\n return scope === undefined\n ? \"vault/secrets/\"\n : `vault/secrets/scoped/${scope}/`;\n}\n","import {\n ErrorCodes,\n err,\n type Result,\n type ServiceError,\n} from \"../types\";\nimport type { IDataVaultService } from \"../vault/IDataVaultService\";\nimport type { VaultError } from \"../vault/types\";\nimport type {\n ISecretsService,\n SecretPayload,\n SecretsError,\n} from \"./ISecretsService\";\nimport {\n canonicalizeSecretScope,\n resolveSecretPath,\n SECRET_NAME_RE,\n type ResolvedSecretPath,\n type SecretScopeOptions,\n} from \"./paths\";\n\nfunction invalidSecretInput(message: string): Result<never, ServiceError> {\n return err({\n code: ErrorCodes.INVALID_INPUT,\n service: \"secrets\",\n message,\n });\n}\n\nfunction resolveSecretPathResult(\n name: string,\n options?: SecretScopeOptions,\n): ResolvedSecretPath | Result<never, ServiceError> {\n try {\n return resolveSecretPath(name, options);\n } catch (error) {\n return invalidSecretInput(error instanceof Error ? error.message : String(error));\n }\n}\n\nexport class SecretsService implements ISecretsService {\n private readonly getVault: () => IDataVaultService;\n\n constructor(vault: IDataVaultService | (() => IDataVaultService)) {\n this.getVault = typeof vault === \"function\" ? vault : () => vault;\n }\n\n get vault(): IDataVaultService {\n return this.getVault();\n }\n\n get isUnlocked(): boolean {\n return this.vault.isUnlocked;\n }\n\n unlock(signer?: unknown): Promise<Result<void, VaultError>> {\n return this.vault.unlock(signer);\n }\n\n lock(): void {\n this.vault.lock();\n }\n\n async get(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<string, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const result = await this.vault.get<SecretPayload>(secretPath.vaultKey);\n if (!result.ok) {\n return result;\n }\n return { ok: true, data: result.data.value.value };\n }\n\n async put(\n name: string,\n value: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const now = new Date().toISOString();\n return this.vault.put(secretPath.vaultKey, {\n value,\n createdAt: now,\n updatedAt: now,\n } satisfies SecretPayload);\n }\n\n async delete(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n return this.vault.delete(secretPath.vaultKey);\n }\n\n async list(options?: SecretScopeOptions): Promise<Result<string[], SecretsError>> {\n let prefix: string;\n try {\n const scope = canonicalizeSecretScope(options?.scope);\n prefix = scope === undefined ? \"secrets/\" : `secrets/scoped/${scope}/`;\n } catch (error) {\n return invalidSecretInput(error instanceof Error ? error.message : String(error));\n }\n\n const result = await this.vault.list({\n prefix,\n removePrefix: true,\n });\n if (!result.ok) {\n return result;\n }\n return {\n ok: true,\n data: result.data.filter((name) => SECRET_NAME_RE.test(name)),\n };\n }\n}\n","/**\n * Canonical JSON serialization and content hashing for TinyCloud\n * encryption requests/responses.\n *\n * The node and SDK must agree byte-for-byte on the canonical form so\n * that body-hash bindings (`bodyHash`, `encryptedSymmetricKeyHash`,\n * `receiverPublicKeyHash`) verify on both sides.\n *\n * Canonical rules:\n * - Object keys are sorted lexicographically by code point.\n * - Strings are encoded with the JSON.stringify default (RFC 8259).\n * - Numbers are emitted via JSON.stringify; callers should restrict to\n * integers or use string fields for high-precision values.\n * - `undefined` properties are dropped. `null` is preserved.\n * - Arrays preserve element order.\n *\n * Hashing uses SHA-256 supplied by the caller (via an `EncryptionCrypto`\n * binding) so this module stays platform-agnostic.\n */\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | Json[]\n | { [key: string]: Json | undefined };\n\n/**\n * Produce the canonical JSON string for {@link value}. Object keys are\n * sorted, `undefined` properties are dropped, and primitive types are\n * encoded by `JSON.stringify`.\n */\nexport function canonicalize(value: Json | undefined): string {\n if (value === undefined) {\n return \"\";\n }\n return stringify(value);\n}\n\nfunction stringify(value: Json): string {\n if (value === null) return \"null\";\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n return JSON.stringify(value);\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n if (Array.isArray(value)) {\n return `[${value.map(stringify).join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = value[k];\n if (v === undefined) continue;\n parts.push(`${JSON.stringify(k)}:${stringify(v)}`);\n }\n return `{${parts.join(\",\")}}`;\n }\n default:\n throw new TypeError(\n `canonicalize: unsupported value type ${typeof value}`,\n );\n }\n}\n\nconst HEX = \"0123456789abcdef\";\n\nexport function hexEncode(bytes: Uint8Array): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i++) {\n const b = bytes[i];\n out += HEX[(b >> 4) & 0xf] + HEX[b & 0xf];\n }\n return out;\n}\n\nexport function hexDecode(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(\"hex string must have even length\");\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const hi = parseInt(hex[i * 2], 16);\n const lo = parseInt(hex[i * 2 + 1], 16);\n if (Number.isNaN(hi) || Number.isNaN(lo)) {\n throw new Error(\"invalid hex character\");\n }\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nexport function base64Encode(bytes: Uint8Array): string {\n // base64 (standard, not url-safe) so envelopes pass through JSON cleanly.\n // We avoid `btoa` to stay node-friendly without polyfills.\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += chars[(b0 >> 2) & 0x3f];\n out += chars[((b0 << 4) | (b1 >> 4)) & 0x3f];\n out += i + 1 < bytes.length ? chars[((b1 << 2) | (b2 >> 6)) & 0x3f] : \"=\";\n out += i + 2 < bytes.length ? chars[b2 & 0x3f] : \"=\";\n }\n return out;\n}\n\nexport function base64Decode(s: string): Uint8Array {\n const clean = s.replace(/[^A-Za-z0-9+/=]/g, \"\");\n const len = clean.length;\n if (len % 4 !== 0) {\n throw new Error(\"invalid base64 input\");\n }\n const padding =\n clean.endsWith(\"==\") ? 2 : clean.endsWith(\"=\") ? 1 : 0;\n const outLen = (len / 4) * 3 - padding;\n const out = new Uint8Array(outLen);\n const lookup: Record<string, number> = {};\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n for (let i = 0; i < chars.length; i++) lookup[chars[i]] = i;\n\n let outIdx = 0;\n for (let i = 0; i < len; i += 4) {\n const v0 = lookup[clean[i]] ?? 0;\n const v1 = lookup[clean[i + 1]] ?? 0;\n const v2 = clean[i + 2] === \"=\" ? 0 : (lookup[clean[i + 2]] ?? 0);\n const v3 = clean[i + 3] === \"=\" ? 0 : (lookup[clean[i + 3]] ?? 0);\n const b0 = (v0 << 2) | (v1 >> 4);\n const b1 = ((v1 & 0x0f) << 4) | (v2 >> 2);\n const b2 = ((v2 & 0x03) << 6) | v3;\n if (outIdx < outLen) out[outIdx++] = b0;\n if (outIdx < outLen) out[outIdx++] = b1;\n if (outIdx < outLen) out[outIdx++] = b2;\n }\n return out;\n}\n\nexport function utf8Encode(s: string): Uint8Array {\n return new TextEncoder().encode(s);\n}\n\nexport function utf8Decode(b: Uint8Array): string {\n return new TextDecoder().decode(b);\n}\n\n/**\n * Compute `hexEncode(sha256(canonicalize(value)))`. The SHA-256 binding\n * is injected so the module remains usable in both the WASM and pure-JS\n * paths.\n */\nexport function canonicalHashHex(\n sha256: (bytes: Uint8Array) => Uint8Array,\n value: Json,\n): string {\n const canonical = canonicalize(value);\n return hexEncode(sha256(utf8Encode(canonical)));\n}\n","/**\n * TinyCloud encryption network identifiers.\n *\n * A network id is `urn:tinycloud:encryption:<ownerDid>:<network>` where\n * `ownerDid` is the owner's DID and `network` is a\n * non-empty label drawn from `[a-z0-9][a-z0-9-]*`.\n *\n * The embedded owner DID is the root authority for the network: any\n * delegation chain ending in a `tinycloud.encryption/decrypt` grant on\n * the network must root at this owner DID.\n */\n\nconst URN_PREFIX = \"urn:tinycloud:encryption:\";\nconst NETWORK_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;\nconst PKH_EIP155_DID_RE = /^did:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40})$/;\n\nexport interface ParsedNetworkId {\n /** The full URN string. */\n networkId: string;\n /** Owner DID embedded in the URN (the network's root authority). */\n ownerDid: string;\n /** Network label (the suffix after the owner DID). */\n name: string;\n}\n\nexport class NetworkIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NetworkIdError\";\n }\n}\n\n/**\n * Parse a network id string into its owner DID and name components.\n *\n * Throws {@link NetworkIdError} when the input does not match\n * `urn:tinycloud:encryption:<did>:<name>`, when the embedded DID is\n * malformed, or when the network name fails {@link NETWORK_NAME_RE}.\n */\nexport function parseNetworkId(networkId: string): ParsedNetworkId {\n if (typeof networkId !== \"string\" || networkId.length === 0) {\n throw new NetworkIdError(\"networkId must be a non-empty string\");\n }\n if (!networkId.startsWith(URN_PREFIX)) {\n throw new NetworkIdError(\n `networkId must start with ${URN_PREFIX} (got ${JSON.stringify(networkId)})`,\n );\n }\n const body = networkId.slice(URN_PREFIX.length);\n // `body` = \"<ownerDid>:<network>\"\n // ownerDid contains ':' (e.g. did:key:z6Mk...), so we split on the LAST colon\n // and treat the suffix as the network name.\n const lastColon = body.lastIndexOf(\":\");\n if (lastColon <= 0 || lastColon === body.length - 1) {\n throw new NetworkIdError(\n `networkId missing ownerDid or name segment (got ${JSON.stringify(networkId)})`,\n );\n }\n const ownerDid = body.slice(0, lastColon);\n const name = body.slice(lastColon + 1);\n\n if (!ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\n `networkId ownerDid must be a DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n // Minimal DID shape: did:<method>:<id> — three colon-separated segments,\n // each non-empty.\n const didParts = ownerDid.split(\":\");\n if (didParts.length < 3 || didParts.some((p) => p.length === 0)) {\n throw new NetworkIdError(\n `networkId ownerDid is not a well-formed DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `networkId name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return { networkId, ownerDid, name };\n}\n\n/**\n * Construct a network id URN from an owner DID and a network name.\n * Validates inputs and throws {@link NetworkIdError} on bad shape.\n */\nexport function buildNetworkId(ownerDid: string, name: string): string {\n if (typeof ownerDid !== \"string\" || !ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\"ownerDid must be a DID\");\n }\n if (typeof name !== \"string\" || !NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n const networkId = `${URN_PREFIX}${ownerDid}:${name}`;\n // Re-validate the composed result so the same error path triggers\n // for caller inputs that compose into a malformed URN.\n parseNetworkId(networkId);\n return networkId;\n}\n\n/**\n * Returns true when {@link networkId} is a syntactically valid network URN.\n */\nexport function isNetworkId(networkId: unknown): networkId is string {\n if (typeof networkId !== \"string\") {\n return false;\n }\n try {\n parseNetworkId(networkId);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction parsePkhOwnerDid(ownerDid: string):\n | { chainId: string; address: string }\n | null {\n const match = ownerDid.match(PKH_EIP155_DID_RE);\n if (!match) return null;\n return {\n chainId: match[1],\n address: match[2].toLowerCase(),\n };\n}\n\n/**\n * Compare owner DIDs as network principals. For `did:pkh:eip155`, EVM\n * address casing is not part of principal identity; other DID methods\n * remain exact string matches.\n */\nexport function ownerDidMatches(a: string, b: string): boolean {\n const aPkh = parsePkhOwnerDid(a);\n const bPkh = parsePkhOwnerDid(b);\n if (aPkh && bPkh) {\n return aPkh.chainId === bPkh.chainId && aPkh.address === bPkh.address;\n }\n return a === b;\n}\n\n/**\n * Resolve the discovery key used to look up a network's descriptor under\n * an owner's public account-space.\n *\n * Format: `.well-known/encryption/network/<name>`.\n */\nexport function networkDiscoveryKey(name: string): string {\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return `.well-known/encryption/network/${name}`;\n}\n\nexport const ENCRYPTION_NETWORK_URN_PREFIX = URN_PREFIX;\nexport const NETWORK_NAME_PATTERN = NETWORK_NAME_RE;\n","/**\n * Type definitions for TinyCloud one-of-one encryption.\n *\n * Wire shapes mirror the protocol described in the encryption\n * architecture: inline envelopes carry the encrypted symmetric key\n * alongside the ciphertext; decrypt requests are short-lived UCAN\n * invocations against a target node plus networkId.\n */\n\nimport type { Json } from \"./canonical\";\n\n/** Default ciphersuite identifier for v1 envelopes. */\nexport const DEFAULT_ENCRYPTION_ALG = \"x25519-aes256gcm/v1\" as const;\n\n/** Inline-envelope schema version. */\nexport const ENVELOPE_VERSION = 1 as const;\n\n/** Default key version on freshly-created networks. */\nexport const DEFAULT_KEY_VERSION = 1 as const;\n\n/** Decrypt-invocation fact type. */\nexport const DECRYPT_FACT_TYPE = \"tinycloud.encryption.decrypt/v1\" as const;\n\n/** Decrypt response type. */\nexport const DECRYPT_RESULT_TYPE =\n \"tinycloud.encryption.decrypt-result/v1\" as const;\n\n/** Encryption service identifier (manifest long form). */\nexport const ENCRYPTION_SERVICE = \"tinycloud.encryption\" as const;\n\n/** Short form used in recap/abilities maps. */\nexport const ENCRYPTION_SERVICE_SHORT = \"encryption\" as const;\n\n/** Decrypt ability URN. */\nexport const DECRYPT_ACTION = \"tinycloud.encryption/decrypt\" as const;\n\n/**\n * Inline encrypted envelope persisted in KV/SQL records.\n *\n * - `encryptedSymmetricKey` is opaque to the SDK; only the network can\n * unwrap it.\n * - `encryptedSymmetricKeyHash` is the canonical hash of the wrapped key\n * bytes (hex-encoded sha-256 of the base64 string's canonical JSON\n * form). The node recomputes this on every decrypt request.\n * - `ciphertext` and `aad` are payload bytes only; the node never sees\n * them.\n */\nexport interface InlineEncryptedEnvelope {\n /** Schema version. */\n v: typeof ENVELOPE_VERSION;\n /** Network id URN. */\n networkId: string;\n /** Ciphersuite identifier. */\n alg: string;\n /** Network key version that was used to wrap the symmetric key. */\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key / capsule. */\n encryptedSymmetricKey: string;\n /** Hex sha-256 of the canonical encryptedSymmetricKey string. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded payload ciphertext. */\n ciphertext: string;\n /** Base64-encoded associated data, if any. */\n aad?: string;\n /** Caller-supplied metadata. Not authenticated against the node. */\n metadata?: Record<string, string>;\n}\n\n/**\n * Node-published network descriptor. The node DB is authoritative; a\n * cached copy may also live under\n * `.well-known/encryption/network/<name>` in the owner's account\n * space (a discovery record only).\n */\nexport interface NetworkDescriptor {\n networkId: string;\n ownerDid: string;\n name: string;\n members: ReadonlyArray<{ nodeId: string; role: \"primary\" | \"share\" }>;\n threshold: { n: number; t: number };\n state: \"pending\" | \"generating\" | \"active\" | \"rotating\" | \"revoked\" | \"failed\";\n /** Base64-encoded network public key. */\n publicEncryptionKey: string;\n alg: string;\n keyVersion: number;\n keyBackend: \"local-one-of-one\" | \"dstack\" | \"threshold\";\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Decrypt-request body sent over the wire. Hashed (canonically) and\n * bound to the UCAN invocation via `facts.bodyHash`.\n */\nexport interface DecryptRequestBody {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n alg: string;\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key from the envelope. */\n encryptedSymmetricKey: string;\n /** Recomputed hash of the wrapped key. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded per-request receiver public key. */\n receiverPublicKey: string;\n /** Hash of the receiver public key. */\n receiverPublicKeyHash: string;\n}\n\n/**\n * Decrypt-response body returned by the node. The SDK verifies the\n * signature, recomputes hashes, then unwraps `wrappedKey` with the\n * per-request receiver private key before decrypting the payload.\n */\nexport interface DecryptResponseBody {\n type: typeof DECRYPT_RESULT_TYPE;\n targetNode: string;\n networkId: string;\n invocationCid: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n /** Base64-encoded symmetric key re-encrypted to receiverPublicKey. */\n wrappedKey: string;\n alg: string;\n keyVersion: number;\n requestHash: string;\n nodeId: string;\n /** Base64-encoded ed25519 signature over canonical(response - signature field). */\n nodeSignature: string;\n}\n\n/**\n * Decrypt-invocation facts attached to the UCAN. Verifiers recompute\n * `bodyHash`, `encryptedSymmetricKeyHash`, and `receiverPublicKeyHash`\n * from the request body and reject any mismatch.\n */\nexport interface DecryptInvocationFact {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n bodyHash: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n alg: string;\n keyVersion: number;\n}\n\n/**\n * Per-request receiver key pair (x25519). The private key never\n * leaves the SDK; the public key is sent to the node so the node can\n * rewrap the symmetric key.\n */\nexport interface ReceiverKeyPair {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n}\n\n/**\n * Crypto primitives injected into the encryption module. The SDK\n * provides these via WASM bindings; tests provide simple in-memory\n * implementations.\n */\nexport interface EncryptionCrypto {\n /** SHA-256 → 32-byte digest. */\n sha256(data: Uint8Array): Uint8Array;\n /** Cryptographically secure random bytes. */\n randomBytes(length: number): Uint8Array;\n /** Derive an x25519 key pair from a 32-byte seed. */\n x25519FromSeed(seed: Uint8Array): ReceiverKeyPair;\n /** Compute the x25519 ECDH shared secret. */\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n /** Authenticated symmetric encryption (the node's symmetric scheme). */\n authEncrypt(\n key: Uint8Array,\n plaintext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /** Authenticated symmetric decryption (matched to authEncrypt). */\n authDecrypt(\n key: Uint8Array,\n ciphertext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /**\n * Wrap a symmetric key for the network's public encryption key using\n * a sealed-box / hpke / x25519+symmetric construction. Implementation\n * is opaque; only the node can unwrap.\n */\n sealToNetworkKey(\n networkPublicKey: Uint8Array,\n symmetricKey: Uint8Array,\n ): Uint8Array;\n /**\n * Open a wrapped symmetric key that was re-encrypted to the\n * per-request receiver public key. The matching private key must be\n * supplied here; the SDK never sends it to the node.\n */\n openWithReceiverKey(\n receiverPrivateKey: Uint8Array,\n wrappedKey: Uint8Array,\n ): Uint8Array;\n /**\n * Verify an ed25519 signature over `message` produced by the node\n * identified by `nodeId` (the public-key DID).\n */\n verifyNodeSignature(\n nodeId: string,\n message: Uint8Array,\n signature: Uint8Array,\n ): boolean;\n}\n\n/**\n * Signer interface used to derive a receiver key pair from a wallet or\n * session signer. The signature is HKDF-extracted into the receiver\n * seed so the public key is reproducible given the same context.\n */\nexport interface ReceiverKeySigner {\n signMessage(message: string): Promise<string>;\n}\n\n/** Capability proof material accompanying a decrypt invocation. */\nexport interface DecryptCapabilityProof {\n /** Delegation chain CIDs rooted at the network owner DID. */\n proofs: ReadonlyArray<string>;\n /** Optional Authorization header value to use instead of building one. */\n authorization?: string;\n}\n\n/**\n * Inputs to the decrypt invocation builder.\n */\nexport interface BuildDecryptInvocationInput {\n /** Target node DID — also the UCAN audience. */\n targetNode: string;\n /** Network id URN — also the recap resource. */\n networkId: string;\n /** Canonical body that will be POSTed. */\n body: DecryptRequestBody;\n /** Facts include hashes bound to the canonical body. */\n facts: DecryptInvocationFact;\n /** Capability proof chain. */\n proof: DecryptCapabilityProof;\n /** Optional `nbf` UCAN field as an ISO date string. */\n notBefore?: string;\n /** Optional `exp` UCAN field as an ISO date string. */\n expiration?: string;\n}\n\n/**\n * The output of {@link buildDecryptInvocation}.\n */\nexport interface BuiltDecryptInvocation {\n /** HTTP `Authorization` header value. */\n authorization: string;\n /** CID of the invocation (used by the node response binding). */\n invocationCid: string;\n /** Canonical body string the node will hash. */\n canonicalBody: string;\n}\n\n/**\n * Signer interface for producing the decrypt invocation. WASM bindings\n * implement this with the same session signer used for KV/SQL\n * invocations; tests can stub it.\n */\nexport interface DecryptInvocationSigner {\n signDecryptInvocation(input: BuildDecryptInvocationInput): Promise<BuiltDecryptInvocation>;\n}\n\n/**\n * Errors thrown / returned from the encryption module.\n */\nexport type EncryptionErrorInput =\n | { code: \"NETWORK_NOT_FOUND\"; networkId?: string; name?: string; message?: string }\n | { code: \"NETWORK_NOT_ACTIVE\"; state: string; message?: string }\n | { code: \"INVALID_NETWORK_ID\"; message: string }\n | { code: \"INVALID_ENVELOPE\"; message: string }\n | { code: \"DECRYPT_DENIED\"; message: string }\n | { code: \"INVALID_RESPONSE\"; message: string }\n | { code: \"RESPONSE_SIGNATURE_INVALID\"; message?: string }\n | { code: \"RESPONSE_BINDING_MISMATCH\"; field: string; message?: string }\n | { code: \"TRANSPORT_ERROR\"; cause: Error; message?: string }\n | { code: \"INVALID_INPUT\"; message: string };\n\nexport type EncryptionError = EncryptionErrorInput & {\n service: \"encryption\";\n message: string;\n};\n\nfunction defaultEncryptionMessage(input: EncryptionErrorInput): string {\n switch (input.code) {\n case \"NETWORK_NOT_FOUND\":\n return (\n input.message ??\n `Network not found: ${input.networkId ?? input.name ?? \"<unknown>\"}`\n );\n case \"NETWORK_NOT_ACTIVE\":\n return input.message ?? `Network not active (state=${input.state})`;\n case \"INVALID_NETWORK_ID\":\n return input.message;\n case \"INVALID_ENVELOPE\":\n return input.message;\n case \"DECRYPT_DENIED\":\n return input.message;\n case \"INVALID_RESPONSE\":\n return input.message;\n case \"RESPONSE_SIGNATURE_INVALID\":\n return input.message ?? \"Node response signature failed to verify\";\n case \"RESPONSE_BINDING_MISMATCH\":\n return (\n input.message ??\n `Node response binding mismatch on field ${JSON.stringify(input.field)}`\n );\n case \"TRANSPORT_ERROR\":\n return input.message ?? input.cause.message;\n case \"INVALID_INPUT\":\n return input.message;\n }\n}\n\nexport function encryptionError(input: EncryptionErrorInput): EncryptionError {\n return {\n ...input,\n service: \"encryption\",\n message: defaultEncryptionMessage(input),\n };\n}\n\n/** Helper for the test/runtime layers to coerce arbitrary throwables. */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\n/** Re-export for ergonomic typing of canonical payloads. */\nexport type CanonicalJson = Json;\n","/**\n * Network-descriptor discovery.\n *\n * Resolution order (per architecture):\n *\n * 1. The node's authoritative endpoint\n * `GET /encryption/networks/<networkId>` returns the current\n * descriptor (`state`, `publicEncryptionKey`, `keyVersion`, ...).\n * 2. If the node is unreachable, fall back to the cached discovery\n * record at `.well-known/encryption/network/<name>` inside the\n * owner's public space.\n *\n * The node DB is authoritative on conflict; cached records are\n * advisory only.\n */\n\nimport {\n NetworkIdError,\n networkDiscoveryKey,\n ownerDidMatches,\n parseNetworkId,\n} from \"./networkId\";\nimport {\n encryptionError,\n type EncryptionError,\n type NetworkDescriptor,\n} from \"./types\";\n\nexport type DiscoverySource = \"node\" | \"well-known\";\n\nexport interface DiscoveredNetwork {\n descriptor: NetworkDescriptor;\n source: DiscoverySource;\n}\n\nexport interface NodeDescriptorFetcher {\n /** Fetch the descriptor by full networkId URN. */\n fetchByNetworkId(networkId: string): Promise<NetworkDescriptor | null>;\n}\n\nexport interface WellKnownDescriptorFetcher {\n /**\n * Read the cached well-known descriptor by owner DID + network name.\n * Returns null if no record exists or the record is unreadable.\n */\n fetchWellKnown(\n ownerDid: string,\n discoveryKey: string,\n ): Promise<NetworkDescriptor | null>;\n}\n\nexport interface DiscoverNetworkInput {\n /** Either a networkId URN or a bare network name (paired with `ownerDid`). */\n identifier: string;\n /** Required when identifier is a bare name. */\n ownerDid?: string;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n}\n\n/**\n * Resolve a network descriptor. The node fetcher is preferred; the\n * well-known fallback is used only on transport failure.\n *\n * The returned descriptor is sanity-checked: `networkId`, `ownerDid`,\n * and `name` must agree with the URN, and the public key field must\n * be non-empty.\n */\nexport async function discoverNetwork(\n input: DiscoverNetworkInput,\n):\n | Promise<{ ok: true; data: DiscoveredNetwork } | { ok: false; error: EncryptionError }> {\n let networkId: string;\n let ownerDid: string;\n let name: string;\n try {\n if (input.identifier.startsWith(\"urn:tinycloud:encryption:\")) {\n const parsed = parseNetworkId(input.identifier);\n networkId = parsed.networkId;\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n } else {\n if (input.ownerDid === undefined) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"discoverNetwork requires `ownerDid` when identifier is a bare network name\",\n }),\n };\n }\n networkId = `urn:tinycloud:encryption:${input.ownerDid}:${input.identifier}`;\n const parsed = parseNetworkId(networkId);\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n }\n } catch (err) {\n if (err instanceof NetworkIdError) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err.message,\n }),\n };\n }\n throw err;\n }\n\n // 1) Try the node first.\n if (input.node !== undefined) {\n try {\n const descriptor = await input.node.fetchByNetworkId(networkId);\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return { ok: true, data: { descriptor: validated.data, source: \"node\" } };\n }\n } catch (err) {\n // Fall through to well-known\n }\n }\n\n // 2) Fallback to well-known cache.\n if (input.wellKnown !== undefined) {\n try {\n const descriptor = await input.wellKnown.fetchWellKnown(\n ownerDid,\n networkDiscoveryKey(name),\n );\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return {\n ok: true,\n data: { descriptor: validated.data, source: \"well-known\" },\n };\n }\n } catch (err) {\n // Fall through to NOT_FOUND\n }\n }\n\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_FOUND\",\n networkId,\n name,\n }),\n };\n}\n\nfunction validateDescriptor(\n descriptor: NetworkDescriptor,\n networkId: string,\n ownerDid: string,\n name: string,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n let descriptorNetwork;\n try {\n descriptorNetwork = parseNetworkId(descriptor.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n\n if (\n descriptorNetwork.name !== name ||\n !ownerDidMatches(descriptorNetwork.ownerDid, ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId ${JSON.stringify(descriptor.networkId)} does not match expected ${JSON.stringify(networkId)}`,\n }),\n };\n }\n\n const descriptorOwnerDid = descriptorOwner(descriptor);\n if (\n descriptorOwnerDid === undefined ||\n !ownerDidMatches(descriptorOwnerDid, ownerDid) ||\n !ownerDidMatches(descriptorOwnerDid, descriptorNetwork.ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor ownerDid does not match networkId ownerDid\",\n }),\n };\n }\n if (descriptor.name !== name) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor name does not match networkId name\",\n }),\n };\n }\n if (\n typeof descriptor.publicEncryptionKey !== \"string\" ||\n descriptor.publicEncryptionKey.length === 0\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor publicEncryptionKey must be a non-empty string\",\n }),\n };\n }\n return {\n ok: true,\n data: {\n ...descriptor,\n ownerDid: descriptorOwnerDid,\n },\n };\n}\n\nfunction descriptorOwner(descriptor: NetworkDescriptor): string | undefined {\n if (typeof descriptor.ownerDid === \"string\" && descriptor.ownerDid.length > 0) {\n return descriptor.ownerDid;\n }\n\n const legacyDescriptor = descriptor as NetworkDescriptor & {\n principal?: unknown;\n };\n return typeof legacyDescriptor.principal === \"string\" &&\n legacyDescriptor.principal.length > 0\n ? legacyDescriptor.principal\n : undefined;\n}\n\n/**\n * Reject a descriptor that is not in a state that accepts decrypt\n * requests. Only `active` and `rotating` networks may decrypt; revoked\n * or pending networks reject.\n */\nexport function ensureNetworkUsableForDecrypt(\n descriptor: NetworkDescriptor,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n if (descriptor.state === \"active\" || descriptor.state === \"rotating\") {\n return { ok: true, data: descriptor };\n }\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_ACTIVE\",\n state: descriptor.state,\n }),\n };\n}\n","/**\n * Inline-envelope encrypt / decrypt helpers.\n *\n * Encryption is fully local: the SDK generates a per-record symmetric\n * key, encrypts the payload, then wraps the symmetric key against the\n * network's public encryption key. The wrapped key (and key hash)\n * travels alongside the ciphertext inside an\n * {@link InlineEncryptedEnvelope}.\n *\n * Decryption is split: the node unwraps the symmetric key to the\n * per-request receiver public key (see {@link buildDecryptInvocation}\n * and the decrypt route); this module is responsible for the local\n * payload decryption once the symmetric key is available.\n */\n\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n DEFAULT_ENCRYPTION_ALG,\n DEFAULT_KEY_VERSION,\n ENVELOPE_VERSION,\n encryptionError,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n} from \"./types\";\nimport { parseNetworkId } from \"./networkId\";\n\nexport interface EncryptToNetworkInput {\n /** Target network id URN. */\n networkId: string;\n /** Network public key bytes (already discovered). */\n networkPublicKey: Uint8Array;\n /** Payload bytes to encrypt. Callers serialize objects to bytes themselves. */\n plaintext: Uint8Array;\n /** Optional associated authenticated data. */\n aad?: Uint8Array;\n /** Ciphersuite identifier. Defaults to {@link DEFAULT_ENCRYPTION_ALG}. */\n alg?: string;\n /** Key version. Defaults to {@link DEFAULT_KEY_VERSION}. */\n keyVersion?: number;\n /** Caller-supplied envelope metadata. */\n metadata?: Record<string, string>;\n}\n\nexport interface EncryptToNetworkResult {\n envelope: InlineEncryptedEnvelope;\n /** Symmetric key returned for caller bookkeeping; do NOT persist. */\n symmetricKey: Uint8Array;\n}\n\n/**\n * Local-only encrypt: generates a symmetric key, encrypts the payload,\n * wraps the key against the network public key, and returns the\n * inline envelope.\n */\nexport function encryptToNetwork(\n crypto: EncryptionCrypto,\n input: EncryptToNetworkInput,\n): EncryptToNetworkResult {\n parseNetworkId(input.networkId);\n const alg = input.alg ?? DEFAULT_ENCRYPTION_ALG;\n const keyVersion = input.keyVersion ?? DEFAULT_KEY_VERSION;\n\n const symmetricKey = crypto.randomBytes(32);\n const ciphertext = crypto.authEncrypt(symmetricKey, input.plaintext, input.aad);\n const wrapped = crypto.sealToNetworkKey(input.networkPublicKey, symmetricKey);\n const encryptedSymmetricKey = base64Encode(wrapped);\n const encryptedSymmetricKeyHash = canonicalHashHex(\n crypto.sha256,\n encryptedSymmetricKey,\n );\n\n const envelope: InlineEncryptedEnvelope = {\n v: ENVELOPE_VERSION,\n networkId: input.networkId,\n alg,\n keyVersion,\n encryptedSymmetricKey,\n encryptedSymmetricKeyHash,\n ciphertext: base64Encode(ciphertext),\n ...(input.aad !== undefined ? { aad: base64Encode(input.aad) } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n };\n\n return { envelope, symmetricKey };\n}\n\n/**\n * Validate an inline envelope shape. Returns an error if the envelope\n * is missing required fields or fails internal hash recomputation.\n */\nexport function validateEnvelope(\n crypto: EncryptionCrypto,\n envelope: unknown,\n): { ok: true; data: InlineEncryptedEnvelope } | { ok: false; error: EncryptionError } {\n if (envelope === null || typeof envelope !== \"object\") {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope must be an object\",\n }),\n };\n }\n const e = envelope as InlineEncryptedEnvelope;\n if (e.v !== ENVELOPE_VERSION) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.v must be ${ENVELOPE_VERSION} (got ${e.v as unknown as string})`,\n }),\n };\n }\n try {\n parseNetworkId(e.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n for (const field of [\n \"alg\",\n \"encryptedSymmetricKey\",\n \"encryptedSymmetricKeyHash\",\n \"ciphertext\",\n ] as const) {\n if (typeof e[field] !== \"string\" || (e[field] as string).length === 0) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.${field} must be a non-empty string`,\n }),\n };\n }\n }\n if (typeof e.keyVersion !== \"number\" || !Number.isInteger(e.keyVersion)) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope.keyVersion must be an integer\",\n }),\n };\n }\n const expectedHash = canonicalHashHex(crypto.sha256, e.encryptedSymmetricKey);\n if (expectedHash !== e.encryptedSymmetricKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message:\n \"envelope.encryptedSymmetricKeyHash does not match canonical hash of encryptedSymmetricKey\",\n }),\n };\n }\n return { ok: true, data: e };\n}\n\n/**\n * Decrypt an inline envelope given the unwrapped symmetric key.\n *\n * Callers typically obtain the symmetric key via the node decrypt\n * endpoint plus the per-request receiver key pair (see\n * `EncryptionService.decryptEnvelope`).\n */\nexport function decryptEnvelopeWithKey(\n crypto: EncryptionCrypto,\n envelope: InlineEncryptedEnvelope,\n symmetricKey: Uint8Array,\n): Uint8Array {\n const ciphertext = base64Decode(envelope.ciphertext);\n const aad = envelope.aad !== undefined ? base64Decode(envelope.aad) : undefined;\n return crypto.authDecrypt(symmetricKey, ciphertext, aad);\n}\n","/**\n * TinyCloud encryption decrypt-invocation builder.\n *\n * The decrypt invocation is a UCAN-style TinyCloud invocation against\n * a node plus a network id. It is structurally distinct from the\n * existing space-shaped invocations:\n *\n * - `aud` (audience) is the **target node DID** (not a space owner).\n * - `att` (attenuation) uses the **networkId URN** as the resource\n * key (not a `tinycloud:pkh:...:<space>` URI).\n * - `fct` (facts) binds `bodyHash`, `encryptedSymmetricKeyHash`, and\n * `receiverPublicKeyHash` so the node can recompute them from the\n * POST body.\n *\n * Production callers inject a `DecryptInvocationSigner` backed by the\n * WASM UCAN/session signer. Tests pass a deterministic stub.\n */\n\nimport { canonicalize, canonicalHashHex, hexEncode, utf8Encode } from \"./canonical\";\nimport { parseNetworkId } from \"./networkId\";\nimport {\n DECRYPT_ACTION,\n DECRYPT_FACT_TYPE,\n ENCRYPTION_SERVICE,\n encryptionError,\n type BuildDecryptInvocationInput,\n type BuiltDecryptInvocation,\n type CanonicalJson,\n type DecryptCapabilityProof,\n type DecryptInvocationFact,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\nexport interface CanonicalDecryptRequest {\n /** The canonical body that the node will hash. */\n canonicalBody: string;\n /** Hex sha-256 of the canonical body bytes. */\n bodyHash: string;\n /** Hex sha-256 of the receiver public key bytes. */\n receiverPublicKeyHash: string;\n}\n\nexport interface BuildCanonicalDecryptRequestInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n receiverPublicKey: Uint8Array;\n}\n\n/**\n * Build the canonical body string and its bound hashes for a decrypt\n * request. The output is what gets POSTed to the node, and what the\n * node will hash to verify `facts.bodyHash`.\n */\nexport function buildCanonicalDecryptRequest(\n input: BuildCanonicalDecryptRequestInput,\n): CanonicalDecryptRequest {\n const canonicalBody = canonicalize(input.body as unknown as CanonicalJson);\n const bodyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return { canonicalBody, bodyHash, receiverPublicKeyHash };\n}\n\nexport interface BuildDecryptFactsInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n /** Encrypted symmetric key hash from the envelope (already canonical). */\n encryptedSymmetricKeyHash: string;\n /** Receiver public key bytes. */\n receiverPublicKey: Uint8Array;\n /** Canonical body string used to derive bodyHash. */\n canonicalBody?: string;\n}\n\n/**\n * Build the {@link DecryptInvocationFact} that will be embedded in the\n * UCAN `fct` field. Hashes are recomputed here so callers cannot drift\n * from the canonical body without the node noticing.\n */\nexport function buildDecryptFacts(\n input: BuildDecryptFactsInput,\n): DecryptInvocationFact {\n // When a precomputed canonicalBody string is supplied, hash its bytes\n // directly. Don't route it through canonicalHashHex, which would\n // re-canonicalize the string itself (escaping it as a JSON value).\n const bodyHash =\n input.canonicalBody !== undefined\n ? hexEncode(input.crypto.sha256(utf8Encode(input.canonicalBody)))\n : canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return {\n type: DECRYPT_FACT_TYPE,\n targetNode: input.body.targetNode,\n networkId: input.body.networkId,\n bodyHash,\n encryptedSymmetricKeyHash: input.encryptedSymmetricKeyHash,\n receiverPublicKeyHash,\n alg: input.body.alg,\n keyVersion: input.body.keyVersion,\n };\n}\n\n/**\n * Recap-shaped attenuation for the decrypt invocation. The resource\n * key is the networkId URN; the ability is the long-form\n * `tinycloud.encryption/decrypt`. This is intentionally distinct from\n * the existing space-shaped invocation map so callers cannot\n * accidentally fake a space prefix.\n */\nexport function buildDecryptAttenuation(\n networkId: string,\n): Record<string, Record<string, Record<string, never>>> {\n parseNetworkId(networkId);\n return {\n [networkId]: {\n [DECRYPT_ACTION]: {},\n },\n };\n}\n\n/**\n * Validate a {@link BuildDecryptInvocationInput} payload — the body\n * shape, the facts bindings, and the audience contract — without\n * actually signing. Returns either the input (typed) or a structured\n * error so callers can short-circuit before calling into WASM.\n */\nexport function checkDecryptInvocationInput(\n crypto: EncryptionCrypto,\n input: BuildDecryptInvocationInput,\n):\n | { ok: true; data: BuildDecryptInvocationInput; canonicalBody: string }\n | { ok: false; error: EncryptionError } {\n if (input.body.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `body.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `facts.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.targetNode must equal targetNode — the UCAN audience binds the request to a single node\",\n }),\n };\n }\n if (input.body.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.targetNode must equal targetNode\",\n }),\n };\n }\n if (input.facts.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.networkId must equal networkId\",\n }),\n };\n }\n if (input.body.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.networkId must equal networkId\",\n }),\n };\n }\n if (input.facts.alg !== input.body.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.alg must equal body.alg\",\n }),\n };\n }\n if (input.facts.keyVersion !== input.body.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.keyVersion must equal body.keyVersion\",\n }),\n };\n }\n if (\n input.facts.encryptedSymmetricKeyHash !==\n input.body.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.encryptedSymmetricKeyHash must equal body.encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (\n input.facts.receiverPublicKeyHash !== input.body.receiverPublicKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.receiverPublicKeyHash must equal body.receiverPublicKeyHash\",\n }),\n };\n }\n try {\n parseNetworkId(input.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err instanceof Error ? err.message : String(err),\n }),\n };\n }\n const canonicalBody = canonicalize(\n input.body as unknown as CanonicalJson,\n );\n const expectedBodyHash = canonicalHashHex(crypto.sha256, input.body as unknown as CanonicalJson);\n if (expectedBodyHash !== input.facts.bodyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.bodyHash does not match the canonical body hash\",\n }),\n };\n }\n return { ok: true, data: input, canonicalBody };\n}\n\n/**\n * Compose the high-level decrypt invocation and hand it to the signer\n * for UCAN minting. The signer returns the Authorization header value\n * plus the invocation CID; this function only validates and\n * orchestrates — it does not perform crypto signing itself.\n */\nexport async function buildDecryptInvocation(\n crypto: EncryptionCrypto,\n signer: DecryptInvocationSigner,\n input: BuildDecryptInvocationInput,\n): Promise<{ ok: true; data: BuiltDecryptInvocation } | { ok: false; error: EncryptionError }> {\n const checked = checkDecryptInvocationInput(crypto, input);\n if (!checked.ok) {\n return checked;\n }\n try {\n const built = await signer.signDecryptInvocation(checked.data);\n if (!built.authorization || !built.invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned an empty authorization or invocationCid\",\n }),\n };\n }\n if (built.canonicalBody !== checked.canonicalBody) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned a canonicalBody that does not match the SDK's canonicalization — signer must use the SDK-provided body\",\n }),\n };\n }\n return { ok: true, data: built };\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: err instanceof Error ? err : new Error(String(err)),\n message: `failed to sign decrypt invocation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n}\n\n/** Re-export so callers can introspect the service+action constants. */\nexport { DECRYPT_ACTION, ENCRYPTION_SERVICE };\n","/**\n * Per-request receiver key generation.\n *\n * The receiver key pair is generated for a single decrypt request: the\n * SDK sends `receiverPublicKey` to the node so the node can rewrap the\n * symmetric key; the matching private key never leaves the SDK.\n *\n * Two derivation modes are supported:\n *\n * 1. **Random** — `crypto.randomBytes(32)` seeds a fresh x25519 pair.\n * This is the default for one-of-one flows.\n *\n * 2. **Signed-context** — the caller provides a signer that signs a\n * deterministic context message (network id + nonce + invocation\n * intent). The signature bytes are SHA-256'd into the seed. This is\n * useful when callers want the receiver key to be reproducible by\n * the same session signer (e.g. for delegated reads where the\n * signer is the only stable secret).\n */\n\nimport { utf8Encode } from \"./canonical\";\nimport type {\n EncryptionCrypto,\n ReceiverKeyPair,\n ReceiverKeySigner,\n} from \"./types\";\n\nexport interface RandomReceiverKeyInput {\n crypto: EncryptionCrypto;\n}\n\nexport function generateRandomReceiverKey(\n input: RandomReceiverKeyInput,\n): ReceiverKeyPair {\n const seed = input.crypto.randomBytes(32);\n return input.crypto.x25519FromSeed(seed);\n}\n\nexport interface SignedReceiverKeyInput {\n crypto: EncryptionCrypto;\n signer: ReceiverKeySigner;\n networkId: string;\n /** Optional extra context (e.g. invocation nonce) folded into the message. */\n context?: string;\n}\n\n/**\n * Deterministic receiver-key derivation: signs a context string with\n * the supplied signer, then SHA-256s the signature bytes into the\n * x25519 seed.\n *\n * The context message is:\n * `tinycloud.encryption.receiver-key/v1:<networkId>:<context>`\n *\n * Callers MUST include unique context (e.g. a fresh nonce) on every\n * request unless they explicitly want reproducibility.\n */\nexport async function deriveSignedReceiverKey(\n input: SignedReceiverKeyInput,\n): Promise<ReceiverKeyPair> {\n const message = `tinycloud.encryption.receiver-key/v1:${input.networkId}:${input.context ?? \"\"}`;\n const sig = await input.signer.signMessage(message);\n // Treat the signature as opaque bytes; sha256 collapses to a 32-byte seed.\n const sigBytes = utf8Encode(sig);\n const seed = input.crypto.sha256(sigBytes);\n return input.crypto.x25519FromSeed(seed);\n}\n","/**\n * Decrypt-response verification.\n *\n * The node returns the unwrapped symmetric key re-encrypted to the\n * per-request receiver public key. Before the SDK uses the wrapped\n * key, it must:\n *\n * 1. Verify the node signature over the canonical response (excluding\n * the signature field).\n * 2. Recompute every binding hash and reject any mismatch.\n * 3. Confirm `targetNode`, `networkId`, `alg`, and `keyVersion` echo\n * what the SDK sent.\n *\n * After verification, the SDK opens `wrappedKey` with the per-request\n * receiver private key and uses the resulting symmetric key to\n * decrypt the inline envelope payload.\n */\n\nimport { base64Decode, canonicalize, hexEncode, utf8Encode } from \"./canonical\";\nimport {\n DECRYPT_RESULT_TYPE,\n encryptionError,\n type CanonicalJson,\n type DecryptInvocationFact,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\n/**\n * Construct the canonical bytes that the node signed.\n *\n * The signature covers the response with `nodeSignature` removed. We\n * canonicalize and hash the same way the node does so the binding is\n * stable.\n */\nexport function canonicalSignedResponse(\n response: DecryptResponseBody,\n): string {\n // Strip the signature; canonicalize sorts keys for us.\n const { nodeSignature: _drop, ...rest } = response;\n return canonicalize(rest as unknown as CanonicalJson);\n}\n\nexport interface VerifyDecryptResponseInput {\n crypto: EncryptionCrypto;\n request: DecryptRequestBody;\n facts: DecryptInvocationFact;\n /** CID of the signed invocation that produced this response. */\n invocationCid: string;\n /** Hex bodyHash that was bound in `facts.bodyHash`. */\n requestBodyHash: string;\n response: DecryptResponseBody;\n}\n\n/**\n * Verify the node's decrypt response. Returns the response on success;\n * a structured error on signature, binding, or shape failure.\n */\nexport function verifyDecryptResponse(\n input: VerifyDecryptResponseInput,\n):\n | { ok: true; data: DecryptResponseBody }\n | { ok: false; error: EncryptionError } {\n const { crypto, request, facts, invocationCid, requestBodyHash, response } =\n input;\n\n if (response.type !== DECRYPT_RESULT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_RESPONSE\",\n message: `response.type must be ${DECRYPT_RESULT_TYPE}`,\n }),\n };\n }\n if (response.targetNode !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"targetNode\",\n }),\n };\n }\n if (response.networkId !== request.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"networkId\",\n }),\n };\n }\n if (response.nodeId !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"nodeId\",\n }),\n };\n }\n if (response.alg !== request.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"alg\",\n }),\n };\n }\n if (response.keyVersion !== request.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"keyVersion\",\n }),\n };\n }\n if (\n response.encryptedSymmetricKeyHash !==\n request.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (response.receiverPublicKeyHash !== request.receiverPublicKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"receiverPublicKeyHash\",\n }),\n };\n }\n if (response.invocationCid !== invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"invocationCid\",\n }),\n };\n }\n // requestHash binds invocationCid || requestBodyHash per spec. The `||`\n // notation is concatenation, not a literal delimiter.\n const expectedRequestHash = hexEncode(\n crypto.sha256(utf8Encode(`${invocationCid}${requestBodyHash}`)),\n );\n if (response.requestHash !== expectedRequestHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"requestHash\",\n }),\n };\n }\n // The facts must agree with the response (defensive: catches a node\n // that returns a fresh body bound to a different invocation).\n if (\n facts.encryptedSymmetricKeyHash !== response.encryptedSymmetricKeyHash ||\n facts.receiverPublicKeyHash !== response.receiverPublicKeyHash ||\n facts.networkId !== response.networkId ||\n facts.targetNode !== response.targetNode ||\n facts.alg !== response.alg ||\n facts.keyVersion !== response.keyVersion\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"facts\",\n }),\n };\n }\n\n const signedBytes = new TextEncoder().encode(\n canonicalSignedResponse(response),\n );\n const signatureBytes = base64Decode(response.nodeSignature);\n if (\n !crypto.verifyNodeSignature(response.nodeId, signedBytes, signatureBytes)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_SIGNATURE_INVALID\",\n }),\n };\n }\n return { ok: true, data: response };\n}\n\n/**\n * After verification, open the response's `wrappedKey` with the\n * per-request receiver private key and return the symmetric key.\n */\nexport function openWrappedKey(\n crypto: EncryptionCrypto,\n receiverPrivateKey: Uint8Array,\n response: DecryptResponseBody,\n): Uint8Array {\n const wrapped = base64Decode(response.wrappedKey);\n return crypto.openWithReceiverKey(receiverPrivateKey, wrapped);\n}\n","/**\n * EncryptionService — TinyCloud one-of-one encryption service.\n *\n * Responsibilities:\n * - Network discovery (`discoverNetwork`).\n * - Local envelope encryption (`encryptToNetwork`).\n * - Node-mediated decrypt with full request/response binding\n * verification (`decryptEnvelope`).\n *\n * Non-responsibilities:\n * - KV/SQL access. Callers fetch encrypted envelopes from their data\n * service of choice and pass them in.\n * - Network onboarding/ceremony. Those routes are node-only.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport { type Result } from \"../types\";\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n discoverNetwork as discoverNetworkFn,\n ensureNetworkUsableForDecrypt,\n type NodeDescriptorFetcher,\n type WellKnownDescriptorFetcher,\n} from \"./discovery\";\nimport {\n decryptEnvelopeWithKey,\n encryptToNetwork as encryptToNetworkFn,\n validateEnvelope,\n} from \"./envelope\";\nimport {\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptInvocation,\n} from \"./invocation\";\nimport { generateRandomReceiverKey } from \"./receiverKey\";\nimport {\n openWrappedKey,\n verifyDecryptResponse,\n} from \"./response\";\nimport {\n DECRYPT_FACT_TYPE,\n encryptionError,\n type DecryptCapabilityProof,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n type NetworkDescriptor,\n toError,\n} from \"./types\";\nimport type {\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n IEncryptionService,\n} from \"./IEncryptionService\";\n\n// Local Result helpers typed to EncryptionError. The shared `ok` / `err`\n// from `../types` default the error generic to `ServiceError`, which\n// widens our return-type inference here.\nfunction encOk<T>(data: T): Result<T, EncryptionError> {\n return { ok: true, data };\n}\nfunction encErr<T = never>(error: EncryptionError): Result<T, EncryptionError> {\n return { ok: false, error };\n}\n\n/**\n * Transport for posting decrypt requests to a TinyCloud node.\n *\n * Implementations supply the `Authorization` header (built by the\n * decrypt-invocation signer) and POST the canonical body. The\n * response body is JSON-decoded into a {@link DecryptResponseBody}.\n */\nexport interface DecryptTransport {\n postDecrypt(input: {\n targetNode: string;\n networkId: string;\n authorization: string;\n canonicalBody: string;\n }): Promise<DecryptResponseBody>;\n}\n\nexport interface EncryptionServiceConfig {\n crypto: EncryptionCrypto;\n signer: DecryptInvocationSigner;\n transport: DecryptTransport;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n [key: string]: unknown;\n}\n\nexport class EncryptionService\n extends BaseService\n implements IEncryptionService\n{\n static readonly serviceName = \"encryption\";\n\n declare protected _config: EncryptionServiceConfig;\n\n constructor(config: EncryptionServiceConfig) {\n super();\n this._config = config;\n }\n\n get config(): EncryptionServiceConfig {\n return this._config;\n }\n\n private get crypto(): EncryptionCrypto {\n return this._config.crypto;\n }\n\n async discoverNetwork(\n identifier: string,\n ownerDid?: string,\n ): Promise<Result<NetworkDescriptor, EncryptionError>> {\n const result = await discoverNetworkFn({\n identifier,\n ...(ownerDid !== undefined ? { ownerDid } : {}),\n ...(this._config.node !== undefined ? { node: this._config.node } : {}),\n ...(this._config.wellKnown !== undefined\n ? { wellKnown: this._config.wellKnown }\n : {}),\n });\n if (!result.ok) return result;\n return encOk(result.data.descriptor);\n }\n\n async encryptToNetwork(\n networkId: string,\n plaintext: Uint8Array,\n options?: EncryptToNetworkOptions,\n ): Promise<Result<InlineEncryptedEnvelope, EncryptionError>> {\n try {\n const discovered = await this.discoverNetwork(networkId);\n if (!discovered.ok) return discovered;\n const usable = ensureNetworkUsableForDecrypt(discovered.data);\n // For encryption we tolerate \"rotating\" but reject revoked/failed/pending —\n // ensureNetworkUsableForDecrypt enforces exactly that constraint.\n if (!usable.ok) return usable;\n\n const descriptor = usable.data;\n const networkPublicKey = base64Decode(descriptor.publicEncryptionKey);\n const result = encryptToNetworkFn(this.crypto, {\n networkId,\n networkPublicKey,\n plaintext,\n ...(options?.aad !== undefined ? { aad: options.aad } : {}),\n alg: options?.alg ?? descriptor.alg,\n keyVersion: options?.keyVersion ?? descriptor.keyVersion,\n ...(options?.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n return encOk(result.envelope);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n }\n\n async decryptEnvelope(\n envelope: InlineEncryptedEnvelope,\n capabilityProof: DecryptCapabilityProof,\n options?: DecryptEnvelopeOptions,\n ): Promise<Result<Uint8Array, EncryptionError>> {\n try {\n const validated = validateEnvelope(this.crypto, envelope);\n if (!validated.ok) return validated;\n if (\n options?.aad !== undefined &&\n validated.data.aad !== base64Encode(options.aad)\n ) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"decryptEnvelope aad does not match the envelope\",\n }),\n );\n }\n\n let descriptor: NetworkDescriptor;\n if (options?.descriptor !== undefined) {\n descriptor = options.descriptor;\n } else {\n const discovered = await this.discoverNetwork(envelope.networkId);\n if (!discovered.ok) return discovered;\n descriptor = discovered.data;\n }\n const usable = ensureNetworkUsableForDecrypt(descriptor);\n if (!usable.ok) return usable;\n\n const targetNode =\n options?.targetNode ?? descriptor.members[0]?.nodeId;\n if (targetNode === undefined) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"no target node available from descriptor\",\n }),\n );\n }\n\n // Generate per-request receiver key. We use the random mode by\n // default; callers wanting deterministic derivation must wrap\n // this service directly.\n const receiverKey = generateRandomReceiverKey({ crypto: this.crypto });\n const receiverPublicKey = base64Encode(receiverKey.publicKey);\n const receiverPublicKeyHash = canonicalHashHex(\n this.crypto.sha256,\n receiverPublicKey,\n );\n\n const body: DecryptRequestBody = {\n type: DECRYPT_FACT_TYPE,\n targetNode,\n networkId: envelope.networkId,\n alg: envelope.alg,\n keyVersion: envelope.keyVersion,\n encryptedSymmetricKey: envelope.encryptedSymmetricKey,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey,\n receiverPublicKeyHash,\n };\n const canonicalRequest = buildCanonicalDecryptRequest({\n crypto: this.crypto,\n body,\n receiverPublicKey: receiverKey.publicKey,\n });\n const facts = buildDecryptFacts({\n crypto: this.crypto,\n body,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey: receiverKey.publicKey,\n canonicalBody: canonicalRequest.canonicalBody,\n });\n\n const built = await buildDecryptInvocation(this.crypto, this._config.signer, {\n targetNode,\n networkId: envelope.networkId,\n body,\n facts,\n proof: capabilityProof,\n });\n if (!built.ok) return built;\n\n let response: DecryptResponseBody;\n try {\n response = await this._config.transport.postDecrypt({\n targetNode,\n networkId: envelope.networkId,\n authorization: built.data.authorization,\n canonicalBody: built.data.canonicalBody,\n });\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n\n const verified = verifyDecryptResponse({\n crypto: this.crypto,\n request: body,\n facts,\n invocationCid: built.data.invocationCid,\n requestBodyHash: facts.bodyHash,\n response,\n });\n if (!verified.ok) return verified;\n\n const symmetricKey = openWrappedKey(\n this.crypto,\n receiverKey.privateKey,\n verified.data,\n );\n const plaintext = decryptEnvelopeWithKey(\n this.crypto,\n envelope,\n symmetricKey,\n );\n return encOk(plaintext);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n }\n}\n"],"mappings":"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","names":["ok","serviceError","errorText","valueDelResult","hexEncode","base64Encode","base64Decode","toError","err","crypto","base64Encode","err","base64Decode","hexEncode","crypto","err","crypto","hexEncode","base64Decode","base64Decode","toError","base64Encode"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/types.schema.ts","../src/context.ts","../src/errors.ts","../src/base/BaseService.ts","../src/kv/PrefixedKVService.ts","../src/kv/types.ts","../src/kv/KVService.ts","../src/sql/DatabaseHandle.ts","../src/sql/types.ts","../src/sql/SQLService.ts","../src/duckdb/DuckDbDatabaseHandle.ts","../src/duckdb/types.ts","../src/duckdb/DuckDbService.ts","../src/hooks/HooksService.ts","../src/quota/TinyCloudQuota.ts","../src/vault/types.ts","../src/vault/SignatureCache.ts","../src/vault/DataVaultService.ts","../src/vault/createVaultCrypto.ts","../src/secrets/paths.ts","../src/secrets/SecretsService.ts","../src/encryption/canonical.ts","../src/encryption/networkId.ts","../src/encryption/types.ts","../src/encryption/discovery.ts","../src/encryption/envelope.ts","../src/encryption/invocation.ts","../src/encryption/receiverKey.ts","../src/encryption/response.ts","../src/encryption/EncryptionService.ts"],"sourcesContent":["/**\n * SDK Services - Core Types\n *\n * These types define the service architecture for TinyCloud SDK.\n * Services use dependency injection via IServiceContext for platform independence.\n */\n\n// =============================================================================\n// Result Type Pattern\n// =============================================================================\n\n/**\n * Result type for service operations.\n * Services return Result instead of throwing, making error handling explicit.\n *\n * @template T - The success data type\n * @template E - The error type (defaults to ServiceError)\n *\n * @example\n * ```typescript\n * const result = await kv.get('key');\n * if (result.ok) {\n * console.log(result.data);\n * } else {\n * console.error(result.error.code);\n * }\n * ```\n */\nexport type Result<T, E = ServiceError> =\n | { ok: true; data: T }\n | { ok: false; error: E };\n\n/**\n * Service error with structured information.\n */\nexport interface ServiceError {\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: string;\n /** Human-readable error message */\n message: string;\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: string;\n /** Original error if this wraps another error */\n cause?: Error;\n /** Additional metadata about the error */\n meta?: Record<string, unknown>;\n}\n\n/**\n * Storage quota information returned with quota-related errors.\n */\nexport interface StorageQuotaInfo {\n usedBytes: number;\n limitBytes: number;\n service: string;\n}\n\n/**\n * Standard error codes used across services.\n */\nexport const ErrorCodes = {\n // Common errors\n NOT_FOUND: \"NOT_FOUND\",\n AUTH_EXPIRED: \"AUTH_EXPIRED\",\n AUTH_REQUIRED: \"AUTH_REQUIRED\",\n AUTH_UNAUTHORIZED: \"AUTH_UNAUTHORIZED\",\n NETWORK_ERROR: \"NETWORK_ERROR\",\n TIMEOUT: \"TIMEOUT\",\n ABORTED: \"ABORTED\",\n INVALID_INPUT: \"INVALID_INPUT\",\n PERMISSION_DENIED: \"PERMISSION_DENIED\",\n\n // KV-specific errors\n KV_NOT_FOUND: \"KV_NOT_FOUND\",\n KV_WRITE_FAILED: \"KV_WRITE_FAILED\",\n\n // SQL-specific errors\n SQL_ERROR: \"SQL_ERROR\",\n SQL_PERMISSION_DENIED: \"SQL_PERMISSION_DENIED\",\n SQL_DATABASE_NOT_FOUND: \"SQL_DATABASE_NOT_FOUND\",\n SQL_RESPONSE_TOO_LARGE: \"SQL_RESPONSE_TOO_LARGE\",\n SQL_QUOTA_EXCEEDED: \"SQL_QUOTA_EXCEEDED\",\n SQL_INVALID_STATEMENT: \"SQL_INVALID_STATEMENT\",\n SQL_SCHEMA_ERROR: \"SQL_SCHEMA_ERROR\",\n SQL_READONLY_VIOLATION: \"SQL_READONLY_VIOLATION\",\n\n // Storage quota errors\n STORAGE_QUOTA_EXCEEDED: \"STORAGE_QUOTA_EXCEEDED\",\n STORAGE_LIMIT_REACHED: \"STORAGE_LIMIT_REACHED\",\n\n // DuckDB-specific errors\n DUCKDB_ERROR: \"DUCKDB_ERROR\",\n DUCKDB_PERMISSION_DENIED: \"DUCKDB_PERMISSION_DENIED\",\n DUCKDB_DATABASE_NOT_FOUND: \"DUCKDB_DATABASE_NOT_FOUND\",\n DUCKDB_RESPONSE_TOO_LARGE: \"DUCKDB_RESPONSE_TOO_LARGE\",\n DUCKDB_QUOTA_EXCEEDED: \"DUCKDB_QUOTA_EXCEEDED\",\n DUCKDB_INVALID_STATEMENT: \"DUCKDB_INVALID_STATEMENT\",\n DUCKDB_SCHEMA_ERROR: \"DUCKDB_SCHEMA_ERROR\",\n DUCKDB_READONLY_VIOLATION: \"DUCKDB_READONLY_VIOLATION\",\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\n// =============================================================================\n// Service Session\n// =============================================================================\n\n/**\n * Session data required for authenticated service operations.\n * Both TinyCloudSession and web-sdk Session can be cast to this interface.\n */\nexport interface ServiceSession {\n /** The delegation header containing the UCAN */\n delegationHeader: { Authorization: string };\n /** The delegation CID */\n delegationCid: string;\n /** The space ID for this session */\n spaceId: string;\n /** The verification method DID */\n verificationMethod: string;\n /** The session key JWK (required for invoke) */\n jwk: object;\n}\n\n// =============================================================================\n// Platform Dependencies (Injected)\n// =============================================================================\n\n/**\n * Headers type - compatible with both browser and Node.js.\n */\nexport type ServiceHeaders = Record<string, string> | [string, string][];\n\n/**\n * A single fact object to include in the UCAN invocation.\n * Facts are key-value objects that the server reads from the UCAN facts field.\n */\nexport interface InvocationFact {\n [key: string]: unknown;\n}\n\n/**\n * Facts to include in the UCAN invocation.\n * This is an array of fact objects per the UCAN spec.\n * Used to pass additional parameters that the server reads from the UCAN facts field.\n */\nexport type InvocationFacts = InvocationFact[];\n\n/**\n * Invoke function signature - platform-specific implementation injected via DI.\n * Both node-sdk-wasm and web-sdk-wasm export this with identical signature.\n *\n * @param session - The service session with delegation data\n * @param service - Service name (e.g., \"kv\")\n * @param path - Resource path or key\n * @param action - Action to perform (e.g., \"tinycloud.kv/get\")\n * @param facts - Optional facts to include in the UCAN (e.g., for capabilities/read params)\n * @returns Headers to include in the request\n */\nexport type InvokeFunction = (\n session: ServiceSession,\n service: string,\n path: string,\n action: string,\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Multi-resource invocation entry.\n */\nexport interface InvokeAnyEntry {\n /**\n * Legacy space-scoped resource. Optional when `resource` is provided.\n */\n spaceId?: string;\n service: string;\n path: string;\n action: string;\n /** Optional raw resource URI. When set, WASM signs this URI directly. */\n resource?: string;\n}\n\n/**\n * Invoke function for minting a single authorization header that covers\n * multiple capabilities across one effective invoker.\n */\nexport type InvokeAnyFunction = (\n session: ServiceSession,\n entries: InvokeAnyEntry[],\n facts?: InvocationFacts,\n) => ServiceHeaders;\n\n/**\n * Fetch request options - compatible with standard fetch API.\n */\nexport interface FetchRequestInit {\n method?: string;\n headers?: ServiceHeaders;\n body?: Blob | FormData | string;\n signal?: AbortSignal;\n}\n\n/**\n * Fetch response interface - compatible with standard Response.\n */\nexport interface FetchResponse {\n ok: boolean;\n status: number;\n statusText: string;\n body?: unknown;\n headers: {\n get(name: string): string | null;\n };\n json(): Promise<unknown>;\n text(): Promise<string>;\n arrayBuffer(): Promise<ArrayBuffer>;\n blob(): Promise<Blob>;\n}\n\n/**\n * Fetch function signature - allows for custom fetch implementations.\n * Compatible with both browser fetch and Node.js fetch.\n */\nexport type FetchFunction = (\n url: string,\n init?: FetchRequestInit,\n) => Promise<FetchResponse>;\n\n// =============================================================================\n// Retry Policy\n// =============================================================================\n\n/**\n * Configuration for automatic retry of failed requests.\n */\nexport interface RetryPolicy {\n /** Maximum number of attempts (including initial) */\n maxAttempts: number;\n /** Backoff strategy between retries */\n backoff: \"none\" | \"linear\" | \"exponential\";\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: number;\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: number;\n /** Error codes that should trigger a retry */\n retryableErrors: string[];\n}\n\n/**\n * Default retry policy.\n */\nexport const defaultRetryPolicy: RetryPolicy = {\n maxAttempts: 3,\n backoff: \"exponential\",\n baseDelayMs: 1000,\n maxDelayMs: 10000,\n retryableErrors: [ErrorCodes.NETWORK_ERROR, ErrorCodes.TIMEOUT],\n};\n\n// =============================================================================\n// Service Context\n// =============================================================================\n\n/**\n * Event handler function type.\n */\nexport type EventHandler = (data: unknown) => void;\n\n/**\n * SDK telemetry event handler.\n */\nexport type TelemetryEventHandler = (event: string, data: unknown) => void;\n\n/**\n * Default-off telemetry configuration.\n */\nexport type TelemetryConfig =\n | boolean\n | {\n enabled?: boolean;\n onEvent?: TelemetryEventHandler;\n };\n\n/**\n * Service interface - base contract for all services.\n */\nexport interface IService {\n /** Initialize service with context */\n initialize(context: IServiceContext): void;\n\n /** Called when session changes (sign-in, sign-out, refresh) */\n onSessionChange(session: ServiceSession | null): void;\n\n /** Called when SDK signs out - should abort pending operations */\n onSignOut(): void;\n\n /** Service-specific configuration */\n readonly config: Record<string, unknown>;\n}\n\n/**\n * Context provided to services for accessing platform dependencies.\n * The SDK creates this context and passes it to services during initialization.\n */\nexport interface IServiceContext {\n // Session management\n /** Current active session, or null if not authenticated */\n readonly session: ServiceSession | null;\n /** Whether there is an active authenticated session */\n readonly isAuthenticated: boolean;\n\n // Platform dependencies (injected by SDK)\n /** Platform-specific invoke function from WASM binding */\n readonly invoke: InvokeFunction;\n /** Optional multi-resource invoke function */\n readonly invokeAny?: InvokeAnyFunction;\n /** Fetch function (defaults to globalThis.fetch) */\n readonly fetch: FetchFunction;\n /** Available TinyCloud host URLs */\n readonly hosts: string[];\n\n // Cross-service access\n /** Get another registered service by name */\n getService<T extends IService>(name: string): T | undefined;\n\n // Telemetry/Events\n /** Emit a telemetry event */\n emit(event: string, data: unknown): void;\n /** Subscribe to events */\n on(event: string, handler: EventHandler): () => void;\n\n // Lifecycle\n /** Abort signal that fires when SDK signs out */\n readonly abortSignal: AbortSignal;\n\n // Retry policy\n /** Retry policy for failed requests */\n readonly retryPolicy: RetryPolicy;\n}\n\n// =============================================================================\n// Telemetry Events\n// =============================================================================\n\n/**\n * Event emitted before a service request.\n */\nexport interface ServiceRequestEvent {\n service: string;\n action: string;\n span?: string;\n key?: string;\n timestamp: number;\n}\n\n/**\n * Event emitted after a service response.\n */\nexport interface ServiceResponseEvent {\n service: string;\n action: string;\n span?: string;\n ok: boolean;\n duration: number;\n durationMs?: number;\n status?: number;\n}\n\n/**\n * Event emitted on service error.\n */\nexport interface ServiceErrorEvent {\n service: string;\n span?: string;\n error: ServiceError;\n}\n\n/**\n * Event emitted on retry attempt.\n */\nexport interface ServiceRetryEvent {\n service: string;\n attempt: number;\n maxAttempts: number;\n error: ServiceError;\n}\n\n/**\n * Generic named span event for aggregating operation timings.\n */\nexport interface TelemetrySpanEvent {\n span: string;\n ok: boolean;\n durationMs: number;\n service?: string;\n action?: string;\n status?: number;\n error?: ServiceError;\n}\n\n/**\n * Telemetry event names.\n */\nexport const TelemetryEvents = {\n SPAN: \"telemetry.span\",\n SERVICE_REQUEST: \"service.request\",\n SERVICE_RESPONSE: \"service.response\",\n SERVICE_ERROR: \"service.error\",\n SERVICE_RETRY: \"service.retry\",\n SESSION_CHANGED: \"session.changed\",\n SESSION_EXPIRED: \"session.expired\",\n} as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Create a success result.\n */\nexport function ok<T>(data: T): Result<T> {\n return { ok: true, data };\n}\n\n/**\n * Create an error result.\n */\nexport function err<E = ServiceError>(error: E): Result<never, E> {\n return { ok: false, error };\n}\n\n/**\n * Create a ServiceError.\n */\nexport function serviceError(\n code: string,\n message: string,\n service: string,\n options?: { cause?: Error; meta?: Record<string, unknown> },\n): ServiceError {\n return {\n code,\n message,\n service,\n cause: options?.cause,\n meta: options?.meta,\n };\n}\n","/**\n * Zod schemas for SDK Services API response types.\n *\n * This is the source of truth for service response types. TypeScript types\n * are derived from these schemas using z.infer<>.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\n\n// =============================================================================\n// Validation Error Type\n// =============================================================================\n\n/**\n * Validation error type for schema validation failures.\n */\nexport interface ValidationError {\n code: \"VALIDATION_ERROR\";\n message: string;\n service: string;\n meta?: {\n issues: z.ZodIssue[];\n path?: string;\n };\n}\n\n// =============================================================================\n// Service Error Schema\n// =============================================================================\n\n/**\n * Schema for service error with structured information.\n */\nexport const ServiceErrorSchema = z.object({\n /** Error code for programmatic handling (e.g., 'KV_NOT_FOUND', 'AUTH_EXPIRED') */\n code: z.string(),\n /** Human-readable error message */\n message: z.string(),\n /** Service that produced the error (e.g., 'kv', 'sql') */\n service: z.string(),\n /** Original error if this wraps another error - not validated since Error is a class */\n cause: z.unknown().optional(),\n /** Additional metadata about the error - passthrough allows any object properties */\n meta: z.object({}).passthrough().optional(),\n});\n\nexport type ServiceErrorType = z.infer<typeof ServiceErrorSchema>;\n\n// =============================================================================\n// Result Schema Factory\n// =============================================================================\n\n/**\n * Creates a Result schema for a given data type.\n * Result is a discriminated union: { ok: true, data: T } | { ok: false, error: E }\n *\n * @param dataSchema - Zod schema for the success data type\n * @param errorSchema - Zod schema for the error type (defaults to ServiceErrorSchema)\n * @returns A Zod schema for Result<T, E>\n *\n * @example\n * ```typescript\n * const KVGetResultSchema = createResultSchema(z.string());\n * type KVGetResult = z.infer<typeof KVGetResultSchema>;\n * ```\n */\nexport function createResultSchema<T extends z.ZodTypeAny, E extends z.ZodTypeAny>(\n dataSchema: T,\n errorSchema: E = ServiceErrorSchema as unknown as E\n) {\n return z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n data: dataSchema,\n }),\n z.object({\n ok: z.literal(false),\n error: errorSchema,\n }),\n ]);\n}\n\n/**\n * Pre-built Result schema with unknown data and ServiceError.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericResultSchema = createResultSchema(z.unknown(), ServiceErrorSchema);\n\n// =============================================================================\n// KV Response Schemas\n// =============================================================================\n\n/**\n * Schema for KV response headers metadata.\n * Note: The `get` method is a function and cannot be validated with Zod.\n * This schema validates the data properties only.\n */\nexport const KVResponseHeadersSchema = z.object({\n /** ETag for conditional requests */\n etag: z.string().optional(),\n /** Content type of the stored value */\n contentType: z.string().optional(),\n /** Last modification timestamp */\n lastModified: z.string().optional(),\n /** Content length in bytes */\n contentLength: z.number().optional(),\n});\n\nexport type KVResponseHeadersType = z.infer<typeof KVResponseHeadersSchema>;\n\n/**\n * Creates a KVResponse schema for a given data type.\n *\n * @param dataSchema - Zod schema for the data payload type\n * @returns A Zod schema for KVResponse<T>\n *\n * @example\n * ```typescript\n * const UserResponseSchema = createKVResponseSchema(UserSchema);\n * type UserResponse = z.infer<typeof UserResponseSchema>;\n * ```\n */\nexport function createKVResponseSchema<T extends z.ZodTypeAny>(dataSchema: T) {\n return z.object({\n /** The data payload */\n data: dataSchema,\n /** Response headers with metadata */\n headers: KVResponseHeadersSchema,\n });\n}\n\n/**\n * Generic KVResponse schema with unknown data.\n * Useful for generic validation before type narrowing.\n */\nexport const GenericKVResponseSchema = createKVResponseSchema(z.unknown());\n\nexport type GenericKVResponseType = z.infer<typeof GenericKVResponseSchema>;\n\n/**\n * Schema for KV list response.\n */\nexport const KVListResponseSchema = z.object({\n /** Array of keys matching the list criteria */\n keys: z.array(z.string()),\n});\n\nexport type KVListResponseType = z.infer<typeof KVListResponseSchema>;\n\n/**\n * Result schema for KV list operations.\n */\nexport const KVListResultSchema = createResultSchema(KVListResponseSchema);\n\nexport type KVListResultType = z.infer<typeof KVListResultSchema>;\n\n// =============================================================================\n// Telemetry Event Schemas\n// =============================================================================\n\n/**\n * Schema for service request event.\n */\nexport const ServiceRequestEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n span: z.string().optional(),\n key: z.string().optional(),\n timestamp: z.number(),\n});\n\nexport type ServiceRequestEventType = z.infer<typeof ServiceRequestEventSchema>;\n\n/**\n * Schema for service response event.\n */\nexport const ServiceResponseEventSchema = z.object({\n service: z.string(),\n action: z.string(),\n span: z.string().optional(),\n ok: z.boolean(),\n duration: z.number(),\n durationMs: z.number().optional(),\n status: z.number().optional(),\n});\n\nexport type ServiceResponseEventType = z.infer<typeof ServiceResponseEventSchema>;\n\n/**\n * Schema for service error event.\n */\nexport const ServiceErrorEventSchema = z.object({\n service: z.string(),\n span: z.string().optional(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceErrorEventType = z.infer<typeof ServiceErrorEventSchema>;\n\n/**\n * Schema for service retry event.\n */\nexport const ServiceRetryEventSchema = z.object({\n service: z.string(),\n attempt: z.number().int().positive(),\n maxAttempts: z.number().int().positive(),\n error: ServiceErrorSchema,\n});\n\nexport type ServiceRetryEventType = z.infer<typeof ServiceRetryEventSchema>;\n\n/**\n * Schema for generic named span event.\n */\nexport const TelemetrySpanEventSchema = z.object({\n span: z.string(),\n ok: z.boolean(),\n durationMs: z.number(),\n service: z.string().optional(),\n action: z.string().optional(),\n status: z.number().optional(),\n error: ServiceErrorSchema.optional(),\n});\n\nexport type TelemetrySpanEventType = z.infer<typeof TelemetrySpanEventSchema>;\n\n// =============================================================================\n// Retry Policy Schema\n// =============================================================================\n\n/**\n * Schema for retry policy configuration.\n */\nexport const RetryPolicySchema = z.object({\n /** Maximum number of attempts (including initial) */\n maxAttempts: z.number().int().positive(),\n /** Backoff strategy between retries */\n backoff: z.enum([\"none\", \"linear\", \"exponential\"]),\n /** Base delay in milliseconds for backoff calculation */\n baseDelayMs: z.number().nonnegative(),\n /** Maximum delay in milliseconds between retries */\n maxDelayMs: z.number().nonnegative(),\n /** Error codes that should trigger a retry */\n retryableErrors: z.array(z.string()),\n});\n\nexport type RetryPolicyType = z.infer<typeof RetryPolicySchema>;\n\n// =============================================================================\n// Service Session Schema\n// =============================================================================\n\n/**\n * Schema for service session data required for authenticated operations.\n */\nexport const ServiceSessionSchema = z.object({\n /** The delegation header containing the UCAN */\n delegationHeader: z.object({\n Authorization: z.string(),\n }),\n /** The delegation CID */\n delegationCid: z.string(),\n /** The space ID for this session */\n spaceId: z.string(),\n /** The verification method DID */\n verificationMethod: z.string(),\n /** The session key JWK (required for invoke) */\n jwk: z.object({}).passthrough(),\n});\n\nexport type ServiceSessionType = z.infer<typeof ServiceSessionSchema>;\n\n// =============================================================================\n// Validation Helpers\n// =============================================================================\n\n/**\n * Validate service error against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceError(\n data: unknown\n): { ok: true; data: ServiceErrorType } | { ok: false; error: ValidationError } {\n const result = ServiceErrorSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"validation\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV list response against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVListResponse(\n data: unknown\n): { ok: true; data: KVListResponseType } | { ok: false; error: ValidationError } {\n const result = KVListResponseSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate KV response headers against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateKVResponseHeaders(\n data: unknown\n): { ok: true; data: KVResponseHeadersType } | { ok: false; error: ValidationError } {\n const result = KVResponseHeadersSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"kv\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service session against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceSession(\n data: unknown\n): { ok: true; data: ServiceSessionType } | { ok: false; error: ValidationError } {\n const result = ServiceSessionSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"session\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate retry policy against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateRetryPolicy(\n data: unknown\n): { ok: true; data: RetryPolicyType } | { ok: false; error: ValidationError } {\n const result = RetryPolicySchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"config\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service request event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceRequestEvent(\n data: unknown\n): { ok: true; data: ServiceRequestEventType } | { ok: false; error: ValidationError } {\n const result = ServiceRequestEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate service response event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateServiceResponseEvent(\n data: unknown\n): { ok: true; data: ServiceResponseEventType } | { ok: false; error: ValidationError } {\n const result = ServiceResponseEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n\n/**\n * Validate named telemetry span event against the schema.\n *\n * @param data - Unknown data to validate\n * @returns Result with validated data or validation error\n */\nexport function validateTelemetrySpanEvent(\n data: unknown\n): { ok: true; data: TelemetrySpanEventType } | { ok: false; error: ValidationError } {\n const result = TelemetrySpanEventSchema.safeParse(data);\n if (!result.success) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: result.error.message,\n service: \"telemetry\",\n meta: { issues: result.error.issues },\n },\n };\n }\n return { ok: true, data: result.data };\n}\n","/**\n * ServiceContext implementation for TinyCloud SDK Services\n * @module @tinycloud/sdk-services\n */\n\nimport {\n IServiceContext,\n IService,\n ServiceSession,\n RetryPolicy,\n InvokeFunction,\n InvokeAnyFunction,\n FetchFunction,\n defaultRetryPolicy,\n EventHandler,\n TelemetryEventHandler,\n TelemetryConfig,\n} from \"./types\";\n\n/**\n * Configuration options for ServiceContext.\n */\nexport interface ServiceContextConfig {\n /** Function to invoke WASM operations */\n invoke: InvokeFunction;\n /** Optional function to mint a single authorization header for multiple capabilities */\n invokeAny?: InvokeAnyFunction;\n /** Function to make HTTP requests (defaults to globalThis.fetch) */\n fetch?: FetchFunction;\n /** List of TinyCloud host URLs */\n hosts: string[];\n /** Initial session (optional) */\n session?: ServiceSession | null;\n /** Retry policy configuration */\n retryPolicy?: Partial<RetryPolicy>;\n /** Default-off telemetry event delivery. */\n telemetry?: TelemetryConfig;\n}\n\n/**\n * ServiceContext provides platform dependencies and cross-service access to services.\n * This is the primary interface services use to interact with the SDK runtime.\n *\n * @example\n * ```typescript\n * const context = new ServiceContext({\n * invoke: wasmInvoke,\n * hosts: ['https://node.tinycloud.xyz'],\n * retryPolicy: { maxAttempts: 5 },\n * });\n *\n * // Register a service\n * const kvService = new KVService({});\n * context.registerService('kv', kvService);\n * kvService.initialize(context);\n *\n * // Update session when user signs in\n * context.setSession(userSession);\n * ```\n */\nexport class ServiceContext implements IServiceContext {\n private _session: ServiceSession | null = null;\n private _services: Map<string, IService> = new Map();\n private _eventHandlers: Map<string, Set<EventHandler>> = new Map();\n private _abortController: AbortController = new AbortController();\n private readonly _invoke: InvokeFunction;\n private readonly _invokeAny?: InvokeAnyFunction;\n private readonly _fetch: FetchFunction;\n private readonly _hosts: string[];\n private readonly _retryPolicy: RetryPolicy;\n private readonly _telemetryEnabled: boolean;\n private readonly _telemetryHandler?: TelemetryEventHandler;\n\n constructor(config: ServiceContextConfig) {\n this._invoke = config.invoke;\n this._invokeAny = config.invokeAny;\n this._fetch = config.fetch ?? globalThis.fetch.bind(globalThis);\n this._hosts = config.hosts;\n this._session = config.session ?? null;\n this._retryPolicy = {\n ...defaultRetryPolicy,\n ...config.retryPolicy,\n };\n this._telemetryEnabled =\n typeof config.telemetry === \"boolean\"\n ? config.telemetry\n : config.telemetry?.enabled === true;\n this._telemetryHandler =\n typeof config.telemetry === \"object\" ? config.telemetry.onEvent : undefined;\n }\n\n // ============================================================\n // Session Management\n // ============================================================\n\n /**\n * Get the current session.\n */\n get session(): ServiceSession | null {\n return this._session;\n }\n\n /**\n * Check if the context has an authenticated session.\n */\n get isAuthenticated(): boolean {\n return this._session !== null;\n }\n\n /**\n * Update the session and notify all registered services.\n *\n * @param session - New session or null to clear\n */\n setSession(session: ServiceSession | null): void {\n this._session = session;\n this.emit('session.changed', { authenticated: session !== null });\n\n // Notify all services of session change\n for (const service of this._services.values()) {\n service.onSessionChange(session);\n }\n }\n\n // ============================================================\n // Platform Dependencies\n // ============================================================\n\n /**\n * Get the invoke function for WASM operations.\n */\n get invoke(): InvokeFunction {\n return this._invoke;\n }\n\n /**\n * Get the multi-resource invoke function when available.\n */\n get invokeAny(): InvokeAnyFunction | undefined {\n return this._invokeAny;\n }\n\n /**\n * Get the fetch function for HTTP requests.\n */\n get fetch(): FetchFunction {\n return this._fetch;\n }\n\n /**\n * Get the list of TinyCloud host URLs.\n */\n get hosts(): string[] {\n return this._hosts;\n }\n\n // ============================================================\n // Service Registry\n // ============================================================\n\n /**\n * Register a service with the context.\n *\n * @param name - Service name (e.g., 'kv')\n * @param service - Service instance\n */\n registerService(name: string, service: IService): void {\n this._services.set(name, service);\n }\n\n /**\n * Unregister a service from the context.\n *\n * @param name - Service name to remove\n */\n unregisterService(name: string): void {\n this._services.delete(name);\n }\n\n /**\n * Get a registered service by name.\n *\n * @param name - Service name\n * @returns The service instance or undefined if not registered\n */\n getService<T extends IService>(name: string): T | undefined {\n return this._services.get(name) as T | undefined;\n }\n\n // ============================================================\n // Event System (Telemetry)\n // ============================================================\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n emit(event: string, data: unknown): void {\n if (this._telemetryEnabled && this._telemetryHandler) {\n try {\n this._telemetryHandler(event, data);\n } catch (error) {\n // Don't let telemetry handlers break SDK operations.\n console.error(`Error in telemetry handler for \"${event}\":`, error);\n }\n }\n\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n // Don't let event handler errors break the flow\n console.error(`Error in event handler for \"${event}\":`, error);\n }\n }\n }\n }\n\n /**\n * Subscribe to telemetry events.\n *\n * @param event - Event name to subscribe to\n * @param handler - Handler function\n * @returns Unsubscribe function\n */\n on(event: string, handler: EventHandler): () => void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n\n // Return unsubscribe function\n return () => {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this._eventHandlers.delete(event);\n }\n }\n };\n }\n\n /**\n * Remove all event handlers for an event.\n *\n * @param event - Event name (if omitted, clears all events)\n */\n clearEventHandlers(event?: string): void {\n if (event) {\n this._eventHandlers.delete(event);\n } else {\n this._eventHandlers.clear();\n }\n }\n\n // ============================================================\n // Lifecycle\n // ============================================================\n\n /**\n * Get the abort signal for cancelling operations.\n */\n get abortSignal(): AbortSignal {\n return this._abortController.signal;\n }\n\n /**\n * Abort all pending operations and notify services.\n * Creates a new AbortController for future operations.\n */\n abort(): void {\n this._abortController.abort();\n this._abortController = new AbortController();\n\n // Notify all services\n for (const service of this._services.values()) {\n service.onSignOut();\n }\n }\n\n /**\n * Sign out - abort operations and clear session.\n */\n signOut(): void {\n this.abort();\n this.setSession(null);\n this.emit('session.expired', {});\n }\n\n // ============================================================\n // Retry Policy\n // ============================================================\n\n /**\n * Get the retry policy configuration.\n */\n get retryPolicy(): RetryPolicy {\n return this._retryPolicy;\n }\n}\n","/**\n * SDK Services - Error Utilities\n *\n * Utilities for creating and handling service errors.\n */\n\nimport { ServiceError, ErrorCodes, err, serviceError } from \"./types\";\n\n/**\n * Create a service error for authentication required.\n */\nexport function authRequiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_REQUIRED,\n message: \"Authentication required. Please sign in first.\",\n service,\n };\n}\n\n/**\n * Create a service error for expired authentication.\n */\nexport function authExpiredError(service: string): ServiceError {\n return {\n code: ErrorCodes.AUTH_EXPIRED,\n message: \"Session has expired. Please sign in again.\",\n service,\n };\n}\n\n/**\n * Create a service error for network issues.\n */\nexport function networkError(\n service: string,\n message: string,\n cause?: Error\n): ServiceError {\n return {\n code: ErrorCodes.NETWORK_ERROR,\n message,\n service,\n cause,\n };\n}\n\n/**\n * Create a service error for timeouts.\n */\nexport function timeoutError(service: string): ServiceError {\n return {\n code: ErrorCodes.TIMEOUT,\n message: \"Request timed out.\",\n service,\n };\n}\n\n/**\n * Create a service error for aborted requests.\n */\nexport function abortedError(service: string): ServiceError {\n return {\n code: ErrorCodes.ABORTED,\n message: \"Request was aborted.\",\n service,\n };\n}\n\n/**\n * Create a service error for not found resources.\n */\nexport function notFoundError(\n service: string,\n resource: string\n): ServiceError {\n return {\n code: ErrorCodes.NOT_FOUND,\n message: `Resource not found: ${resource}`,\n service,\n };\n}\n\n/**\n * Create a service error for permission denied.\n */\nexport function permissionDeniedError(\n service: string,\n action: string\n): ServiceError {\n return {\n code: ErrorCodes.PERMISSION_DENIED,\n message: `Permission denied for action: ${action}`,\n service,\n };\n}\n\n/**\n * Parse the server's \"Unauthorized Action: {resource} / {ability}\" pattern.\n */\nexport function parseAuthError(responseText: string): { resource?: string; action?: string } {\n const match = responseText.match(/^Unauthorized Action:\\s*(.+?)\\s*\\/\\s*(tinycloud\\.\\S+)$/m);\n if (match) {\n return { resource: match[1].trim(), action: match[2].trim() };\n }\n return {};\n}\n\n/**\n * Create a service error for unauthorized action (missing capability).\n */\nexport function authUnauthorizedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return serviceError(ErrorCodes.AUTH_UNAUTHORIZED, message, service, { meta });\n}\n\n/**\n * Create a service error for storage quota exceeded (402 Payment Required).\n */\nexport function storageQuotaExceededError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_QUOTA_EXCEEDED,\n message,\n service,\n meta,\n };\n}\n\n/**\n * Create a service error for storage limit reached (413 Payload Too Large).\n */\nexport function storageLimitReachedError(\n service: string,\n message: string,\n meta?: Record<string, unknown>\n): ServiceError {\n return {\n code: ErrorCodes.STORAGE_LIMIT_REACHED,\n message,\n service,\n meta,\n };\n}\n\n/**\n * Wrap an unknown error in a ServiceError.\n */\nexport function wrapError(\n service: string,\n error: unknown,\n defaultCode: string = ErrorCodes.NETWORK_ERROR\n): ServiceError {\n if (error instanceof Error) {\n // Check for abort errors\n if (error.name === \"AbortError\") {\n return abortedError(service);\n }\n\n // Check for timeout errors (varies by platform)\n if (\n error.name === \"TimeoutError\" ||\n error.message.toLowerCase().includes(\"timeout\")\n ) {\n return timeoutError(service);\n }\n\n return {\n code: defaultCode,\n message: error.message,\n service,\n cause: error,\n };\n }\n\n return {\n code: defaultCode,\n message: String(error),\n service,\n };\n}\n\n/**\n * Create an error Result from a ServiceError.\n */\nexport function errorResult(error: ServiceError) {\n return err(error);\n}\n","/**\n * BaseService - Abstract base class for all TinyCloud services.\n *\n * Provides common functionality:\n * - Context management\n * - Session lifecycle hooks\n * - Abort signal handling\n * - Telemetry emission\n */\n\nimport {\n IService,\n IServiceContext,\n ServiceSession,\n ServiceError,\n TelemetryEvents,\n err,\n Result,\n} from \"../types\";\nimport { authRequiredError, wrapError } from \"../errors\";\n\n/**\n * Abstract base class for TinyCloud services.\n *\n * Services extend this class to get common functionality like\n * context management, session lifecycle, and abort handling.\n *\n * @example\n * ```typescript\n * class MyService extends BaseService implements IMyService {\n * static readonly serviceName = 'myservice';\n *\n * constructor(config: MyServiceConfig = {}) {\n * super();\n * this._config = config;\n * }\n *\n * async doSomething(): Promise<Result<Data>> {\n * if (!this.requireAuth()) {\n * return err(authRequiredError('myservice'));\n * }\n * // ... implementation\n * }\n * }\n * ```\n */\nexport abstract class BaseService implements IService {\n /**\n * Service identifier used for registration.\n * Must be overridden by subclasses.\n */\n static readonly serviceName: string;\n\n /**\n * Service context providing access to platform dependencies.\n * Set during initialize().\n */\n protected context!: IServiceContext;\n\n /**\n * Abort controller for this service's operations.\n * Reset on sign-out.\n */\n protected abortController: AbortController = new AbortController();\n\n /**\n * Service-specific configuration.\n */\n protected _config: Record<string, unknown> = {};\n\n /**\n * Get the service configuration.\n */\n get config(): Record<string, unknown> {\n return this._config;\n }\n\n /**\n * Initialize the service with context.\n * Called by the SDK after instantiation.\n *\n * @param context - The service context\n */\n initialize(context: IServiceContext): void {\n this.context = context;\n }\n\n /**\n * Called when session changes (sign-in, sign-out, refresh).\n * Override in subclasses to handle session changes.\n *\n * @param session - The new session, or null if signed out\n */\n onSessionChange(session: ServiceSession | null): void {\n // Override in subclass if needed\n }\n\n /**\n * Called when SDK signs out.\n * Aborts all pending operations.\n */\n onSignOut(): void {\n this.abortController.abort();\n this.abortController = new AbortController();\n }\n\n /**\n * Get the abort signal for this service.\n * Combines the service-level abort with context-level abort.\n */\n protected get abortSignal(): AbortSignal {\n return this.abortController.signal;\n }\n\n /**\n * Check if the service is authenticated.\n */\n protected get isAuthenticated(): boolean {\n return this.context?.isAuthenticated ?? false;\n }\n\n /**\n * Get the current session.\n * Throws if not authenticated.\n */\n protected get session(): ServiceSession {\n if (!this.context?.session) {\n throw new Error(\"Not authenticated\");\n }\n return this.context.session;\n }\n\n /**\n * Check authentication and return error result if not authenticated.\n * Use this at the start of methods that require authentication.\n *\n * @returns true if authenticated, false otherwise\n */\n protected requireAuth(): boolean {\n return this.isAuthenticated;\n }\n\n /**\n * Emit a telemetry event.\n *\n * @param event - Event name\n * @param data - Event data\n */\n protected emit(event: string, data: unknown): void {\n this.context?.emit(event, data);\n }\n\n /**\n * Emit a service request event.\n *\n * @param action - The action being performed\n * @param key - Optional key/path being accessed\n */\n protected emitRequest(action: string, key?: string): void {\n const service = this.getServiceName();\n this.emit(TelemetryEvents.SERVICE_REQUEST, {\n service,\n action,\n span: this.spanName(action),\n key,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Emit a service response event.\n *\n * @param action - The action that was performed\n * @param ok - Whether the request was successful\n * @param startTime - Start time for duration calculation\n * @param status - Optional HTTP status code\n */\n protected emitResponse(\n action: string,\n ok: boolean,\n startTime: number,\n status?: number\n ): void {\n const service = this.getServiceName();\n const durationMs = Date.now() - startTime;\n const span = this.spanName(action);\n this.emit(TelemetryEvents.SERVICE_RESPONSE, {\n service,\n action,\n span,\n ok,\n duration: durationMs,\n durationMs,\n status,\n });\n this.emit(TelemetryEvents.SPAN, {\n span,\n service,\n action,\n ok,\n durationMs,\n status,\n });\n }\n\n /**\n * Emit a service error event.\n *\n * @param error - The service error\n */\n protected emitError(error: ServiceError, action?: string): void {\n const span = action ? this.spanName(action) : undefined;\n this.emit(TelemetryEvents.SERVICE_ERROR, {\n service: this.getServiceName(),\n ...(span ? { span } : {}),\n error,\n });\n }\n\n /**\n * Get the service name from the static property.\n * Subclasses must define static serviceName.\n */\n protected getServiceName(): string {\n return (this.constructor as typeof BaseService).serviceName;\n }\n\n /**\n * Stable span name used by SDK telemetry sinks.\n */\n protected spanName(action: string): string {\n return `sdk.${this.getServiceName()}.${action}`;\n }\n\n /**\n * Create a combined abort signal from multiple sources.\n *\n * @param signals - Additional abort signals to combine\n * @returns A combined abort signal\n */\n protected combineSignals(...signals: (AbortSignal | undefined)[]): AbortSignal {\n const controller = new AbortController();\n const allSignals = [this.abortSignal, ...signals.filter(Boolean)] as AbortSignal[];\n\n for (const signal of allSignals) {\n if (signal.aborted) {\n controller.abort(signal.reason);\n return controller.signal;\n }\n signal.addEventListener(\"abort\", () => controller.abort(signal.reason), {\n once: true,\n });\n }\n\n return controller.signal;\n }\n\n /**\n * Wrap an operation with error handling and telemetry.\n *\n * @param action - The action name for telemetry\n * @param key - Optional key for telemetry\n * @param operation - The operation to execute\n * @returns Result of the operation\n */\n protected async withTelemetry<T>(\n action: string,\n key: string | undefined,\n operation: () => Promise<Result<T>>\n ): Promise<Result<T>> {\n const startTime = Date.now();\n this.emitRequest(action, key);\n\n try {\n const result = await operation();\n\n if (result.ok) {\n this.emitResponse(action, true, startTime);\n } else {\n this.emitResponse(action, false, startTime);\n this.emitError(result.error, action);\n }\n\n return result;\n } catch (error) {\n const serviceError = wrapError(this.getServiceName(), error);\n this.emitResponse(action, false, startTime);\n this.emitError(serviceError, action);\n return err(serviceError);\n }\n }\n}\n","/**\n * PrefixedKVService - A prefix-scoped view of KVService.\n *\n * Provides key-value operations scoped to a specific prefix.\n * All operations automatically prefix keys, enabling app data isolation\n * within a shared space.\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n\nimport { Result } from \"../types\";\nimport {\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVListOptions,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVSignedReadUrlResponse,\n} from \"./types\";\n\n/**\n * Interface for prefixed KV operations.\n *\n * Provides the same operations as IKVService but scoped to a prefix.\n * Supports nested prefixes via withPrefix().\n */\nexport interface IPrefixedKVService {\n /**\n * The current prefix for this scoped view.\n */\n readonly prefix: string;\n\n /**\n * Get a value by key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to retrieve (will be prefixed)\n * @param options - Optional get configuration\n * @returns Result with the stored value and headers\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.get('settings.json');\n * // -> Reads from: /app.myapp.com/settings.json\n * ```\n */\n get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>>;\n\n /**\n * Store a value at a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to store under (will be prefixed)\n * @param value - The value to store\n * @param options - Optional put configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Stores at: /app.myapp.com/settings.json\n * ```\n */\n put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>>;\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>>;\n\n /**\n * List keys within this prefix.\n *\n * Returns keys that match the prefix, with keys returned relative\n * to the prefix when removePrefix is true (default for prefixed service).\n *\n * @param options - Optional list configuration\n * @returns Result with array of matching keys\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.list();\n * // -> Lists keys under: /app.myapp.com/*\n * // Returns: ['settings.json', 'data/user.json', ...]\n * ```\n */\n list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>>;\n\n /**\n * Delete a key.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to delete (will be prefixed)\n * @param options - Optional delete configuration\n * @returns Result indicating success/failure\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * await myApp.delete('old-settings.json');\n * // -> Deletes: /app.myapp.com/old-settings.json\n * ```\n */\n delete(key: string, options?: Omit<KVDeleteOptions, 'prefix'>): Promise<Result<void>>;\n\n /**\n * Get metadata for a key without retrieving the value.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to check (will be prefixed)\n * @param options - Optional head configuration\n * @returns Result with headers only\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const result = await myApp.head('large-file.bin');\n * // -> Gets metadata for: /app.myapp.com/large-file.bin\n * ```\n */\n head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n *\n * The key is automatically prefixed with this service's prefix.\n *\n * @param key - The key to expose via a signed read URL (will be prefixed)\n * @param options - Optional signed URL configuration\n * @returns Result with URL and expiry metadata\n */\n createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>>;\n\n /**\n * Create a nested prefix-scoped view.\n *\n * The subPrefix is appended to the current prefix.\n *\n * @param subPrefix - The sub-prefix to append\n * @returns A new PrefixedKVService with the combined prefix\n *\n * @example\n * ```typescript\n * const myApp = kv.withPrefix('/app.myapp.com');\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json');\n * // -> Reads from: /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(subPrefix: string): IPrefixedKVService;\n}\n\n/**\n * Interface for a KV service that supports prefix delegation.\n *\n * This is the subset of IKVService methods needed by PrefixedKVService.\n */\ninterface IKVServiceLike {\n get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>>;\n\n put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>>;\n\n batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>>;\n\n list(options?: KVListOptions): Promise<Result<KVListResponse>>;\n\n delete(key: string, options?: KVDeleteOptions): Promise<Result<void>>;\n\n head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;\n\n createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>>;\n}\n\n/**\n * PrefixedKVService - Implementation of prefix-scoped KV operations.\n *\n * This class wraps a KVService (or another PrefixedKVService) and\n * automatically prefixes all key operations with the configured prefix.\n *\n * ## Prefix Convention\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * // Create from KVService\n * const prefixed = new PrefixedKVService(kvService, '/app.myapp.com');\n *\n * // Or use the withPrefix factory method on KVService\n * const prefixed = kvService.withPrefix('/app.myapp.com');\n *\n * // All operations are automatically prefixed\n * await prefixed.put('settings.json', { theme: 'dark' });\n * await prefixed.get('settings.json');\n *\n * // Nested prefixes\n * const nested = prefixed.withPrefix('/settings');\n * await nested.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\nexport class PrefixedKVService implements IPrefixedKVService {\n /**\n * The underlying KV service.\n */\n private readonly _kv: IKVServiceLike;\n\n /**\n * The prefix for this scoped view.\n */\n private readonly _prefix: string;\n\n /**\n * Create a new PrefixedKVService.\n *\n * @param kv - The underlying KV service to delegate to\n * @param prefix - The prefix to apply to all operations\n */\n constructor(kv: IKVServiceLike, prefix: string) {\n this._kv = kv;\n // Normalize prefix: ensure it doesn't end with slash\n this._prefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n }\n\n /**\n * The current prefix for this scoped view.\n */\n get prefix(): string {\n return this._prefix;\n }\n\n /**\n * Compute the full key path by combining prefix and key.\n *\n * @param key - The key to prefix\n * @returns The full path including prefix\n */\n private getFullKey(key: string): string {\n // Handle keys that start with slash\n const normalizedKey = key.startsWith('/') ? key : `/${key}`;\n return `${this._prefix}${normalizedKey}`;\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: Omit<KVGetOptions, 'prefix'>\n ): Promise<Result<KVResponse<T>>> {\n const fullKey = this.getFullKey(key);\n // Use empty prefix override to use the full key as-is\n return this._kv.get<T>(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: Omit<KVPutOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.put(fullKey, value, { ...options, prefix: '' });\n }\n\n /**\n * Store multiple values within this prefix in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: Omit<KVBatchPutOptions, 'prefix'>\n ): Promise<Result<KVBatchPutResponse>> {\n return this._kv.batchPut(\n items.map((item) => ({\n ...item,\n key: this.getFullKey(item.key),\n })),\n { ...options, prefix: '' }\n );\n }\n\n /**\n * List keys within this prefix.\n */\n async list(options?: Omit<KVListOptions, 'prefix'>): Promise<Result<KVListResponse>> {\n // List uses the prefix directly, and by default removes the prefix from results\n const removePrefix = options?.removePrefix ?? true;\n return this._kv.list({\n ...options,\n prefix: this._prefix,\n removePrefix,\n });\n }\n\n /**\n * Delete a key.\n */\n async delete(key: string, options?: Omit<KVDeleteOptions, 'prefix'>): Promise<Result<void>> {\n const fullKey = this.getFullKey(key);\n return this._kv.delete(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: Omit<KVHeadOptions, 'prefix'>\n ): Promise<Result<KVResponse<void>>> {\n const fullKey = this.getFullKey(key);\n return this._kv.head(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>\n ): Promise<Result<KVSignedReadUrlResponse>> {\n const fullKey = this.getFullKey(key);\n return this._kv.createSignedReadUrl(fullKey, { ...options, prefix: '' });\n }\n\n /**\n * Create a nested prefix-scoped view.\n */\n withPrefix(subPrefix: string): IPrefixedKVService {\n // Normalize subPrefix\n const normalizedSubPrefix = subPrefix.startsWith('/')\n ? subPrefix\n : `/${subPrefix}`;\n const combinedPrefix = `${this._prefix}${normalizedSubPrefix}`;\n return new PrefixedKVService(this._kv, combinedPrefix);\n }\n}\n","/**\n * KV Service Types\n *\n * Type definitions for the KV (Key-Value) service operations.\n */\n\n/**\n * Configuration for KVService.\n */\nexport interface KVServiceConfig {\n /**\n * Default prefix for all keys.\n * Useful for namespacing data within a space.\n *\n * @example\n * ```typescript\n * const kv = new KVService({ prefix: 'myapp/settings' });\n * await kv.put('theme', 'dark'); // Stores at 'myapp/settings/theme'\n * ```\n */\n prefix?: string;\n\n /**\n * Default timeout in milliseconds for KV operations.\n * Overrides the context-level timeout if set.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for KV get operations.\n */\nexport interface KVGetOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Return raw response instead of parsed JSON.\n * When true, data will be the raw response text.\n */\n raw?: boolean;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV put operations.\n */\nexport interface KVPutOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Content type for the value.\n * Defaults to 'application/json' for objects.\n */\n contentType?: string;\n\n /**\n * Custom metadata headers to store with the value.\n */\n metadata?: Record<string, string>;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * One entry in a KV batch put request.\n */\nexport interface KVBatchPutItem {\n /**\n * The key to store under.\n */\n key: string;\n\n /**\n * The value to store.\n *\n * Objects are JSON stringified. Strings are stored as text. Binary values\n * should be supplied as Blob, ArrayBuffer, or Uint8Array.\n */\n value: unknown;\n\n /**\n * Content type for this item. Defaults to application/json for objects and\n * application/octet-stream for binary values.\n */\n contentType?: string;\n}\n\n/**\n * Options for KV batch put operations.\n */\nexport interface KVBatchPutOptions {\n /**\n * Override the default prefix for all entries in this batch.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response from KV batch put operations.\n */\nexport interface KVBatchPutResponse {\n /**\n * Keys successfully written by the batch.\n */\n written: string[];\n\n /**\n * Number of written keys.\n */\n count: number;\n}\n\n/**\n * Options for KV list operations.\n */\nexport interface KVListOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Additional path to append to the prefix.\n */\n path?: string;\n\n /**\n * Whether to remove the prefix from returned keys.\n * When true, keys are returned relative to the prefix.\n */\n removePrefix?: boolean;\n\n /**\n * Return raw response instead of parsed JSON.\n */\n raw?: boolean;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV delete operations.\n */\nexport interface KVDeleteOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for KV head (metadata) operations.\n */\nexport interface KVHeadOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Default lifetime for signed KV read URLs when a caller omits expiresInSeconds.\n * SDK duration defaults are stored in milliseconds; createSignedReadUrl converts\n * this to the node endpoint's ttl_seconds field.\n *\n * Keep this in sync with EXPIRY.SIGNED_READ_URL_MS in @tinycloud/sdk-core.\n * sdk-services cannot import sdk-core because sdk-core depends on sdk-services.\n */\nexport const DEFAULT_SIGNED_READ_URL_EXPIRY_MS = 5 * 60 * 1000;\n\n/**\n * Options for creating a signed KV read URL.\n */\nexport interface KVCreateSignedReadUrlOptions {\n /**\n * Override the default prefix for this operation.\n */\n prefix?: string;\n\n /**\n * Requested URL lifetime in seconds.\n * Defaults to {@link DEFAULT_SIGNED_READ_URL_EXPIRY_MS} converted to seconds.\n * The node may cap this by its configured maximum, the invocation expiry,\n * or the parent delegation expiry.\n */\n expiresInSeconds?: number;\n\n /**\n * Optional blake3 content hash to bind the signed URL to a specific object.\n */\n contentHash?: string;\n\n /**\n * Optional ETag to bind the signed URL to a specific object version.\n */\n etag?: string;\n\n /**\n * Custom timeout for this operation in milliseconds.\n */\n timeout?: number;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Response headers from KV operations.\n */\nexport interface KVResponseHeaders {\n /**\n * ETag for conditional requests.\n */\n etag?: string;\n\n /**\n * Content type of the stored value.\n */\n contentType?: string;\n\n /**\n * Last modification timestamp.\n */\n lastModified?: string;\n\n /**\n * Content length in bytes.\n */\n contentLength?: number;\n\n /**\n * Get a header value by name.\n * @param name - Header name (case-insensitive)\n */\n get(name: string): string | null;\n}\n\n/**\n * Response from KV get/put operations.\n *\n * @template T - Type of the data payload\n */\nexport interface KVResponse<T = unknown> {\n /**\n * The data payload.\n * For get: the stored value.\n * For put: undefined.\n */\n data: T;\n\n /**\n * Response headers with metadata.\n */\n headers: KVResponseHeaders;\n}\n\n/**\n * Response from KV list operations.\n */\nexport interface KVListResponse {\n /**\n * Array of keys matching the list criteria.\n */\n keys: string[];\n}\n\n/**\n * Response from signed KV read URL creation.\n */\nexport interface KVSignedReadUrlResponse {\n /**\n * Absolute URL suitable for passing to external readers.\n */\n url: string;\n\n /**\n * Opaque URL returned by tinycloud-node, usually relative to the node host.\n */\n relativeUrl: string;\n\n /**\n * Opaque signed KV ticket identifier.\n */\n ticketId: string;\n\n /**\n * Expiry timestamp as returned by tinycloud-node.\n */\n expiresAt: string;\n}\n\n/**\n * KV service action types.\n */\nexport const KVAction = {\n GET: \"tinycloud.kv/get\",\n PUT: \"tinycloud.kv/put\",\n LIST: \"tinycloud.kv/list\",\n DELETE: \"tinycloud.kv/del\",\n HEAD: \"tinycloud.kv/metadata\",\n} as const;\n\nexport type KVActionType = (typeof KVAction)[keyof typeof KVAction];\n","/**\n * KVService - Key-Value storage service implementation.\n *\n * Platform-agnostic KV service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n FetchResponse,\n ServiceHeaders,\n} from \"../types\";\nimport {\n authRequiredError,\n wrapError,\n storageQuotaExceededError,\n storageLimitReachedError,\n parseAuthError,\n authUnauthorizedError,\n} from \"../errors\";\nimport { IKVService } from \"./IKVService\";\nimport { PrefixedKVService, IPrefixedKVService } from \"./PrefixedKVService\";\nimport {\n DEFAULT_SIGNED_READ_URL_EXPIRY_MS,\n KVServiceConfig,\n KVGetOptions,\n KVPutOptions,\n KVBatchPutItem,\n KVBatchPutOptions,\n KVBatchPutResponse,\n KVListOptions,\n KVDeleteOptions,\n KVHeadOptions,\n KVCreateSignedReadUrlOptions,\n KVResponse,\n KVListResponse,\n KVResponseHeaders,\n KVSignedReadUrlResponse,\n KVAction,\n} from \"./types\";\n\ninterface SignedKvUrlNodeResponse {\n url: string;\n ticketId: string;\n expiresAt: string;\n}\n\nfunction encodeKvBatchPartName(path: string): string {\n return encodeURIComponent(path).replace(/[!'()*]/g, (char) =>\n `%${char.charCodeAt(0).toString(16).toUpperCase()}`\n );\n}\n\n/**\n * KV service implementation.\n *\n * Provides key-value storage operations using TinyCloud's KV API.\n * Uses the Result type pattern for explicit error handling.\n *\n * @example\n * ```typescript\n * // Register with SDK\n * const sdk = new TinyCloud({\n * services: { kv: KVService },\n * serviceConfigs: { kv: { prefix: 'myapp' } },\n * });\n *\n * // Use the service\n * const result = await sdk.kv.get('settings');\n * if (result.ok) {\n * console.log(result.data.data);\n * }\n * ```\n */\nexport class KVService extends BaseService implements IKVService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"kv\";\n\n /**\n * Service configuration.\n */\n declare protected _config: KVServiceConfig;\n\n /**\n * Create a new KVService instance.\n *\n * @param config - Service configuration\n */\n constructor(config: KVServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): KVServiceConfig {\n return this._config;\n }\n\n // Parses \"Used: X bytes, Limit: Y bytes\" from tinycloud-node error responses\n private parseQuotaInfo(\n errorText: string\n ): { usedBytes: number; limitBytes: number } | undefined {\n const match = errorText.match(\n /Used:\\s*(\\d+)\\s*bytes,\\s*Limit:\\s*(\\d+)\\s*bytes/i\n );\n if (match) {\n return {\n usedBytes: parseInt(match[1], 10),\n limitBytes: parseInt(match[2], 10),\n };\n }\n return undefined;\n }\n\n private handleQuotaErrorResponse(\n response: FetchResponse,\n errorText: string,\n key: string\n ): Result<never> | undefined {\n if (response.status === 402) {\n const quotaInfo = this.parseQuotaInfo(errorText);\n return err(\n storageQuotaExceededError(\n \"kv\",\n `Storage quota exceeded for key \"${key}\": ${errorText}`,\n {\n status: response.status,\n ...(quotaInfo\n ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes }\n : {}),\n }\n )\n );\n }\n\n if (response.status === 413) {\n const quotaInfo = this.parseQuotaInfo(errorText);\n return err(\n storageLimitReachedError(\n \"kv\",\n `Storage limit reached for key \"${key}\": ${errorText}`,\n {\n status: response.status,\n ...(quotaInfo\n ? { usedBytes: quotaInfo.usedBytes, limitBytes: quotaInfo.limitBytes }\n : {}),\n }\n )\n );\n }\n\n return undefined;\n }\n\n /**\n * Get the full path with optional prefix.\n *\n * @param key - The key\n * @param prefixOverride - Optional prefix override\n * @returns The full path\n */\n private getFullPath(key: string, prefixOverride?: string): string {\n const prefix = prefixOverride ?? this._config.prefix ?? \"\";\n return prefix ? `${prefix}/${key}` : key;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.context.hosts[0];\n }\n\n private withJsonContentType(headers: ServiceHeaders): ServiceHeaders {\n if (Array.isArray(headers)) {\n return [...headers, [\"content-type\", \"application/json\"]];\n }\n\n return {\n ...headers,\n \"content-type\": \"application/json\",\n };\n }\n\n /**\n * Execute an invoke operation.\n *\n * @param path - Resource path\n * @param action - KV action\n * @param body - Optional request body\n * @param signal - Optional abort signal\n * @returns Fetch response\n */\n private async invokeOperation(\n path: string,\n action: string,\n body?: Blob | string,\n signal?: AbortSignal\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n action\n );\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body,\n signal: this.combineSignals(signal),\n });\n }\n\n private serializeBatchPutValue(item: KVBatchPutItem): Blob {\n const contentType = item.contentType;\n\n if (item.value instanceof Blob) {\n if (!contentType || item.value.type === contentType) {\n return item.value;\n }\n return new Blob([item.value], { type: contentType });\n }\n\n if (item.value instanceof ArrayBuffer) {\n return new Blob([item.value], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (ArrayBuffer.isView(item.value)) {\n const value = item.value;\n const bytes = new Uint8Array(value.byteLength);\n bytes.set(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));\n return new Blob([bytes], {\n type: contentType ?? \"application/octet-stream\",\n });\n }\n\n if (typeof item.value === \"string\") {\n return new Blob([item.value], {\n type: contentType ?? \"text/plain;charset=UTF-8\",\n });\n }\n\n const json = JSON.stringify(item.value);\n if (json === undefined) {\n throw new Error(`Cannot JSON serialize KV batch value for key \"${item.key}\"`);\n }\n\n return new Blob([json], {\n type: contentType ?? \"application/json\",\n });\n }\n\n private normalizeBatchPutResponse(data: unknown): KVBatchPutResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<KVBatchPutResponse>;\n if (\n !Array.isArray(response.written) ||\n !response.written.every((key) => typeof key === \"string\") ||\n typeof response.count !== \"number\"\n ) {\n return undefined;\n }\n\n return {\n written: response.written,\n count: response.count,\n };\n }\n\n /**\n * Create KVResponseHeaders from fetch response headers.\n *\n * @param headers - Fetch response headers\n * @returns KVResponseHeaders object\n */\n private createResponseHeaders(headers: {\n get(name: string): string | null;\n }): KVResponseHeaders {\n return {\n etag: headers.get(\"etag\") ?? undefined,\n contentType: headers.get(\"content-type\") ?? undefined,\n lastModified: headers.get(\"last-modified\") ?? undefined,\n contentLength: headers.get(\"content-length\")\n ? parseInt(headers.get(\"content-length\")!, 10)\n : undefined,\n get: (name: string) => headers.get(name),\n };\n }\n\n /**\n * Parse response body based on content type.\n *\n * @param response - Fetch response\n * @param raw - Whether to return raw text\n * @returns Parsed data\n */\n private async parseResponse<T>(\n response: FetchResponse,\n raw: boolean = false\n ): Promise<T | undefined> {\n if (!response.ok) {\n return undefined;\n }\n\n if (raw) {\n return (await response.text()) as unknown as T;\n }\n\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n return (await response.json()) as T;\n } else if (contentType?.startsWith(\"text/\")) {\n return (await response.text()) as unknown as T;\n }\n\n // No content-type header - try to parse as JSON, fall back to text\n const text = await response.text();\n if (!text) {\n return undefined;\n }\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n }\n\n private async createSignedReadUrlError(\n response: FetchResponse,\n key: string\n ): Promise<Result<never>> {\n let errorText = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n errorText = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n\n if (response.status === 401 || response.status === 403) {\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const code =\n response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;\n return err(\n serviceError(\n code,\n `Failed to create signed read URL for key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n private normalizeSignedReadUrlResponse(\n data: unknown\n ): KVSignedReadUrlResponse | undefined {\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n\n const response = data as Partial<SignedKvUrlNodeResponse>;\n if (\n typeof response.url !== \"string\" ||\n typeof response.ticketId !== \"string\" ||\n typeof response.expiresAt !== \"string\"\n ) {\n return undefined;\n }\n\n return {\n url: new URL(response.url, this.host).toString(),\n relativeUrl: response.url,\n ticketId: response.ticketId,\n expiresAt: response.expiresAt,\n };\n }\n\n /**\n * Get a value by key.\n */\n async get<T = unknown>(\n key: string,\n options?: KVGetOptions\n ): Promise<Result<KVResponse<T>>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.GET,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `Key not found: ${key}`,\n \"kv\"\n )\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n const data = await this.parseResponse<T>(response, options?.raw);\n return ok({\n data: data as T,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Store a value at a key.\n */\n async put(\n key: string,\n value: unknown,\n options?: KVPutOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n // Serialize value to string\n let body: string;\n if (typeof value === \"string\") {\n body = value;\n } else {\n body = JSON.stringify(value);\n }\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.PUT,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const errorText = await response.text();\n\n // Check for storage quota errors (402, 413)\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n key\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to put key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Store multiple values in one TinyCloud KV invocation.\n */\n async batchPut(\n items: KVBatchPutItem[],\n options?: KVBatchPutOptions\n ): Promise<Result<KVBatchPutResponse>> {\n return this.withTelemetry(\"batchPut\", String(items.length), async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n if (items.length === 0) {\n return ok({ written: [], count: 0 });\n }\n\n if (!this.context.invokeAny) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"KV batchPut requires SDK runtime support for multi-resource invocations\",\n \"kv\"\n )\n );\n }\n\n const session = this.context.session!;\n const paths = items.map((item) => this.getFullPath(item.key, options?.prefix));\n const seen = new Set<string>();\n for (const path of paths) {\n if (seen.has(path)) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n `KV batchPut received duplicate key after prefix resolution: ${path}`,\n \"kv\"\n )\n );\n }\n seen.add(path);\n }\n\n try {\n const body = new FormData();\n for (let index = 0; index < items.length; index++) {\n body.append(\n encodeKvBatchPartName(paths[index]!),\n this.serializeBatchPutValue(items[index]!)\n );\n }\n\n const headers = this.context.invokeAny(\n session,\n paths.map((path) => ({\n spaceId: session.spaceId,\n service: \"kv\",\n path,\n action: KVAction.PUT,\n }))\n );\n\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers,\n body,\n signal: this.combineSignals(options?.signal),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n\n if (response.status === 401 || response.status === 403) {\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const quotaError = this.handleQuotaErrorResponse(\n response,\n errorText,\n \"batch\"\n );\n if (quotaError) {\n return quotaError;\n }\n\n return err(\n serviceError(\n ErrorCodes.KV_WRITE_FAILED,\n `Failed to batch put ${items.length} key(s): ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n const batchResponse = this.normalizeBatchPutResponse(await response.json());\n if (!batchResponse || batchResponse.count !== batchResponse.written.length) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"KV batchPut response did not include matching written keys and count\",\n \"kv\"\n )\n );\n }\n\n return ok(batchResponse);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * List keys with optional prefix filtering.\n */\n async list(options?: KVListOptions): Promise<Result<KVListResponse>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n // Build the path from prefix and optional path\n let listPath = options?.prefix ?? this._config.prefix ?? \"\";\n if (options?.path) {\n listPath = listPath ? `${listPath}/${options.path}` : options.path;\n }\n\n try {\n const response = await this.invokeOperation(\n listPath,\n KVAction.LIST,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to list keys: ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n let keys = await this.parseResponse<string[]>(response, options?.raw);\n keys = keys ?? [];\n\n // Optionally remove prefix from keys\n if (options?.removePrefix && listPath) {\n const prefixWithSlash = listPath.endsWith(\"/\")\n ? listPath\n : `${listPath}/`;\n keys = keys.map((key) =>\n key.startsWith(prefixWithSlash)\n ? key.slice(prefixWithSlash.length)\n : key\n );\n }\n\n return ok({ keys });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Delete a key.\n */\n async delete(key: string, options?: KVDeleteOptions): Promise<Result<void>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.DELETE,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `Key not found: ${key}`,\n \"kv\"\n )\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to delete key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Get metadata for a key without retrieving the value.\n */\n async head(\n key: string,\n options?: KVHeadOptions\n ): Promise<Result<KVResponse<void>>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n\n try {\n const response = await this.invokeOperation(\n path,\n KVAction.HEAD,\n undefined,\n options?.signal\n );\n\n if (!response.ok) {\n if (response.status === 401) {\n const errorText = await response.text();\n const { resource, action } = parseAuthError(errorText);\n return err(authUnauthorizedError(\"kv\", errorText, {\n status: response.status,\n ...(action && { requiredAction: action }),\n ...(resource && { resource }),\n }));\n }\n\n if (response.status === 404) {\n return err(\n serviceError(\n ErrorCodes.KV_NOT_FOUND,\n `Key not found: ${key}`,\n \"kv\"\n )\n );\n }\n\n const errorText = await response.text();\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n `Failed to get metadata for key \"${key}\": ${response.status} - ${errorText}`,\n \"kv\",\n { meta: { status: response.status, statusText: response.statusText } }\n )\n );\n }\n\n return ok({\n data: undefined as void,\n headers: this.createResponseHeaders(response.headers),\n });\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Create a short-lived signed URL for reading a KV object.\n */\n async createSignedReadUrl(\n key: string,\n options?: KVCreateSignedReadUrlOptions\n ): Promise<Result<KVSignedReadUrlResponse>> {\n return this.withTelemetry(\"createSignedReadUrl\", key, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"kv\"));\n }\n\n const path = this.getFullPath(key, options?.prefix);\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"kv\",\n path,\n KVAction.GET\n );\n\n const body: {\n space: string;\n path: string;\n ttl_seconds: number;\n content_hash?: string;\n etag?: string;\n } = {\n space: session.spaceId,\n path,\n ttl_seconds:\n options?.expiresInSeconds ??\n Math.ceil(DEFAULT_SIGNED_READ_URL_EXPIRY_MS / 1000),\n };\n\n if (options?.contentHash !== undefined) {\n body.content_hash = options.contentHash;\n }\n if (options?.etag !== undefined) {\n body.etag = options.etag;\n }\n\n try {\n const response = await this.context.fetch(`${this.host}/signed/kv`, {\n method: \"POST\",\n headers: this.withJsonContentType(headers),\n body: JSON.stringify(body),\n signal: this.combineSignals(options?.signal),\n });\n\n if (!response.ok) {\n return this.createSignedReadUrlError(response, key);\n }\n\n const signedUrl = this.normalizeSignedReadUrlResponse(\n await response.json()\n );\n if (!signedUrl) {\n return err(\n serviceError(\n ErrorCodes.NETWORK_ERROR,\n \"Signed read URL response did not include url, ticketId, and expiresAt\",\n \"kv\"\n )\n );\n }\n\n return ok(signedUrl);\n } catch (error) {\n return err(wrapError(\"kv\", error));\n }\n });\n }\n\n /**\n * Create a prefix-scoped view of this KV service.\n *\n * Returns a PrefixedKVService that automatically prefixes all\n * key operations with the specified prefix. This enables apps\n * to isolate their data within a shared space.\n *\n * @param prefix - The prefix to apply to all operations\n * @returns A PrefixedKVService scoped to the prefix\n *\n * ## Prefix Conventions\n *\n * | Pattern | Use Case | Example |\n * | -- | -- | -- |\n * | `/app.{domain}/` | App-private data | `/app.photos.xyz/settings.json` |\n * | `/{type}/` | Shared data type | `/photos/vacation.jpg` |\n * | `/.{name}/` | Hidden/system data | `/.cache/thumbnails/` |\n * | `/public/` | Explicitly shareable | `/public/profile.json` |\n *\n * @example\n * ```typescript\n * const space = sdk.space('default');\n *\n * // Create prefix-scoped views\n * const myApp = space.kv.withPrefix('/app.myapp.com');\n * const sharedPhotos = space.kv.withPrefix('/photos');\n *\n * // Operations are automatically prefixed\n * await myApp.put('settings.json', { theme: 'dark' });\n * // -> Actually writes to: /app.myapp.com/settings.json\n *\n * await myApp.get('settings.json');\n * // -> Actually reads from: /app.myapp.com/settings.json\n *\n * await sharedPhotos.list();\n * // -> Lists: /photos/*\n *\n * // Nested prefixes\n * const settings = myApp.withPrefix('/settings');\n * await settings.get('theme.json'); // -> /app.myapp.com/settings/theme.json\n * ```\n */\n withPrefix(prefix: string): IPrefixedKVService {\n return new PrefixedKVService(this, prefix);\n }\n}\n","/**\n * DatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent SQLService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDatabaseHandle } from \"./ISQLService\";\nimport type { SQLService } from \"./SQLService\";\nimport type {\n SqlValue,\n SqlStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n} from \"./types\";\n\nexport class DatabaseHandle implements IDatabaseHandle {\n private service: SQLService;\n public readonly name: string;\n\n constructor(service: SQLService, name: string) {\n this.service = service;\n this.name = name;\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async export(options?: QueryOptions): Promise<Result<Blob>> {\n return this.service.exportDb(this.name, options);\n }\n}\n","/**\n * SQL Service Types\n *\n * Type definitions for the SQL service operations.\n */\n\n/**\n * Configuration for SQLService.\n */\nexport interface SQLServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Default timeout in milliseconds for SQL operations.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for SQL query operations.\n */\nexport interface QueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for SQL execute operations.\n */\nexport interface ExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for SQL batch operations.\n */\nexport interface BatchOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A SQL value: null, number, string, or binary data.\n */\nexport type SqlValue = null | number | string | Uint8Array;\n\n/**\n * A SQL statement with optional parameters.\n */\nexport interface SqlStatement {\n sql: string;\n params?: SqlValue[];\n}\n\n/**\n * Response from SQL query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from SQL execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n lastInsertRowId: number;\n}\n\n/**\n * Response from SQL batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * SQL service action types.\n */\nexport const SQLAction = {\n READ: \"tinycloud.sql/read\",\n WRITE: \"tinycloud.sql/write\",\n ADMIN: \"tinycloud.sql/admin\",\n SELECT: \"tinycloud.sql/select\",\n INSERT: \"tinycloud.sql/insert\",\n UPDATE: \"tinycloud.sql/update\",\n DELETE: \"tinycloud.sql/delete\",\n EXECUTE: \"tinycloud.sql/execute\",\n EXPORT: \"tinycloud.sql/export\",\n ALL: \"tinycloud.sql/*\",\n} as const;\n\nexport type SQLActionType = (typeof SQLAction)[keyof typeof SQLAction];\n","/**\n * SQLService - SQL database service implementation.\n *\n * Platform-agnostic SQL service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n} from \"../types\";\nimport { authRequiredError, wrapError, parseAuthError } from \"../errors\";\nimport type { ISQLService } from \"./ISQLService\";\nimport type { IDatabaseHandle } from \"./ISQLService\";\nimport { DatabaseHandle } from \"./DatabaseHandle\";\nimport {\n type SQLServiceConfig,\n type QueryOptions,\n type ExecuteOptions,\n type BatchOptions,\n type SqlValue,\n type SqlStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n SQLAction,\n} from \"./types\";\n\nexport class SQLService extends BaseService implements ISQLService {\n static readonly serviceName = \"sql\";\n\n declare protected _config: SQLServiceConfig;\n\n constructor(config: SQLServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): SQLServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDatabaseHandle {\n return new DatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database.\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n // === Internal methods called by DatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n this.actionForSql(sql, SQLAction.READ),\n { action: \"query\", sql, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\");\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: SqlValue[],\n options?: ExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: params ?? [],\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const response = await this.invokeSQL(\n dbName,\n this.actionForSql(sql, SQLAction.WRITE),\n body,\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\");\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: SqlStatement[],\n options?: BatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n this.actionForSqlBatch(statements),\n { action: \"batch\", statements },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\");\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: SqlValue[],\n options?: QueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n SQLAction.EXECUTE,\n { action: \"execute_statement\", name, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\");\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n async exportDb(\n dbName: string,\n options?: QueryOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"sql\"));\n }\n\n try {\n const response = await this.invokeSQL(\n dbName,\n SQLAction.EXPORT,\n { action: \"export\" },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\");\n }\n\n // FetchResponse doesn't expose blob(), so access it from the\n // underlying response which is a standard fetch Response at runtime\n const resp = response as any;\n if (typeof resp.blob === \"function\") {\n const blob = await resp.blob();\n return ok(blob as Blob);\n }\n // If blob() is not available, return the raw text as a Blob-like\n const text = await response.text();\n return ok(text as unknown as Blob);\n } catch (error) {\n return err(wrapError(\"sql\", error));\n }\n });\n }\n\n // === Private helpers ===\n\n private async invokeSQL(\n dbName: string,\n action: string,\n body: Record<string, unknown>,\n signal?: AbortSignal\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(session, \"sql\", dbName, action);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body) as any,\n signal: this.combineSignals(signal),\n });\n }\n\n private actionForSql(sql: string, fallback: string): string {\n return firstSqlToken(sql) === \"pragma\" ? SQLAction.ADMIN : fallback;\n }\n\n private actionForSqlBatch(statements: SqlStatement[]): string {\n return statements.some(\n (statement) => this.actionForSql(statement.sql, SQLAction.WRITE) === SQLAction.ADMIN,\n )\n ? SQLAction.ADMIN\n : SQLAction.WRITE;\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n\n let errorBody: { error?: string; message?: string; code?: string } = {};\n try {\n errorBody = JSON.parse(errorText);\n } catch {\n // Not JSON\n }\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message =\n errorBody.message ||\n `SQL ${operation} failed: ${response.status} - ${errorText}`;\n\n const meta: Record<string, unknown> = { status: response.status, statusText: response.statusText };\n\n if (response.status === 401) {\n const { resource, action } = parseAuthError(errorText);\n if (action) meta.requiredAction = action;\n if (resource) meta.resource = resource;\n }\n\n return err(\n serviceError(errorCode, message, \"sql\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.SQL_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"sql_readonly_violation\") {\n return ErrorCodes.SQL_READONLY_VIOLATION;\n }\n return ErrorCodes.SQL_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.SQL_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.SQL_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.SQL_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n\nfunction firstSqlToken(sql: string): string | undefined {\n let index = 0;\n\n while (index < sql.length) {\n while (index < sql.length && /\\s/.test(sql[index])) {\n index++;\n }\n\n if (sql.startsWith(\"--\", index)) {\n const newline = sql.indexOf(\"\\n\", index + 2);\n if (newline === -1) {\n return undefined;\n }\n index = newline + 1;\n continue;\n }\n\n if (sql.startsWith(\"/*\", index)) {\n const end = sql.indexOf(\"*/\", index + 2);\n if (end === -1) {\n return undefined;\n }\n index = end + 2;\n continue;\n }\n\n break;\n }\n\n const match = /^[A-Za-z_]+/.exec(sql.slice(index));\n return match?.[0].toLowerCase();\n}\n","/**\n * DuckDbDatabaseHandle - Handle for operations on a specific named database.\n *\n * Delegates all operations to the parent DuckDbService with the database name.\n */\n\nimport type { Result } from \"../types\";\nimport type { IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport type { DuckDbService } from \"./DuckDbService\";\nimport type {\n DuckDbValue,\n DuckDbStatement,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SchemaInfo,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n} from \"./types\";\n\nexport class DuckDbDatabaseHandle implements IDuckDbDatabaseHandle {\n private service: DuckDbService;\n public readonly name: string;\n\n constructor(service: DuckDbService, name: string) {\n this.service = service;\n this.name = name;\n }\n\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.service.queryOnDb<T>(this.name, sql, params, options);\n }\n\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.service.queryArrowOnDb(this.name, sql, params, options);\n }\n\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.service.executeOnDb(this.name, sql, params, options);\n }\n\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.service.batchOnDb(this.name, statements, options);\n }\n\n async executeStatement(\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.service.executeStatementOnDb(this.name, name, params, options);\n }\n\n async describe(options?: DuckDbOptions): Promise<Result<SchemaInfo>> {\n return this.service.describeDb(this.name, options);\n }\n\n async export(options?: DuckDbOptions): Promise<Result<Blob>> {\n return this.service.exportOnDb(this.name, options);\n }\n\n async import(data: Uint8Array, options?: DuckDbOptions): Promise<Result<void>> {\n return this.service.importOnDb(this.name, data, options);\n }\n}\n","/**\n * DuckDB Service Types\n *\n * Type definitions for the DuckDB service operations.\n */\n\n/**\n * Configuration for DuckDbService.\n */\nexport interface DuckDbServiceConfig {\n /**\n * Default database name.\n * If not set, operations default to \"default\".\n */\n defaultDatabase?: string;\n\n /**\n * Default timeout in milliseconds for DuckDB operations.\n */\n timeout?: number;\n\n /** Allow additional config properties */\n [key: string]: unknown;\n}\n\n/**\n * Options for DuckDB query operations.\n */\nexport interface DuckDbQueryOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB execute operations.\n */\nexport interface DuckDbExecuteOptions {\n /**\n * Schema initialization statements (CREATE TABLE IF NOT EXISTS ...).\n * Executed before the main statement on first write.\n */\n schema?: string[];\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB batch operations.\n */\nexport interface DuckDbBatchOptions {\n /**\n * Whether to run statements in a transaction.\n */\n transactional?: boolean;\n\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Options for DuckDB operations that only need an abort signal.\n */\nexport interface DuckDbOptions {\n /**\n * Custom abort signal for this operation.\n */\n signal?: AbortSignal;\n}\n\n/**\n * A DuckDB value: null, boolean, number, string, binary, array, or object.\n */\nexport type DuckDbValue =\n | null\n | boolean\n | number\n | string\n | Uint8Array\n | DuckDbValueArray\n | DuckDbValueRecord;\n\n/** Array of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueArray extends Array<DuckDbValue> {}\n\n/** Record of DuckDB values (workaround for circular type alias). */\nexport interface DuckDbValueRecord {\n [key: string]: DuckDbValue;\n}\n\n/**\n * A DuckDB statement with optional parameters.\n */\nexport interface DuckDbStatement {\n sql: string;\n params?: DuckDbValue[];\n}\n\n/**\n * Response from DuckDB query operations.\n */\nexport interface QueryResponse<T = Record<string, unknown>> {\n columns: string[];\n rows: T[][];\n rowCount: number;\n}\n\n/**\n * Response from DuckDB execute operations.\n */\nexport interface ExecuteResponse {\n changes: number;\n}\n\n/**\n * Response from DuckDB batch operations.\n */\nexport interface BatchResponse {\n results: ExecuteResponse[];\n}\n\n/**\n * Schema information for a DuckDB database.\n */\nexport interface SchemaInfo {\n tables: TableInfo[];\n views: ViewInfo[];\n}\n\n/**\n * Information about a table.\n */\nexport interface TableInfo {\n name: string;\n columns: ColumnInfo[];\n}\n\n/**\n * Information about a column.\n */\nexport interface ColumnInfo {\n name: string;\n type: string;\n nullable: boolean;\n}\n\n/**\n * Information about a view.\n */\nexport interface ViewInfo {\n name: string;\n sql: string;\n}\n\n/**\n * DuckDB service action types.\n */\nexport const DuckDbAction = {\n READ: \"tinycloud.duckdb/read\",\n WRITE: \"tinycloud.duckdb/write\",\n ADMIN: \"tinycloud.duckdb/admin\",\n DESCRIBE: \"tinycloud.duckdb/describe\",\n EXPORT: \"tinycloud.duckdb/export\",\n IMPORT: \"tinycloud.duckdb/import\",\n EXECUTE: \"tinycloud.duckdb/execute\",\n ALL: \"tinycloud.duckdb/*\",\n} as const;\n\nexport type DuckDbActionType = (typeof DuckDbAction)[keyof typeof DuckDbAction];\n","/**\n * DuckDbService - DuckDB database service implementation.\n *\n * Platform-agnostic DuckDB service that works with both web-sdk and node-sdk.\n * Uses dependency injection via IServiceContext for platform dependencies.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n ErrorCodes,\n serviceError,\n type FetchResponse,\n} from \"../types\";\nimport { authRequiredError, wrapError, parseAuthError } from \"../errors\";\nimport type { IDuckDbService, IDuckDbDatabaseHandle } from \"./IDuckDbService\";\nimport { DuckDbDatabaseHandle } from \"./DuckDbDatabaseHandle\";\nimport {\n type DuckDbServiceConfig,\n type DuckDbQueryOptions,\n type DuckDbExecuteOptions,\n type DuckDbBatchOptions,\n type DuckDbOptions,\n type DuckDbValue,\n type DuckDbStatement,\n type QueryResponse,\n type ExecuteResponse,\n type BatchResponse,\n type SchemaInfo,\n DuckDbAction,\n} from \"./types\";\n\nexport class DuckDbService extends BaseService implements IDuckDbService {\n static readonly serviceName = \"duckdb\";\n\n declare protected _config: DuckDbServiceConfig;\n\n constructor(config: DuckDbServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): DuckDbServiceConfig {\n return this._config;\n }\n\n private get defaultDbName(): string {\n return this._config.defaultDatabase ?? \"default\";\n }\n\n private get host(): string {\n return this.context.hosts[0];\n }\n\n /**\n * Get a handle to a named database.\n */\n db(name?: string): IDuckDbDatabaseHandle {\n return new DuckDbDatabaseHandle(this, name ?? this.defaultDbName);\n }\n\n /**\n * Shortcut: query the default database (JSON format).\n */\n async query<T = Record<string, unknown>>(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.queryOnDb<T>(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: query the default database (Arrow IPC format).\n */\n async queryArrow(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.queryArrowOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: execute on the default database.\n */\n async execute(\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.executeOnDb(this.defaultDbName, sql, params, options);\n }\n\n /**\n * Shortcut: batch on the default database.\n */\n async batch(\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.batchOnDb(this.defaultDbName, statements, options);\n }\n\n // === Internal methods called by DuckDbDatabaseHandle ===\n\n async queryOnDb<T = Record<string, unknown>>(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse<T>>> {\n return this.withTelemetry<QueryResponse<T>>(\"query\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"query\");\n }\n\n const data = (await response.json()) as QueryResponse<T>;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async queryArrowOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<ArrayBuffer>> {\n return this.withTelemetry<ArrayBuffer>(\"queryArrow\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.READ,\n { action: \"query\", sql, params: params ?? [] },\n options?.signal,\n { Accept: \"application/vnd.apache.arrow.stream\" }\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"queryArrow\");\n }\n\n const buffer = await response.arrayBuffer();\n return ok(buffer);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async executeOnDb(\n dbName: string,\n sql: string,\n params?: DuckDbValue[],\n options?: DuckDbExecuteOptions\n ): Promise<Result<ExecuteResponse>> {\n return this.withTelemetry(\"execute\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const body: Record<string, unknown> = {\n action: \"execute\",\n sql,\n params: params ?? [],\n };\n if (options?.schema) {\n body.schema = options.schema;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"execute\");\n }\n\n const data = (await response.json()) as ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async batchOnDb(\n dbName: string,\n statements: DuckDbStatement[],\n options?: DuckDbBatchOptions\n ): Promise<Result<BatchResponse>> {\n return this.withTelemetry(\"batch\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const body: Record<string, unknown> = {\n action: \"batch\",\n statements,\n };\n if (options?.transactional !== undefined) {\n body.transactional = options.transactional;\n }\n\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.WRITE,\n body,\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"batch\");\n }\n\n const data = (await response.json()) as BatchResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async executeStatementOnDb(\n dbName: string,\n name: string,\n params?: DuckDbValue[],\n options?: DuckDbQueryOptions\n ): Promise<Result<QueryResponse | ExecuteResponse>> {\n return this.withTelemetry(\"executeStatement\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.EXECUTE,\n { action: \"executeStatement\", name, params: params ?? [] },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"executeStatement\");\n }\n\n const data = (await response.json()) as\n | QueryResponse\n | ExecuteResponse;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async describeDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<SchemaInfo>> {\n return this.withTelemetry(\"describe\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.DESCRIBE,\n { action: \"describe\" },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"describe\");\n }\n\n const data = (await response.json()) as SchemaInfo;\n return ok(data);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async exportOnDb(\n dbName: string,\n options?: DuckDbOptions\n ): Promise<Result<Blob>> {\n return this.withTelemetry(\"export\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const response = await this.invokeDuckDb(\n dbName,\n DuckDbAction.EXPORT,\n { action: \"export\" },\n options?.signal\n );\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"export\");\n }\n\n const blob = await response.blob();\n return ok(blob);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n async importOnDb(\n dbName: string,\n data: Uint8Array,\n options?: DuckDbOptions\n ): Promise<Result<void>> {\n return this.withTelemetry(\"import\", dbName, async () => {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"duckdb\"));\n }\n\n try {\n const session = this.context.session!;\n const headers = this.context.invoke(\n session,\n \"duckdb\",\n dbName,\n DuckDbAction.IMPORT\n );\n\n const response = await this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/x-duckdb\",\n },\n body: new Blob([data]),\n signal: this.combineSignals(options?.signal),\n });\n\n if (!response.ok) {\n return this.handleErrorResponse(response, \"import\");\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"duckdb\", error));\n }\n });\n }\n\n // === Private helpers ===\n\n private async invokeDuckDb(\n dbName: string,\n action: string,\n body: Record<string, unknown>,\n signal?: AbortSignal,\n extraHeaders?: Record<string, string>\n ): Promise<FetchResponse> {\n const session = this.context.session!;\n const headers = this.context.invoke(session, \"duckdb\", dbName, action);\n\n return this.context.fetch(`${this.host}/invoke`, {\n method: \"POST\",\n headers: {\n ...(headers as Record<string, string>),\n \"Content-Type\": \"application/json\",\n ...extraHeaders,\n },\n body: JSON.stringify(body),\n signal: this.combineSignals(signal),\n });\n }\n\n private async handleErrorResponse(\n response: FetchResponse,\n operation: string\n ): Promise<Result<never>> {\n const errorText = await response.text();\n\n let errorBody: { error?: string; message?: string; code?: string } = {};\n try {\n errorBody = JSON.parse(errorText);\n } catch {\n // Not JSON\n }\n\n const errorCode = this.mapHttpStatusToErrorCode(\n response.status,\n errorBody.error\n );\n const message =\n errorBody.message ||\n `DuckDB ${operation} failed: ${response.status} - ${errorText}`;\n\n const meta: Record<string, unknown> = { status: response.status, statusText: response.statusText };\n\n if (response.status === 401) {\n const { resource, action } = parseAuthError(errorText);\n if (action) meta.requiredAction = action;\n if (resource) meta.resource = resource;\n }\n\n return err(\n serviceError(errorCode, message, \"duckdb\", { meta })\n );\n }\n\n private mapHttpStatusToErrorCode(\n status: number,\n serverError?: string\n ): string {\n switch (status) {\n case 400:\n return ErrorCodes.DUCKDB_ERROR;\n case 401:\n return ErrorCodes.AUTH_UNAUTHORIZED;\n case 403:\n if (serverError === \"duckdb_readonly_violation\") {\n return ErrorCodes.DUCKDB_READONLY_VIOLATION;\n }\n return ErrorCodes.DUCKDB_PERMISSION_DENIED;\n case 404:\n return ErrorCodes.DUCKDB_DATABASE_NOT_FOUND;\n case 413:\n return ErrorCodes.DUCKDB_RESPONSE_TOO_LARGE;\n case 429:\n return ErrorCodes.DUCKDB_QUOTA_EXCEEDED;\n default:\n return ErrorCodes.NETWORK_ERROR;\n }\n }\n}\n","import { BaseService } from \"../base/BaseService\";\nimport type {\n FetchResponse,\n InvokeAnyEntry,\n ServiceHeaders,\n Result,\n} from \"../types\";\nimport { ErrorCodes, err, ok, serviceError } from \"../types\";\nimport { authRequiredError, wrapError } from \"../errors\";\nimport type { IHooksService } from \"./IHooksService\";\nimport type {\n HookEvent,\n HookStreamEvent,\n HookSubscription,\n HooksServiceConfig,\n SubscribeOptions,\n HookWebhookListOptions,\n HookWebhookRecord,\n HookWebhookRegistration,\n HookWebhookUnregisterOptions,\n} from \"./types\";\n\ninterface HookTicketResponse {\n ticket: string;\n expiresAt: string;\n}\n\ninterface HookSubscriber {\n requested: HookSubscription[];\n ttlSeconds?: number;\n queue: AsyncQueue<HookEvent>;\n}\n\nclass AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this;\n }\n\n push(value: T): void {\n if (this.closed) {\n return;\n }\n\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter({ value, done: false });\n return;\n }\n\n this.values.push(value);\n }\n\n close(): void {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n while (this.waiters.length > 0) {\n const waiter = this.waiters.shift();\n waiter?.({ value: undefined as never, done: true });\n }\n }\n\n next(): Promise<IteratorResult<T>> {\n if (this.values.length > 0) {\n const value = this.values.shift()!;\n return Promise.resolve({ value, done: false });\n }\n\n if (this.closed) {\n return Promise.resolve({ value: undefined as never, done: true });\n }\n\n return new Promise<IteratorResult<T>>((resolve) => {\n this.waiters.push(resolve);\n });\n }\n}\n\nexport class HooksService extends BaseService implements IHooksService {\n static readonly serviceName = \"hooks\";\n\n declare protected _config: HooksServiceConfig;\n private readonly _subscribers: Set<HookSubscriber> = new Set();\n private _sharedStreamTask?: Promise<void>;\n private _sharedStreamAbort?: AbortController;\n private _refreshChain: Promise<void> = Promise.resolve();\n private _activeSignature = \"\";\n\n constructor(config: HooksServiceConfig = {}) {\n super();\n this._config = config;\n }\n\n get config(): HooksServiceConfig {\n return this._config;\n }\n\n private get host(): string {\n return this._config.host ?? this.context.hosts[0];\n }\n\n async *subscribe(\n subscriptions: HookSubscription[],\n options: SubscribeOptions = {},\n ): AsyncIterable<HookEvent> {\n if (!this.requireAuth()) {\n throw new Error(\"Authentication required for hooks subscription\");\n }\n if (subscriptions.length === 0) {\n throw new Error(\"At least one hook subscription is required\");\n }\n\n const normalized = subscriptions.map(normalizeSubscription);\n const subscriber: HookSubscriber = {\n requested: normalized,\n ttlSeconds: options.ttlSeconds,\n queue: new AsyncQueue<HookEvent>(),\n };\n\n this._subscribers.add(subscriber);\n const abortHandler = () => {\n this._subscribers.delete(subscriber);\n subscriber.queue.close();\n void this.scheduleSharedStreamRefresh();\n };\n\n if (options.signal) {\n if (options.signal.aborted) {\n abortHandler();\n } else {\n options.signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n }\n\n void this.scheduleSharedStreamRefresh();\n\n try {\n for await (const event of subscriber.queue) {\n yield event;\n }\n } finally {\n if (options.signal) {\n options.signal.removeEventListener(\"abort\", abortHandler);\n }\n abortHandler();\n }\n }\n\n async register(\n webhook: HookWebhookRegistration,\n ): Promise<Result<HookWebhookRecord>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n if (typeof webhook.secret !== \"string\" || webhook.secret.trim().length === 0) {\n return err(\n serviceError(\n ErrorCodes.INVALID_INPUT,\n \"Webhook secret is required\",\n \"hooks\",\n { meta: { field: \"secret\" } },\n ),\n );\n }\n\n try {\n const response = await this.context.fetch(`${this.host}/hooks/webhooks`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/register\",\n buildScopePath(webhook.service, webhook.pathPrefix),\n ),\n ),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n space: webhook.space,\n service: webhook.service,\n pathPrefix: normalizePathPrefix(webhook.pathPrefix),\n abilities: webhook.abilities ?? [],\n callbackUrl: webhook.callbackUrl,\n secret: webhook.secret,\n }),\n });\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to register webhook\", response),\n );\n }\n\n const data = normalizeWebhookRecord(await response.json());\n if (!data) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook registration response did not include a record\"),\n ),\n );\n }\n\n return ok(data);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async list(\n options: HookWebhookListOptions = {},\n ): Promise<Result<HookWebhookRecord[]>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const query = new URLSearchParams();\n if (options.space) {\n query.set(\"space\", options.space);\n }\n if (options.service) {\n query.set(\"service\", options.service);\n }\n if (options.pathPrefix) {\n const normalizedPrefix = normalizePathPrefix(options.pathPrefix);\n if (normalizedPrefix) {\n query.set(\"prefix\", normalizedPrefix);\n }\n }\n\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks${query.size > 0 ? `?${query.toString()}` : \"\"}`,\n {\n method: \"GET\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/list\",\n options.service\n ? buildScopePath(options.service, options.pathPrefix)\n : \"webhooks\",\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\"hooks\", \"failed to list webhooks\", response),\n );\n }\n\n const payload = await response.json();\n const records = normalizeWebhookRecordList(payload);\n if (!records) {\n return err(\n wrapError(\n \"hooks\",\n new Error(\"Webhook list response did not include records\"),\n ),\n );\n }\n\n return ok(records);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n async unregister(\n id: string,\n options: HookWebhookUnregisterOptions = {},\n ): Promise<Result<void>> {\n if (!this.requireAuth()) {\n return err(authRequiredError(\"hooks\"));\n }\n\n try {\n const response = await this.context.fetch(\n `${this.host}/hooks/webhooks/${encodeURIComponent(id)}`,\n {\n method: \"DELETE\",\n headers: serviceHeadersToRecord(\n this.createHookHeaders(\n \"tinycloud.hooks/unregister\",\n options.target\n ? buildScopePath(\n options.target.service,\n options.target.pathPrefix,\n )\n : `webhooks/${id}`,\n ),\n ),\n },\n );\n\n if (!response.ok) {\n return err(\n await responseError(\n \"hooks\",\n \"failed to unregister webhook\",\n response,\n ),\n );\n }\n\n return ok(undefined);\n } catch (error) {\n return err(wrapError(\"hooks\", error));\n }\n }\n\n private async scheduleSharedStreamRefresh(): Promise<void> {\n this._refreshChain = this._refreshChain\n .then(() => this.refreshSharedStream())\n .catch(() => undefined);\n await this._refreshChain;\n }\n\n private async refreshSharedStream(): Promise<void> {\n if (!this.requireAuth() || this._subscribers.size === 0) {\n this.abortSharedStream();\n this._activeSignature = \"\";\n return;\n }\n\n const state = this.collectSharedStreamState();\n if (state.signature !== this._activeSignature) {\n this._activeSignature = state.signature;\n this.abortSharedStream();\n }\n\n if (!this._sharedStreamTask) {\n this._sharedStreamTask = this.runSharedStream(state)\n .catch((error: unknown) => {\n if (!isAbortError(error)) {\n throw error;\n }\n })\n .finally(() => {\n this._sharedStreamTask = undefined;\n this._sharedStreamAbort = undefined;\n if (this._subscribers.size > 0) {\n void this.scheduleSharedStreamRefresh();\n }\n });\n }\n }\n\n private collectSharedStreamState(): {\n subscriptions: HookSubscription[];\n ttlSeconds?: number;\n signature: string;\n } {\n const merged = new Map<string, HookSubscription>();\n const ttlCandidates: number[] = [];\n\n for (const subscriber of this._subscribers) {\n if (typeof subscriber.ttlSeconds === \"number\") {\n ttlCandidates.push(subscriber.ttlSeconds);\n }\n for (const subscription of subscriber.requested) {\n merged.set(subscriptionSignature(subscription), subscription);\n }\n }\n\n const subscriptions = [...merged.values()].sort((left, right) =>\n subscriptionSignature(left).localeCompare(subscriptionSignature(right)),\n );\n const ttlSeconds =\n ttlCandidates.length > 0 ? Math.min(...ttlCandidates) : undefined;\n const signature = JSON.stringify({\n subscriptions: subscriptions.map(subscriptionSignature),\n ttlSeconds,\n });\n\n return {\n subscriptions,\n ttlSeconds,\n signature,\n };\n }\n\n private async runSharedStream(state: {\n subscriptions: HookSubscription[];\n ttlSeconds?: number;\n }): Promise<void> {\n const abortController = new AbortController();\n this._sharedStreamAbort = abortController;\n\n try {\n const host = this._config.host ?? this.context.hosts[0];\n const ticketResponse = await this.mintHookTicket(\n state.subscriptions,\n state.ttlSeconds,\n abortController.signal,\n );\n const streamResponse = await this.openHookStream(\n host,\n ticketResponse.ticket,\n abortController.signal,\n );\n\n for await (const message of parseSseStream(\n streamResponse.body,\n abortController.signal,\n )) {\n if (!message.data) {\n continue;\n }\n const event = parseHookEvent(message);\n for (const subscriber of this._subscribers) {\n if (matchesAnySubscription(event, subscriber.requested)) {\n subscriber.queue.push(event);\n }\n }\n }\n } finally {\n if (this._sharedStreamAbort === abortController) {\n this._sharedStreamAbort = undefined;\n }\n }\n }\n\n private abortSharedStream(): void {\n this._sharedStreamAbort?.abort();\n }\n\n private createHookHeaders(action: string, path: string): ServiceHeaders {\n return this.context.invoke(this.session, \"hooks\", path, action);\n }\n\n private async mintHookTicket(\n subscriptions: HookSubscription[],\n ttlSeconds: number | undefined,\n signal?: AbortSignal,\n ): Promise<HookTicketResponse> {\n const host = this._config.host ?? this.context.hosts[0];\n const headers = this.createInvokeHeaders(subscriptions);\n const ticketResponse = await this.context.fetch(`${host}/hooks/tickets`, {\n method: \"POST\",\n headers: {\n ...serviceHeadersToRecord(headers),\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n subscriptions,\n ttlSeconds,\n }),\n signal,\n });\n\n if (!ticketResponse.ok) {\n throw await responseError(\n \"hooks\",\n \"failed to mint hook ticket\",\n ticketResponse,\n );\n }\n\n const ticketJson = (await ticketResponse.json()) as HookTicketResponse;\n if (!ticketJson?.ticket) {\n throw new Error(\"Hook ticket response did not include a ticket\");\n }\n\n return ticketJson;\n }\n\n private async openHookStream(\n host: string,\n ticket: string,\n signal?: AbortSignal,\n ): Promise<FetchResponse> {\n const streamResponse = await this.context.fetch(\n `${host}/hooks/events?ticket=${encodeURIComponent(ticket)}`,\n {\n method: \"GET\",\n headers: { accept: \"text/event-stream\" },\n signal,\n },\n );\n\n if (!streamResponse.ok) {\n throw await responseError(\n \"hooks\",\n \"failed to open hook stream\",\n streamResponse,\n );\n }\n\n return streamResponse;\n }\n\n private createInvokeHeaders(\n subscriptions: HookSubscription[],\n ): ServiceHeaders {\n const entries: InvokeAnyEntry[] = subscriptions.map((subscription) => ({\n spaceId: subscription.space,\n service: \"hooks\",\n path: subscription.pathPrefix\n ? `${subscription.service}/${subscription.pathPrefix}`\n : subscription.service,\n action: \"tinycloud.hooks/subscribe\",\n }));\n\n if (this.context.invokeAny) {\n return this.context.invokeAny(this.session, entries);\n }\n\n if (entries.length === 1) {\n const entry = entries[0];\n return this.context.invoke(\n this.session,\n entry.service,\n entry.path,\n entry.action,\n );\n }\n\n throw new Error(\n \"This SDK runtime does not support multi-scope hook invocations\",\n );\n }\n}\n\nfunction buildScopePath(\n service: HookSubscription[\"service\"],\n pathPrefix?: string,\n): string {\n const normalized = normalizePathPrefix(pathPrefix);\n return normalized ? `${service}/${normalized}` : service;\n}\n\nfunction normalizeSubscription(\n subscription: HookSubscription,\n): HookSubscription {\n return {\n ...subscription,\n pathPrefix: normalizePathPrefix(subscription.pathPrefix),\n abilities: subscription.abilities ?? [],\n };\n}\n\nfunction subscriptionSignature(subscription: HookSubscription): string {\n return JSON.stringify({\n space: subscription.space,\n service: subscription.service,\n pathPrefix: subscription.pathPrefix ?? \"\",\n abilities: [...(subscription.abilities ?? [])].sort(),\n });\n}\n\nfunction matchesAnySubscription(\n event: HookEvent,\n subscriptions: HookSubscription[],\n): boolean {\n return subscriptions.some((subscription) =>\n matchesSubscription(event, subscription),\n );\n}\n\nfunction matchesSubscription(\n event: HookEvent,\n subscription: HookSubscription,\n): boolean {\n if (event.space !== subscription.space) {\n return false;\n }\n if (event.service !== subscription.service) {\n return false;\n }\n if (subscription.pathPrefix) {\n const prefix = subscription.pathPrefix.endsWith(\"/\")\n ? subscription.pathPrefix\n : `${subscription.pathPrefix}/`;\n if (\n event.path &&\n event.path !== subscription.pathPrefix &&\n !event.path.startsWith(prefix)\n ) {\n return false;\n }\n }\n const abilities = subscription.abilities ?? [];\n if (abilities.length > 0 && !abilities.includes(event.ability)) {\n return false;\n }\n return true;\n}\n\nfunction normalizePathPrefix(pathPrefix?: string): string | undefined {\n if (!pathPrefix) {\n return undefined;\n }\n const trimmed = pathPrefix.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction serviceHeadersToRecord(\n headers: ServiceHeaders,\n): Record<string, string> {\n if (Array.isArray(headers)) {\n return Object.fromEntries(headers);\n }\n return { ...headers };\n}\n\nasync function responseError(\n service: string,\n message: string,\n response: FetchResponse,\n): Promise<ReturnType<typeof wrapError>> {\n let detail = response.statusText;\n try {\n const text = await response.text();\n if (text) {\n detail = text;\n }\n } catch {\n // Ignore secondary body read failure.\n }\n return wrapError(\n service,\n new Error(`${message}: ${response.status} ${detail}`),\n );\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n\nasync function* parseSseStream(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<HookStreamEvent> {\n if (!body) {\n throw new Error(\"Hook stream response does not expose a readable body\");\n }\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n for await (const chunk of readBodyChunks(body, signal)) {\n buffer += decoder.decode(chunk, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\");\n while (separatorIndex >= 0) {\n const rawEvent = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + 2);\n const parsed = parseSseEvent(rawEvent);\n if (parsed) {\n yield parsed;\n }\n separatorIndex = buffer.indexOf(\"\\n\\n\");\n }\n }\n\n buffer += decoder.decode();\n const trailing = parseSseEvent(buffer.trim());\n if (trailing) {\n yield trailing;\n }\n}\n\nasync function* readBodyChunks(\n body: unknown,\n signal?: AbortSignal,\n): AsyncIterable<Uint8Array> {\n const asyncIterable = body as AsyncIterable<Uint8Array>;\n if (typeof asyncIterable?.[Symbol.asyncIterator] === \"function\") {\n for await (const chunk of asyncIterable) {\n if (signal?.aborted) {\n break;\n }\n yield chunk;\n }\n return;\n }\n\n const stream = body as {\n getReader?: () => {\n read: () => Promise<{ done: boolean; value?: Uint8Array }>;\n releaseLock?: () => void;\n cancel?: () => Promise<void>;\n };\n };\n\n if (typeof stream.getReader !== \"function\") {\n throw new Error(\"Unsupported hook stream body type\");\n }\n\n const reader = stream.getReader();\n try {\n while (!signal?.aborted) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value) {\n yield value;\n }\n }\n } finally {\n try {\n await reader.cancel?.();\n } catch {\n // Ignore cancellation failures.\n }\n reader.releaseLock?.();\n }\n}\n\nfunction parseSseEvent(rawEvent: string): HookStreamEvent | null {\n if (!rawEvent) {\n return null;\n }\n\n let event = \"message\";\n let id: string | undefined;\n const dataLines: string[] = [];\n\n for (const line of rawEvent.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) {\n continue;\n }\n const [field, ...rest] = line.split(\":\");\n const value = rest.join(\":\").replace(/^ /, \"\");\n switch (field) {\n case \"event\":\n event = value;\n break;\n case \"id\":\n id = value;\n break;\n case \"data\":\n dataLines.push(value);\n break;\n default:\n break;\n }\n }\n\n if (dataLines.length === 0) {\n return null;\n }\n\n return {\n event,\n id,\n data: dataLines.join(\"\\n\"),\n };\n}\n\nfunction parseHookEvent(message: HookStreamEvent): HookEvent {\n const parsed = JSON.parse(message.data) as Partial<HookEvent>;\n return {\n type: \"write\",\n id: parsed.id ?? message.id ?? \"\",\n space: parsed.space ?? \"\",\n service: parsed.service ?? \"\",\n ability: parsed.ability ?? \"\",\n path: parsed.path,\n actor: parsed.actor ?? \"\",\n epoch: parsed.epoch ?? \"\",\n eventIndex: parsed.eventIndex ?? 0,\n timestamp: parsed.timestamp ?? \"\",\n };\n}\n\nfunction normalizeWebhookRecord(data: unknown): HookWebhookRecord | null {\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const candidate =\n pickWebhookRecord(record) ??\n normalizeWebhookRecord(record.webhook) ??\n normalizeWebhookRecord(record.hook) ??\n normalizeWebhookRecord(record.subscription) ??\n normalizeWebhookRecord(record.data);\n return candidate ?? null;\n}\n\nfunction normalizeWebhookRecordList(data: unknown): HookWebhookRecord[] | null {\n if (Array.isArray(data)) {\n const records = data\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n }\n\n if (!data || typeof data !== \"object\") {\n return null;\n }\n\n const record = isRecordContainer(data);\n const nested =\n maybeRecordArray(record.webhooks) ??\n maybeRecordArray(record.subscriptions) ??\n maybeRecordArray(record.hooks) ??\n maybeRecordArray(record.data);\n if (nested) {\n return nested;\n }\n\n const single = pickWebhookRecord(record);\n return single ? [single] : null;\n}\n\nfunction maybeRecordArray(value: unknown): HookWebhookRecord[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n\n const records = value\n .map((entry) => normalizeWebhookRecord(entry))\n .filter((entry): entry is HookWebhookRecord => entry !== null);\n return records;\n}\n\nfunction pickWebhookRecord(\n value: Record<string, unknown>,\n): HookWebhookRecord | null {\n const id = stringField(value, \"id\");\n const space = stringField(value, \"space\") ?? stringField(value, \"spaceId\");\n const service = stringField(value, \"service\");\n const callbackUrl =\n stringField(value, \"callbackUrl\") ?? stringField(value, \"callback_url\");\n if (!id || !space || !service || !callbackUrl) {\n return null;\n }\n\n return {\n id,\n space,\n service: service as HookWebhookRecord[\"service\"],\n pathPrefix:\n optionalStringField(value, \"pathPrefix\") ??\n optionalStringField(value, \"path_prefix\"),\n abilities:\n stringArrayField(value, \"abilities\") ??\n parsedStringArrayField(value, \"abilitiesJson\") ??\n parsedStringArrayField(value, \"abilities_json\"),\n callbackUrl,\n active: booleanField(value, \"active\") ?? true,\n createdAt:\n stringField(value, \"createdAt\") ??\n stringField(value, \"created_at\") ??\n new Date().toISOString(),\n subscriberDid:\n optionalStringField(value, \"subscriberDid\") ??\n optionalStringField(value, \"subscriber_did\"),\n };\n}\n\nfunction isRecordContainer(value: object): Record<string, unknown> {\n return value as Record<string, unknown>;\n}\n\nfunction stringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n const field = value[key];\n return typeof field === \"string\" ? field : undefined;\n}\n\nfunction optionalStringField(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n return stringField(value, key);\n}\n\nfunction booleanField(\n value: Record<string, unknown>,\n key: string,\n): boolean | undefined {\n const field = value[key];\n return typeof field === \"boolean\" ? field : undefined;\n}\n\nfunction stringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (!Array.isArray(field)) {\n return undefined;\n }\n const strings = field.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === field.length ? strings : undefined;\n}\n\nfunction parsedStringArrayField(\n value: Record<string, unknown>,\n key: string,\n): string[] | undefined {\n const field = value[key];\n if (typeof field !== \"string\") {\n return undefined;\n }\n\n try {\n const parsed = JSON.parse(field) as unknown;\n if (!Array.isArray(parsed)) {\n return undefined;\n }\n const strings = parsed.filter(\n (item): item is string => typeof item === \"string\",\n );\n return strings.length === parsed.length ? strings : undefined;\n } catch {\n return undefined;\n }\n}\n","import type { StorageQuotaInfo } from \"../types\";\n\nexport interface QuotaConfig {\n /** Called when a storage quota error is detected (402/413) */\n onUpgradeRequired?: (info: StorageQuotaInfo) => void;\n}\n\nexport interface QuotaStatus {\n /** Storage limit in bytes for this space */\n limitBytes: number;\n /** Storage used in bytes for this space */\n usedBytes?: number;\n /** Remaining storage in bytes */\n remainingBytes?: number;\n}\n\nexport class TinyCloudQuota {\n private config: QuotaConfig;\n private quotaUrl: string | null = null;\n\n constructor(config: QuotaConfig = {}) {\n this.config = config;\n }\n\n /** Set the quota URL discovered from the /info endpoint */\n setQuotaUrl(url: string | null): void {\n this.quotaUrl = url;\n }\n\n /** Whether a quota service is available */\n get available(): boolean {\n return this.quotaUrl !== null;\n }\n\n /** Query quota status for a space from the quota URL */\n async getQuota(spaceId: string): Promise<QuotaStatus | null> {\n if (!this.quotaUrl) return null;\n\n const resp = await fetch(\n `${this.quotaUrl}/api/quota/${encodeURIComponent(spaceId)}`\n );\n if (!resp.ok) return null;\n\n const data = (await resp.json()) as { storage_limit_bytes?: number };\n return {\n limitBytes: data.storage_limit_bytes ?? 0,\n };\n }\n\n /** Trigger the upgrade callback when a quota error is encountered */\n handleQuotaError(info: StorageQuotaInfo): void {\n this.config.onUpgradeRequired?.(info);\n }\n}\n","/**\n * Data Vault Service Types\n *\n * Type definitions for the Data Vault (encrypted KV) service operations.\n */\n\nimport type {\n DecryptCapabilityProof,\n IEncryptionService,\n} from \"../encryption\";\n\nexport interface VaultNetworkEncryptionConfig {\n /** Default encryption network used for inline vault envelopes. */\n networkId: string;\n /** TinyCloud encryption module used for local encrypt and node-mediated decrypt. */\n service: IEncryptionService;\n /** Proof material presented to the encryption module for decrypt requests. */\n decryptCapabilityProof?:\n | DecryptCapabilityProof\n | (() => DecryptCapabilityProof | Promise<DecryptCapabilityProof>);\n}\n\n/**\n * Configuration for DataVaultService.\n */\nexport interface DataVaultConfig {\n /** Space ID for encrypted data storage */\n spaceId: string;\n /** Key rotation policy */\n keyRotation?: \"per-write\" | \"per-key\"; // default: \"per-write\"\n /** Network-envelope encryption mode. When set, vault.unlock/key grants are not used. */\n encryption?: VaultNetworkEncryptionConfig;\n}\n\n/**\n * Options for vault put operations.\n */\nexport interface VaultPutOptions {\n /** Custom metadata tags appended to the envelope */\n metadata?: Record<string, string>;\n /** Content type hint for deserialization (default: auto-detect) */\n contentType?: string;\n /** Custom serializer (default: JSON.stringify for objects) */\n serialize?: (value: unknown) => Uint8Array;\n}\n\n/**\n * Options for vault get operations.\n */\nexport interface VaultGetOptions<T = unknown> {\n /** Custom deserializer (default: JSON.parse if content-type is JSON) */\n deserialize?: (data: Uint8Array) => T;\n /** Return raw decrypted bytes without deserialization */\n raw?: boolean;\n /** Delegated KV service for reading from the grantor's space (used by getShared) */\n kv?: { get<V>(key: string, options?: { raw?: boolean }): Promise<{ ok: boolean; data?: { data: V }; error?: { message: string } }> };\n}\n\n/**\n * Options for vault list operations.\n */\nexport interface VaultListOptions {\n /** Prefix filter for key names */\n prefix?: string;\n /** Remove prefix from returned keys */\n removePrefix?: boolean;\n}\n\n/**\n * Options for vault grant (sharing) operations.\n */\nexport interface VaultGrantOptions {\n /** Additional metadata on the grant */\n metadata?: Record<string, string>;\n}\n\n/**\n * A decrypted vault entry returned by get operations.\n *\n * @template T - Type of the decrypted value\n */\nexport interface VaultEntry<T> {\n /** Decrypted value */\n value: T;\n /** Envelope metadata */\n metadata: Record<string, string>;\n /** Key ID used for encryption */\n keyId: string;\n}\n\n/**\n * Structured error codes for vault operations.\n */\n/**\n * Input types for creating vault errors (service field added automatically).\n */\nexport type VaultErrorInput =\n | { code: \"DECRYPTION_FAILED\"; message?: string; cause?: Error }\n | { code: \"KEY_NOT_FOUND\"; key: string; message?: string }\n | { code: \"INTEGRITY_ERROR\"; message?: string; cause?: Error }\n | { code: \"GRANT_NOT_FOUND\"; grantor: string; key: string; message?: string }\n | { code: \"VAULT_LOCKED\"; message?: string }\n | { code: \"PUBLIC_KEY_NOT_FOUND\"; did: string; message?: string }\n | { code: \"STORAGE_ERROR\"; cause: Error; message?: string };\n\n/**\n * Vault error with service field (compatible with ServiceError).\n */\nexport type VaultError = VaultErrorInput & { service: \"vault\"; message: string };\n\n\n/** KV actions the vault needs on the public space for key publishing. */\nexport const VaultPublicSpaceKVActions = [\n \"tinycloud.kv/get\",\n \"tinycloud.kv/put\",\n \"tinycloud.kv/metadata\",\n] as const;\n\n/** Version-keyed signing message configuration for vault key derivation. */\nexport const VaultVersionConfig = {\n \"1\": {\n masterMessage: (spaceId: string) => `tinycloud-vault-master-v1:${spaceId}`,\n identityMessage: \"tinycloud-encryption-identity-v1\",\n },\n} as const;\n\nexport const CURRENT_VAULT_VERSION = \"1\" as const;\n\n/** Metadata header keys used in vault envelopes */\nexport const VaultHeaders = {\n VERSION: \"x-vault-version\",\n CIPHER: \"x-vault-cipher\",\n KEY_ID: \"x-vault-key-id\",\n CONTENT_TYPE: \"x-vault-content-type\",\n KDF: \"x-vault-kdf\",\n KEY_ROTATION: \"x-vault-key-rotation\",\n GRANT_VERSION: \"x-vault-grant-version\",\n GRANTOR: \"x-vault-grantor\",\n} as const;\n","/**\n * Caches vault signatures in IndexedDB, encrypted with a\n * non-extractable CryptoKey. Browser-only — no-ops in Node.\n */\n\n// Minimal type declarations for browser APIs used below.\n// The sdk-services tsconfig targets ES2020 without DOM lib;\n// these declarations let the file compile while the runtime\n// guards (isBrowser()) ensure we never call them in Node.\ndeclare const indexedDB: {\n open(name: string, version?: number): IDBOpenDBRequest;\n};\ninterface IDBOpenDBRequest {\n result: IDBDatabase;\n error: DOMException | null;\n onupgradeneeded: ((this: IDBOpenDBRequest) => void) | null;\n onsuccess: ((this: IDBOpenDBRequest) => void) | null;\n onerror: ((this: IDBOpenDBRequest) => void) | null;\n}\ninterface IDBDatabase {\n objectStoreNames: { contains(name: string): boolean };\n createObjectStore(name: string): void;\n transaction(storeNames: string | string[], mode?: string): IDBTransaction;\n}\ninterface IDBTransaction {\n objectStore(name: string): IDBObjectStore;\n}\ninterface IDBObjectStore {\n get(key: string): IDBRequest;\n put(value: unknown, key: string): IDBRequest;\n delete(key: string): IDBRequest;\n getAllKeys(): IDBRequest;\n}\ninterface IDBRequest<T = unknown> {\n result: T;\n error: DOMException | null;\n onsuccess: ((this: IDBRequest<T>) => void) | null;\n onerror: ((this: IDBRequest<T>) => void) | null;\n}\ntype IDBValidKey = string | number | Date | ArrayBuffer | Uint8Array | IDBValidKey[];\n\nconst DB_NAME = \"tinycloud-vault-cache\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"signatures\";\nconst WRAP_KEY_ID = \"__wrap_key__\";\n\n/** Check whether we're in a browser with IndexedDB + SubtleCrypto support. */\nfunction isBrowser(): boolean {\n try {\n return (\n typeof indexedDB !== \"undefined\" &&\n typeof crypto !== \"undefined\" &&\n typeof crypto.subtle !== \"undefined\"\n );\n } catch {\n return false;\n }\n}\n\n/** Open (or create) the IndexedDB database. */\nfunction openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n}\n\n/** Generic IDB get helper. */\nfunction idbGet<T>(db: IDBDatabase, key: string): Promise<T | undefined> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.get(key);\n req.onsuccess = () => resolve(req.result as T | undefined);\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB put helper. */\nfunction idbPut(db: IDBDatabase, key: string, value: unknown): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.put(value, key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** Generic IDB delete helper. */\nfunction idbDelete(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readwrite\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.delete(key);\n req.onsuccess = () => resolve();\n req.onerror = () => reject(req.error);\n });\n}\n\n/** List all keys in the store. */\nfunction idbKeys(db: IDBDatabase): Promise<string[]> {\n return new Promise((resolve, reject) => {\n const tx = db.transaction(STORE_NAME, \"readonly\");\n const store = tx.objectStore(STORE_NAME);\n const req = store.getAllKeys();\n req.onsuccess = () =>\n resolve((req.result as IDBValidKey[]).filter((k) => typeof k === \"string\") as string[]);\n req.onerror = () => reject(req.error);\n });\n}\n\ninterface EncryptedEntry {\n iv: Uint8Array;\n ciphertext: Uint8Array;\n}\n\n/**\n * Get or create the non-extractable AES-GCM wrapping key.\n * The key is stored directly in IndexedDB (structured-clone preserves CryptoKey).\n */\nasync function getWrapKey(db: IDBDatabase): Promise<CryptoKey> {\n const existing = await idbGet<CryptoKey>(db, WRAP_KEY_ID);\n if (existing) return existing;\n\n const key = await crypto.subtle.generateKey(\n { name: \"AES-GCM\", length: 256 },\n false, // non-extractable\n [\"encrypt\", \"decrypt\"]\n );\n await idbPut(db, WRAP_KEY_ID, key);\n return key;\n}\n\n/** Encrypt signature bytes with the wrap key. */\nasync function encryptSig(\n wrapKey: CryptoKey,\n sigBytes: Uint8Array\n): Promise<EncryptedEntry> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = new Uint8Array(\n await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, wrapKey, sigBytes)\n );\n return { iv, ciphertext };\n}\n\n/** Decrypt an encrypted entry back to signature bytes. */\nasync function decryptSig(\n wrapKey: CryptoKey,\n entry: EncryptedEntry\n): Promise<Uint8Array> {\n const plaintext = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: entry.iv },\n wrapKey,\n entry.ciphertext\n );\n return new Uint8Array(plaintext);\n}\n\n/** Cache key for a given spaceId. */\nfunction cacheKey(spaceId: string): string {\n return `sig:${spaceId}`;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Load a cached signature for the given spaceId.\n * Returns null on cache miss or in non-browser environments.\n */\nexport async function loadCachedSignature(\n spaceId: string\n): Promise<Uint8Array | null> {\n if (!isBrowser()) return null;\n try {\n const db = await openDB();\n const entry = await idbGet<EncryptedEntry>(db, cacheKey(spaceId));\n if (!entry) return null;\n const wrapKey = await getWrapKey(db);\n return await decryptSig(wrapKey, entry);\n } catch {\n return null;\n }\n}\n\n/**\n * Cache a signature for the given spaceId.\n * No-ops in non-browser environments.\n */\nexport async function cacheSignature(\n spaceId: string,\n sigBytes: Uint8Array\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n const wrapKey = await getWrapKey(db);\n const encrypted = await encryptSig(wrapKey, sigBytes);\n await idbPut(db, cacheKey(spaceId), encrypted);\n } catch {\n // Best-effort — swallow errors\n }\n}\n\n/**\n * Clear cached signature(s).\n * If spaceId is provided, clears only that entry; otherwise clears all.\n */\nexport async function clearSignatureCache(\n spaceId?: string\n): Promise<void> {\n if (!isBrowser()) return;\n try {\n const db = await openDB();\n if (spaceId) {\n await idbDelete(db, cacheKey(spaceId));\n } else {\n // Clear all sig entries but keep the wrap key\n const keys = await idbKeys(db);\n for (const k of keys) {\n if (k.startsWith(\"sig:\")) {\n await idbDelete(db, k);\n }\n }\n }\n } catch {\n // Best-effort\n }\n}\n","/**\n * DataVaultService - Encrypted key-value storage service implementation.\n *\n * Platform-agnostic encrypted KV service that wraps KVService internally.\n * Uses dependency injection via VaultCrypto for WASM crypto operations\n * and DataVaultServiceConfig for platform dependencies.\n *\n * Architecture:\n * - Extends BaseService (not KVService)\n * - Wraps two KV instances: dataKV (prefix \"vault/\") and keyKV (prefix \"keys/\")\n * - Master key and encryption identity live in memory only (cleared on lock)\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport {\n Result,\n ok,\n err,\n serviceError,\n IServiceContext,\n ServiceSession,\n} from \"../types\";\nimport { wrapError } from \"../errors\";\nimport type { IKVService } from \"../kv/IKVService\";\nimport type { KVService } from \"../kv/KVService\";\nimport type {\n DecryptCapabilityProof,\n InlineEncryptedEnvelope,\n} from \"../encryption\";\nimport type { IDataVaultService } from \"./IDataVaultService\";\nimport {\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultGrantOptions,\n VaultEntry,\n VaultError,\n VaultErrorInput,\n VaultHeaders,\n VaultVersionConfig,\n CURRENT_VAULT_VERSION,\n} from \"./types\";\nimport {\n loadCachedSignature,\n cacheSignature,\n clearSignatureCache,\n} from \"./SignatureCache\";\n\n// =============================================================================\n// Crypto Interface\n// =============================================================================\n\n/**\n * Crypto operations interface - implementations provided by WASM bindings.\n * Passed via DataVaultServiceConfig to keep the service platform-agnostic.\n */\nexport interface VaultCrypto {\n encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n deriveKey(\n signature: Uint8Array,\n salt: Uint8Array,\n info: Uint8Array\n ): Uint8Array;\n x25519FromSeed(\n seed: Uint8Array\n ): { publicKey: Uint8Array; privateKey: Uint8Array };\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n randomBytes(length: number): Uint8Array;\n sha256(data: Uint8Array): Uint8Array;\n}\n\n// =============================================================================\n// Extended Config\n// =============================================================================\n\n/**\n * Extended config used internally by DataVaultService.\n * Includes crypto operations and TinyCloud instance references.\n */\ninterface DataVaultServiceConfig extends DataVaultConfig {\n [key: string]: unknown;\n /** Crypto operations (WASM bindings) */\n crypto: VaultCrypto;\n /** TinyCloud instance for space/kv/delegation operations */\n tc: {\n kv: IKVService;\n ensurePublicSpace(): Promise<Result<void>>;\n publicKV: IKVService;\n readPublicSpace<T>(\n host: string,\n spaceId: string,\n key: string\n ): Promise<Result<T>>;\n makePublicSpaceId(address: string, chainId: number): string;\n did: string;\n address: string;\n chainId: number;\n hosts: string[];\n };\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/** Convert a caught value to an Error. WASM throws plain objects, not Error instances. */\nfunction toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\nfunction toBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nfunction fromBytes(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nfunction hexEncode(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((acc, arr) => acc + arr.length, 0);\n const result = new Uint8Array(total);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction base64Encode(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64Decode(str: string): Uint8Array {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\nfunction unwrapKVData<T = unknown>(value: unknown): T {\n if (value !== null && typeof value === \"object\" && \"data\" in value) {\n return (value as { data: T }).data;\n }\n return value as T;\n}\n\nfunction isUnlockSigner(\n signer: unknown\n): signer is { signMessage(message: string): Promise<string> } {\n return (\n typeof signer === \"object\" &&\n signer !== null &&\n typeof (signer as { signMessage?: unknown }).signMessage === \"function\"\n );\n}\n\nfunction defaultVaultMessage(input: VaultErrorInput): string {\n switch (input.code) {\n case \"DECRYPTION_FAILED\": return input.message ?? \"Decryption failed\";\n case \"KEY_NOT_FOUND\": return input.message ?? `Key not found: ${input.key}`;\n case \"INTEGRITY_ERROR\": return input.message ?? \"Integrity check failed\";\n case \"GRANT_NOT_FOUND\": return input.message ?? `Grant not found: ${input.grantor} / ${input.key}`;\n case \"VAULT_LOCKED\": return input.message ?? \"Vault is locked\";\n case \"PUBLIC_KEY_NOT_FOUND\": return input.message ?? `Public key not found for ${input.did}`;\n case \"STORAGE_ERROR\": return input.message ?? input.cause.message;\n }\n}\n\nfunction vaultError(input: VaultErrorInput): Result<never, VaultError> {\n const error: VaultError = {\n ...input,\n service: \"vault\",\n message: defaultVaultMessage(input),\n };\n return { ok: false, error };\n}\n\n// =============================================================================\n// DataVaultService\n// =============================================================================\n\n/**\n * Data Vault service implementation.\n *\n * Provides encrypted key-value storage with client-side encryption,\n * key management, and sharing via X25519 grants.\n *\n * @example\n * ```typescript\n * // Unlock the vault\n * await vault.unlock(signer);\n *\n * // Store encrypted data\n * await vault.put('secret/notes', { content: 'Hello' });\n *\n * // Retrieve and decrypt\n * const entry = await vault.get<{ content: string }>('secret/notes');\n * if (entry.ok) {\n * console.log(entry.data.value.content); // 'Hello'\n * }\n *\n * // Share with another user\n * await vault.grant('secret/notes', recipientDID);\n * ```\n */\nexport class DataVaultService extends BaseService implements IDataVaultService {\n /**\n * Service identifier for registration.\n */\n static readonly serviceName = \"vault\";\n\n /**\n * Service configuration.\n */\n declare protected _config: DataVaultServiceConfig;\n\n private masterKey: Uint8Array | null = null;\n private encryptionIdentity: {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n } | null = null;\n private _isUnlocked = false;\n private vaultConfig: DataVaultServiceConfig;\n private unlockInFlight: Promise<Result<void, VaultError>> | null = null;\n\n /**\n * Create a new DataVaultService instance.\n *\n * @param config - Service configuration including crypto and tc references\n */\n constructor(config: DataVaultServiceConfig) {\n super();\n this.vaultConfig = config;\n this._config = config;\n }\n\n /**\n * Get the service configuration.\n */\n get config(): DataVaultServiceConfig {\n return this._config;\n }\n\n /**\n * Whether the vault is currently unlocked.\n */\n get isUnlocked(): boolean {\n return this.usesNetworkEncryption || this._isUnlocked;\n }\n\n /**\n * The vault's public encryption key (X25519).\n * Throws if vault is locked.\n */\n get publicKey(): Uint8Array {\n if (this.usesNetworkEncryption) {\n throw new Error(\"Network-encrypted vaults do not expose a local public key\");\n }\n if (!this.encryptionIdentity) {\n throw new Error(\"Vault is locked\");\n }\n return this.encryptionIdentity.publicKey;\n }\n\n /**\n * Convenience accessor for crypto operations.\n */\n private get crypto(): VaultCrypto {\n return this.vaultConfig.crypto;\n }\n\n /**\n * Convenience accessor for TinyCloud instance.\n */\n private get tc() {\n return this.vaultConfig.tc;\n }\n\n private get networkEncryption() {\n return this.vaultConfig.encryption;\n }\n\n private get usesNetworkEncryption(): boolean {\n return this.networkEncryption !== undefined;\n }\n\n /**\n * Get the host URL.\n */\n private get host(): string {\n return this.tc.hosts[0];\n }\n\n private async decryptCapabilityProof(): Promise<DecryptCapabilityProof> {\n const proof = this.networkEncryption?.decryptCapabilityProof;\n if (typeof proof === \"function\") {\n return await proof();\n }\n return proof ?? { proofs: [] };\n }\n\n private serializeValue(\n value: unknown,\n options?: VaultPutOptions,\n ): { plaintext: Uint8Array; contentType: string } {\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array ? \"application/octet-stream\" : \"application/json\");\n return { plaintext, contentType };\n }\n\n private deserializeValue<T>(\n plaintext: Uint8Array,\n contentType: string,\n options?: VaultGetOptions<T>,\n ): T {\n if (options?.raw) {\n return plaintext as unknown as T;\n }\n if (options?.deserialize) {\n return options.deserialize(plaintext);\n }\n if (contentType === \"application/json\") {\n return JSON.parse(fromBytes(plaintext)) as T;\n }\n return plaintext as unknown as T;\n }\n\n // =========================================================================\n // Phase 1: Core Operations\n // =========================================================================\n\n /**\n * Unlock the vault. Derives keys from two wallet signatures:\n * 1. Master signature (per-space) — used to derive the master encryption key\n * 2. Identity signature (per-address) — used to derive X25519 encryption identity\n *\n * If the identity public key already exists in the public space, the identity\n * signature is skipped entirely (no wallet popup). The identity private key is\n * only needed for sharing operations.\n *\n * @param signer - Object with signMessage method. Optional when cached\n * signatures exist (browser only).\n */\n async unlock(\n signer?: { signMessage(message: string): Promise<string> } | unknown\n ): Promise<Result<void, VaultError>> {\n if (this.usesNetworkEncryption) {\n this._isUnlocked = true;\n return { ok: true, data: undefined };\n }\n\n const unlockSigner = isUnlockSigner(signer) ? signer : undefined;\n if (\n this._isUnlocked &&\n this.masterKey &&\n (this.encryptionIdentity || !unlockSigner)\n ) {\n return { ok: true, data: undefined };\n }\n\n if (this.unlockInFlight) {\n return this.unlockInFlight;\n }\n\n this.unlockInFlight = this.withTelemetry(\"unlock\", undefined, async () => {\n const spaceId = this.vaultConfig.spaceId;\n const versionConfig = VaultVersionConfig[CURRENT_VAULT_VERSION];\n const masterCacheKey = `vault-master:${spaceId}`;\n const identityCacheKey = `vault-identity:${this.tc.address}`;\n\n try {\n // -----------------------------------------------------------------\n // Step 1: Master signature → master key\n // -----------------------------------------------------------------\n if (!this.masterKey) {\n let masterSigBytes = await loadCachedSignature(masterCacheKey);\n\n if (!masterSigBytes) {\n if (!unlockSigner) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Signer is required when no cached master signature exists\",\n });\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.masterMessage(spaceId)\n );\n masterSigBytes = toBytes(sig);\n await cacheSignature(masterCacheKey, masterSigBytes);\n }\n\n // Derive master key: deriveKey(sigBytes, sha256(spaceId), \"vault-master\")\n this.masterKey = this.crypto.deriveKey(\n masterSigBytes,\n this.crypto.sha256(toBytes(spaceId)),\n toBytes(\"vault-master\")\n );\n }\n\n // -----------------------------------------------------------------\n // Step 2: Identity — check public space first, then sign if needed\n // -----------------------------------------------------------------\n const publicSpaceId = this.tc.makePublicSpaceId(this.tc.address, this.tc.chainId);\n\n // Check public space for existing vault pubkey\n let existingPubKey: string | null = null;\n try {\n const existing = await this.tc.readPublicSpace<string>(\n this.host, publicSpaceId, \".well-known/vault-pubkey\"\n );\n if (existing.ok && existing.data) {\n existingPubKey = existing.data as string;\n }\n } catch {\n // Read failed — treat as missing\n }\n\n if (existingPubKey) {\n // Public key exists — trust it, skip identity signing entirely\n this.encryptionIdentity = {\n publicKey: base64Decode(existingPubKey),\n privateKey: new Uint8Array(0), // private key not available without signing\n };\n } else {\n // Public key missing — need identity signature to derive keypair\n let identitySigBytes = await loadCachedSignature(identityCacheKey);\n\n if (!identitySigBytes) {\n if (!unlockSigner) {\n // No signer available — skip identity derivation.\n // Vault still works for get/put (only needs master key).\n this.encryptionIdentity = null;\n this._isUnlocked = true;\n return ok(undefined);\n }\n const sig = await unlockSigner.signMessage(\n versionConfig.identityMessage\n );\n identitySigBytes = toBytes(sig);\n await cacheSignature(identityCacheKey, identitySigBytes);\n }\n\n // Derive X25519 keypair from identity signature\n const seed = this.crypto.deriveKey(\n identitySigBytes,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"encryption-identity\")\n );\n this.encryptionIdentity = this.crypto.x25519FromSeed(seed);\n\n // Publish public key to public space\n try {\n const pubKeyB64 = base64Encode(this.encryptionIdentity.publicKey);\n await this.tc.ensurePublicSpace();\n await this.tc.publicKV.put(\".well-known/vault-pubkey\", pubKeyB64);\n await this.tc.publicKV.put(\".well-known/vault-version\", CURRENT_VAULT_VERSION);\n await this.tc.publicKV.put(\".well-known/vault-space\", this.vaultConfig.spaceId);\n } catch {\n // Publishing failed — vault still usable\n }\n }\n\n this._isUnlocked = true;\n return ok(undefined);\n } catch (error) {\n // Clear key material on failure\n this.masterKey = null;\n this.encryptionIdentity = null;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n\n try {\n return await this.unlockInFlight;\n } finally {\n this.unlockInFlight = null;\n }\n }\n\n /**\n * Clear the cached vault signatures.\n *\n * @param spaceId - Clear only this space's master cache. If omitted, clears all.\n */\n async clearCache(spaceId?: string): Promise<void> {\n if (spaceId) {\n await clearSignatureCache(`vault-master:${spaceId}`);\n } else {\n await clearSignatureCache();\n }\n }\n\n /**\n * Lock the vault, clearing all key material from memory.\n */\n lock(): void {\n this.masterKey = null;\n this.encryptionIdentity = null;\n this._isUnlocked = false;\n }\n\n /**\n * Called when SDK signs out. Locks the vault and aborts operations.\n */\n onSignOut(): void {\n this.lock();\n super.onSignOut();\n }\n\n private async putNetworkEncrypted(\n key: string,\n value: unknown,\n options?: VaultPutOptions,\n ): Promise<Result<void, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const { plaintext, contentType } = this.serializeValue(value, options);\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"2\",\n [VaultHeaders.CIPHER]: \"tinycloud-network-envelope\",\n [VaultHeaders.CONTENT_TYPE]: contentType,\n ...(options?.metadata ?? {}),\n };\n const aad = toBytes(`tinycloud.vault:${this.vaultConfig.spaceId}:${key}`);\n const envelopeResult = await config.service.encryptToNetwork(\n config.networkId,\n plaintext,\n { aad, metadata },\n );\n if (!envelopeResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(envelopeResult.error.message),\n });\n }\n\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n JSON.stringify(envelopeResult.data),\n );\n if (!valuePutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store encrypted value: ${valuePutResult.error.message}`,\n ),\n });\n }\n\n return { ok: true, data: undefined };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n private async getNetworkEncrypted<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>,\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(envelope, proof);\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n private async headNetworkEncrypted(\n key: string,\n ): Promise<Result<Record<string, string>, VaultError>> {\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n return { ok: true, data: envelope.metadata ?? {} };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n /**\n * Encrypt and store a value at the given key.\n *\n * @param key - The key to store under\n * @param value - The value to encrypt and store\n * @param options - Optional put configuration\n */\n async put(\n key: string,\n value: unknown,\n options?: VaultPutOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"put\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.putNetworkEncrypted(key, value, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before storing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Serialize value\n let plaintext: Uint8Array;\n if (value instanceof Uint8Array) {\n plaintext = value;\n } else if (options?.serialize) {\n plaintext = options.serialize(value);\n } else if (typeof value === \"string\") {\n plaintext = toBytes(value);\n } else {\n plaintext = toBytes(JSON.stringify(value));\n }\n\n const contentType =\n options?.contentType ??\n (value instanceof Uint8Array\n ? \"application/octet-stream\"\n : \"application/json\");\n\n // Generate per-entry key\n const entryKey = this.crypto.randomBytes(32);\n const keyId = hexEncode(this.crypto.sha256(entryKey)).slice(0, 16);\n\n // Encrypt value with entry key\n const encrypted = this.crypto.encrypt(entryKey, plaintext);\n\n // Encrypt entry key with master key\n const keyBlob = this.crypto.encrypt(this.masterKey, entryKey);\n\n // Build metadata\n const metadata: Record<string, string> = {\n [VaultHeaders.VERSION]: \"1\",\n [VaultHeaders.CIPHER]: \"aes-256-gcm\",\n [VaultHeaders.KEY_ID]: keyId,\n [VaultHeaders.CONTENT_TYPE]: contentType,\n [VaultHeaders.KDF]: \"hkdf-sha256\",\n [VaultHeaders.KEY_ROTATION]:\n this.vaultConfig.keyRotation ?? \"per-write\",\n ...(options?.metadata ?? {}),\n };\n\n // Store encrypted entry key in key space\n const keyMetadata = JSON.stringify({\n keyId,\n contentType,\n ...metadata,\n });\n const keyPayload = JSON.stringify({\n key: base64Encode(keyBlob),\n metadata: keyMetadata,\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store key blob: ${keyPutResult.error.message}`\n ),\n });\n }\n\n // Store encrypted value in data space\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store encrypted value: ${valuePutResult.error.message}`\n ),\n });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * Retrieve and decrypt a value by key.\n *\n * @param key - The key to retrieve\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async get<T = unknown>(\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"get\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.getNetworkEncrypted<T>(key, options);\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch encrypted entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Fetch encrypted value from data space\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const encryptedBytes = base64Decode(valueEnvelope.data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Delete an encrypted key.\n * Removes both the encrypted value and the key blob.\n *\n * @param key - The key to delete\n */\n async delete(key: string): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"delete\", key, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before deleting data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n if (this.usesNetworkEncryption) {\n const valueDelResult = await this.tc.kv.delete(`vault/${key}`);\n if (!valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n return ok(undefined);\n }\n\n // Delete from both key space and data space\n const [keyDelResult, valueDelResult] = await Promise.all([\n this.tc.kv.delete(`keys/${key}`),\n this.tc.kv.delete(`vault/${key}`),\n ]);\n\n if (!keyDelResult.ok && !valueDelResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * List vault keys with optional prefix filtering.\n *\n * @param options - Optional list configuration\n * @returns Result with array of key names (vault/ prefix stripped)\n */\n async list(\n options?: VaultListOptions\n ): Promise<Result<string[], VaultError>> {\n return this.withTelemetry(\"list\", options?.prefix, async () => {\n if (!this.isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listPrefix = options?.prefix\n ? `vault/${options.prefix}`\n : \"vault/\";\n\n const listResult = await this.tc.kv.list({\n prefix: listPrefix,\n removePrefix: true,\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list vault keys: ${listResult.error.message}`\n ),\n });\n }\n\n // Keys are already stripped of the \"vault/\" prefix by removePrefix\n let keys = listResult.data.keys;\n\n // If a user prefix was provided, strip it too if requested\n if (options?.removePrefix && options.prefix) {\n const userPrefix = options.prefix.endsWith(\"/\")\n ? options.prefix\n : `${options.prefix}/`;\n keys = keys.map((k) =>\n k.startsWith(userPrefix) ? k.slice(userPrefix.length) : k\n );\n }\n\n return ok(keys);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<string[], VaultError>>;\n }\n\n /**\n * Get envelope metadata for a key without decrypting the value.\n *\n * @param key - The key to inspect\n * @returns Result with metadata headers\n */\n async head(\n key: string\n ): Promise<Result<Record<string, string>, VaultError>> {\n return this.withTelemetry(\"head\", key, async () => {\n if (this.usesNetworkEncryption) {\n return this.headNetworkEncrypted(key);\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading metadata\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Fetch envelope without decrypting\n const valueResult = await this.tc.kv.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const valueEnvelope = JSON.parse(valueResult.data.data as string);\n const metadata: Record<string, string> = valueEnvelope.metadata ?? {};\n return ok(metadata);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<Record<string, string>, VaultError>>;\n }\n\n // =========================================================================\n // Batch Operations\n // =========================================================================\n\n /**\n * Encrypt and store multiple entries.\n *\n * @param entries - Array of key/value pairs with optional per-entry options\n * @returns Array of results, one per entry\n */\n async putMany(\n entries: Array<{ key: string; value: unknown; options?: VaultPutOptions }>\n ): Promise<Result<void, VaultError>[]> {\n return Promise.all(\n entries.map((entry) => this.put(entry.key, entry.value, entry.options))\n );\n }\n\n /**\n * Retrieve and decrypt multiple keys.\n *\n * @param keys - Array of keys to retrieve\n * @param options - Optional get configuration applied to all entries\n * @returns Array of results, one per key\n */\n async getMany<T = unknown>(\n keys: string[],\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>[]> {\n return Promise.all(keys.map((key) => this.get<T>(key, options)));\n }\n\n // =========================================================================\n // Phase 2: Sharing\n // =========================================================================\n\n /**\n * Re-encrypt a vault key for another user (renamed from grant).\n * Re-encrypts the data key to the recipient's public key via X25519 DH.\n *\n * @param key - The key to share\n * @param recipientDID - The recipient's primary DID (did:pkh:...)\n * @param options - Optional grant configuration\n */\n async reencrypt(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"reencrypt\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n void options;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; grant tinycloud.encryption/decrypt on the network plus KV access to vault data.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before granting access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: Resolve recipient's public key\n const pubKeyResult = await this.resolvePublicKey(recipientDID);\n if (!pubKeyResult.ok) {\n return pubKeyResult;\n }\n const bobPubKey = pubKeyResult.data;\n\n // Step 2: Fetch and decrypt entry key from key space\n const keyResult = await this.tc.kv.get<string>(`keys/${key}`, {\n raw: true,\n });\n if (!keyResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n\n const keyEnvelope = JSON.parse(keyResult.data.data as string);\n const keyBlobBytes = base64Decode(keyEnvelope.key);\n const entryKey = this.crypto.decrypt(this.masterKey, keyBlobBytes);\n\n // Step 3: Create ephemeral X25519 key pair\n const ephemeralSeed = this.crypto.randomBytes(32);\n const ephemeralKeyPair = this.crypto.x25519FromSeed(ephemeralSeed);\n\n // Step 4: Compute shared secret via DH\n const sharedSecret = this.crypto.x25519Dh(\n ephemeralKeyPair.privateKey,\n bobPubKey\n );\n\n // Step 5: Derive encryption key from shared secret\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 6: Encrypt entry key with derived key\n const encryptedGrant = this.crypto.encrypt(encryptionKey, entryKey);\n\n // Step 7: Concatenate ephemeral public key + encrypted grant\n const grantBlob = concatBytes(\n ephemeralKeyPair.publicKey,\n encryptedGrant\n );\n\n // Step 8: Store grant in key space\n const grantPayload = JSON.stringify({\n grant: base64Encode(grantBlob),\n spaceId: this.vaultConfig.spaceId,\n metadata: {\n [VaultHeaders.GRANT_VERSION]: \"1\",\n [VaultHeaders.GRANTOR]: this.tc.did,\n ...(options?.metadata ?? {}),\n },\n });\n // Store grant in the vault's space (main space)\n const grantPutResult = await this.tc.kv.put(\n `grants/${recipientDID}/${key}`,\n grantPayload\n );\n if (!grantPutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store grant: ${grantPutResult.error.message}`\n ),\n });\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n /**\n * @deprecated Use reencrypt() instead.\n */\n async grant(\n key: string,\n recipientDID: string,\n options?: VaultGrantOptions\n ): Promise<Result<void, VaultError>> {\n return this.reencrypt(key, recipientDID, options);\n }\n\n /**\n * Retrieve and decrypt a value shared by another user.\n *\n * @param grantorDID - The DID of the user who shared the data\n * @param key - The key that was shared\n * @param options - Optional get configuration\n * @returns Result with the decrypted entry\n */\n async getShared<T = unknown>(\n grantorDID: string,\n key: string,\n options?: VaultGetOptions<T>\n ): Promise<Result<VaultEntry<T>, VaultError>> {\n return this.withTelemetry(\"getShared\", key, async () => {\n if (this.usesNetworkEncryption) {\n const grantorKV = options?.kv;\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv.\",\n ),\n });\n }\n\n const config = this.networkEncryption;\n if (!config) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Network encryption is not configured\",\n });\n }\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({ code: \"KEY_NOT_FOUND\", key });\n }\n const rawEnvelope = unwrapKVData<string>(valueResult.data);\n const envelope = (\n typeof rawEnvelope === \"string\" ? JSON.parse(rawEnvelope) : rawEnvelope\n ) as InlineEncryptedEnvelope;\n const proof = await this.decryptCapabilityProof();\n const plaintextResult = await config.service.decryptEnvelope(\n envelope,\n proof,\n );\n if (!plaintextResult.ok) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: plaintextResult.error.message,\n });\n }\n\n const metadata: Record<string, string> = envelope.metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId =\n metadata[VaultHeaders.KEY_ID] ??\n envelope.encryptedSymmetricKeyHash.slice(0, 16);\n const value = this.deserializeValue<T>(\n plaintextResult.data,\n contentType,\n options,\n );\n void grantorDID;\n return { ok: true, data: { value, metadata, keyId } };\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: toError(error),\n });\n }\n }\n\n if (\n !this._isUnlocked ||\n !this.masterKey ||\n !this.encryptionIdentity\n ) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before reading shared data\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const myDID = this.tc.did;\n const grantorKV = options?.kv;\n\n if (!grantorKV) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"getShared requires a delegated KV service via options.kv. \" +\n \"Use useDelegation() to get delegated access, then pass { kv: access.kv }.\"\n ),\n });\n }\n\n // Step 1: Fetch grant from grantor's space via delegated KV\n const grantResult = await grantorKV.get<string>(`grants/${myDID}/${key}`, {\n raw: true,\n });\n if (!grantResult.ok) {\n return vaultError({\n code: \"GRANT_NOT_FOUND\",\n grantor: grantorDID,\n key,\n });\n }\n\n const grantEnvelope = typeof grantResult.data?.data === \"string\"\n ? JSON.parse(grantResult.data.data as string)\n : grantResult.data?.data;\n const grantBlobBytes = base64Decode((grantEnvelope as any).grant);\n\n // Step 2: Extract ephemeral public key and encrypted grant\n const ephemeralPubKey = grantBlobBytes.slice(0, 32);\n const encryptedGrant = grantBlobBytes.slice(32);\n\n // Step 3: Compute shared secret using our private key\n const sharedSecret = this.crypto.x25519Dh(\n this.encryptionIdentity.privateKey,\n ephemeralPubKey\n );\n\n // Step 4: Derive decryption key\n const encryptionKey = this.crypto.deriveKey(\n sharedSecret,\n toBytes(\"tinycloud-x25519\"),\n toBytes(\"vault-grant\")\n );\n\n // Step 5: Decrypt entry key\n const entryKey = this.crypto.decrypt(encryptionKey, encryptedGrant);\n\n // Step 6: Fetch encrypted value from grantor's space via delegated KV\n const valueResult = await grantorKV.get<string>(`vault/${key}`, {\n raw: true,\n });\n if (!valueResult.ok) {\n return vaultError({\n code: \"KEY_NOT_FOUND\",\n key,\n });\n }\n\n const valueEnvelope = typeof valueResult.data?.data === \"string\"\n ? JSON.parse(valueResult.data.data as string)\n : valueResult.data?.data;\n const encryptedBytes = base64Decode((valueEnvelope as any).data);\n const plaintext = this.crypto.decrypt(entryKey, encryptedBytes);\n\n // Read metadata\n const metadata: Record<string, string> = (valueEnvelope as any).metadata ?? {};\n const contentType =\n metadata[VaultHeaders.CONTENT_TYPE] ?? \"application/json\";\n const keyId = metadata[VaultHeaders.KEY_ID] ?? \"\";\n\n // Deserialize\n let value: T;\n if (options?.raw) {\n value = plaintext as unknown as T;\n } else if (options?.deserialize) {\n value = options.deserialize(plaintext);\n } else if (contentType === \"application/json\") {\n value = JSON.parse(fromBytes(plaintext)) as T;\n } else {\n value = plaintext as unknown as T;\n }\n\n return ok({ value, metadata, keyId });\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"decryption\")\n ) {\n return vaultError({\n code: \"DECRYPTION_FAILED\",\n message: error.message,\n });\n }\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<VaultEntry<T>, VaultError>>;\n }\n\n /**\n * Resolve another user's public encryption key from their DID.\n *\n * @param did - The DID to resolve (did:pkh:eip155:{chainId}:{address})\n * @returns Result with the public key bytes\n */\n async resolvePublicKey(\n did: string\n ): Promise<Result<Uint8Array, VaultError>> {\n try {\n const parts = this.parseDID(did);\n if (!parts) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const spaceId = this.tc.makePublicSpaceId(\n parts.address,\n parts.chainId\n );\n\n const result = await this.tc.readPublicSpace<string>(\n this.host,\n spaceId,\n \".well-known/vault-pubkey\"\n );\n\n if (!result.ok) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n\n const pubKeyBytes = base64Decode(result.data as string);\n return { ok: true, data: pubKeyBytes } as Result<Uint8Array, VaultError>;\n } catch (error) {\n return vaultError({ code: \"PUBLIC_KEY_NOT_FOUND\", did });\n }\n }\n\n /**\n * List DIDs that have been granted access to a key.\n *\n * @param key - The key to list grants for\n * @returns Result with array of recipient DIDs\n */\n async listGrants(\n key: string\n ): Promise<Result<string[], VaultError>> {\n return this.withTelemetry(\"listGrants\", key, async () => {\n if (this.usesNetworkEncryption) {\n void key;\n return { ok: true, data: [] };\n }\n\n if (!this._isUnlocked) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before listing grants\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n const listResult = await this.tc.kv.list({\n prefix: \"grants/\",\n removePrefix: true,\n });\n\n if (!listResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to list grants: ${listResult.error.message}`\n ),\n });\n }\n\n // Grant paths are: {recipientDID}/{key}\n // Filter for the specific key and extract DIDs\n const dids: string[] = [];\n for (const grantPath of listResult.data.keys) {\n // Path format: {recipientDID}/{key}\n // The key may contain slashes, so we need to match the suffix\n if (grantPath.endsWith(`/${key}`)) {\n const did = grantPath.slice(\n 0,\n grantPath.length - key.length - 1\n );\n if (did) {\n dids.push(did);\n }\n }\n }\n\n return ok(dids);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<string[], VaultError>>;\n }\n\n // =========================================================================\n // Phase 3: Key Rotation / Revocation\n // =========================================================================\n\n /**\n * Revoke a previously issued grant.\n *\n * This performs a full key rotation:\n * 1. Lists current grantees\n * 2. Removes the revoked recipient\n * 3. Re-encrypts the value with a new entry key\n * 4. Re-issues grants to remaining recipients\n *\n * @param key - The key to revoke access to\n * @param recipientDID - The recipient whose access to revoke\n */\n async revoke(\n key: string,\n recipientDID: string\n ): Promise<Result<void, VaultError>> {\n return this.withTelemetry(\"revoke\", key, async () => {\n if (this.usesNetworkEncryption) {\n void recipientDID;\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n \"Vault key grants are deprecated for network-encrypted vaults; revoke KV and tinycloud.encryption/decrypt grants instead.\",\n ),\n });\n }\n\n if (!this._isUnlocked || !this.masterKey) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Vault must be unlocked before revoking access\",\n });\n }\n\n if (!this.requireAuth()) {\n return vaultError({\n code: \"VAULT_LOCKED\",\n message: \"Authentication required\",\n });\n }\n\n try {\n // Step 1: List all current grantees\n const granteesResult = await this.listGrants(key);\n if (!granteesResult.ok) {\n return granteesResult;\n }\n\n const remainingGrantees = granteesResult.data.filter(\n (did) => did !== recipientDID\n );\n\n // Step 2: Delete the grant for the revoked recipient\n const deleteGrantResult = await this.tc.kv.delete(\n `grants/${recipientDID}/${key}`\n );\n // Grant may already be deleted, that's fine\n\n // Step 3: Fetch and decrypt current value\n const getResult = await this.get(key);\n if (!getResult.ok) {\n return getResult as Result<never, VaultError>;\n }\n\n const currentEntry = getResult.data;\n\n // Step 4: Generate new entry key\n const newEntryKey = this.crypto.randomBytes(32);\n const newKeyId = hexEncode(this.crypto.sha256(newEntryKey)).slice(\n 0,\n 16\n );\n\n // Step 5: Re-serialize and re-encrypt value with new key\n let plaintext: Uint8Array;\n if (currentEntry.value instanceof Uint8Array) {\n plaintext = currentEntry.value;\n } else {\n plaintext = toBytes(JSON.stringify(currentEntry.value));\n }\n\n const encrypted = this.crypto.encrypt(newEntryKey, plaintext);\n\n // Step 6: Encrypt new entry key with master key\n const newKeyBlob = this.crypto.encrypt(this.masterKey, newEntryKey);\n\n // Step 7: Update metadata with new key ID\n const metadata: Record<string, string> = {\n ...currentEntry.metadata,\n [VaultHeaders.KEY_ID]: newKeyId,\n };\n\n // Step 8: Store updated key blob\n const keyPayload = JSON.stringify({\n key: base64Encode(newKeyBlob),\n metadata: JSON.stringify({\n keyId: newKeyId,\n ...metadata,\n }),\n });\n const keyPutResult = await this.tc.kv.put(\n `keys/${key}`,\n keyPayload\n );\n if (!keyPutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store rotated key blob: ${keyPutResult.error.message}`\n ),\n });\n }\n\n // Step 9: Store re-encrypted value\n const valuePayload = JSON.stringify({\n data: base64Encode(encrypted),\n metadata,\n });\n const valuePutResult = await this.tc.kv.put(\n `vault/${key}`,\n valuePayload\n );\n if (!valuePutResult.ok) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause: new Error(\n `Failed to store re-encrypted value: ${valuePutResult.error.message}`\n ),\n });\n }\n\n // Step 10: Re-issue grants to remaining recipients\n for (const did of remainingGrantees) {\n const grantResult = await this.reencrypt(key, did);\n if (!grantResult.ok) {\n // Continue re-issuing to other recipients even if one fails\n // The failed grant can be re-issued manually\n }\n }\n\n return ok(undefined);\n } catch (error) {\n return vaultError({\n code: \"STORAGE_ERROR\",\n cause:\n toError(error),\n });\n }\n }) as Promise<Result<void, VaultError>>;\n }\n\n // =========================================================================\n // Internal Helpers\n // =========================================================================\n\n /**\n * Parse a DID string to extract address and chainId.\n * Expected format: did:pkh:eip155:{chainId}:{address}\n *\n * @param did - The DID to parse\n * @returns Parsed address and chainId, or null if invalid\n */\n private parseDID(\n did: string\n ): { address: string; chainId: number } | null {\n // did:pkh:eip155:{chainId}:{address}\n const parts = did.split(\":\");\n if (\n parts.length !== 5 ||\n parts[0] !== \"did\" ||\n parts[1] !== \"pkh\" ||\n parts[2] !== \"eip155\"\n ) {\n return null;\n }\n\n const chainId = parseInt(parts[3], 10);\n const address = parts[4];\n if (isNaN(chainId) || !address) {\n return null;\n }\n\n return { address, chainId };\n }\n}\n","import type { VaultCrypto } from \"./DataVaultService\";\n\nexport interface WasmVaultFunctions {\n vault_encrypt(key: Uint8Array, plaintext: Uint8Array): Uint8Array;\n vault_decrypt(key: Uint8Array, blob: Uint8Array): Uint8Array;\n /** WASM order: (salt, signature, info) — NOT (signature, salt, info) */\n vault_derive_key(salt: Uint8Array, signature: Uint8Array, info: Uint8Array): Uint8Array;\n vault_x25519_from_seed(seed: Uint8Array): { publicKey: Uint8Array; privateKey: Uint8Array };\n vault_x25519_dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n vault_random_bytes(length: number): Uint8Array;\n vault_sha256(data: Uint8Array): Uint8Array;\n}\n\nexport function createVaultCrypto(wasm: WasmVaultFunctions): VaultCrypto {\n return {\n encrypt: (key, plaintext) => wasm.vault_encrypt(key, plaintext),\n decrypt: (key, blob) => wasm.vault_decrypt(key, blob),\n deriveKey: (signature, salt, info) => wasm.vault_derive_key(salt, signature, info),\n x25519FromSeed: (seed) => wasm.vault_x25519_from_seed(seed),\n x25519Dh: (privateKey, publicKey) => wasm.vault_x25519_dh(privateKey, publicKey),\n randomBytes: (length) => wasm.vault_random_bytes(length),\n sha256: (data) => wasm.vault_sha256(data),\n };\n}\n","export const SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;\n\nconst SECRET_PREFIX = \"secrets/\";\nconst SCOPED_SECRET_PREFIX = \"secrets/scoped/\";\nconst RESERVED_SECRET_SCOPES = new Set([\"default\", \"global\"]);\n\nexport interface SecretScopeOptions {\n /** Optional logical scope. Omit for the global secret namespace. */\n scope?: string;\n}\n\nexport interface ResolvedSecretPath {\n /** Canonical env-style secret name. */\n name: string;\n /** Canonical scope. Undefined means global. */\n scope?: string;\n /** Key passed to the data vault service. */\n vaultKey: string;\n /** KV permission path that backs the encrypted vault entry. */\n permissionPaths: {\n vault: string;\n };\n}\n\nexport function canonicalizeSecretScope(scope: string | undefined): string | undefined {\n if (scope === undefined) {\n return undefined;\n }\n\n const trimmed = scope.trim();\n if (trimmed === \"\") {\n throw new Error(\"Secret scope must be non-empty; omit scope for global secrets.\");\n }\n\n const canonical = trimmed\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n\n if (canonical === \"\") {\n throw new Error(\"Secret scope must contain at least one letter or number.\");\n }\n if (RESERVED_SECRET_SCOPES.has(canonical)) {\n throw new Error(\n `Secret scope ${JSON.stringify(scope)} is reserved; omit scope for global secrets.`,\n );\n }\n\n return canonical;\n}\n\nexport function resolveSecretPath(\n name: string,\n options: SecretScopeOptions = {},\n): ResolvedSecretPath {\n const normalizedName = name.trim();\n if (!SECRET_NAME_RE.test(normalizedName)) {\n throw new Error(\n `Invalid secret name ${JSON.stringify(name)}. Secret names must match ${SECRET_NAME_RE.source}.`,\n );\n }\n\n const scope = canonicalizeSecretScope(options.scope);\n const vaultKey = scope === undefined\n ? `${SECRET_PREFIX}${normalizedName}`\n : `${SCOPED_SECRET_PREFIX}${scope}/${normalizedName}`;\n\n return {\n name: normalizedName,\n ...(scope !== undefined ? { scope } : {}),\n vaultKey,\n permissionPaths: {\n vault: `vault/${vaultKey}`,\n },\n };\n}\n\nexport function resolveSecretListPrefix(\n options: SecretScopeOptions = {},\n): string {\n const scope = canonicalizeSecretScope(options.scope);\n return scope === undefined\n ? \"vault/secrets/\"\n : `vault/secrets/scoped/${scope}/`;\n}\n","import {\n ErrorCodes,\n err,\n type Result,\n type ServiceError,\n} from \"../types\";\nimport type { IDataVaultService } from \"../vault/IDataVaultService\";\nimport type { VaultError } from \"../vault/types\";\nimport type {\n ISecretsService,\n SecretPayload,\n SecretsError,\n} from \"./ISecretsService\";\nimport {\n canonicalizeSecretScope,\n resolveSecretPath,\n SECRET_NAME_RE,\n type ResolvedSecretPath,\n type SecretScopeOptions,\n} from \"./paths\";\n\nfunction invalidSecretInput(message: string): Result<never, ServiceError> {\n return err({\n code: ErrorCodes.INVALID_INPUT,\n service: \"secrets\",\n message,\n });\n}\n\nfunction resolveSecretPathResult(\n name: string,\n options?: SecretScopeOptions,\n): ResolvedSecretPath | Result<never, ServiceError> {\n try {\n return resolveSecretPath(name, options);\n } catch (error) {\n return invalidSecretInput(error instanceof Error ? error.message : String(error));\n }\n}\n\nexport class SecretsService implements ISecretsService {\n private readonly getVault: () => IDataVaultService;\n\n constructor(vault: IDataVaultService | (() => IDataVaultService)) {\n this.getVault = typeof vault === \"function\" ? vault : () => vault;\n }\n\n get vault(): IDataVaultService {\n return this.getVault();\n }\n\n get isUnlocked(): boolean {\n return this.vault.isUnlocked;\n }\n\n unlock(signer?: unknown): Promise<Result<void, VaultError>> {\n return this.vault.unlock(signer);\n }\n\n lock(): void {\n this.vault.lock();\n }\n\n async get(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<string, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const result = await this.vault.get<SecretPayload>(secretPath.vaultKey);\n if (!result.ok) {\n return result;\n }\n return { ok: true, data: result.data.value.value };\n }\n\n async put(\n name: string,\n value: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n const now = new Date().toISOString();\n return this.vault.put(secretPath.vaultKey, {\n value,\n createdAt: now,\n updatedAt: now,\n } satisfies SecretPayload);\n }\n\n async delete(\n name: string,\n options?: SecretScopeOptions,\n ): Promise<Result<void, SecretsError>> {\n const secretPath = resolveSecretPathResult(name, options);\n if (\"ok\" in secretPath) return secretPath;\n\n return this.vault.delete(secretPath.vaultKey);\n }\n\n async list(options?: SecretScopeOptions): Promise<Result<string[], SecretsError>> {\n let prefix: string;\n try {\n const scope = canonicalizeSecretScope(options?.scope);\n prefix = scope === undefined ? \"secrets/\" : `secrets/scoped/${scope}/`;\n } catch (error) {\n return invalidSecretInput(error instanceof Error ? error.message : String(error));\n }\n\n const result = await this.vault.list({\n prefix,\n removePrefix: true,\n });\n if (!result.ok) {\n return result;\n }\n return {\n ok: true,\n data: result.data.filter((name) => SECRET_NAME_RE.test(name)),\n };\n }\n}\n","/**\n * Canonical JSON serialization and content hashing for TinyCloud\n * encryption requests/responses.\n *\n * The node and SDK must agree byte-for-byte on the canonical form so\n * that body-hash bindings (`bodyHash`, `encryptedSymmetricKeyHash`,\n * `receiverPublicKeyHash`) verify on both sides.\n *\n * Canonical rules:\n * - Object keys are sorted lexicographically by code point.\n * - Strings are encoded with the JSON.stringify default (RFC 8259).\n * - Numbers are emitted via JSON.stringify; callers should restrict to\n * integers or use string fields for high-precision values.\n * - `undefined` properties are dropped. `null` is preserved.\n * - Arrays preserve element order.\n *\n * Hashing uses SHA-256 supplied by the caller (via an `EncryptionCrypto`\n * binding) so this module stays platform-agnostic.\n */\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | Json[]\n | { [key: string]: Json | undefined };\n\n/**\n * Produce the canonical JSON string for {@link value}. Object keys are\n * sorted, `undefined` properties are dropped, and primitive types are\n * encoded by `JSON.stringify`.\n */\nexport function canonicalize(value: Json | undefined): string {\n if (value === undefined) {\n return \"\";\n }\n return stringify(value);\n}\n\nfunction stringify(value: Json): string {\n if (value === null) return \"null\";\n switch (typeof value) {\n case \"boolean\":\n case \"number\":\n return JSON.stringify(value);\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n if (Array.isArray(value)) {\n return `[${value.map(stringify).join(\",\")}]`;\n }\n const keys = Object.keys(value).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const v = value[k];\n if (v === undefined) continue;\n parts.push(`${JSON.stringify(k)}:${stringify(v)}`);\n }\n return `{${parts.join(\",\")}}`;\n }\n default:\n throw new TypeError(\n `canonicalize: unsupported value type ${typeof value}`,\n );\n }\n}\n\nconst HEX = \"0123456789abcdef\";\n\nexport function hexEncode(bytes: Uint8Array): string {\n let out = \"\";\n for (let i = 0; i < bytes.length; i++) {\n const b = bytes[i];\n out += HEX[(b >> 4) & 0xf] + HEX[b & 0xf];\n }\n return out;\n}\n\nexport function hexDecode(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(\"hex string must have even length\");\n }\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const hi = parseInt(hex[i * 2], 16);\n const lo = parseInt(hex[i * 2 + 1], 16);\n if (Number.isNaN(hi) || Number.isNaN(lo)) {\n throw new Error(\"invalid hex character\");\n }\n out[i] = (hi << 4) | lo;\n }\n return out;\n}\n\nexport function base64Encode(bytes: Uint8Array): string {\n // base64 (standard, not url-safe) so envelopes pass through JSON cleanly.\n // We avoid `btoa` to stay node-friendly without polyfills.\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n let out = \"\";\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i];\n const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;\n const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;\n out += chars[(b0 >> 2) & 0x3f];\n out += chars[((b0 << 4) | (b1 >> 4)) & 0x3f];\n out += i + 1 < bytes.length ? chars[((b1 << 2) | (b2 >> 6)) & 0x3f] : \"=\";\n out += i + 2 < bytes.length ? chars[b2 & 0x3f] : \"=\";\n }\n return out;\n}\n\nexport function base64Decode(s: string): Uint8Array {\n const clean = s.replace(/[^A-Za-z0-9+/=]/g, \"\");\n const len = clean.length;\n if (len % 4 !== 0) {\n throw new Error(\"invalid base64 input\");\n }\n const padding =\n clean.endsWith(\"==\") ? 2 : clean.endsWith(\"=\") ? 1 : 0;\n const outLen = (len / 4) * 3 - padding;\n const out = new Uint8Array(outLen);\n const lookup: Record<string, number> = {};\n const chars =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n for (let i = 0; i < chars.length; i++) lookup[chars[i]] = i;\n\n let outIdx = 0;\n for (let i = 0; i < len; i += 4) {\n const v0 = lookup[clean[i]] ?? 0;\n const v1 = lookup[clean[i + 1]] ?? 0;\n const v2 = clean[i + 2] === \"=\" ? 0 : (lookup[clean[i + 2]] ?? 0);\n const v3 = clean[i + 3] === \"=\" ? 0 : (lookup[clean[i + 3]] ?? 0);\n const b0 = (v0 << 2) | (v1 >> 4);\n const b1 = ((v1 & 0x0f) << 4) | (v2 >> 2);\n const b2 = ((v2 & 0x03) << 6) | v3;\n if (outIdx < outLen) out[outIdx++] = b0;\n if (outIdx < outLen) out[outIdx++] = b1;\n if (outIdx < outLen) out[outIdx++] = b2;\n }\n return out;\n}\n\nexport function utf8Encode(s: string): Uint8Array {\n return new TextEncoder().encode(s);\n}\n\nexport function utf8Decode(b: Uint8Array): string {\n return new TextDecoder().decode(b);\n}\n\n/**\n * Compute `hexEncode(sha256(canonicalize(value)))`. The SHA-256 binding\n * is injected so the module remains usable in both the WASM and pure-JS\n * paths.\n */\nexport function canonicalHashHex(\n sha256: (bytes: Uint8Array) => Uint8Array,\n value: Json,\n): string {\n const canonical = canonicalize(value);\n return hexEncode(sha256(utf8Encode(canonical)));\n}\n","/**\n * TinyCloud encryption network identifiers.\n *\n * A network id is `urn:tinycloud:encryption:<ownerDid>:<network>` where\n * `ownerDid` is the owner's DID and `network` is a\n * non-empty label drawn from `[a-z0-9][a-z0-9-]*`.\n *\n * The embedded owner DID is the root authority for the network: any\n * delegation chain ending in a `tinycloud.encryption/decrypt` grant on\n * the network must root at this owner DID.\n */\n\nconst URN_PREFIX = \"urn:tinycloud:encryption:\";\nconst NETWORK_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;\nconst PKH_EIP155_DID_RE = /^did:pkh:eip155:(\\d+):(0x[a-fA-F0-9]{40})$/;\n\nexport interface ParsedNetworkId {\n /** The full URN string. */\n networkId: string;\n /** Owner DID embedded in the URN (the network's root authority). */\n ownerDid: string;\n /** Network label (the suffix after the owner DID). */\n name: string;\n}\n\nexport class NetworkIdError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"NetworkIdError\";\n }\n}\n\n/**\n * Parse a network id string into its owner DID and name components.\n *\n * Throws {@link NetworkIdError} when the input does not match\n * `urn:tinycloud:encryption:<did>:<name>`, when the embedded DID is\n * malformed, or when the network name fails {@link NETWORK_NAME_RE}.\n */\nexport function parseNetworkId(networkId: string): ParsedNetworkId {\n if (typeof networkId !== \"string\" || networkId.length === 0) {\n throw new NetworkIdError(\"networkId must be a non-empty string\");\n }\n if (!networkId.startsWith(URN_PREFIX)) {\n throw new NetworkIdError(\n `networkId must start with ${URN_PREFIX} (got ${JSON.stringify(networkId)})`,\n );\n }\n const body = networkId.slice(URN_PREFIX.length);\n // `body` = \"<ownerDid>:<network>\"\n // ownerDid contains ':' (e.g. did:key:z6Mk...), so we split on the LAST colon\n // and treat the suffix as the network name.\n const lastColon = body.lastIndexOf(\":\");\n if (lastColon <= 0 || lastColon === body.length - 1) {\n throw new NetworkIdError(\n `networkId missing ownerDid or name segment (got ${JSON.stringify(networkId)})`,\n );\n }\n const ownerDid = body.slice(0, lastColon);\n const name = body.slice(lastColon + 1);\n\n if (!ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\n `networkId ownerDid must be a DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n // Minimal DID shape: did:<method>:<id> — three colon-separated segments,\n // each non-empty.\n const didParts = ownerDid.split(\":\");\n if (didParts.length < 3 || didParts.some((p) => p.length === 0)) {\n throw new NetworkIdError(\n `networkId ownerDid is not a well-formed DID (got ${JSON.stringify(ownerDid)})`,\n );\n }\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `networkId name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return { networkId, ownerDid, name };\n}\n\n/**\n * Construct a network id URN from an owner DID and a network name.\n * Validates inputs and throws {@link NetworkIdError} on bad shape.\n */\nexport function buildNetworkId(ownerDid: string, name: string): string {\n if (typeof ownerDid !== \"string\" || !ownerDid.startsWith(\"did:\")) {\n throw new NetworkIdError(\"ownerDid must be a DID\");\n }\n if (typeof name !== \"string\" || !NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n const networkId = `${URN_PREFIX}${ownerDid}:${name}`;\n // Re-validate the composed result so the same error path triggers\n // for caller inputs that compose into a malformed URN.\n parseNetworkId(networkId);\n return networkId;\n}\n\n/**\n * Returns true when {@link networkId} is a syntactically valid network URN.\n */\nexport function isNetworkId(networkId: unknown): networkId is string {\n if (typeof networkId !== \"string\") {\n return false;\n }\n try {\n parseNetworkId(networkId);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction parsePkhOwnerDid(ownerDid: string):\n | { chainId: string; address: string }\n | null {\n const match = ownerDid.match(PKH_EIP155_DID_RE);\n if (!match) return null;\n return {\n chainId: match[1],\n address: match[2].toLowerCase(),\n };\n}\n\n/**\n * Compare owner DIDs as network principals. For `did:pkh:eip155`, EVM\n * address casing is not part of principal identity; other DID methods\n * remain exact string matches.\n */\nexport function ownerDidMatches(a: string, b: string): boolean {\n const aPkh = parsePkhOwnerDid(a);\n const bPkh = parsePkhOwnerDid(b);\n if (aPkh && bPkh) {\n return aPkh.chainId === bPkh.chainId && aPkh.address === bPkh.address;\n }\n return a === b;\n}\n\n/**\n * Resolve the discovery key used to look up a network's descriptor under\n * an owner's public account-space.\n *\n * Format: `.well-known/encryption/network/<name>`.\n */\nexport function networkDiscoveryKey(name: string): string {\n if (!NETWORK_NAME_RE.test(name)) {\n throw new NetworkIdError(\n `network name ${JSON.stringify(name)} must match ${NETWORK_NAME_RE.source}`,\n );\n }\n return `.well-known/encryption/network/${name}`;\n}\n\nexport const ENCRYPTION_NETWORK_URN_PREFIX = URN_PREFIX;\nexport const NETWORK_NAME_PATTERN = NETWORK_NAME_RE;\n","/**\n * Type definitions for TinyCloud one-of-one encryption.\n *\n * Wire shapes mirror the protocol described in the encryption\n * architecture: inline envelopes carry the encrypted symmetric key\n * alongside the ciphertext; decrypt requests are short-lived UCAN\n * invocations against a target node plus networkId.\n */\n\nimport type { Json } from \"./canonical\";\n\n/** Default ciphersuite identifier for v1 envelopes. */\nexport const DEFAULT_ENCRYPTION_ALG = \"x25519-aes256gcm/v1\" as const;\n\n/** Inline-envelope schema version. */\nexport const ENVELOPE_VERSION = 1 as const;\n\n/** Default key version on freshly-created networks. */\nexport const DEFAULT_KEY_VERSION = 1 as const;\n\n/** Decrypt-invocation fact type. */\nexport const DECRYPT_FACT_TYPE = \"tinycloud.encryption.decrypt/v1\" as const;\n\n/** Decrypt response type. */\nexport const DECRYPT_RESULT_TYPE =\n \"tinycloud.encryption.decrypt-result/v1\" as const;\n\n/** Encryption service identifier (manifest long form). */\nexport const ENCRYPTION_SERVICE = \"tinycloud.encryption\" as const;\n\n/** Short form used in recap/abilities maps. */\nexport const ENCRYPTION_SERVICE_SHORT = \"encryption\" as const;\n\n/** Decrypt ability URN. */\nexport const DECRYPT_ACTION = \"tinycloud.encryption/decrypt\" as const;\n\n/**\n * Inline encrypted envelope persisted in KV/SQL records.\n *\n * - `encryptedSymmetricKey` is opaque to the SDK; only the network can\n * unwrap it.\n * - `encryptedSymmetricKeyHash` is the canonical hash of the wrapped key\n * bytes (hex-encoded sha-256 of the base64 string's canonical JSON\n * form). The node recomputes this on every decrypt request.\n * - `ciphertext` and `aad` are payload bytes only; the node never sees\n * them.\n */\nexport interface InlineEncryptedEnvelope {\n /** Schema version. */\n v: typeof ENVELOPE_VERSION;\n /** Network id URN. */\n networkId: string;\n /** Ciphersuite identifier. */\n alg: string;\n /** Network key version that was used to wrap the symmetric key. */\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key / capsule. */\n encryptedSymmetricKey: string;\n /** Hex sha-256 of the canonical encryptedSymmetricKey string. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded payload ciphertext. */\n ciphertext: string;\n /** Base64-encoded associated data, if any. */\n aad?: string;\n /** Caller-supplied metadata. Not authenticated against the node. */\n metadata?: Record<string, string>;\n}\n\n/**\n * Node-published network descriptor. The node DB is authoritative; a\n * cached copy may also live under\n * `.well-known/encryption/network/<name>` in the owner's account\n * space (a discovery record only).\n */\nexport interface NetworkDescriptor {\n networkId: string;\n ownerDid: string;\n name: string;\n members: ReadonlyArray<{ nodeId: string; role: \"primary\" | \"share\" }>;\n threshold: { n: number; t: number };\n state: \"pending\" | \"generating\" | \"active\" | \"rotating\" | \"revoked\" | \"failed\";\n /** Base64-encoded network public key. */\n publicEncryptionKey: string;\n alg: string;\n keyVersion: number;\n keyBackend: \"local-one-of-one\" | \"dstack\" | \"threshold\";\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Decrypt-request body sent over the wire. Hashed (canonically) and\n * bound to the UCAN invocation via `facts.bodyHash`.\n */\nexport interface DecryptRequestBody {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n alg: string;\n keyVersion: number;\n /** Base64-encoded wrapped symmetric key from the envelope. */\n encryptedSymmetricKey: string;\n /** Recomputed hash of the wrapped key. */\n encryptedSymmetricKeyHash: string;\n /** Base64-encoded per-request receiver public key. */\n receiverPublicKey: string;\n /** Hash of the receiver public key. */\n receiverPublicKeyHash: string;\n}\n\n/**\n * Decrypt-response body returned by the node. The SDK verifies the\n * signature, recomputes hashes, then unwraps `wrappedKey` with the\n * per-request receiver private key before decrypting the payload.\n */\nexport interface DecryptResponseBody {\n type: typeof DECRYPT_RESULT_TYPE;\n targetNode: string;\n networkId: string;\n invocationCid: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n /** Base64-encoded symmetric key re-encrypted to receiverPublicKey. */\n wrappedKey: string;\n alg: string;\n keyVersion: number;\n requestHash: string;\n nodeId: string;\n /** Base64-encoded ed25519 signature over canonical(response - signature field). */\n nodeSignature: string;\n}\n\n/**\n * Decrypt-invocation facts attached to the UCAN. Verifiers recompute\n * `bodyHash`, `encryptedSymmetricKeyHash`, and `receiverPublicKeyHash`\n * from the request body and reject any mismatch.\n */\nexport interface DecryptInvocationFact {\n type: typeof DECRYPT_FACT_TYPE;\n targetNode: string;\n networkId: string;\n bodyHash: string;\n encryptedSymmetricKeyHash: string;\n receiverPublicKeyHash: string;\n alg: string;\n keyVersion: number;\n}\n\n/**\n * Per-request receiver key pair (x25519). The private key never\n * leaves the SDK; the public key is sent to the node so the node can\n * rewrap the symmetric key.\n */\nexport interface ReceiverKeyPair {\n publicKey: Uint8Array;\n privateKey: Uint8Array;\n}\n\n/**\n * Crypto primitives injected into the encryption module. The SDK\n * provides these via WASM bindings; tests provide simple in-memory\n * implementations.\n */\nexport interface EncryptionCrypto {\n /** SHA-256 → 32-byte digest. */\n sha256(data: Uint8Array): Uint8Array;\n /** Cryptographically secure random bytes. */\n randomBytes(length: number): Uint8Array;\n /** Derive an x25519 key pair from a 32-byte seed. */\n x25519FromSeed(seed: Uint8Array): ReceiverKeyPair;\n /** Compute the x25519 ECDH shared secret. */\n x25519Dh(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n /** Authenticated symmetric encryption (the node's symmetric scheme). */\n authEncrypt(\n key: Uint8Array,\n plaintext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /** Authenticated symmetric decryption (matched to authEncrypt). */\n authDecrypt(\n key: Uint8Array,\n ciphertext: Uint8Array,\n aad?: Uint8Array,\n ): Uint8Array;\n /**\n * Wrap a symmetric key for the network's public encryption key using\n * a sealed-box / hpke / x25519+symmetric construction. Implementation\n * is opaque; only the node can unwrap.\n */\n sealToNetworkKey(\n networkPublicKey: Uint8Array,\n symmetricKey: Uint8Array,\n ): Uint8Array;\n /**\n * Open a wrapped symmetric key that was re-encrypted to the\n * per-request receiver public key. The matching private key must be\n * supplied here; the SDK never sends it to the node.\n */\n openWithReceiverKey(\n receiverPrivateKey: Uint8Array,\n wrappedKey: Uint8Array,\n ): Uint8Array;\n /**\n * Verify an ed25519 signature over `message` produced by the node\n * identified by `nodeId` (the public-key DID).\n */\n verifyNodeSignature(\n nodeId: string,\n message: Uint8Array,\n signature: Uint8Array,\n ): boolean;\n}\n\n/**\n * Signer interface used to derive a receiver key pair from a wallet or\n * session signer. The signature is HKDF-extracted into the receiver\n * seed so the public key is reproducible given the same context.\n */\nexport interface ReceiverKeySigner {\n signMessage(message: string): Promise<string>;\n}\n\n/** Capability proof material accompanying a decrypt invocation. */\nexport interface DecryptCapabilityProof {\n /** Delegation chain CIDs rooted at the network owner DID. */\n proofs: ReadonlyArray<string>;\n /** Optional Authorization header value to use instead of building one. */\n authorization?: string;\n}\n\n/**\n * Inputs to the decrypt invocation builder.\n */\nexport interface BuildDecryptInvocationInput {\n /** Target node DID — also the UCAN audience. */\n targetNode: string;\n /** Network id URN — also the recap resource. */\n networkId: string;\n /** Canonical body that will be POSTed. */\n body: DecryptRequestBody;\n /** Facts include hashes bound to the canonical body. */\n facts: DecryptInvocationFact;\n /** Capability proof chain. */\n proof: DecryptCapabilityProof;\n /** Optional `nbf` UCAN field as an ISO date string. */\n notBefore?: string;\n /** Optional `exp` UCAN field as an ISO date string. */\n expiration?: string;\n}\n\n/**\n * The output of {@link buildDecryptInvocation}.\n */\nexport interface BuiltDecryptInvocation {\n /** HTTP `Authorization` header value. */\n authorization: string;\n /** CID of the invocation (used by the node response binding). */\n invocationCid: string;\n /** Canonical body string the node will hash. */\n canonicalBody: string;\n}\n\n/**\n * Signer interface for producing the decrypt invocation. WASM bindings\n * implement this with the same session signer used for KV/SQL\n * invocations; tests can stub it.\n */\nexport interface DecryptInvocationSigner {\n signDecryptInvocation(input: BuildDecryptInvocationInput): Promise<BuiltDecryptInvocation>;\n}\n\n/**\n * Errors thrown / returned from the encryption module.\n */\nexport type EncryptionErrorInput =\n | { code: \"NETWORK_NOT_FOUND\"; networkId?: string; name?: string; message?: string }\n | { code: \"NETWORK_NOT_ACTIVE\"; state: string; message?: string }\n | { code: \"INVALID_NETWORK_ID\"; message: string }\n | { code: \"INVALID_ENVELOPE\"; message: string }\n | { code: \"DECRYPT_DENIED\"; message: string }\n | { code: \"INVALID_RESPONSE\"; message: string }\n | { code: \"RESPONSE_SIGNATURE_INVALID\"; message?: string }\n | { code: \"RESPONSE_BINDING_MISMATCH\"; field: string; message?: string }\n | { code: \"TRANSPORT_ERROR\"; cause: Error; message?: string }\n | { code: \"INVALID_INPUT\"; message: string };\n\nexport type EncryptionError = EncryptionErrorInput & {\n service: \"encryption\";\n message: string;\n};\n\nfunction defaultEncryptionMessage(input: EncryptionErrorInput): string {\n switch (input.code) {\n case \"NETWORK_NOT_FOUND\":\n return (\n input.message ??\n `Network not found: ${input.networkId ?? input.name ?? \"<unknown>\"}`\n );\n case \"NETWORK_NOT_ACTIVE\":\n return input.message ?? `Network not active (state=${input.state})`;\n case \"INVALID_NETWORK_ID\":\n return input.message;\n case \"INVALID_ENVELOPE\":\n return input.message;\n case \"DECRYPT_DENIED\":\n return input.message;\n case \"INVALID_RESPONSE\":\n return input.message;\n case \"RESPONSE_SIGNATURE_INVALID\":\n return input.message ?? \"Node response signature failed to verify\";\n case \"RESPONSE_BINDING_MISMATCH\":\n return (\n input.message ??\n `Node response binding mismatch on field ${JSON.stringify(input.field)}`\n );\n case \"TRANSPORT_ERROR\":\n return input.message ?? input.cause.message;\n case \"INVALID_INPUT\":\n return input.message;\n }\n}\n\nexport function encryptionError(input: EncryptionErrorInput): EncryptionError {\n return {\n ...input,\n service: \"encryption\",\n message: defaultEncryptionMessage(input),\n };\n}\n\n/** Helper for the test/runtime layers to coerce arbitrary throwables. */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null) {\n return new Error(JSON.stringify(error));\n }\n return new Error(String(error));\n}\n\n/** Re-export for ergonomic typing of canonical payloads. */\nexport type CanonicalJson = Json;\n","/**\n * Network-descriptor discovery.\n *\n * Resolution order (per architecture):\n *\n * 1. The node's authoritative endpoint\n * `GET /encryption/networks/<networkId>` returns the current\n * descriptor (`state`, `publicEncryptionKey`, `keyVersion`, ...).\n * 2. If the node is unreachable, fall back to the cached discovery\n * record at `.well-known/encryption/network/<name>` inside the\n * owner's public space.\n *\n * The node DB is authoritative on conflict; cached records are\n * advisory only.\n */\n\nimport {\n NetworkIdError,\n networkDiscoveryKey,\n ownerDidMatches,\n parseNetworkId,\n} from \"./networkId\";\nimport {\n encryptionError,\n type EncryptionError,\n type NetworkDescriptor,\n} from \"./types\";\n\nexport type DiscoverySource = \"node\" | \"well-known\";\n\nexport interface DiscoveredNetwork {\n descriptor: NetworkDescriptor;\n source: DiscoverySource;\n}\n\nexport interface NodeDescriptorFetcher {\n /** Fetch the descriptor by full networkId URN. */\n fetchByNetworkId(networkId: string): Promise<NetworkDescriptor | null>;\n}\n\nexport interface WellKnownDescriptorFetcher {\n /**\n * Read the cached well-known descriptor by owner DID + network name.\n * Returns null if no record exists or the record is unreadable.\n */\n fetchWellKnown(\n ownerDid: string,\n discoveryKey: string,\n ): Promise<NetworkDescriptor | null>;\n}\n\nexport interface DiscoverNetworkInput {\n /** Either a networkId URN or a bare network name (paired with `ownerDid`). */\n identifier: string;\n /** Required when identifier is a bare name. */\n ownerDid?: string;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n}\n\n/**\n * Resolve a network descriptor. The node fetcher is preferred; the\n * well-known fallback is used only on transport failure.\n *\n * The returned descriptor is sanity-checked: `networkId`, `ownerDid`,\n * and `name` must agree with the URN, and the public key field must\n * be non-empty.\n */\nexport async function discoverNetwork(\n input: DiscoverNetworkInput,\n):\n | Promise<{ ok: true; data: DiscoveredNetwork } | { ok: false; error: EncryptionError }> {\n let networkId: string;\n let ownerDid: string;\n let name: string;\n try {\n if (input.identifier.startsWith(\"urn:tinycloud:encryption:\")) {\n const parsed = parseNetworkId(input.identifier);\n networkId = parsed.networkId;\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n } else {\n if (input.ownerDid === undefined) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"discoverNetwork requires `ownerDid` when identifier is a bare network name\",\n }),\n };\n }\n networkId = `urn:tinycloud:encryption:${input.ownerDid}:${input.identifier}`;\n const parsed = parseNetworkId(networkId);\n ownerDid = parsed.ownerDid;\n name = parsed.name;\n }\n } catch (err) {\n if (err instanceof NetworkIdError) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err.message,\n }),\n };\n }\n throw err;\n }\n\n // 1) Try the node first.\n if (input.node !== undefined) {\n try {\n const descriptor = await input.node.fetchByNetworkId(networkId);\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return { ok: true, data: { descriptor: validated.data, source: \"node\" } };\n }\n } catch (err) {\n // Fall through to well-known\n }\n }\n\n // 2) Fallback to well-known cache.\n if (input.wellKnown !== undefined) {\n try {\n const descriptor = await input.wellKnown.fetchWellKnown(\n ownerDid,\n networkDiscoveryKey(name),\n );\n if (descriptor !== null) {\n const validated = validateDescriptor(descriptor, networkId, ownerDid, name);\n if (!validated.ok) return validated;\n return {\n ok: true,\n data: { descriptor: validated.data, source: \"well-known\" },\n };\n }\n } catch (err) {\n // Fall through to NOT_FOUND\n }\n }\n\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_FOUND\",\n networkId,\n name,\n }),\n };\n}\n\nfunction validateDescriptor(\n descriptor: NetworkDescriptor,\n networkId: string,\n ownerDid: string,\n name: string,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n let descriptorNetwork;\n try {\n descriptorNetwork = parseNetworkId(descriptor.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n\n if (\n descriptorNetwork.name !== name ||\n !ownerDidMatches(descriptorNetwork.ownerDid, ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: `descriptor networkId ${JSON.stringify(descriptor.networkId)} does not match expected ${JSON.stringify(networkId)}`,\n }),\n };\n }\n\n const descriptorOwnerDid = descriptorOwner(descriptor);\n if (\n descriptorOwnerDid === undefined ||\n !ownerDidMatches(descriptorOwnerDid, ownerDid) ||\n !ownerDidMatches(descriptorOwnerDid, descriptorNetwork.ownerDid)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor ownerDid does not match networkId ownerDid\",\n }),\n };\n }\n if (descriptor.name !== name) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor name does not match networkId name\",\n }),\n };\n }\n if (\n typeof descriptor.publicEncryptionKey !== \"string\" ||\n descriptor.publicEncryptionKey.length === 0\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: \"descriptor publicEncryptionKey must be a non-empty string\",\n }),\n };\n }\n return {\n ok: true,\n data: {\n ...descriptor,\n ownerDid: descriptorOwnerDid,\n },\n };\n}\n\nfunction descriptorOwner(descriptor: NetworkDescriptor): string | undefined {\n if (typeof descriptor.ownerDid === \"string\" && descriptor.ownerDid.length > 0) {\n return descriptor.ownerDid;\n }\n\n const legacyDescriptor = descriptor as NetworkDescriptor & {\n principal?: unknown;\n };\n return typeof legacyDescriptor.principal === \"string\" &&\n legacyDescriptor.principal.length > 0\n ? legacyDescriptor.principal\n : undefined;\n}\n\n/**\n * Reject a descriptor that is not in a state that accepts decrypt\n * requests. Only `active` and `rotating` networks may decrypt; revoked\n * or pending networks reject.\n */\nexport function ensureNetworkUsableForDecrypt(\n descriptor: NetworkDescriptor,\n):\n | { ok: true; data: NetworkDescriptor }\n | { ok: false; error: EncryptionError } {\n if (descriptor.state === \"active\" || descriptor.state === \"rotating\") {\n return { ok: true, data: descriptor };\n }\n return {\n ok: false,\n error: encryptionError({\n code: \"NETWORK_NOT_ACTIVE\",\n state: descriptor.state,\n }),\n };\n}\n","/**\n * Inline-envelope encrypt / decrypt helpers.\n *\n * Encryption is fully local: the SDK generates a per-record symmetric\n * key, encrypts the payload, then wraps the symmetric key against the\n * network's public encryption key. The wrapped key (and key hash)\n * travels alongside the ciphertext inside an\n * {@link InlineEncryptedEnvelope}.\n *\n * Decryption is split: the node unwraps the symmetric key to the\n * per-request receiver public key (see {@link buildDecryptInvocation}\n * and the decrypt route); this module is responsible for the local\n * payload decryption once the symmetric key is available.\n */\n\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n DEFAULT_ENCRYPTION_ALG,\n DEFAULT_KEY_VERSION,\n ENVELOPE_VERSION,\n encryptionError,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n} from \"./types\";\nimport { parseNetworkId } from \"./networkId\";\n\nexport interface EncryptToNetworkInput {\n /** Target network id URN. */\n networkId: string;\n /** Network public key bytes (already discovered). */\n networkPublicKey: Uint8Array;\n /** Payload bytes to encrypt. Callers serialize objects to bytes themselves. */\n plaintext: Uint8Array;\n /** Optional associated authenticated data. */\n aad?: Uint8Array;\n /** Ciphersuite identifier. Defaults to {@link DEFAULT_ENCRYPTION_ALG}. */\n alg?: string;\n /** Key version. Defaults to {@link DEFAULT_KEY_VERSION}. */\n keyVersion?: number;\n /** Caller-supplied envelope metadata. */\n metadata?: Record<string, string>;\n}\n\nexport interface EncryptToNetworkResult {\n envelope: InlineEncryptedEnvelope;\n /** Symmetric key returned for caller bookkeeping; do NOT persist. */\n symmetricKey: Uint8Array;\n}\n\n/**\n * Local-only encrypt: generates a symmetric key, encrypts the payload,\n * wraps the key against the network public key, and returns the\n * inline envelope.\n */\nexport function encryptToNetwork(\n crypto: EncryptionCrypto,\n input: EncryptToNetworkInput,\n): EncryptToNetworkResult {\n parseNetworkId(input.networkId);\n const alg = input.alg ?? DEFAULT_ENCRYPTION_ALG;\n const keyVersion = input.keyVersion ?? DEFAULT_KEY_VERSION;\n\n const symmetricKey = crypto.randomBytes(32);\n const ciphertext = crypto.authEncrypt(symmetricKey, input.plaintext, input.aad);\n const wrapped = crypto.sealToNetworkKey(input.networkPublicKey, symmetricKey);\n const encryptedSymmetricKey = base64Encode(wrapped);\n const encryptedSymmetricKeyHash = canonicalHashHex(\n crypto.sha256,\n encryptedSymmetricKey,\n );\n\n const envelope: InlineEncryptedEnvelope = {\n v: ENVELOPE_VERSION,\n networkId: input.networkId,\n alg,\n keyVersion,\n encryptedSymmetricKey,\n encryptedSymmetricKeyHash,\n ciphertext: base64Encode(ciphertext),\n ...(input.aad !== undefined ? { aad: base64Encode(input.aad) } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n };\n\n return { envelope, symmetricKey };\n}\n\n/**\n * Validate an inline envelope shape. Returns an error if the envelope\n * is missing required fields or fails internal hash recomputation.\n */\nexport function validateEnvelope(\n crypto: EncryptionCrypto,\n envelope: unknown,\n): { ok: true; data: InlineEncryptedEnvelope } | { ok: false; error: EncryptionError } {\n if (envelope === null || typeof envelope !== \"object\") {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope must be an object\",\n }),\n };\n }\n const e = envelope as InlineEncryptedEnvelope;\n if (e.v !== ENVELOPE_VERSION) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.v must be ${ENVELOPE_VERSION} (got ${e.v as unknown as string})`,\n }),\n };\n }\n try {\n parseNetworkId(e.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.networkId is malformed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n for (const field of [\n \"alg\",\n \"encryptedSymmetricKey\",\n \"encryptedSymmetricKeyHash\",\n \"ciphertext\",\n ] as const) {\n if (typeof e[field] !== \"string\" || (e[field] as string).length === 0) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: `envelope.${field} must be a non-empty string`,\n }),\n };\n }\n }\n if (typeof e.keyVersion !== \"number\" || !Number.isInteger(e.keyVersion)) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message: \"envelope.keyVersion must be an integer\",\n }),\n };\n }\n const expectedHash = canonicalHashHex(crypto.sha256, e.encryptedSymmetricKey);\n if (expectedHash !== e.encryptedSymmetricKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_ENVELOPE\",\n message:\n \"envelope.encryptedSymmetricKeyHash does not match canonical hash of encryptedSymmetricKey\",\n }),\n };\n }\n return { ok: true, data: e };\n}\n\n/**\n * Decrypt an inline envelope given the unwrapped symmetric key.\n *\n * Callers typically obtain the symmetric key via the node decrypt\n * endpoint plus the per-request receiver key pair (see\n * `EncryptionService.decryptEnvelope`).\n */\nexport function decryptEnvelopeWithKey(\n crypto: EncryptionCrypto,\n envelope: InlineEncryptedEnvelope,\n symmetricKey: Uint8Array,\n): Uint8Array {\n const ciphertext = base64Decode(envelope.ciphertext);\n const aad = envelope.aad !== undefined ? base64Decode(envelope.aad) : undefined;\n return crypto.authDecrypt(symmetricKey, ciphertext, aad);\n}\n","/**\n * TinyCloud encryption decrypt-invocation builder.\n *\n * The decrypt invocation is a UCAN-style TinyCloud invocation against\n * a node plus a network id. It is structurally distinct from the\n * existing space-shaped invocations:\n *\n * - `aud` (audience) is the **target node DID** (not a space owner).\n * - `att` (attenuation) uses the **networkId URN** as the resource\n * key (not a `tinycloud:pkh:...:<space>` URI).\n * - `fct` (facts) binds `bodyHash`, `encryptedSymmetricKeyHash`, and\n * `receiverPublicKeyHash` so the node can recompute them from the\n * POST body.\n *\n * Production callers inject a `DecryptInvocationSigner` backed by the\n * WASM UCAN/session signer. Tests pass a deterministic stub.\n */\n\nimport { canonicalize, canonicalHashHex, hexEncode, utf8Encode } from \"./canonical\";\nimport { parseNetworkId } from \"./networkId\";\nimport {\n DECRYPT_ACTION,\n DECRYPT_FACT_TYPE,\n ENCRYPTION_SERVICE,\n encryptionError,\n type BuildDecryptInvocationInput,\n type BuiltDecryptInvocation,\n type CanonicalJson,\n type DecryptCapabilityProof,\n type DecryptInvocationFact,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\nexport interface CanonicalDecryptRequest {\n /** The canonical body that the node will hash. */\n canonicalBody: string;\n /** Hex sha-256 of the canonical body bytes. */\n bodyHash: string;\n /** Hex sha-256 of the receiver public key bytes. */\n receiverPublicKeyHash: string;\n}\n\nexport interface BuildCanonicalDecryptRequestInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n receiverPublicKey: Uint8Array;\n}\n\n/**\n * Build the canonical body string and its bound hashes for a decrypt\n * request. The output is what gets POSTed to the node, and what the\n * node will hash to verify `facts.bodyHash`.\n */\nexport function buildCanonicalDecryptRequest(\n input: BuildCanonicalDecryptRequestInput,\n): CanonicalDecryptRequest {\n const canonicalBody = canonicalize(input.body as unknown as CanonicalJson);\n const bodyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return { canonicalBody, bodyHash, receiverPublicKeyHash };\n}\n\nexport interface BuildDecryptFactsInput {\n crypto: EncryptionCrypto;\n body: DecryptRequestBody;\n /** Encrypted symmetric key hash from the envelope (already canonical). */\n encryptedSymmetricKeyHash: string;\n /** Receiver public key bytes. */\n receiverPublicKey: Uint8Array;\n /** Canonical body string used to derive bodyHash. */\n canonicalBody?: string;\n}\n\n/**\n * Build the {@link DecryptInvocationFact} that will be embedded in the\n * UCAN `fct` field. Hashes are recomputed here so callers cannot drift\n * from the canonical body without the node noticing.\n */\nexport function buildDecryptFacts(\n input: BuildDecryptFactsInput,\n): DecryptInvocationFact {\n // When a precomputed canonicalBody string is supplied, hash its bytes\n // directly. Don't route it through canonicalHashHex, which would\n // re-canonicalize the string itself (escaping it as a JSON value).\n const bodyHash =\n input.canonicalBody !== undefined\n ? hexEncode(input.crypto.sha256(utf8Encode(input.canonicalBody)))\n : canonicalHashHex(\n input.crypto.sha256,\n input.body as unknown as CanonicalJson,\n );\n const receiverPublicKeyHash = canonicalHashHex(\n input.crypto.sha256,\n input.body.receiverPublicKey,\n );\n return {\n type: DECRYPT_FACT_TYPE,\n targetNode: input.body.targetNode,\n networkId: input.body.networkId,\n bodyHash,\n encryptedSymmetricKeyHash: input.encryptedSymmetricKeyHash,\n receiverPublicKeyHash,\n alg: input.body.alg,\n keyVersion: input.body.keyVersion,\n };\n}\n\n/**\n * Recap-shaped attenuation for the decrypt invocation. The resource\n * key is the networkId URN; the ability is the long-form\n * `tinycloud.encryption/decrypt`. This is intentionally distinct from\n * the existing space-shaped invocation map so callers cannot\n * accidentally fake a space prefix.\n */\nexport function buildDecryptAttenuation(\n networkId: string,\n): Record<string, Record<string, Record<string, never>>> {\n parseNetworkId(networkId);\n return {\n [networkId]: {\n [DECRYPT_ACTION]: {},\n },\n };\n}\n\n/**\n * Validate a {@link BuildDecryptInvocationInput} payload — the body\n * shape, the facts bindings, and the audience contract — without\n * actually signing. Returns either the input (typed) or a structured\n * error so callers can short-circuit before calling into WASM.\n */\nexport function checkDecryptInvocationInput(\n crypto: EncryptionCrypto,\n input: BuildDecryptInvocationInput,\n):\n | { ok: true; data: BuildDecryptInvocationInput; canonicalBody: string }\n | { ok: false; error: EncryptionError } {\n if (input.body.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `body.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.type !== DECRYPT_FACT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: `facts.type must be ${DECRYPT_FACT_TYPE}`,\n }),\n };\n }\n if (input.facts.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.targetNode must equal targetNode — the UCAN audience binds the request to a single node\",\n }),\n };\n }\n if (input.body.targetNode !== input.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.targetNode must equal targetNode\",\n }),\n };\n }\n if (input.facts.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.networkId must equal networkId\",\n }),\n };\n }\n if (input.body.networkId !== input.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"body.networkId must equal networkId\",\n }),\n };\n }\n if (input.facts.alg !== input.body.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.alg must equal body.alg\",\n }),\n };\n }\n if (input.facts.keyVersion !== input.body.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.keyVersion must equal body.keyVersion\",\n }),\n };\n }\n if (\n input.facts.encryptedSymmetricKeyHash !==\n input.body.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.encryptedSymmetricKeyHash must equal body.encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (\n input.facts.receiverPublicKeyHash !== input.body.receiverPublicKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"facts.receiverPublicKeyHash must equal body.receiverPublicKeyHash\",\n }),\n };\n }\n try {\n parseNetworkId(input.networkId);\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_NETWORK_ID\",\n message: err instanceof Error ? err.message : String(err),\n }),\n };\n }\n const canonicalBody = canonicalize(\n input.body as unknown as CanonicalJson,\n );\n const expectedBodyHash = canonicalHashHex(crypto.sha256, input.body as unknown as CanonicalJson);\n if (expectedBodyHash !== input.facts.bodyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message: \"facts.bodyHash does not match the canonical body hash\",\n }),\n };\n }\n return { ok: true, data: input, canonicalBody };\n}\n\n/**\n * Compose the high-level decrypt invocation and hand it to the signer\n * for UCAN minting. The signer returns the Authorization header value\n * plus the invocation CID; this function only validates and\n * orchestrates — it does not perform crypto signing itself.\n */\nexport async function buildDecryptInvocation(\n crypto: EncryptionCrypto,\n signer: DecryptInvocationSigner,\n input: BuildDecryptInvocationInput,\n): Promise<{ ok: true; data: BuiltDecryptInvocation } | { ok: false; error: EncryptionError }> {\n const checked = checkDecryptInvocationInput(crypto, input);\n if (!checked.ok) {\n return checked;\n }\n try {\n const built = await signer.signDecryptInvocation(checked.data);\n if (!built.authorization || !built.invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned an empty authorization or invocationCid\",\n }),\n };\n }\n if (built.canonicalBody !== checked.canonicalBody) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_INPUT\",\n message:\n \"decrypt-invocation signer returned a canonicalBody that does not match the SDK's canonicalization — signer must use the SDK-provided body\",\n }),\n };\n }\n return { ok: true, data: built };\n } catch (err) {\n return {\n ok: false,\n error: encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: err instanceof Error ? err : new Error(String(err)),\n message: `failed to sign decrypt invocation: ${\n err instanceof Error ? err.message : String(err)\n }`,\n }),\n };\n }\n}\n\n/** Re-export so callers can introspect the service+action constants. */\nexport { DECRYPT_ACTION, ENCRYPTION_SERVICE };\n","/**\n * Per-request receiver key generation.\n *\n * The receiver key pair is generated for a single decrypt request: the\n * SDK sends `receiverPublicKey` to the node so the node can rewrap the\n * symmetric key; the matching private key never leaves the SDK.\n *\n * Two derivation modes are supported:\n *\n * 1. **Random** — `crypto.randomBytes(32)` seeds a fresh x25519 pair.\n * This is the default for one-of-one flows.\n *\n * 2. **Signed-context** — the caller provides a signer that signs a\n * deterministic context message (network id + nonce + invocation\n * intent). The signature bytes are SHA-256'd into the seed. This is\n * useful when callers want the receiver key to be reproducible by\n * the same session signer (e.g. for delegated reads where the\n * signer is the only stable secret).\n */\n\nimport { utf8Encode } from \"./canonical\";\nimport type {\n EncryptionCrypto,\n ReceiverKeyPair,\n ReceiverKeySigner,\n} from \"./types\";\n\nexport interface RandomReceiverKeyInput {\n crypto: EncryptionCrypto;\n}\n\nexport function generateRandomReceiverKey(\n input: RandomReceiverKeyInput,\n): ReceiverKeyPair {\n const seed = input.crypto.randomBytes(32);\n return input.crypto.x25519FromSeed(seed);\n}\n\nexport interface SignedReceiverKeyInput {\n crypto: EncryptionCrypto;\n signer: ReceiverKeySigner;\n networkId: string;\n /** Optional extra context (e.g. invocation nonce) folded into the message. */\n context?: string;\n}\n\n/**\n * Deterministic receiver-key derivation: signs a context string with\n * the supplied signer, then SHA-256s the signature bytes into the\n * x25519 seed.\n *\n * The context message is:\n * `tinycloud.encryption.receiver-key/v1:<networkId>:<context>`\n *\n * Callers MUST include unique context (e.g. a fresh nonce) on every\n * request unless they explicitly want reproducibility.\n */\nexport async function deriveSignedReceiverKey(\n input: SignedReceiverKeyInput,\n): Promise<ReceiverKeyPair> {\n const message = `tinycloud.encryption.receiver-key/v1:${input.networkId}:${input.context ?? \"\"}`;\n const sig = await input.signer.signMessage(message);\n // Treat the signature as opaque bytes; sha256 collapses to a 32-byte seed.\n const sigBytes = utf8Encode(sig);\n const seed = input.crypto.sha256(sigBytes);\n return input.crypto.x25519FromSeed(seed);\n}\n","/**\n * Decrypt-response verification.\n *\n * The node returns the unwrapped symmetric key re-encrypted to the\n * per-request receiver public key. Before the SDK uses the wrapped\n * key, it must:\n *\n * 1. Verify the node signature over the canonical response (excluding\n * the signature field).\n * 2. Recompute every binding hash and reject any mismatch.\n * 3. Confirm `targetNode`, `networkId`, `alg`, and `keyVersion` echo\n * what the SDK sent.\n *\n * After verification, the SDK opens `wrappedKey` with the per-request\n * receiver private key and uses the resulting symmetric key to\n * decrypt the inline envelope payload.\n */\n\nimport { base64Decode, canonicalize, hexEncode, utf8Encode } from \"./canonical\";\nimport {\n DECRYPT_RESULT_TYPE,\n encryptionError,\n type CanonicalJson,\n type DecryptInvocationFact,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n} from \"./types\";\n\n/**\n * Construct the canonical bytes that the node signed.\n *\n * The signature covers the response with `nodeSignature` removed. We\n * canonicalize and hash the same way the node does so the binding is\n * stable.\n */\nexport function canonicalSignedResponse(\n response: DecryptResponseBody,\n): string {\n // Strip the signature; canonicalize sorts keys for us.\n const { nodeSignature: _drop, ...rest } = response;\n return canonicalize(rest as unknown as CanonicalJson);\n}\n\nexport interface VerifyDecryptResponseInput {\n crypto: EncryptionCrypto;\n request: DecryptRequestBody;\n facts: DecryptInvocationFact;\n /** CID of the signed invocation that produced this response. */\n invocationCid: string;\n /** Hex bodyHash that was bound in `facts.bodyHash`. */\n requestBodyHash: string;\n response: DecryptResponseBody;\n}\n\n/**\n * Verify the node's decrypt response. Returns the response on success;\n * a structured error on signature, binding, or shape failure.\n */\nexport function verifyDecryptResponse(\n input: VerifyDecryptResponseInput,\n):\n | { ok: true; data: DecryptResponseBody }\n | { ok: false; error: EncryptionError } {\n const { crypto, request, facts, invocationCid, requestBodyHash, response } =\n input;\n\n if (response.type !== DECRYPT_RESULT_TYPE) {\n return {\n ok: false,\n error: encryptionError({\n code: \"INVALID_RESPONSE\",\n message: `response.type must be ${DECRYPT_RESULT_TYPE}`,\n }),\n };\n }\n if (response.targetNode !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"targetNode\",\n }),\n };\n }\n if (response.networkId !== request.networkId) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"networkId\",\n }),\n };\n }\n if (response.nodeId !== request.targetNode) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"nodeId\",\n }),\n };\n }\n if (response.alg !== request.alg) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"alg\",\n }),\n };\n }\n if (response.keyVersion !== request.keyVersion) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"keyVersion\",\n }),\n };\n }\n if (\n response.encryptedSymmetricKeyHash !==\n request.encryptedSymmetricKeyHash\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"encryptedSymmetricKeyHash\",\n }),\n };\n }\n if (response.receiverPublicKeyHash !== request.receiverPublicKeyHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"receiverPublicKeyHash\",\n }),\n };\n }\n if (response.invocationCid !== invocationCid) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"invocationCid\",\n }),\n };\n }\n // requestHash binds invocationCid || requestBodyHash per spec. The `||`\n // notation is concatenation, not a literal delimiter.\n const expectedRequestHash = hexEncode(\n crypto.sha256(utf8Encode(`${invocationCid}${requestBodyHash}`)),\n );\n if (response.requestHash !== expectedRequestHash) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"requestHash\",\n }),\n };\n }\n // The facts must agree with the response (defensive: catches a node\n // that returns a fresh body bound to a different invocation).\n if (\n facts.encryptedSymmetricKeyHash !== response.encryptedSymmetricKeyHash ||\n facts.receiverPublicKeyHash !== response.receiverPublicKeyHash ||\n facts.networkId !== response.networkId ||\n facts.targetNode !== response.targetNode ||\n facts.alg !== response.alg ||\n facts.keyVersion !== response.keyVersion\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_BINDING_MISMATCH\",\n field: \"facts\",\n }),\n };\n }\n\n const signedBytes = new TextEncoder().encode(\n canonicalSignedResponse(response),\n );\n const signatureBytes = base64Decode(response.nodeSignature);\n if (\n !crypto.verifyNodeSignature(response.nodeId, signedBytes, signatureBytes)\n ) {\n return {\n ok: false,\n error: encryptionError({\n code: \"RESPONSE_SIGNATURE_INVALID\",\n }),\n };\n }\n return { ok: true, data: response };\n}\n\n/**\n * After verification, open the response's `wrappedKey` with the\n * per-request receiver private key and return the symmetric key.\n */\nexport function openWrappedKey(\n crypto: EncryptionCrypto,\n receiverPrivateKey: Uint8Array,\n response: DecryptResponseBody,\n): Uint8Array {\n const wrapped = base64Decode(response.wrappedKey);\n return crypto.openWithReceiverKey(receiverPrivateKey, wrapped);\n}\n","/**\n * EncryptionService — TinyCloud one-of-one encryption service.\n *\n * Responsibilities:\n * - Network discovery (`discoverNetwork`).\n * - Local envelope encryption (`encryptToNetwork`).\n * - Node-mediated decrypt with full request/response binding\n * verification (`decryptEnvelope`).\n *\n * Non-responsibilities:\n * - KV/SQL access. Callers fetch encrypted envelopes from their data\n * service of choice and pass them in.\n * - Network onboarding/ceremony. Those routes are node-only.\n */\n\nimport { BaseService } from \"../base/BaseService\";\nimport { type Result } from \"../types\";\nimport {\n base64Decode,\n base64Encode,\n canonicalHashHex,\n} from \"./canonical\";\nimport {\n discoverNetwork as discoverNetworkFn,\n ensureNetworkUsableForDecrypt,\n type NodeDescriptorFetcher,\n type WellKnownDescriptorFetcher,\n} from \"./discovery\";\nimport {\n decryptEnvelopeWithKey,\n encryptToNetwork as encryptToNetworkFn,\n validateEnvelope,\n} from \"./envelope\";\nimport {\n buildCanonicalDecryptRequest,\n buildDecryptFacts,\n buildDecryptInvocation,\n} from \"./invocation\";\nimport { generateRandomReceiverKey } from \"./receiverKey\";\nimport {\n openWrappedKey,\n verifyDecryptResponse,\n} from \"./response\";\nimport {\n DECRYPT_FACT_TYPE,\n encryptionError,\n type DecryptCapabilityProof,\n type DecryptInvocationSigner,\n type DecryptRequestBody,\n type DecryptResponseBody,\n type EncryptionCrypto,\n type EncryptionError,\n type InlineEncryptedEnvelope,\n type NetworkDescriptor,\n toError,\n} from \"./types\";\nimport type {\n EncryptToNetworkOptions,\n DecryptEnvelopeOptions,\n IEncryptionService,\n} from \"./IEncryptionService\";\n\n// Local Result helpers typed to EncryptionError. The shared `ok` / `err`\n// from `../types` default the error generic to `ServiceError`, which\n// widens our return-type inference here.\nfunction encOk<T>(data: T): Result<T, EncryptionError> {\n return { ok: true, data };\n}\nfunction encErr<T = never>(error: EncryptionError): Result<T, EncryptionError> {\n return { ok: false, error };\n}\n\n/**\n * Transport for posting decrypt requests to a TinyCloud node.\n *\n * Implementations supply the `Authorization` header (built by the\n * decrypt-invocation signer) and POST the canonical body. The\n * response body is JSON-decoded into a {@link DecryptResponseBody}.\n */\nexport interface DecryptTransport {\n postDecrypt(input: {\n targetNode: string;\n networkId: string;\n authorization: string;\n canonicalBody: string;\n }): Promise<DecryptResponseBody>;\n}\n\nexport interface EncryptionServiceConfig {\n crypto: EncryptionCrypto;\n signer: DecryptInvocationSigner;\n transport: DecryptTransport;\n node?: NodeDescriptorFetcher;\n wellKnown?: WellKnownDescriptorFetcher;\n [key: string]: unknown;\n}\n\nexport class EncryptionService\n extends BaseService\n implements IEncryptionService\n{\n static readonly serviceName = \"encryption\";\n\n declare protected _config: EncryptionServiceConfig;\n\n constructor(config: EncryptionServiceConfig) {\n super();\n this._config = config;\n }\n\n get config(): EncryptionServiceConfig {\n return this._config;\n }\n\n private get crypto(): EncryptionCrypto {\n return this._config.crypto;\n }\n\n async discoverNetwork(\n identifier: string,\n ownerDid?: string,\n ): Promise<Result<NetworkDescriptor, EncryptionError>> {\n const result = await discoverNetworkFn({\n identifier,\n ...(ownerDid !== undefined ? { ownerDid } : {}),\n ...(this._config.node !== undefined ? { node: this._config.node } : {}),\n ...(this._config.wellKnown !== undefined\n ? { wellKnown: this._config.wellKnown }\n : {}),\n });\n if (!result.ok) return result;\n return encOk(result.data.descriptor);\n }\n\n async encryptToNetwork(\n networkId: string,\n plaintext: Uint8Array,\n options?: EncryptToNetworkOptions,\n ): Promise<Result<InlineEncryptedEnvelope, EncryptionError>> {\n try {\n const discovered = await this.discoverNetwork(networkId);\n if (!discovered.ok) return discovered;\n const usable = ensureNetworkUsableForDecrypt(discovered.data);\n // For encryption we tolerate \"rotating\" but reject revoked/failed/pending —\n // ensureNetworkUsableForDecrypt enforces exactly that constraint.\n if (!usable.ok) return usable;\n\n const descriptor = usable.data;\n const networkPublicKey = base64Decode(descriptor.publicEncryptionKey);\n const result = encryptToNetworkFn(this.crypto, {\n networkId,\n networkPublicKey,\n plaintext,\n ...(options?.aad !== undefined ? { aad: options.aad } : {}),\n alg: options?.alg ?? descriptor.alg,\n keyVersion: options?.keyVersion ?? descriptor.keyVersion,\n ...(options?.metadata !== undefined ? { metadata: options.metadata } : {}),\n });\n return encOk(result.envelope);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n }\n\n async decryptEnvelope(\n envelope: InlineEncryptedEnvelope,\n capabilityProof: DecryptCapabilityProof,\n options?: DecryptEnvelopeOptions,\n ): Promise<Result<Uint8Array, EncryptionError>> {\n try {\n const validated = validateEnvelope(this.crypto, envelope);\n if (!validated.ok) return validated;\n if (\n options?.aad !== undefined &&\n validated.data.aad !== base64Encode(options.aad)\n ) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"decryptEnvelope aad does not match the envelope\",\n }),\n );\n }\n\n let descriptor: NetworkDescriptor;\n if (options?.descriptor !== undefined) {\n descriptor = options.descriptor;\n } else {\n const discovered = await this.discoverNetwork(envelope.networkId);\n if (!discovered.ok) return discovered;\n descriptor = discovered.data;\n }\n const usable = ensureNetworkUsableForDecrypt(descriptor);\n if (!usable.ok) return usable;\n\n const targetNode =\n options?.targetNode ?? descriptor.members[0]?.nodeId;\n if (targetNode === undefined) {\n return encErr(\n encryptionError({\n code: \"INVALID_INPUT\",\n message: \"no target node available from descriptor\",\n }),\n );\n }\n\n // Generate per-request receiver key. We use the random mode by\n // default; callers wanting deterministic derivation must wrap\n // this service directly.\n const receiverKey = generateRandomReceiverKey({ crypto: this.crypto });\n const receiverPublicKey = base64Encode(receiverKey.publicKey);\n const receiverPublicKeyHash = canonicalHashHex(\n this.crypto.sha256,\n receiverPublicKey,\n );\n\n const body: DecryptRequestBody = {\n type: DECRYPT_FACT_TYPE,\n targetNode,\n networkId: envelope.networkId,\n alg: envelope.alg,\n keyVersion: envelope.keyVersion,\n encryptedSymmetricKey: envelope.encryptedSymmetricKey,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey,\n receiverPublicKeyHash,\n };\n const canonicalRequest = buildCanonicalDecryptRequest({\n crypto: this.crypto,\n body,\n receiverPublicKey: receiverKey.publicKey,\n });\n const facts = buildDecryptFacts({\n crypto: this.crypto,\n body,\n encryptedSymmetricKeyHash: envelope.encryptedSymmetricKeyHash,\n receiverPublicKey: receiverKey.publicKey,\n canonicalBody: canonicalRequest.canonicalBody,\n });\n\n const built = await buildDecryptInvocation(this.crypto, this._config.signer, {\n targetNode,\n networkId: envelope.networkId,\n body,\n facts,\n proof: capabilityProof,\n });\n if (!built.ok) return built;\n\n let response: DecryptResponseBody;\n try {\n response = await this._config.transport.postDecrypt({\n targetNode,\n networkId: envelope.networkId,\n authorization: built.data.authorization,\n canonicalBody: built.data.canonicalBody,\n });\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n\n const verified = verifyDecryptResponse({\n crypto: this.crypto,\n request: body,\n facts,\n invocationCid: built.data.invocationCid,\n requestBodyHash: facts.bodyHash,\n response,\n });\n if (!verified.ok) return verified;\n\n const symmetricKey = openWrappedKey(\n this.crypto,\n receiverKey.privateKey,\n verified.data,\n );\n const plaintext = decryptEnvelopeWithKey(\n this.crypto,\n envelope,\n symmetricKey,\n );\n return encOk(plaintext);\n } catch (error) {\n return encErr(\n encryptionError({\n code: \"TRANSPORT_ERROR\",\n cause: toError(error),\n }),\n );\n }\n }\n}\n"],"mappings":"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","names":["ok","serviceError","errorText","valueDelResult","hexEncode","base64Encode","base64Decode","toError","err","crypto","base64Encode","err","base64Decode","hexEncode","crypto","err","crypto","hexEncode","base64Decode","base64Decode","toError","base64Encode"]}