@tinycloud/node-sdk 2.0.3-beta.2 → 2.0.3

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/core.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core.ts","../src/storage/MemorySessionStorage.ts","../src/storage/FileSessionStorage.ts","../src/authorization/NodeUserAuthorization.ts","../src/authorization/strategies.ts","../src/TinyCloudNode.ts","../src/DelegatedAccess.ts","../src/keys/WasmKeyProvider.ts","../src/delegation.ts"],"sourcesContent":["/**\n * @tinycloud/node-sdk/core\n *\n * Platform-agnostic entry point for TinyCloud node-sdk.\n *\n * This entry point excludes Node.js-specific modules that depend on\n * @tinycloud/node-sdk-wasm (PrivateKeySigner, NodeWasmBindings), making it\n * safe to import in browser builds without webpack aliases or shims.\n *\n * Browser consumers (e.g., @tinycloud/web-sdk) should import from this\n * entry point instead of the root \"@tinycloud/node-sdk\".\n *\n * @packageDocumentation\n */\n\n// Re-export core values\nexport { TinyCloud } from \"@tinycloud/sdk-core\";\n\n// Re-export core types\nexport type {\n TinyCloudConfig,\n ISigner,\n ISessionStorage,\n IUserAuthorization,\n ClientSession,\n Extension,\n PersistedSessionData,\n TinyCloudSession,\n INotificationHandler,\n IENSResolver,\n IWasmBindings,\n ISessionManager,\n ISpaceCreationHandler,\n SpaceCreationContext,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export core values for extensibility\nexport {\n SilentNotificationHandler,\n AutoApproveSpaceCreationHandler,\n defaultSpaceCreationHandler,\n} from \"@tinycloud/sdk-core\";\n\n// Storage implementations\nexport { MemorySessionStorage } from \"./storage/MemorySessionStorage\";\nexport { FileSessionStorage } from \"./storage/FileSessionStorage\";\n\n// Authorization\nexport {\n NodeUserAuthorization,\n NodeUserAuthorizationConfig,\n} from \"./authorization/NodeUserAuthorization\";\n\n// Sign strategies — value exports\nexport { defaultSignStrategy } from \"./authorization/strategies\";\n\n// Sign strategies — type exports (re-exported from sdk-core + Node.js-specific types)\nexport type {\n SignRequest,\n SignResponse,\n SignCallback,\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n NodeEventEmitterStrategy,\n SignStrategy,\n} from \"./authorization/strategies\";\n\n// High-level API\nexport { TinyCloudNode, TinyCloudNodeConfig } from \"./TinyCloudNode\";\n\n// Delegation\nexport { DelegatedAccess } from \"./DelegatedAccess\";\nexport {\n PortableDelegation,\n serializeDelegation,\n deserializeDelegation,\n} from \"./delegation\";\n\n// Re-export KV service values\nexport { KVService, PrefixedKVService } from \"@tinycloud/sdk-core\";\n\n// Re-export KV service types\nexport type {\n IKVService,\n KVServiceConfig,\n KVResponse,\n IPrefixedKVService,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export SQL service values\nexport { SQLService, SQLAction, DatabaseHandle } from \"@tinycloud/sdk-core\";\n\n// Re-export SQL service types\nexport type {\n ISQLService,\n IDatabaseHandle,\n SQLServiceConfig,\n SqlValue,\n SqlStatement,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SQLActionType,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export DuckDB service values\nexport { DuckDbService, DuckDbDatabaseHandle, DuckDbAction } from \"@tinycloud/sdk-core\";\n\n// Re-export DuckDB service types\nexport type {\n IDuckDbService,\n IDuckDbDatabaseHandle,\n DuckDbServiceConfig,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n DuckDbValue,\n DuckDbStatement,\n DuckDbQueryResponse,\n DuckDbExecuteResponse,\n DuckDbBatchResponse,\n DuckDbActionType,\n SchemaInfo,\n TableInfo,\n ColumnInfo,\n ViewInfo,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export Vault service values\nexport { DataVaultService, VaultHeaders, VaultPublicSpaceKVActions, createVaultCrypto } from \"@tinycloud/sdk-core\";\n\n// Re-export Vault service types\nexport type {\n IDataVaultService,\n VaultCrypto,\n WasmVaultFunctions,\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultGrantOptions,\n VaultEntry,\n VaultError,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export v2 Delegation service values\nexport {\n DelegationManager,\n SharingService,\n createSharingService,\n DelegationErrorCodes,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export v2 Delegation types\nexport type {\n DelegationManagerConfig,\n ISharingService,\n SharingServiceConfig,\n EncodedShareData,\n ReceiveOptions,\n ShareAccess,\n Delegation,\n CreateDelegationParams,\n DelegationResult,\n DelegationError,\n DelegationErrorCode,\n JWK,\n KeyType,\n KeyInfo,\n CapabilityEntry,\n DelegationRecord,\n SpaceOwnership,\n SpaceInfo,\n ShareSchema,\n ShareLink,\n ShareLinkData,\n IngestOptions,\n GenerateShareParams,\n DelegationChain,\n DelegationChainV2,\n DelegationDirection,\n DelegationFilters,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export CapabilityKeyRegistry values (v2)\nexport {\n CapabilityKeyRegistry,\n createCapabilityKeyRegistry,\n CapabilityKeyRegistryErrorCodes,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export CapabilityKeyRegistry types (v2)\nexport type {\n ICapabilityKeyRegistry,\n StoredDelegationChain,\n CapabilityKeyRegistryErrorCode,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export SpaceService values (v2)\nexport {\n SpaceService,\n SpaceErrorCodes,\n createSpaceService,\n parseSpaceUri,\n buildSpaceUri,\n makePublicSpaceId,\n Space,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export SpaceService types (v2)\nexport type {\n ISpaceService,\n SpaceServiceConfig,\n SpaceErrorCode,\n ISpace,\n SpaceConfig,\n ISpaceScopedDelegations,\n ISpaceScopedSharing,\n} from \"@tinycloud/sdk-core\";\n\n// Protocol version checking\nexport {\n ProtocolMismatchError,\n VersionCheckError,\n UnsupportedFeatureError,\n checkNodeInfo,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export ServiceContext value for advanced usage\nexport { ServiceContext } from \"@tinycloud/sdk-core\";\n\n// Re-export ServiceContext types for advanced usage\nexport type {\n ServiceContextConfig,\n ServiceSession,\n InvokeFunction,\n FetchFunction,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export KeyProvider interface from sdk-core\nexport type { KeyProvider } from \"@tinycloud/sdk-core\";\n\n// Key management for node-sdk\nexport {\n WasmKeyProvider,\n WasmKeyProviderConfig,\n createWasmKeyProvider,\n} from \"./keys/WasmKeyProvider\";\n","import { ISessionStorage, PersistedSessionData } from \"@tinycloud/sdk-core\";\n\n/**\n * In-memory session storage for Node.js.\n *\n * Sessions are stored in memory and lost when the process exits.\n * Suitable for:\n * - Development and testing\n * - Stateless server deployments\n * - Short-lived processes\n *\n * @example\n * ```typescript\n * const storage = new MemorySessionStorage();\n * await storage.save(\"0x123...\", sessionData);\n * const session = await storage.load(\"0x123...\");\n * ```\n */\nexport class MemorySessionStorage implements ISessionStorage {\n private sessions: Map<string, PersistedSessionData> = new Map();\n\n /**\n * Save a session for an address.\n */\n async save(address: string, session: PersistedSessionData): Promise<void> {\n const normalizedAddress = address.toLowerCase();\n this.sessions.set(normalizedAddress, session);\n }\n\n /**\n * Load a session for an address.\n */\n async load(address: string): Promise<PersistedSessionData | null> {\n const normalizedAddress = address.toLowerCase();\n const session = this.sessions.get(normalizedAddress);\n\n if (!session) {\n return null;\n }\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n this.sessions.delete(normalizedAddress);\n return null;\n }\n\n return session;\n }\n\n /**\n * Clear a session for an address.\n */\n async clear(address: string): Promise<void> {\n const normalizedAddress = address.toLowerCase();\n this.sessions.delete(normalizedAddress);\n }\n\n /**\n * Check if a session exists for an address.\n */\n exists(address: string): boolean {\n const normalizedAddress = address.toLowerCase();\n const session = this.sessions.get(normalizedAddress);\n\n if (!session) {\n return false;\n }\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n this.sessions.delete(normalizedAddress);\n return false;\n }\n\n return true;\n }\n\n /**\n * Memory storage is always available.\n */\n isAvailable(): boolean {\n return true;\n }\n\n /**\n * Clear all sessions.\n */\n clearAll(): void {\n this.sessions.clear();\n }\n\n /**\n * Get the number of stored sessions.\n */\n size(): number {\n return this.sessions.size;\n }\n}\n","import { ISessionStorage, PersistedSessionData, validatePersistedSessionData } from \"@tinycloud/sdk-core\";\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n/**\n * File-based session storage for Node.js.\n *\n * Sessions are persisted to the file system and survive process restarts.\n * Suitable for:\n * - CLI applications\n * - Long-running server processes\n * - Development environments\n *\n * @example\n * ```typescript\n * const storage = new FileSessionStorage(\"/tmp/tinycloud-sessions\");\n * await storage.save(\"0x123...\", sessionData);\n * // Session persists across process restarts\n * ```\n */\nexport class FileSessionStorage implements ISessionStorage {\n private readonly baseDir: string;\n\n /**\n * Create a new FileSessionStorage.\n *\n * @param baseDir - Directory to store session files (default: ~/.tinycloud/sessions)\n */\n constructor(baseDir?: string) {\n this.baseDir = baseDir || this.getDefaultDir();\n this.ensureDirectoryExists();\n }\n\n /**\n * Get the default session storage directory.\n */\n private getDefaultDir(): string {\n const home = process.env.HOME || process.env.USERPROFILE || \"/tmp\";\n return join(home, \".tinycloud\", \"sessions\");\n }\n\n /**\n * Ensure the storage directory exists.\n */\n private ensureDirectoryExists(): void {\n if (!existsSync(this.baseDir)) {\n mkdirSync(this.baseDir, { recursive: true });\n }\n }\n\n /**\n * Get the file path for an address.\n */\n private getFilePath(address: string): string {\n const normalizedAddress = address.toLowerCase();\n // Use a hash of the address to avoid filesystem issues\n const filename = `${normalizedAddress.replace(\"0x\", \"\")}.json`;\n return join(this.baseDir, filename);\n }\n\n /**\n * Save a session for an address.\n */\n async save(address: string, session: PersistedSessionData): Promise<void> {\n const filePath = this.getFilePath(address);\n const data = JSON.stringify(session, null, 2);\n writeFileSync(filePath, data, \"utf-8\");\n }\n\n /**\n * Load a session for an address.\n */\n async load(address: string): Promise<PersistedSessionData | null> {\n const filePath = this.getFilePath(address);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const data = readFileSync(filePath, \"utf-8\");\n const parsed = JSON.parse(data);\n\n // Validate loaded data against schema\n const validation = validatePersistedSessionData(parsed);\n if (!validation.ok) {\n console.warn(`Invalid session data for ${address}:`, validation.error.message);\n // Clean up invalid session\n unlinkSync(filePath);\n return null;\n }\n\n const session = validation.data;\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n // Clean up expired session\n unlinkSync(filePath);\n return null;\n }\n\n return session;\n } catch (error) {\n // Invalid JSON or read error - remove the file\n try {\n unlinkSync(filePath);\n } catch {\n // Ignore cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Clear a session for an address.\n */\n async clear(address: string): Promise<void> {\n const filePath = this.getFilePath(address);\n if (existsSync(filePath)) {\n unlinkSync(filePath);\n }\n }\n\n /**\n * Check if a session exists for an address.\n */\n exists(address: string): boolean {\n const filePath = this.getFilePath(address);\n if (!existsSync(filePath)) {\n return false;\n }\n\n try {\n const data = readFileSync(filePath, \"utf-8\");\n const session: PersistedSessionData = JSON.parse(data);\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n // Clean up expired session\n unlinkSync(filePath);\n return false;\n }\n\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if file system storage is available.\n */\n isAvailable(): boolean {\n try {\n this.ensureDirectoryExists();\n return existsSync(this.baseDir);\n } catch {\n return false;\n }\n }\n}\n","import { EventEmitter } from \"events\";\nimport {\n IUserAuthorization,\n ISigner,\n ISessionStorage,\n ClientSession,\n Extension,\n PersistedSessionData,\n TinyCloudSession,\n SiweConfig,\n fetchPeerId,\n submitHostDelegation,\n activateSessionWithHost,\n checkNodeInfo,\n ISpaceCreationHandler,\n AutoApproveSpaceCreationHandler,\n IWasmBindings,\n ISessionManager,\n} from \"@tinycloud/sdk-core\";\nimport {\n SignStrategy,\n SignRequest,\n SignResponse,\n defaultSignStrategy,\n} from \"./strategies\";\nimport { MemorySessionStorage } from \"../storage/MemorySessionStorage\";\n\n/**\n * Configuration for NodeUserAuthorization.\n */\nexport interface NodeUserAuthorizationConfig {\n /** The signer used for signing messages */\n signer: ISigner;\n /** Sign strategy for handling sign requests */\n signStrategy?: SignStrategy;\n /** Session storage implementation */\n sessionStorage?: ISessionStorage;\n /** Domain for SIWE messages */\n domain: string;\n /** URI for SIWE messages (default: domain) */\n uri?: string;\n /** Statement included in SIWE messages */\n statement?: string;\n /** Space prefix for new sessions */\n spacePrefix?: string;\n /** Default actions for sessions */\n defaultActions?: Record<string, Record<string, string[]>>;\n /** Session expiration time in milliseconds (default: 1 hour) */\n sessionExpirationMs?: number;\n /** Automatically create space if it doesn't exist (default: false) */\n autoCreateSpace?: boolean;\n /** Custom space creation handler. If provided, takes precedence over autoCreateSpace. */\n spaceCreationHandler?: ISpaceCreationHandler;\n /** TinyCloud server endpoints (default: [\"https://node.tinycloud.xyz\"]) */\n tinycloudHosts?: string[];\n /** Whether to include public space capabilities in the session (default: true) */\n enablePublicSpace?: boolean;\n /** WASM bindings for cryptographic operations. Required. */\n wasmBindings: IWasmBindings;\n /** Optional SIWE configuration overrides (e.g., nonce for server-provided nonces) */\n siweConfig?: SiweConfig;\n}\n\n/**\n * Node.js implementation of IUserAuthorization.\n *\n * Supports multiple sign strategies for different use cases:\n * - auto-sign: Automatically approve all sign requests (trusted backends)\n * - auto-reject: Reject all sign requests (read-only mode)\n * - callback: Delegate to a custom callback function (CLI prompts)\n * - event-emitter: Emit sign requests as events (async workflows)\n *\n * @example\n * ```typescript\n * // Auto-sign for backend services\n * const auth = new NodeUserAuthorization({\n * signer: new PrivateKeySigner(process.env.PRIVATE_KEY),\n * signStrategy: { type: 'auto-sign' },\n * domain: 'api.myapp.com',\n * });\n *\n * // Callback for CLI prompts\n * const auth = new NodeUserAuthorization({\n * signer,\n * signStrategy: {\n * type: 'callback',\n * handler: async (req) => {\n * const approved = await promptUser(`Sign for ${req.address}?`);\n * return { approved };\n * }\n * },\n * domain: 'cli.myapp.com',\n * });\n * ```\n */\nexport class NodeUserAuthorization implements IUserAuthorization {\n private readonly signer: ISigner;\n private readonly signStrategy: SignStrategy;\n private readonly sessionStorage: ISessionStorage;\n private readonly domain: string;\n private readonly uri: string;\n private readonly statement?: string;\n private readonly spacePrefix: string;\n private readonly defaultActions: Record<string, Record<string, string[]>>;\n private readonly sessionExpirationMs: number;\n private readonly autoCreateSpace: boolean;\n private readonly spaceCreationHandler?: ISpaceCreationHandler;\n private readonly tinycloudHosts: string[];\n private readonly enablePublicSpace: boolean;\n private readonly siweConfig?: SiweConfig;\n private readonly wasm: IWasmBindings;\n\n private sessionManager: ISessionManager;\n private extensions: Extension[] = [];\n private _session?: ClientSession;\n private _tinyCloudSession?: TinyCloudSession;\n private _address?: string;\n private _chainId?: number;\n private _nodeFeatures: string[] = [];\n\n constructor(config: NodeUserAuthorizationConfig) {\n this.wasm = config.wasmBindings;\n\n this.signer = config.signer;\n this.signStrategy = config.signStrategy ?? defaultSignStrategy;\n this.sessionStorage = config.sessionStorage ?? new MemorySessionStorage();\n this.domain = config.domain;\n this.uri = config.uri ?? `https://${config.domain}`;\n this.statement = config.statement;\n this.spacePrefix = config.spacePrefix ?? \"default\";\n this.defaultActions = config.defaultActions ?? {\n kv: {\n \"\": [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n ],\n },\n sql: {\n \"\": [\n \"tinycloud.sql/read\",\n \"tinycloud.sql/write\",\n \"tinycloud.sql/admin\",\n \"tinycloud.sql/export\",\n ],\n },\n duckdb: {\n \"\": [\n \"tinycloud.duckdb/read\",\n \"tinycloud.duckdb/write\",\n \"tinycloud.duckdb/admin\",\n \"tinycloud.duckdb/describe\",\n \"tinycloud.duckdb/export\",\n \"tinycloud.duckdb/import\",\n \"tinycloud.duckdb/execute\",\n ],\n },\n capabilities: {\n \"\": [\"tinycloud.capabilities/read\"],\n },\n };\n this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1000;\n this.autoCreateSpace = config.autoCreateSpace ?? false;\n this.spaceCreationHandler = config.spaceCreationHandler;\n this.tinycloudHosts = config.tinycloudHosts ?? [\"https://node.tinycloud.xyz\"];\n this.enablePublicSpace = config.enablePublicSpace ?? true;\n this.siweConfig = config.siweConfig;\n\n // Initialize session manager via WASM bindings\n this.sessionManager = this.wasm.createSessionManager();\n }\n\n /**\n * The current active session (web-core compatible).\n */\n get session(): ClientSession | undefined {\n return this._session;\n }\n\n /**\n * The current TinyCloud session with full delegation data.\n * Includes spaceId, delegationHeader, and delegationCid.\n */\n get tinyCloudSession(): TinyCloudSession | undefined {\n return this._tinyCloudSession;\n }\n\n get nodeFeatures(): string[] {\n return this._nodeFeatures;\n }\n\n /**\n * Build SIWE overrides from siweConfig.\n * - statement is prepended to the default statement\n * - resources are appended to the default resources\n * - uri triggers a warning (overwriting delegation target)\n * - all other fields override directly\n */\n private buildSiweOverrides(): Record<string, unknown> {\n if (!this.siweConfig) return { uri: this.uri };\n\n const { statement, resources, uri, ...rest } = this.siweConfig;\n const overrides: Record<string, unknown> = { uri: this.uri, ...rest };\n\n if (statement) {\n overrides.statement = this.statement\n ? `${statement} ${this.statement}`\n : statement;\n }\n\n if (resources && resources.length > 0) {\n overrides.resources = resources;\n }\n\n if (uri) {\n console.warn(\n \"[tinycloud] siweConfig.uri is overwriting the delegation target URI. \" +\n \"This may break delegation chain validation if the URI does not match the session key DID.\",\n );\n overrides.uri = uri;\n }\n\n return overrides;\n }\n\n /**\n * Add an extension to the authorization flow.\n */\n extend(extension: Extension): void {\n this.extensions.push(extension);\n }\n\n /**\n * Get the space ID for the current session.\n */\n getSpaceId(): string | undefined {\n return this._tinyCloudSession?.spaceId;\n }\n\n /**\n * Create the space on the TinyCloud server (host delegation).\n * This registers the user as the owner of the space.\n */\n private async hostSpace(targetSpaceId?: string): Promise<boolean> {\n if (!this._tinyCloudSession || !this._address || !this._chainId) {\n throw new Error(\"Must be signed in to host space\");\n }\n\n const host = this.tinycloudHosts[0];\n const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;\n\n // Get peer ID from TinyCloud server\n const peerId = await fetchPeerId(host, spaceId);\n\n // Generate host SIWE message\n const siwe = this.wasm.generateHostSIWEMessage({\n address: this._address,\n chainId: this._chainId,\n domain: this.domain,\n issuedAt: new Date().toISOString(),\n spaceId,\n peerId,\n });\n\n // Sign the message\n const signature = await this.signMessage(siwe);\n\n // Convert to delegation headers and submit\n const headers = this.wasm.siweToDelegationHeaders({ siwe, signature });\n const result = await submitHostDelegation(host, headers);\n\n return result.success;\n }\n\n /**\n * Create a specific space on the server via host delegation.\n * Used for lazy creation of additional spaces (e.g., public).\n */\n async hostPublicSpace(spaceId: string): Promise<boolean> {\n return this.hostSpace(spaceId);\n }\n\n /**\n * Ensure the user's space exists on the TinyCloud server.\n * Creates the space if it doesn't exist and autoCreateSpace is enabled.\n * If autoCreateSpace is false and space doesn't exist, silently returns\n * (user may be using delegations to access other spaces).\n *\n * @throws Error if space creation fails\n */\n async ensureSpaceExists(): Promise<void> {\n if (!this._tinyCloudSession) {\n throw new Error(\"Must be signed in to ensure space exists\");\n }\n\n const host = this.tinycloudHosts[0];\n const primarySpaceId = this._tinyCloudSession.spaceId;\n\n // Try to activate the session\n const result = await activateSessionWithHost(\n host,\n this._tinyCloudSession.delegationHeader\n );\n\n // Determine the effective space creation handler:\n // 1. Explicit spaceCreationHandler takes precedence\n // 2. autoCreateSpace: true uses AutoApproveSpaceCreationHandler\n // 3. Otherwise, no handler (space creation skipped silently)\n const handler: ISpaceCreationHandler | undefined = this.spaceCreationHandler\n ?? (this.autoCreateSpace ? new AutoApproveSpaceCreationHandler() : undefined);\n\n const creationContext = {\n spaceId: primarySpaceId,\n address: this._address!,\n chainId: this._chainId!,\n host,\n };\n\n if (result.success) {\n // Check if primary space was actually activated or just skipped\n const primarySkipped = result.skipped?.includes(primarySpaceId);\n\n if (!primarySkipped) {\n // Primary space exists and session is activated\n return;\n }\n\n // Primary space was skipped (doesn't exist yet)\n if (!handler) {\n return;\n }\n\n const confirmed = await handler.confirmSpaceCreation(creationContext);\n if (!confirmed) {\n return;\n }\n\n // Create the primary space\n try {\n const created = await this.hostSpace();\n if (!created) {\n const err = new Error(`Failed to create space: ${primarySpaceId}`);\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n } catch (error) {\n handler.onSpaceCreationFailed?.(creationContext, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n\n // Small delay to allow space creation to propagate\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n // Retry activation\n const retryResult = await activateSessionWithHost(\n host,\n this._tinyCloudSession.delegationHeader\n );\n\n if (!retryResult.success) {\n const err = new Error(\n `Failed to activate session after creating space: ${retryResult.error}`\n );\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n\n handler.onSpaceCreated?.(creationContext);\n return;\n }\n\n // Handle 404 (backwards compat with older servers)\n if (result.status === 404) {\n if (!handler) {\n return;\n }\n\n const confirmed = await handler.confirmSpaceCreation(creationContext);\n if (!confirmed) {\n return;\n }\n\n try {\n const created = await this.hostSpace();\n if (!created) {\n const err = new Error(`Failed to create space: ${primarySpaceId}`);\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n } catch (error) {\n handler.onSpaceCreationFailed?.(creationContext, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n const retryResult = await activateSessionWithHost(\n host,\n this._tinyCloudSession.delegationHeader\n );\n\n if (!retryResult.success) {\n const err = new Error(\n `Failed to activate session after creating space: ${retryResult.error}`\n );\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n\n handler.onSpaceCreated?.(creationContext);\n return;\n }\n\n throw new Error(`Failed to activate session: ${result.error}`);\n }\n\n /**\n * Sign in and create a new session.\n *\n * This follows the correct SIWE-ReCap flow:\n * 1. Create session key and get JWK\n * 2. Call prepareSession() which generates the SIWE with ReCap capabilities\n * 3. Sign the SIWE string from prepareSession\n * 4. Call completeSessionSetup() with the prepared session + signature\n */\n async signIn(): Promise<ClientSession> {\n // Get signer address and chain ID\n this._address = await this.signer.getAddress();\n this._chainId = await this.signer.getChainId();\n\n const address = this.wasm.ensureEip55(this._address);\n const chainId = this._chainId;\n\n // Create a session key\n const keyId = `session-${Date.now()}`;\n this.sessionManager.renameSessionKeyId(\"default\", keyId);\n\n // Get JWK for session key\n const jwkString = this.sessionManager.jwk(keyId);\n if (!jwkString) {\n throw new Error(\"Failed to create session key\");\n }\n const jwk = JSON.parse(jwkString);\n\n // Create space ID\n const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);\n\n const now = new Date();\n const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);\n\n // Prepare session - this creates the SIWE message with ReCap capabilities\n const prepared = this.wasm.prepareSession({\n abilities: this.defaultActions,\n address,\n chainId,\n domain: this.domain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId,\n jwk,\n ...this.buildSiweOverrides(),\n });\n\n // Sign the SIWE message from prepareSession (NOT a separately generated SIWE)\n const signature = await this.requestSignature({\n address,\n chainId,\n message: prepared.siwe,\n type: \"siwe\",\n });\n\n // Complete session setup with the prepared session + signature\n const session = this.wasm.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Create client session (web-core compatible)\n const clientSession: ClientSession = {\n address,\n walletAddress: address,\n chainId,\n sessionKey: keyId,\n siwe: prepared.siwe,\n signature,\n };\n\n // Compute additional spaces as metadata (not in the delegation itself).\n // The public space delegation is created lazily via ensurePublicSpace(),\n // not at signIn time, to avoid creating spaces the user may never use.\n const spacesMetadata: Record<string, string> | undefined =\n this.enablePublicSpace\n ? { public: this.wasm.makeSpaceId(address, chainId, \"public\") }\n : undefined;\n\n // Create TinyCloud session with full delegation data\n // Use sessionManager.getDID(keyId) for verificationMethod to get properly formatted DID URL\n // The prepared.verificationMethod from Rust WASM has a bug that doubles the DID fragment\n const tinyCloudSession: TinyCloudSession = {\n address,\n chainId,\n sessionKey: keyId,\n spaceId,\n spaces: spacesMetadata,\n delegationCid: session.delegationCid,\n delegationHeader: session.delegationHeader,\n verificationMethod: this.sessionManager.getDID(keyId),\n jwk,\n siwe: prepared.siwe,\n signature,\n };\n\n // Persist session with TinyCloud-specific data\n const persistedData: PersistedSessionData = {\n address,\n chainId,\n sessionKey: JSON.stringify(jwk),\n siwe: prepared.siwe,\n signature,\n tinycloudSession: {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId,\n spaces: spacesMetadata,\n verificationMethod: this.sessionManager.getDID(keyId),\n },\n expiresAt: expirationTime.toISOString(),\n createdAt: now.toISOString(),\n version: \"1.0\",\n };\n await this.sessionStorage.save(address, persistedData);\n\n // Set current session\n this._session = clientSession;\n this._tinyCloudSession = tinyCloudSession;\n this._address = address;\n this._chainId = chainId;\n\n // Verify SDK-node protocol compatibility and discover supported features\n const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], this.wasm.protocolVersion());\n this._nodeFeatures = nodeInfo.features;\n\n // Call extension hooks\n for (const ext of this.extensions) {\n if (ext.afterSignIn) {\n await ext.afterSignIn(clientSession);\n }\n }\n\n // Ensure space exists (creates if needed when autoCreateSpace is true)\n await this.ensureSpaceExists();\n\n return clientSession;\n }\n\n /**\n * Sign out and clear the current session.\n */\n async signOut(): Promise<void> {\n if (this._address) {\n await this.clearPersistedSession(this._address);\n }\n this._session = undefined;\n }\n\n /**\n * Get the current wallet/signer address.\n */\n address(): string | undefined {\n return this._address;\n }\n\n /**\n * Get the current chain ID.\n */\n chainId(): number | undefined {\n return this._chainId;\n }\n\n /**\n * Sign a message with the connected signer.\n */\n async signMessage(message: string): Promise<string> {\n if (!this._address) {\n this._address = await this.signer.getAddress();\n }\n if (!this._chainId) {\n this._chainId = await this.signer.getChainId();\n }\n\n return this.requestSignature({\n address: this._address,\n chainId: this._chainId,\n message,\n type: \"message\",\n });\n }\n\n\n /**\n * Prepare a session for external signing.\n *\n * Use this method when you need to sign the SIWE message externally (e.g., via\n * a hardware wallet, multi-sig, or external service). After obtaining the signature,\n * call `signInWithPreparedSession()` to complete the sign-in.\n *\n * @example\n * ```typescript\n * const { prepared, keyId, jwk } = await auth.prepareSessionForSigning();\n * const signature = await externalSigner.signMessage(prepared.siwe);\n * const session = await auth.signInWithPreparedSession(prepared, signature, keyId, jwk);\n * ```\n */\n async prepareSessionForSigning(): Promise<{\n prepared: {\n siwe: string;\n jwk: Record<string, unknown>;\n spaceId: string;\n verificationMethod: string;\n };\n keyId: string;\n jwk: Record<string, unknown>;\n address: string;\n chainId: number;\n }> {\n const address = this.wasm.ensureEip55(await this.signer.getAddress());\n const chainId = await this.signer.getChainId();\n\n // Create a session key\n const keyId = `session-${Date.now()}`;\n this.sessionManager.renameSessionKeyId(\"default\", keyId);\n\n // Get JWK for session key\n const jwkString = this.sessionManager.jwk(keyId);\n if (!jwkString) {\n throw new Error(\"Failed to create session key\");\n }\n const jwk = JSON.parse(jwkString);\n\n // Create space ID\n const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);\n\n const now = new Date();\n const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);\n\n // Prepare session - this creates the SIWE message with ReCap capabilities\n const prepared = this.wasm.prepareSession({\n abilities: this.defaultActions,\n address,\n chainId,\n domain: this.domain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId,\n jwk,\n ...this.buildSiweOverrides(),\n });\n\n return {\n prepared,\n keyId,\n jwk,\n address,\n chainId,\n };\n }\n\n /**\n * Complete sign-in with a prepared session and signature.\n *\n * Use this method after obtaining a signature for the SIWE message from\n * `prepareSessionForSigning()`. The signature MUST be over `prepared.siwe`.\n *\n * @param prepared - The prepared session from `prepareSessionForSigning()`\n * @param signature - The signature over `prepared.siwe`\n * @param keyId - The session key ID from `prepareSessionForSigning()`\n * @param jwk - The JWK from `prepareSessionForSigning()`\n */\n async signInWithPreparedSession(\n prepared: {\n siwe: string;\n jwk: Record<string, unknown>;\n spaceId: string;\n verificationMethod: string;\n },\n signature: string,\n keyId: string,\n jwk: Record<string, unknown>,\n ): Promise<ClientSession> {\n // Complete session setup with the prepared session + signature\n const session = this.wasm.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Parse address and chainId from the prepared session\n // The SIWE message contains this info, but we need to extract it\n // For now, we'll get it from the signer since it should match\n const address = this.wasm.ensureEip55(await this.signer.getAddress());\n const chainId = await this.signer.getChainId();\n\n // Create client session (web-core compatible)\n const clientSession: ClientSession = {\n address,\n walletAddress: address,\n chainId,\n sessionKey: keyId,\n siwe: prepared.siwe,\n signature,\n };\n\n // Compute additional spaces as metadata (not in the delegation itself).\n const spacesMetadata: Record<string, string> | undefined =\n this.enablePublicSpace\n ? { public: this.wasm.makeSpaceId(address, chainId, \"public\") }\n : undefined;\n\n // Create TinyCloud session with full delegation data\n // Use sessionManager.getDID(keyId) for properly formatted DID URL\n const tinyCloudSession: TinyCloudSession = {\n address,\n chainId,\n sessionKey: keyId,\n spaceId: prepared.spaceId,\n spaces: spacesMetadata,\n delegationCid: session.delegationCid,\n delegationHeader: session.delegationHeader,\n verificationMethod: this.sessionManager.getDID(keyId),\n jwk,\n siwe: prepared.siwe,\n signature,\n };\n\n // Extract expiration from SIWE message (parse the string)\n const expirationMatch = prepared.siwe.match(/Expiration Time: (.+)/);\n const issuedAtMatch = prepared.siwe.match(/Issued At: (.+)/);\n const expiresAt =\n expirationMatch?.[1] ??\n new Date(Date.now() + this.sessionExpirationMs).toISOString();\n const createdAt = issuedAtMatch?.[1] ?? new Date().toISOString();\n\n // Persist session with TinyCloud-specific data\n const persistedData: PersistedSessionData = {\n address,\n chainId,\n sessionKey: JSON.stringify(jwk),\n siwe: prepared.siwe,\n signature,\n tinycloudSession: {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: prepared.spaceId,\n spaces: spacesMetadata,\n verificationMethod: this.sessionManager.getDID(keyId),\n },\n expiresAt,\n createdAt,\n version: \"1.0\",\n };\n await this.sessionStorage.save(address, persistedData);\n\n // Set current session\n this._session = clientSession;\n this._tinyCloudSession = tinyCloudSession;\n this._address = address;\n this._chainId = chainId;\n\n // Verify SDK-node protocol compatibility and discover supported features\n const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], this.wasm.protocolVersion());\n this._nodeFeatures = nodeInfo.features;\n\n // Call extension hooks\n for (const ext of this.extensions) {\n if (ext.afterSignIn) {\n await ext.afterSignIn(clientSession);\n }\n }\n\n // Ensure space exists (creates if needed when autoCreateSpace is true)\n await this.ensureSpaceExists();\n\n return clientSession;\n }\n\n /**\n * Clear persisted session data.\n */\n async clearPersistedSession(address?: string): Promise<void> {\n const targetAddress = address ?? this._address;\n if (targetAddress) {\n await this.sessionStorage.clear(targetAddress);\n }\n }\n\n /**\n * Check if a session is persisted for an address.\n */\n isSessionPersisted(address: string): boolean {\n return this.sessionStorage.exists(address);\n }\n\n /**\n * Request a signature based on the configured strategy.\n */\n private async requestSignature(request: SignRequest): Promise<string> {\n switch (this.signStrategy.type) {\n case \"auto-sign\":\n return this.signer.signMessage(request.message);\n\n case \"auto-reject\":\n throw new Error(\"Sign request rejected by auto-reject strategy\");\n\n case \"callback\": {\n const response = await this.signStrategy.handler(request);\n if (!response.approved) {\n throw new Error(\n response.reason ?? \"Sign request rejected by callback\"\n );\n }\n // If callback provides signature, use it; otherwise sign with signer\n return (\n response.signature ?? (await this.signer.signMessage(request.message))\n );\n }\n\n case \"event-emitter\": {\n return this.requestSignatureViaEmitter(\n request,\n this.signStrategy.emitter,\n this.signStrategy.timeout ?? 60000\n );\n }\n\n default:\n throw new Error(`Unknown sign strategy: ${(this.signStrategy as any).type}`);\n }\n }\n\n /**\n * Request signature via event emitter with timeout.\n */\n private requestSignatureViaEmitter(\n request: SignRequest,\n emitter: EventEmitter,\n timeout: number\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(\"Sign request timed out\"));\n }, timeout);\n\n const respond = async (response: SignResponse) => {\n clearTimeout(timeoutId);\n if (!response.approved) {\n reject(\n new Error(response.reason ?? \"Sign request rejected via emitter\")\n );\n } else {\n // If response provides signature, use it; otherwise sign with signer\n const signature =\n response.signature ??\n (await this.signer.signMessage(request.message));\n resolve(signature);\n }\n };\n\n emitter.emit(\"sign-request\", request, respond);\n });\n }\n}\n","/**\n * Node.js-specific SignStrategy types for TinyCloud authorization.\n *\n * This module re-exports common types from sdk-core and provides\n * Node.js-specific implementations (e.g., NodeEventEmitterStrategy\n * using Node's EventEmitter instead of browser EventTarget).\n *\n * @packageDocumentation\n */\n\nimport { EventEmitter } from \"events\";\n\n// Import types for local use in SignStrategy union\nimport type {\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export common types from sdk-core (type-only — erased at runtime in sdk-core dist)\nexport type {\n SignRequest,\n SignResponse,\n SignCallback,\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n} from \"@tinycloud/sdk-core\";\n\n/**\n * Node.js event emitter strategy: emits sign requests as events.\n *\n * Uses Node.js EventEmitter for compatibility with Node.js applications.\n * For browser environments, use the EventEmitterStrategy from sdk-core\n * which uses EventTarget.\n *\n * Events emitted:\n * - 'sign-request': When a sign request is received\n *\n * Use cases:\n * - Async approval workflows in Node.js\n * - External signing services\n * - Multi-step authorization flows\n *\n * @example\n * ```typescript\n * const emitter = new EventEmitter();\n * const strategy: NodeEventEmitterStrategy = { type: 'event-emitter', emitter };\n *\n * emitter.on('sign-request', async (req, respond) => {\n * const approved = await externalApprovalService.check(req);\n * respond({ approved, signature: approved ? await sign(req.message) : undefined });\n * });\n * ```\n */\nexport interface NodeEventEmitterStrategy {\n type: \"event-emitter\";\n emitter: EventEmitter;\n /** Timeout in milliseconds for waiting on event response (default: 60000) */\n timeout?: number;\n}\n\n/**\n * Node.js sign strategy union type.\n *\n * Determines how sign requests are handled in NodeUserAuthorization.\n * Uses Node.js EventEmitter for the event-emitter strategy.\n */\nexport type SignStrategy =\n | AutoSignStrategy\n | AutoRejectStrategy\n | CallbackStrategy\n | NodeEventEmitterStrategy;\n\n/**\n * Default sign strategy is auto-sign for convenience.\n * This is the Node.js-specific version typed with SignStrategy.\n */\nexport const defaultSignStrategy: SignStrategy = { type: \"auto-sign\" };\n","/**\n * TinyCloudNode - High-level API for Node.js users.\n *\n * Each user has their own TinyCloudNode instance with their own key.\n * This class provides a simplified interface for:\n * - Signing in and managing sessions\n * - Key-value storage operations on own space\n * - Creating and using delegations\n *\n * @example\n * ```typescript\n * const alice = new TinyCloudNode({\n * privateKey: process.env.ALICE_PRIVATE_KEY,\n * host: \"https://node.tinycloud.xyz\",\n * prefix: \"myapp\",\n * });\n *\n * await alice.signIn();\n * await alice.kv.put(\"greeting\", \"Hello, world!\");\n *\n * // Delegate access to Bob\n * const delegation = await alice.createDelegation({\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * delegateDID: bob.did,\n * });\n *\n * // Bob uses the delegation\n * const access = await bob.useDelegation(delegation);\n * const data = await access.kv.get(\"shared/data\");\n * ```\n */\n\nimport {\n TinyCloud,\n TinyCloudSession,\n activateSessionWithHost,\n KVService,\n IKVService,\n SQLService,\n ISQLService,\n DuckDbService,\n IDuckDbService,\n DataVaultService,\n IDataVaultService,\n createVaultCrypto,\n ServiceSession,\n ServiceContext,\n ISessionStorage,\n ISigner,\n INotificationHandler,\n SilentNotificationHandler,\n IENSResolver,\n IWasmBindings,\n ISessionManager,\n ISpaceCreationHandler,\n // v2 services\n DelegationManager,\n SpaceService,\n ISpaceService,\n CapabilityKeyRegistry,\n ICapabilityKeyRegistry,\n SharingService,\n ISharingService,\n // v2 types\n SiweConfig,\n Delegation,\n CreateDelegationParams,\n KeyInfo,\n JWK,\n DelegationResult,\n CreateDelegationWasmParams,\n CreateDelegationWasmResult,\n UnsupportedFeatureError,\n makePublicSpaceId,\n} from \"@tinycloud/sdk-core\";\nimport { NodeUserAuthorization } from \"./authorization/NodeUserAuthorization\";\nimport { FileSessionStorage } from \"./storage/FileSessionStorage\";\nimport { MemorySessionStorage } from \"./storage/MemorySessionStorage\";\nimport { PortableDelegation } from \"./delegation\";\nimport { DelegatedAccess } from \"./DelegatedAccess\";\nimport { WasmKeyProvider } from \"./keys/WasmKeyProvider\";\n\n/** Default TinyCloud host */\nconst DEFAULT_HOST = \"https://node.tinycloud.xyz\";\n\n/**\n * Configuration for TinyCloudNode.\n * All fields are optional - TinyCloudNode can work with zero configuration.\n */\nexport interface TinyCloudNodeConfig {\n /** Hex-encoded private key (with or without 0x prefix). Optional - only needed for wallet mode and signIn() */\n privateKey?: string;\n /** Custom signer implementation. If provided, takes precedence over privateKey. */\n signer?: ISigner;\n /** TinyCloud server URL (default: \"https://node.tinycloud.xyz\") */\n host?: string;\n /** Space prefix for this user's space. Optional - only needed for signIn() */\n prefix?: string;\n /** Domain for SIWE messages (default: derived from host) */\n domain?: string;\n /** Session expiration time in milliseconds (default: 1 hour) */\n sessionExpirationMs?: number;\n /** Whether to automatically create space if it doesn't exist (default: false) */\n autoCreateSpace?: boolean;\n /** Custom session storage implementation (default: MemorySessionStorage) */\n sessionStorage?: ISessionStorage;\n /** Whether to include public space capabilities in the session (default: true).\n * When true, signIn() automatically includes capabilities for the user's public space,\n * accessible via spaces.get('public').kv */\n enablePublicSpace?: boolean;\n /** Custom WASM bindings (default: @tinycloud/node-sdk-wasm). Used by browser wrapper. */\n wasmBindings?: IWasmBindings;\n /** Notification handler for sign-in/sign-out/error events (default: SilentNotificationHandler) */\n notificationHandler?: INotificationHandler;\n /** ENS resolver for resolving .eth names in delegation methods */\n ensResolver?: IENSResolver;\n /** Custom space creation handler (default: auto-approve when autoCreateSpace is true) */\n spaceCreationHandler?: ISpaceCreationHandler;\n /** Optional SIWE configuration overrides (e.g., nonce for server-provided nonces) */\n siweConfig?: SiweConfig;\n}\n\n/**\n * High-level TinyCloud API for Node.js environments.\n *\n * Each user creates their own TinyCloudNode instance with their private key.\n * The instance manages the user's session and provides access to their space.\n */\n/** @internal */\nexport interface NodeDefaults {\n createWasmBindings: () => IWasmBindings;\n createSigner: (privateKey: string, chainId?: number) => ISigner;\n}\n\nexport class TinyCloudNode {\n /** @internal Registered by importing @tinycloud/node-sdk (not /core) */\n private static nodeDefaults?: NodeDefaults;\n\n /** @internal Register Node.js-specific defaults (NodeWasmBindings, PrivateKeySigner) */\n static registerNodeDefaults(defaults: NodeDefaults): void {\n TinyCloudNode.nodeDefaults = defaults;\n }\n\n private config: TinyCloudNodeConfig;\n private signer: ISigner | null = null;\n private auth: NodeUserAuthorization | null = null;\n private tc: TinyCloud | null = null;\n private _address?: string;\n private _chainId: number = 1;\n private wasmBindings: IWasmBindings;\n private sessionManager: ISessionManager;\n private _serviceContext?: ServiceContext;\n private _kv?: KVService;\n private _sql?: SQLService;\n private _duckdb?: DuckDbService;\n private _vault?: DataVaultService;\n /** Cached public KV with proper delegation (set by ensurePublicSpace) */\n private _publicKV?: KVService;\n\n /** Session key ID - always available */\n private sessionKeyId: string;\n /** Session key JWK as object - always available */\n private sessionKeyJwk: object;\n\n /** Notification handler for user-facing events */\n private notificationHandler: INotificationHandler;\n\n // v2 services (initialized in constructor)\n private _capabilityRegistry: CapabilityKeyRegistry;\n private _keyProvider: WasmKeyProvider;\n private _sharingService: SharingService;\n // These are initialized after signIn()\n private _delegationManager?: DelegationManager;\n private _spaceService?: SpaceService;\n\n private get nodeFeatures(): string[] {\n return this.auth?.nodeFeatures ?? [];\n }\n\n /** SIWE domain — uses config override or defaults to app.tinycloud.xyz */\n private get siweDomain(): string {\n return this.config.domain ?? 'app.tinycloud.xyz';\n }\n\n /**\n * Create a new TinyCloudNode instance.\n *\n * All configuration is optional. Without a privateKey, the instance operates\n * in \"session-only\" mode where it can receive delegations but cannot create\n * its own space via signIn().\n *\n * @param config - Configuration options (all optional)\n *\n * @example\n * ```typescript\n * // Session-only mode - can receive delegations\n * const bob = new TinyCloudNode();\n * console.log(bob.did); // did:key:z6Mk... - available immediately\n *\n * // Wallet mode - can create own space\n * const alice = new TinyCloudNode({\n * privateKey: process.env.ALICE_PRIVATE_KEY,\n * prefix: \"myapp\",\n * });\n * await alice.signIn();\n * ```\n */\n constructor(config: TinyCloudNodeConfig = {}) {\n // Store config with default host\n this.config = {\n ...config,\n host: config.host ?? DEFAULT_HOST,\n };\n\n // Initialize WASM bindings (uses registered Node defaults if not provided)\n if (config.wasmBindings) {\n this.wasmBindings = config.wasmBindings;\n } else if (TinyCloudNode.nodeDefaults) {\n this.wasmBindings = TinyCloudNode.nodeDefaults.createWasmBindings();\n } else {\n throw new Error(\n \"wasmBindings must be provided in config. \" +\n \"Import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults.\"\n );\n }\n\n // Always create session manager and session key immediately\n this.sessionManager = this.wasmBindings.createSessionManager();\n\n // Try to use \"default\" key, create if it doesn't exist\n const defaultKeyId = \"default\";\n let jwkStr = this.sessionManager.jwk(defaultKeyId);\n if (jwkStr) {\n // Key already exists, reuse it\n this.sessionKeyId = defaultKeyId;\n } else {\n // Create new key\n this.sessionKeyId = this.sessionManager.createSessionKey(defaultKeyId);\n jwkStr = this.sessionManager.jwk(this.sessionKeyId);\n }\n\n if (!jwkStr) {\n throw new Error(\"Failed to get session key JWK\");\n }\n this.sessionKeyJwk = JSON.parse(jwkStr);\n\n // Initialize capability registry for all users (needed for tracking received delegations)\n this._capabilityRegistry = new CapabilityKeyRegistry();\n\n // Initialize KeyProvider for SharingService\n this._keyProvider = new WasmKeyProvider({\n sessionManager: this.sessionManager,\n });\n\n // Initialize notification handler\n this.notificationHandler = config.notificationHandler ?? new SilentNotificationHandler();\n\n // Initialize SharingService for receive-only access (no session required)\n // This allows session-only users to receive sharing links without signIn()\n // Full capabilities (generate) are added after signIn()\n this._sharingService = new SharingService({\n hosts: [this.config.host!],\n // session: undefined - not needed for receive()\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n keyProvider: this._keyProvider,\n registry: this._capabilityRegistry,\n // delegationManager: undefined - not needed for receive()\n createKVService: (config) => {\n // Use pathPrefix as the KV service prefix for sharing links\n // Strip trailing slash to match DelegatedAccess behavior\n const prefix = config.pathPrefix?.replace(/\\/$/, '');\n const kvService = new KVService({ prefix });\n // Create a new service context for the KV service\n const kvContext = new ServiceContext({\n invoke: config.invoke,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n hosts: config.hosts,\n });\n kvContext.setSession(config.session);\n kvService.initialize(kvContext);\n return kvService;\n },\n });\n\n // Set up wallet/auth if signer or privateKey is provided\n if (config.signer) {\n this.signer = config.signer;\n this.setupAuth(config);\n } else if (config.privateKey) {\n if (!TinyCloudNode.nodeDefaults) {\n throw new Error(\n \"privateKey requires PrivateKeySigner. Either provide a signer in config, \" +\n \"or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults.\"\n );\n }\n this.signer = TinyCloudNode.nodeDefaults.createSigner(config.privateKey, this._chainId);\n this.setupAuth(config);\n }\n }\n\n /**\n * Set up authorization handler and TinyCloud instance.\n * @internal\n */\n private setupAuth(config: TinyCloudNodeConfig): void {\n const host = this.config.host!;\n\n this.auth = new NodeUserAuthorization({\n signer: this.signer!,\n signStrategy: { type: \"auto-sign\" },\n wasmBindings: this.wasmBindings,\n sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),\n domain: this.siweDomain,\n spacePrefix: config.prefix,\n sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1000,\n tinycloudHosts: [host],\n autoCreateSpace: config.autoCreateSpace,\n enablePublicSpace: config.enablePublicSpace ?? true,\n spaceCreationHandler: config.spaceCreationHandler,\n siweConfig: config.siweConfig,\n });\n\n this.tc = new TinyCloud(this.auth);\n }\n\n /**\n * Get the primary identity DID for this user.\n * - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})\n * - If session-only mode: returns session key DID (did:key:z6Mk...)\n *\n * Use this for delegations - it always returns the appropriate identity.\n */\n get did(): string {\n // If wallet is connected and signed in, return PKH (persistent identity)\n if (this._address) {\n return `did:pkh:eip155:${this._chainId}:${this._address}`;\n }\n // Session-only mode: return session key DID (ephemeral identity)\n return this.sessionManager.getDID(this.sessionKeyId);\n }\n\n /**\n * Get the session key DID. Always available.\n * Format: did:key:z6Mk...#z6Mk...\n *\n * Use this when you specifically need the session key, not the user identity.\n */\n get sessionDid(): string {\n return this.sessionManager.getDID(this.sessionKeyId);\n }\n\n /**\n * Get the Ethereum address for this user.\n */\n get address(): string | undefined {\n return this._address;\n }\n\n /**\n * Check if this instance is in session-only mode (no wallet).\n * In session-only mode, the instance can receive delegations but cannot\n * create its own space via signIn().\n */\n get isSessionOnly(): boolean {\n return this.signer === null;\n }\n\n /**\n * Get the space ID for this user.\n * Available after signIn().\n */\n get spaceId(): string | undefined {\n return this.auth?.tinyCloudSession?.spaceId;\n }\n\n /**\n * Get the current TinyCloud session.\n * Available after signIn().\n */\n get session(): TinyCloudSession | undefined {\n return this.auth?.tinyCloudSession;\n }\n\n /**\n * Sign in and create a new session.\n * This creates the user's space if it doesn't exist.\n * Requires wallet mode (privateKey in config).\n */\n async signIn(): Promise<void> {\n if (!this.signer || !this.tc) {\n throw new Error(\n \"Cannot signIn() in session-only mode. Provide a privateKey in config to create your own space.\"\n );\n }\n\n // Ensure WASM is ready (critical for browser where WASM loads asynchronously)\n await this.wasmBindings.ensureInitialized?.();\n\n this._address = await this.signer.getAddress();\n this._chainId = await this.signer.getChainId();\n\n // Reset services so they get recreated with new session\n this._kv = undefined;\n this._sql = undefined;\n this._duckdb = undefined;\n this._serviceContext = undefined;\n\n await this.tc.signIn();\n\n // Initialize service context with session\n this.initializeServices();\n\n this.notificationHandler.success(\"Successfully signed in\");\n }\n\n /**\n * Restore a previously established session from stored delegation data.\n *\n * This is used by the CLI to restore a session that was created via the\n * browser-based delegation flow (OpenKey `/delegate` page). Instead of\n * signing in with a private key, it injects the delegation data directly.\n *\n * @param sessionData - The stored delegation data from the browser flow\n */\n async restoreSession(sessionData: {\n delegationHeader: { Authorization: string };\n delegationCid: string;\n spaceId: string;\n jwk: object;\n verificationMethod: string;\n address?: string;\n chainId?: number;\n }): Promise<void> {\n // Ensure WASM is ready (critical for browser where WASM loads asynchronously)\n await this.wasmBindings.ensureInitialized?.();\n\n // Reset services so they get recreated with new session\n this._kv = undefined;\n this._sql = undefined;\n this._duckdb = undefined;\n this._serviceContext = undefined;\n\n if (sessionData.address) {\n this._address = sessionData.address;\n }\n if (sessionData.chainId) {\n this._chainId = sessionData.chainId;\n }\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n hosts: [this.config.host!],\n });\n\n // Create and register KV service\n this._kv = new KVService({});\n this._kv.initialize(this._serviceContext);\n this._serviceContext.registerService('kv', this._kv);\n\n // Create and register SQL service\n this._sql = new SQLService({});\n this._sql.initialize(this._serviceContext);\n this._serviceContext.registerService('sql', this._sql);\n\n // Create and register DuckDB service\n this._duckdb = new DuckDbService({});\n this._duckdb.initialize(this._serviceContext);\n this._serviceContext.registerService('duckdb', this._duckdb);\n\n // Set session on context\n const serviceSession: ServiceSession = {\n delegationHeader: sessionData.delegationHeader,\n delegationCid: sessionData.delegationCid,\n spaceId: sessionData.spaceId,\n verificationMethod: sessionData.verificationMethod,\n jwk: sessionData.jwk,\n };\n this._serviceContext.setSession(serviceSession);\n\n // Create and register Vault service (matches initializeServices behavior)\n const wasm = this.wasmBindings;\n const vaultCrypto = createVaultCrypto({\n vault_encrypt: wasm.vault_encrypt, vault_decrypt: wasm.vault_decrypt, vault_derive_key: wasm.vault_derive_key,\n vault_x25519_from_seed: wasm.vault_x25519_from_seed, vault_x25519_dh: wasm.vault_x25519_dh,\n vault_random_bytes: wasm.vault_random_bytes, vault_sha256: wasm.vault_sha256,\n });\n const self = this;\n this._vault = new DataVaultService({\n spaceId: sessionData.spaceId,\n crypto: vaultCrypto,\n tc: {\n kv: this._kv!,\n ensurePublicSpace: async () => {\n try {\n await self.ensurePublicSpace();\n return { ok: true as const, data: undefined };\n } catch (error) {\n return { ok: false as const, error: { code: \"STORAGE_ERROR\", message: error instanceof Error ? error.message : String(error), service: \"vault\" } };\n }\n },\n get publicKV() { return self._publicKV ?? self.tc!.publicKV; },\n readPublicSpace: <T>(host: string, spaceId: string, key: string) =>\n TinyCloud.readPublicSpace<T>(host, spaceId, key),\n makePublicSpaceId: TinyCloud.makePublicSpaceId,\n did: this.did,\n address: sessionData.address ?? this._address ?? \"\",\n chainId: sessionData.chainId ?? this._chainId,\n hosts: [this.config.host!],\n },\n });\n this._vault.initialize(this._serviceContext);\n this._serviceContext.registerService('vault', this._vault);\n\n // Initialize v2 services\n this.initializeV2Services(serviceSession);\n }\n\n /**\n * Connect a wallet to upgrade from session-only mode to wallet mode.\n *\n * This allows a user who started in session-only mode to later connect\n * a wallet and gain the ability to create their own space.\n *\n * Note: This does NOT automatically sign in. Call signIn() after connecting\n * the wallet to create your space.\n *\n * @param privateKey - The Ethereum private key (hex string, no 0x prefix)\n * @param options - Optional configuration\n * @param options.prefix - Space name prefix (defaults to \"default\")\n *\n * @example\n * ```typescript\n * // Start in session-only mode\n * const node = new TinyCloudNode({ host: \"https://node.tinycloud.xyz\" });\n * console.log(node.did); // did:key:z6Mk... (session key)\n *\n * // Later, connect a wallet\n * node.connectWallet(privateKey);\n * await node.signIn();\n * console.log(node.did); // did:pkh:eip155:1:0x... (PKH)\n * ```\n */\n connectWallet(privateKey: string, options?: { prefix?: string; sessionStorage?: ISessionStorage }): void {\n if (this.signer) {\n throw new Error(\"Wallet already connected. Cannot connect another wallet.\");\n }\n\n const prefix = options?.prefix ?? \"default\";\n const host = this.config.host!;\n\n // Create signer from private key\n if (!TinyCloudNode.nodeDefaults) {\n throw new Error(\n \"connectWallet() requires PrivateKeySigner. Use connectSigner() instead, \" +\n \"or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults.\"\n );\n }\n this.signer = TinyCloudNode.nodeDefaults.createSigner(privateKey);\n\n // Create authorization handler\n this.auth = new NodeUserAuthorization({\n signer: this.signer,\n signStrategy: { type: \"auto-sign\" },\n wasmBindings: this.wasmBindings,\n sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),\n domain: this.siweDomain,\n spacePrefix: prefix,\n sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1000,\n tinycloudHosts: [host],\n autoCreateSpace: this.config.autoCreateSpace,\n enablePublicSpace: this.config.enablePublicSpace ?? true,\n spaceCreationHandler: this.config.spaceCreationHandler,\n });\n\n // Create TinyCloud instance\n this.tc = new TinyCloud(this.auth);\n\n // Update config with prefix\n this.config.prefix = prefix;\n }\n\n /**\n * Connect any ISigner to upgrade from session-only mode to wallet mode.\n *\n * Same as connectWallet() but accepts any ISigner implementation instead\n * of a raw private key string. Use this for browser wallets, hardware wallets,\n * or custom signing backends.\n *\n * Note: This does NOT automatically sign in. Call signIn() after connecting.\n *\n * @param signer - Any ISigner implementation\n * @param options - Optional configuration\n * @param options.prefix - Space name prefix (defaults to \"default\")\n */\n connectSigner(signer: ISigner, options?: { prefix?: string; sessionStorage?: ISessionStorage }): void {\n if (this.signer) {\n throw new Error(\"Signer already connected. Cannot connect another signer.\");\n }\n\n const prefix = options?.prefix ?? \"default\";\n const host = this.config.host!;\n\n this.signer = signer;\n\n this.auth = new NodeUserAuthorization({\n signer: this.signer,\n signStrategy: { type: \"auto-sign\" },\n wasmBindings: this.wasmBindings,\n sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),\n domain: this.siweDomain,\n spacePrefix: prefix,\n sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1000,\n tinycloudHosts: [host],\n autoCreateSpace: this.config.autoCreateSpace,\n enablePublicSpace: this.config.enablePublicSpace ?? true,\n spaceCreationHandler: this.config.spaceCreationHandler,\n });\n\n this.tc = new TinyCloud(this.auth);\n this.config.prefix = prefix;\n }\n\n /**\n * Initialize the service context and KV service after sign-in.\n * @internal\n */\n private initializeServices(): void {\n const session = this.auth?.tinyCloudSession;\n if (!session) {\n return;\n }\n\n // Initialize TinyCloud core services (needed for publicKV, ensurePublicSpace)\n this.tc!.initializeServices(this.wasmBindings.invoke, [this.config.host!]);\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n hosts: [this.config.host!],\n });\n\n // Create and register KV service\n this._kv = new KVService({});\n this._kv.initialize(this._serviceContext);\n this._serviceContext.registerService('kv', this._kv);\n\n // Create and register SQL service (if supported)\n const features = this.nodeFeatures;\n if (features.length === 0 || features.includes(\"sql\")) {\n this._sql = new SQLService({});\n this._sql.initialize(this._serviceContext);\n this._serviceContext.registerService('sql', this._sql);\n }\n\n // Create and register DuckDB service (if supported)\n if (features.length === 0 || features.includes(\"duckdb\")) {\n this._duckdb = new DuckDbService({});\n this._duckdb.initialize(this._serviceContext);\n this._serviceContext.registerService('duckdb', this._duckdb);\n }\n\n // Set session on context\n const serviceSession: ServiceSession = {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: session.spaceId,\n verificationMethod: session.verificationMethod,\n jwk: session.jwk,\n };\n this._serviceContext.setSession(serviceSession);\n (this.tc!.serviceContext as ServiceContext).setSession(serviceSession);\n\n // Create and register Vault service\n const wasm = this.wasmBindings;\n const vaultCrypto = createVaultCrypto({\n vault_encrypt: wasm.vault_encrypt, vault_decrypt: wasm.vault_decrypt, vault_derive_key: wasm.vault_derive_key,\n vault_x25519_from_seed: wasm.vault_x25519_from_seed, vault_x25519_dh: wasm.vault_x25519_dh,\n vault_random_bytes: wasm.vault_random_bytes, vault_sha256: wasm.vault_sha256,\n });\n const self = this;\n this._vault = new DataVaultService({\n spaceId: session.spaceId,\n crypto: vaultCrypto,\n tc: {\n kv: this._kv!,\n ensurePublicSpace: async () => {\n try {\n await self.ensurePublicSpace();\n return { ok: true as const, data: undefined };\n } catch (error) {\n return { ok: false as const, error: { code: \"STORAGE_ERROR\", message: error instanceof Error ? error.message : String(error), service: \"vault\" } };\n }\n },\n get publicKV() { return self._publicKV ?? self.tc!.publicKV; },\n readPublicSpace: <T>(host: string, spaceId: string, key: string) =>\n TinyCloud.readPublicSpace<T>(host, spaceId, key),\n makePublicSpaceId: TinyCloud.makePublicSpaceId,\n did: this.did,\n address: this._address!,\n chainId: this._chainId,\n hosts: [this.config.host!],\n },\n });\n this._vault.initialize(this._serviceContext);\n this._serviceContext.registerService('vault', this._vault);\n\n // Initialize v2 services\n this.initializeV2Services(serviceSession);\n }\n\n /**\n * Initialize the v2 delegation system services.\n * @internal\n */\n private initializeV2Services(serviceSession: ServiceSession): void {\n // Initialize CapabilityKeyRegistry\n this._capabilityRegistry = new CapabilityKeyRegistry();\n\n const tcSession = this.auth?.tinyCloudSession;\n // Register the session key with its capabilities\n if (tcSession && this._address) {\n const sessionKey: KeyInfo = {\n id: tcSession.sessionKey,\n did: tcSession.verificationMethod,\n type: \"session\",\n // Cast jwk from generic object to JWK - we know it has the required structure\n jwk: tcSession.jwk as JWK,\n priority: 0, // Session keys have highest priority\n };\n\n // Create root delegation for the session\n const rootDelegation: Delegation = {\n cid: tcSession.delegationCid,\n delegateDID: tcSession.verificationMethod,\n spaceId: tcSession.spaceId,\n path: \"\", // Root access\n actions: [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n \"tinycloud.sql/read\",\n \"tinycloud.sql/write\",\n \"tinycloud.sql/admin\",\n \"tinycloud.sql/*\",\n \"tinycloud.duckdb/read\",\n \"tinycloud.duckdb/write\",\n \"tinycloud.duckdb/admin\",\n \"tinycloud.duckdb/describe\",\n \"tinycloud.duckdb/export\",\n \"tinycloud.duckdb/import\",\n \"tinycloud.duckdb/*\",\n ],\n expiry: this.getSessionExpiry(),\n isRevoked: false,\n allowSubDelegation: true,\n };\n\n // Register root delegations\n const delegations = [rootDelegation];\n\n // If session includes additional spaces (e.g., public), register delegations for those too\n if (tcSession.spaces) {\n for (const [spaceName, spaceId] of Object.entries(tcSession.spaces)) {\n delegations.push({\n cid: tcSession.delegationCid,\n delegateDID: tcSession.verificationMethod,\n spaceId,\n path: \"\",\n actions: [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n \"tinycloud.sql/read\",\n \"tinycloud.sql/write\",\n \"tinycloud.sql/admin\",\n \"tinycloud.sql/*\",\n \"tinycloud.duckdb/read\",\n \"tinycloud.duckdb/write\",\n \"tinycloud.duckdb/admin\",\n \"tinycloud.duckdb/describe\",\n \"tinycloud.duckdb/export\",\n \"tinycloud.duckdb/import\",\n \"tinycloud.duckdb/*\",\n ],\n expiry: this.getSessionExpiry(),\n isRevoked: false,\n allowSubDelegation: true,\n });\n }\n }\n\n this._capabilityRegistry.registerKey(sessionKey, delegations);\n }\n\n // Initialize DelegationManager\n this._delegationManager = new DelegationManager({\n hosts: [this.config.host!],\n session: serviceSession,\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n });\n\n // Initialize SpaceService\n this._spaceService = new SpaceService({\n hosts: [this.config.host!],\n session: serviceSession,\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n capabilityRegistry: this._capabilityRegistry,\n userDid: this.did,\n createKVService: (spaceId: string) => {\n // Create a new KV service scoped to the specified space\n const kvService = new KVService({});\n if (this._serviceContext) {\n const spaceScopedContext = new ServiceContext({\n invoke: this._serviceContext.invoke,\n fetch: this._serviceContext.fetch,\n hosts: this._serviceContext.hosts,\n });\n const session = this._serviceContext.session;\n if (session) {\n spaceScopedContext.setSession({ ...session, spaceId });\n }\n kvService.initialize(spaceScopedContext);\n }\n return kvService;\n },\n // Enable space.delegations.create() via SIWE-based delegation\n createDelegation: async (params) => {\n try {\n // Use the existing createDelegation method which calls /delegate with SIWE\n const portableDelegation = await this.createDelegation({\n delegateDID: params.delegateDID,\n path: params.path,\n actions: params.actions,\n disableSubDelegation: params.disableSubDelegation,\n expiryMs: params.expiry\n ? params.expiry.getTime() - Date.now()\n : undefined,\n });\n\n // Convert PortableDelegation to Delegation type for Space API\n const delegation: Delegation = {\n cid: portableDelegation.cid,\n delegateDID: portableDelegation.delegateDID,\n delegatorDID: this.did,\n spaceId: portableDelegation.spaceId,\n path: portableDelegation.path,\n actions: portableDelegation.actions,\n expiry: portableDelegation.expiry,\n isRevoked: false,\n allowSubDelegation: !portableDelegation.disableSubDelegation,\n createdAt: new Date(),\n authHeader: portableDelegation.delegationHeader.Authorization,\n };\n\n return { ok: true, data: delegation };\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"CREATION_FAILED\",\n message: error instanceof Error ? error.message : String(error),\n service: \"delegation\",\n },\n };\n }\n },\n });\n\n // Update SharingService with full capabilities (session + createDelegation)\n // SharingService was initialized in constructor for receive-only access\n this._sharingService.updateConfig({\n session: serviceSession,\n delegationManager: this._delegationManager,\n sessionExpiry: this.getSessionExpiry(),\n // WASM-based delegation creation (preferred - no server roundtrip)\n createDelegationWasm: (params) => this.createDelegationWrapper(params),\n // Root delegation for long-lived share links (bypasses session expiry)\n // In node-sdk we have direct signer access, so no popup needed\n onRootDelegationNeeded: this.signer\n ? async (params) => this.createRootDelegationForSharing(params)\n : undefined,\n });\n\n // Wire up SharingService to SpaceService for space.sharing.generate()\n this._spaceService.updateConfig({\n sharingService: this._sharingService,\n });\n }\n\n /**\n * Get the session expiry time.\n * @internal\n */\n private getSessionExpiry(): Date {\n // Default to 1 hour from now if not explicitly set\n const expirationMs = this.config.sessionExpirationMs ?? 60 * 60 * 1000;\n return new Date(Date.now() + expirationMs);\n }\n\n /**\n * Wrapper for the WASM createDelegation function.\n * Adapts the WASM interface to what SharingService expects.\n * @internal\n */\n private createDelegationWrapper(params: CreateDelegationWasmParams): CreateDelegationWasmResult {\n // Convert ServiceSession to the format WASM expects\n const wasmSession = {\n delegationHeader: params.session.delegationHeader,\n delegationCid: params.session.delegationCid,\n jwk: params.session.jwk,\n spaceId: params.session.spaceId,\n verificationMethod: params.session.verificationMethod,\n };\n\n const result = this.wasmBindings.createDelegation(\n wasmSession,\n params.delegateDID,\n params.spaceId,\n params.path,\n params.actions,\n params.expirationSecs,\n params.notBeforeSecs\n );\n\n return {\n delegation: result.delegation,\n cid: result.cid,\n delegateDID: result.delegateDid,\n path: result.path,\n actions: result.actions,\n expiry: new Date(result.expiry * 1000),\n };\n }\n\n /**\n * Create a direct root delegation from the wallet to a share key.\n * This bypasses the session delegation chain, allowing share links\n * with expiry longer than the current session.\n * @internal\n */\n private async createRootDelegationForSharing(params: {\n shareKeyDID: string;\n spaceId: string;\n path: string;\n actions: string[];\n requestedExpiry: Date;\n }): Promise<Delegation | undefined> {\n if (!this.signer) {\n return undefined;\n }\n\n const session = this.auth?.tinyCloudSession;\n if (!session) {\n return undefined;\n }\n\n try {\n const host = this.config.host!;\n const now = new Date();\n\n // Build abilities for the share key\n const abilities: Record<string, Record<string, string[]>> = {\n kv: {\n [params.path]: params.actions,\n },\n };\n\n // Prepare a direct delegation to the share key (no parents = root delegation)\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(session.address),\n chainId: session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: params.requestedExpiry.toISOString(),\n spaceId: params.spaceId,\n delegateUri: params.shareKeyDID,\n });\n\n // Sign with the signer (no popup in node-sdk)\n const signature = await this.signer.signMessage(prepared.siwe);\n\n const delegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate the delegation with the server\n const activateResult = await activateSessionWithHost(\n host,\n delegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n return undefined;\n }\n\n return {\n cid: delegationSession.delegationCid,\n delegateDID: params.shareKeyDID,\n delegatorDID: `did:pkh:eip155:${session.chainId}:${session.address}`,\n spaceId: params.spaceId,\n path: params.path,\n actions: params.actions,\n expiry: params.requestedExpiry,\n isRevoked: false,\n allowSubDelegation: true,\n createdAt: now,\n authHeader: delegationSession.delegationHeader.Authorization,\n };\n } catch {\n return undefined;\n }\n }\n\n /**\n * Track a received delegation in the capability registry.\n * @internal\n */\n private trackReceivedDelegation(delegation: PortableDelegation, jwk: JWK): void {\n if (!this._capabilityRegistry) {\n return;\n }\n\n const keyInfo: KeyInfo = {\n id: `received:${delegation.cid}`,\n did: this.sessionDid,\n type: \"ingested\",\n jwk,\n priority: 2,\n };\n\n // Convert PortableDelegation to Delegation type\n const delegationRecord: Delegation = {\n cid: delegation.cid,\n delegateDID: delegation.delegateDID,\n spaceId: delegation.spaceId,\n path: delegation.path,\n actions: delegation.actions,\n expiry: delegation.expiry,\n isRevoked: false,\n allowSubDelegation: !delegation.disableSubDelegation,\n };\n\n this._capabilityRegistry.ingestKey(keyInfo, delegationRecord);\n }\n\n /**\n * Key-value storage operations on this user's space.\n */\n get kv(): IKVService {\n if (!this._kv) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._kv;\n }\n\n /**\n * SQL database operations on this user's space.\n */\n get sql(): ISQLService {\n if (!this._sql) {\n const features = this.nodeFeatures;\n if (features.length > 0 && !features.includes(\"sql\")) {\n throw new UnsupportedFeatureError(\"sql\", this.config.host!, features);\n }\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._sql;\n }\n\n /**\n * DuckDB database operations on this user's space.\n */\n get duckdb(): IDuckDbService {\n if (!this._duckdb) {\n const features = this.nodeFeatures;\n if (features.length > 0 && !features.includes(\"duckdb\")) {\n throw new UnsupportedFeatureError(\"duckdb\", this.config.host!, features);\n }\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._duckdb;\n }\n\n /**\n * Data Vault operations - client-side encrypted KV storage.\n * Call `vault.unlock(signer)` after signIn() to derive encryption keys.\n */\n get vault(): IDataVaultService {\n if (!this._vault) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._vault;\n }\n\n // ===========================================================================\n // v2 Service Accessors\n // ===========================================================================\n\n /**\n * Get the CapabilityKeyRegistry for managing keys and their capabilities.\n *\n * The registry tracks keys (session, main, ingested) and their associated\n * delegations, enabling automatic key selection for operations.\n *\n * @example\n * ```typescript\n * const registry = alice.capabilityRegistry;\n *\n * // Get the best key for an operation\n * const key = registry.getKeyForCapability(\n * \"tinycloud://my-space/kv/data\",\n * \"tinycloud.kv/get\"\n * );\n *\n * // List all capabilities\n * const capabilities = registry.getAllCapabilities();\n * ```\n */\n get capabilityRegistry(): ICapabilityKeyRegistry {\n if (!this._capabilityRegistry) {\n throw new Error(\"CapabilityKeyRegistry not initialized.\");\n }\n return this._capabilityRegistry;\n }\n\n /**\n * Access received delegations (recipient view).\n *\n * Use this to see what delegations have been received via useDelegation().\n *\n * @example\n * ```typescript\n * // List all received delegations\n * const received = bob.delegations.list();\n * console.log(\"I have access to:\", received.length, \"spaces\");\n *\n * // Get a specific delegation by CID\n * const delegation = bob.delegations.get(cid);\n * ```\n */\n get delegations(): {\n /** List all received delegations */\n list: () => Delegation[];\n /** Get a delegation by CID */\n get: (cid: string) => Delegation | undefined;\n } {\n const registry = this._capabilityRegistry;\n if (!registry) {\n return {\n list: () => [],\n get: () => undefined,\n };\n }\n\n return {\n list: () => registry.getAllCapabilities().map((entry) => entry.delegation),\n get: (cid: string) => {\n const capabilities = registry.getAllCapabilities();\n const entry = capabilities.find((e) => e.delegation.cid === cid);\n return entry?.delegation;\n },\n };\n }\n\n /**\n * Get the DelegationManager for delegation CRUD operations.\n *\n * This is the v2 delegation service providing a cleaner API than\n * the legacy createDelegation/useDelegation methods.\n *\n * @example\n * ```typescript\n * const delegations = alice.delegationManager;\n *\n * // Create a delegation\n * const result = await delegations.create({\n * delegateDID: bob.did,\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours\n * });\n *\n * // List delegations\n * const listResult = await delegations.list();\n *\n * // Revoke a delegation\n * await delegations.revoke(delegationCid);\n * ```\n */\n get delegationManager(): DelegationManager {\n if (!this._delegationManager) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._delegationManager;\n }\n\n /**\n * Get the SpaceService for managing spaces.\n *\n * The SpaceService provides access to owned and delegated spaces,\n * including space creation, listing, and scoped operations.\n *\n * @example\n * ```typescript\n * const spaces = alice.spaces;\n *\n * // List all accessible spaces\n * const result = await spaces.list();\n *\n * // Create a new space\n * const createResult = await spaces.create('photos');\n *\n * // Get a space object for operations\n * const mySpace = spaces.get('default');\n * await mySpace.kv.put('key', 'value');\n *\n * // Check if a space exists\n * const exists = await spaces.exists('photos');\n * ```\n */\n get spaces(): ISpaceService {\n if (!this._spaceService) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._spaceService;\n }\n\n /**\n * Alias for `spaces` - get the SpaceService.\n * @see spaces\n */\n get spaceService(): ISpaceService {\n return this.spaces;\n }\n\n /**\n * Get the SharingService for creating and receiving v2 sharing links.\n *\n * The SharingService creates sharing links with embedded private keys,\n * allowing recipients to exercise delegations without prior session setup.\n *\n * @example\n * ```typescript\n * const sharing = alice.sharing;\n *\n * // Generate a sharing link\n * const result = await sharing.generate({\n * path: \"/kv/documents/report.pdf\",\n * actions: [\"tinycloud.kv/get\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000),\n * });\n *\n * if (result.ok) {\n * console.log(\"Share URL:\", result.data.url);\n * // Send the URL to the recipient\n * }\n *\n * // Receive a sharing link\n * const receiveResult = await sharing.receive(shareUrl);\n * if (receiveResult.ok) {\n * // Use the pre-configured KV service\n * const data = await receiveResult.data.kv.get(\"report.pdf\");\n * }\n * ```\n */\n get sharing(): ISharingService {\n // SharingService is initialized in constructor for receive-only access\n // Full capabilities (generate) are added after signIn()\n return this._sharingService;\n }\n\n /**\n * Alias for `sharing` - get the SharingService.\n * @see sharing\n */\n get sharingService(): ISharingService {\n return this.sharing;\n }\n\n // ===========================================================================\n // Public Space Methods\n // ===========================================================================\n\n /**\n * Ensure the user's public space exists and is accessible.\n * Creates the space and activates a session delegation for it.\n * This is the trigger for lazy public space creation — call it\n * before writing to spaces.get('public').kv.\n */\n async ensurePublicSpace() {\n if (!this.auth || !this.session || !this.signer) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n const publicSpaceId = this.session.spaces?.public;\n if (!publicSpaceId) {\n throw new Error(\"Public space not enabled. Set enablePublicSpace: true in config.\");\n }\n\n // Create the public space on the server (host SIWE)\n await (this.auth as NodeUserAuthorization).hostPublicSpace(publicSpaceId);\n\n // Create a session delegation for the public space using the session key JWK.\n // This mirrors the primary session flow (prepareSession with jwk), ensuring\n // the delegation targets the session key — not the PKH DID — so that\n // invoke() requests signed by the session key are properly authorized.\n const kvActions = [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n ];\n const abilities = { kv: { \"\": kvActions } };\n const now = new Date();\n const expiryMs = 60 * 60 * 1000;\n const expirationTime = new Date(now.getTime() + expiryMs);\n\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(this.session.address),\n chainId: this.session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: publicSpaceId,\n jwk: this.session.jwk,\n parents: [this.session.delegationCid],\n });\n\n const signature = await this.signer.signMessage(prepared.siwe);\n\n const delegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n const activateResult = await activateSessionWithHost(\n this.config.host!,\n delegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate public space delegation: ${activateResult.error}`);\n }\n\n // Register the delegation in the capability registry so\n // spaces.get('public').kv operations are authorized\n if (this._capabilityRegistry && this.session) {\n const sessionKey: KeyInfo = {\n id: this.session.sessionKey,\n did: this.session.verificationMethod,\n type: \"session\",\n jwk: this.session.jwk as JWK,\n priority: 0,\n };\n this._capabilityRegistry.registerKey(sessionKey, [{\n cid: delegationSession.delegationCid,\n delegateDID: this.session.verificationMethod,\n spaceId: publicSpaceId,\n path: \"\",\n actions: kvActions,\n expiry: expirationTime,\n isRevoked: false,\n allowSubDelegation: true,\n }]);\n }\n\n // Cache a properly authorized public KV service using the new delegation\n if (this._serviceContext) {\n const publicKV = new KVService({ prefix: \"\" });\n const publicContext = new ServiceContext({\n invoke: this.wasmBindings.invoke,\n fetch: this._serviceContext.fetch,\n hosts: this._serviceContext.hosts,\n });\n publicContext.setSession({\n delegationHeader: delegationSession.delegationHeader,\n delegationCid: delegationSession.delegationCid,\n spaceId: publicSpaceId,\n verificationMethod: this.session.verificationMethod,\n jwk: this.session.jwk,\n });\n publicKV.initialize(publicContext);\n this._publicKV = publicKV;\n }\n }\n\n /**\n * Get a KVService scoped to the user's own public space.\n * Writes require authentication (owner/delegate).\n */\n get publicKV(): IKVService {\n if (this._publicKV) {\n return this._publicKV;\n }\n if (!this.tc) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this.tc.publicKV;\n }\n\n // ===========================================================================\n // v2 Delegation Convenience Methods\n // ===========================================================================\n\n /**\n * Create a delegation using the v2 DelegationManager.\n *\n * This is a convenience method that wraps DelegationManager.create().\n * For more control, use `this.delegationManager` directly.\n *\n * @param params - Delegation parameters\n * @returns Result containing the created Delegation\n *\n * @example\n * ```typescript\n * const result = await alice.delegate({\n * delegateDID: bob.did,\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000),\n * });\n *\n * if (result.ok) {\n * console.log(\"Delegation created:\", result.data.cid);\n * }\n * ```\n */\n async delegate(params: CreateDelegationParams): Promise<DelegationResult<Delegation>> {\n return this.delegationManager.create(params);\n }\n\n /**\n * Revoke a delegation using the v2 DelegationManager.\n *\n * @param cid - The CID of the delegation to revoke\n * @returns Result indicating success or failure\n */\n async revokeDelegation(cid: string): Promise<DelegationResult<void>> {\n return this.delegationManager.revoke(cid);\n }\n\n /**\n * List all delegations for the current session's space.\n *\n * @returns Result containing an array of Delegations\n */\n async listDelegations(): Promise<DelegationResult<Delegation[]>> {\n return this.delegationManager.list();\n }\n\n /**\n * Check if the current session has permission for a path and action.\n *\n * @param path - The resource path to check\n * @param action - The action to check (e.g., \"tinycloud.kv/get\")\n * @returns Result containing boolean permission status\n */\n async checkPermission(path: string, action: string): Promise<DelegationResult<boolean>> {\n return this.delegationManager.checkPermission(path, action);\n }\n\n /**\n * Create a delegation from this user to another user.\n *\n * The delegation grants the recipient access to a specific path and actions\n * within this user's space.\n *\n * @param params - Delegation parameters\n * @returns A portable delegation that can be sent to the recipient\n */\n async createDelegation(params: {\n /** Path within the space to delegate access to */\n path: string;\n /** Actions to allow (e.g., [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]) */\n actions: string[];\n /** DID of the recipient (from their TinyCloudNode.did) */\n delegateDID: string;\n /** Whether to prevent the recipient from creating sub-delegations (default: false) */\n disableSubDelegation?: boolean;\n /** Expiration time in milliseconds from now (default: 1 hour) */\n expiryMs?: number;\n /** Override space ID (for creating delegations to non-primary spaces like public) */\n spaceIdOverride?: string;\n /** Include a companion delegation for the user's public space (default: true) */\n includePublicSpace?: boolean;\n }): Promise<PortableDelegation> {\n if (!this.signer) {\n throw new Error(\"Cannot createDelegation() in session-only mode. Requires wallet mode.\");\n }\n const session = this.auth?.tinyCloudSession;\n if (!session) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n // Resolve ENS names to PKH DIDs\n if (params.delegateDID.endsWith('.eth') && this.config.ensResolver) {\n const address = await this.config.ensResolver.resolveAddress(params.delegateDID);\n if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);\n params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };\n }\n\n // Build abilities for the delegation\n const abilities: Record<string, Record<string, string[]>> = {};\n const kvActions = params.actions.filter(a => a.startsWith(\"tinycloud.kv/\"));\n const sqlActions = params.actions.filter(a => a.startsWith(\"tinycloud.sql/\"));\n const duckdbActions = params.actions.filter(a => a.startsWith(\"tinycloud.duckdb/\"));\n if (kvActions.length > 0) {\n abilities.kv = { [params.path]: kvActions };\n }\n if (sqlActions.length > 0) {\n abilities.sql = { [params.path]: sqlActions };\n }\n if (duckdbActions.length > 0) {\n abilities.duckdb = { [params.path]: duckdbActions };\n }\n\n const now = new Date();\n const expiryMs = params.expiryMs ?? 60 * 60 * 1000; // Default 1 hour\n const expirationTime = new Date(now.getTime() + expiryMs);\n\n // Prepare the delegation session with:\n // - delegateUri: target the recipient's DID directly (for user-to-user delegation)\n // - parents: reference our session CID for chain validation\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(session.address),\n chainId: session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: params.spaceIdOverride ?? session.spaceId,\n delegateUri: params.delegateDID,\n parents: [session.delegationCid],\n });\n\n // Sign the SIWE message with this user's signer\n const signature = await this.signer.signMessage(prepared.siwe);\n\n // Complete the session setup\n const delegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate the delegation with the server\n const activateResult = await activateSessionWithHost(\n this.config.host!,\n delegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate delegation: ${activateResult.error}`);\n }\n\n const result: PortableDelegation = {\n cid: delegationSession.delegationCid,\n delegationHeader: delegationSession.delegationHeader,\n spaceId: params.spaceIdOverride ?? session.spaceId,\n path: params.path,\n actions: params.actions,\n disableSubDelegation: params.disableSubDelegation ?? false,\n expiry: expirationTime,\n delegateDID: params.delegateDID,\n ownerAddress: session.address,\n chainId: session.chainId,\n host: this.config.host,\n };\n\n // Auto-create public-space delegation for vault key publishing\n const hasKvActions = params.actions.some(a => a.startsWith(\"tinycloud.kv/\"));\n if (hasKvActions && params.includePublicSpace !== false) {\n const publicSpaceId = makePublicSpaceId(\n this.wasmBindings.ensureEip55(session.address), session.chainId\n );\n const publicAbilities: Record<string, Record<string, string[]>> = {\n kv: { \"\": [\"tinycloud.kv/get\", \"tinycloud.kv/put\", \"tinycloud.kv/metadata\"] },\n };\n const publicPrepared = this.wasmBindings.prepareSession({\n abilities: publicAbilities,\n address: this.wasmBindings.ensureEip55(session.address),\n chainId: session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: publicSpaceId,\n delegateUri: params.delegateDID,\n parents: [session.delegationCid],\n });\n const publicSignature = await this.signer.signMessage(publicPrepared.siwe);\n const publicSession = this.wasmBindings.completeSessionSetup({\n ...publicPrepared,\n signature: publicSignature,\n });\n\n const publicActivateResult = await activateSessionWithHost(\n this.config.host!,\n publicSession.delegationHeader\n );\n\n if (publicActivateResult.success) {\n result.publicDelegation = {\n cid: publicSession.delegationCid,\n delegationHeader: publicSession.delegationHeader,\n spaceId: publicSpaceId,\n path: \"\",\n actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\", \"tinycloud.kv/metadata\"],\n disableSubDelegation: params.disableSubDelegation ?? false,\n expiry: expirationTime,\n delegateDID: params.delegateDID,\n ownerAddress: session.address,\n chainId: session.chainId,\n host: this.config.host,\n };\n }\n }\n\n return result;\n }\n\n /**\n * Use a delegation received from another user.\n *\n * This creates a new session key for this user that chains from the\n * received delegation, allowing operations on the delegator's space.\n *\n * Works in both modes:\n * - **Wallet mode**: Creates a SIWE sub-delegation from PKH to session key\n * - **Session-only mode**: Uses the delegation directly (must target session key DID)\n *\n * @param delegation - The PortableDelegation to use (from createDelegation or transport)\n * @returns A DelegatedAccess instance for performing operations\n */\n async useDelegation(delegation: PortableDelegation): Promise<DelegatedAccess> {\n const delegationHeader = delegation.delegationHeader;\n\n // Use the host from the delegation if provided, otherwise fall back to config\n const targetHost = delegation.host ?? this.config.host!;\n\n // Session-only mode: use the delegation directly\n // The delegation must target this user's session key DID\n if (this.isSessionOnly) {\n // Verify the delegation targets our session key DID\n const myDid = this.did; // In session-only mode, this is the session key DID\n if (delegation.delegateDID !== myDid) {\n throw new Error(\n `Delegation targets ${delegation.delegateDID} but this user's DID is ${myDid}. ` +\n `The delegation must target this user's DID.`\n );\n }\n\n // Create a session using the delegation directly\n // In session-only mode, we use the received delegation as-is\n const session: TinyCloudSession = {\n address: delegation.ownerAddress,\n chainId: delegation.chainId,\n sessionKey: JSON.stringify(this.sessionKeyJwk),\n spaceId: delegation.spaceId,\n delegationCid: delegation.cid,\n delegationHeader,\n verificationMethod: this.sessionDid,\n jwk: this.sessionKeyJwk as unknown as JWK,\n siwe: \"\", // Not used in session-only mode\n signature: \"\", // Not used in session-only mode\n };\n\n // Track received delegation in registry\n this.trackReceivedDelegation(delegation, this.sessionKeyJwk as unknown as JWK);\n\n return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);\n }\n\n // Wallet mode: create a SIWE sub-delegation\n const mySession = this.auth?.tinyCloudSession;\n if (!mySession) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n // Use our existing session key - the delegation targets our DID from signIn\n // We must use the same key that the delegation was created for\n const jwk = mySession.jwk;\n\n // Build abilities from the delegation\n const abilities: Record<string, Record<string, string[]>> = {};\n const kvActions = delegation.actions.filter(a => a.startsWith(\"tinycloud.kv/\"));\n const sqlActions = delegation.actions.filter(a => a.startsWith(\"tinycloud.sql/\"));\n const duckdbActions = delegation.actions.filter(a => a.startsWith(\"tinycloud.duckdb/\"));\n if (kvActions.length > 0) {\n abilities.kv = { [delegation.path]: kvActions };\n }\n if (sqlActions.length > 0) {\n abilities.sql = { [delegation.path]: sqlActions };\n }\n if (duckdbActions.length > 0) {\n abilities.duckdb = { [delegation.path]: duckdbActions };\n }\n\n const now = new Date();\n // Use delegation expiry or 1 hour, whichever is sooner\n const maxExpiry = new Date(now.getTime() + 60 * 60 * 1000);\n const expirationTime = delegation.expiry < maxExpiry ? delegation.expiry : maxExpiry;\n\n // Prepare the session with:\n // - THIS user's address (we are the invoker)\n // - The delegation owner's space (where we're accessing data)\n // - Our existing session key (must match the DID the delegation targets)\n // - Parent reference to the received delegation\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(mySession.address),\n chainId: mySession.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: delegation.spaceId,\n jwk,\n parents: [delegation.cid],\n });\n\n // Sign with THIS user's signer\n const signature = await this.signer!.signMessage(prepared.siwe);\n\n // Complete the session setup\n const invokerSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate with server\n const activateResult = await activateSessionWithHost(\n targetHost,\n invokerSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate delegated session: ${activateResult.error}`);\n }\n\n // Create TinyCloudSession for the delegated access\n const session: TinyCloudSession = {\n address: mySession.address,\n chainId: mySession.chainId,\n sessionKey: mySession.sessionKey,\n spaceId: delegation.spaceId,\n delegationCid: invokerSession.delegationCid,\n delegationHeader: invokerSession.delegationHeader,\n verificationMethod: mySession.verificationMethod,\n jwk,\n siwe: prepared.siwe,\n signature,\n };\n\n // Track received delegation in registry\n this.trackReceivedDelegation(delegation, jwk as unknown as JWK);\n\n return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);\n }\n\n /**\n * Create a sub-delegation from a received delegation.\n *\n * This allows further delegating access that was received from another user,\n * if the original delegation allows sub-delegation.\n *\n * @param parentDelegation - The delegation received from another user\n * @param params - Sub-delegation parameters (must be within parent's scope)\n * @returns A portable delegation for the sub-delegate\n */\n async createSubDelegation(\n parentDelegation: PortableDelegation,\n params: {\n /** Path within the delegated path to sub-delegate */\n path: string;\n /** Actions to allow (must be subset of parent's actions) */\n actions: string[];\n /** DID of the recipient */\n delegateDID: string;\n /** Whether to prevent the recipient from creating further sub-delegations */\n disableSubDelegation?: boolean;\n /** Expiration time in milliseconds from now (must be before parent's expiry) */\n expiryMs?: number;\n }\n ): Promise<PortableDelegation> {\n if (!this.signer) {\n throw new Error(\"Cannot createSubDelegation() in session-only mode. Requires wallet mode.\");\n }\n if (!this._address) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n // Validate sub-delegation is allowed\n if (parentDelegation.disableSubDelegation) {\n throw new Error(\"Parent delegation does not allow sub-delegation\");\n }\n\n // Validate path is within parent's path\n if (!params.path.startsWith(parentDelegation.path)) {\n throw new Error(\n `Sub-delegation path \"${params.path}\" must be within parent path \"${parentDelegation.path}\"`\n );\n }\n\n // Validate actions are subset of parent's actions\n const parentActions = new Set(parentDelegation.actions);\n for (const action of params.actions) {\n if (!parentActions.has(action)) {\n throw new Error(\n `Sub-delegation action \"${action}\" is not in parent's actions: ${parentDelegation.actions.join(\", \")}`\n );\n }\n }\n\n // Calculate expiry - cap at parent's expiry\n const now = new Date();\n const expiryMs = params.expiryMs ?? 60 * 60 * 1000;\n const requestedExpiry = new Date(now.getTime() + expiryMs);\n // Sub-delegation cannot outlive parent, so cap at parent's expiry\n const actualExpiry =\n requestedExpiry > parentDelegation.expiry ? parentDelegation.expiry : requestedExpiry;\n\n // Build abilities for the sub-delegation\n const abilities: Record<string, Record<string, string[]>> = {};\n const kvActions = params.actions.filter(a => a.startsWith(\"tinycloud.kv/\"));\n const sqlActions = params.actions.filter(a => a.startsWith(\"tinycloud.sql/\"));\n const duckdbActions = params.actions.filter(a => a.startsWith(\"tinycloud.duckdb/\"));\n if (kvActions.length > 0) {\n abilities.kv = { [params.path]: kvActions };\n }\n if (sqlActions.length > 0) {\n abilities.sql = { [params.path]: sqlActions };\n }\n if (duckdbActions.length > 0) {\n abilities.duckdb = { [params.path]: duckdbActions };\n }\n\n // Use parent's host or fall back to config\n const targetHost = parentDelegation.host ?? this.config.host!;\n\n // Prepare the sub-delegation session\n // Uses THIS user's address (who received the delegation and is now sub-delegating)\n // Targets the recipient's PKH DID (delegateUri)\n // References the parent delegation as the chain\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(this._address),\n chainId: this._chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: actualExpiry.toISOString(),\n spaceId: parentDelegation.spaceId,\n delegateUri: params.delegateDID,\n parents: [parentDelegation.cid],\n });\n\n // Sign with THIS user's signer\n const signature = await this.signer.signMessage(prepared.siwe);\n\n // Complete the session setup\n const subDelegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate the sub-delegation with the server\n const activateResult = await activateSessionWithHost(\n targetHost,\n subDelegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate sub-delegation: ${activateResult.error}`);\n }\n\n // Return the portable sub-delegation\n return {\n cid: subDelegationSession.delegationCid,\n delegationHeader: subDelegationSession.delegationHeader,\n spaceId: parentDelegation.spaceId,\n path: params.path,\n actions: params.actions,\n disableSubDelegation: params.disableSubDelegation ?? false,\n expiry: actualExpiry,\n delegateDID: params.delegateDID,\n ownerAddress: parentDelegation.ownerAddress!,\n chainId: parentDelegation.chainId!,\n host: targetHost,\n };\n }\n}\n","import {\n TinyCloudSession,\n KVService,\n IKVService,\n SQLService,\n ISQLService,\n DuckDbService,\n IDuckDbService,\n ServiceSession,\n ServiceContext,\n} from \"@tinycloud/sdk-core\";\nimport type { InvokeFunction } from \"@tinycloud/sdk-services\";\nimport { PortableDelegation } from \"./delegation\";\n\n/**\n * Provides access to a space via a received delegation.\n *\n * This is returned by TinyCloudNode.useDelegation() and provides\n * KV operations on the delegated space.\n */\nexport class DelegatedAccess {\n private session: TinyCloudSession;\n private _delegation: PortableDelegation;\n private host: string;\n private _serviceContext: ServiceContext;\n private _kv: KVService;\n private _sql: SQLService;\n private _duckdb: DuckDbService;\n\n constructor(\n session: TinyCloudSession,\n delegation: PortableDelegation,\n host: string,\n invoke: InvokeFunction,\n ) {\n this.session = session;\n this._delegation = delegation;\n this.host = host;\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke,\n fetch: globalThis.fetch.bind(globalThis),\n hosts: [host],\n });\n\n // Create and initialize KV service with path prefix from delegation\n // Strip trailing slash to avoid double-slash in paths\n const prefix = this._delegation.path.replace(/\\/$/, '');\n this._kv = new KVService({ prefix });\n this._kv.initialize(this._serviceContext);\n this._serviceContext.registerService('kv', this._kv);\n\n // Create and initialize SQL service with same delegation context\n this._sql = new SQLService({});\n this._sql.initialize(this._serviceContext);\n this._serviceContext.registerService('sql', this._sql);\n\n // Create and initialize DuckDB service with same delegation context\n this._duckdb = new DuckDbService({});\n this._duckdb.initialize(this._serviceContext);\n this._serviceContext.registerService('duckdb', this._duckdb);\n\n // Set session on context\n const serviceSession: ServiceSession = {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: session.spaceId,\n verificationMethod: session.verificationMethod,\n jwk: session.jwk,\n };\n this._serviceContext.setSession(serviceSession);\n }\n\n /**\n * Get the delegation this access was created from.\n */\n get delegation(): PortableDelegation {\n return this._delegation;\n }\n\n /**\n * The space ID this access is for.\n */\n get spaceId(): string {\n return this._delegation.spaceId;\n }\n\n /**\n * The path this access is scoped to.\n */\n get path(): string {\n return this._delegation.path;\n }\n\n /**\n * KV operations on the delegated space.\n */\n get kv(): IKVService {\n return this._kv;\n }\n\n /**\n * SQL operations on the delegated space.\n */\n get sql(): ISQLService {\n return this._sql;\n }\n\n /**\n * DuckDB operations on the delegated space.\n */\n get duckdb(): IDuckDbService {\n return this._duckdb;\n }\n}\n","/**\n * WasmKeyProvider - KeyProvider implementation using WASM session manager.\n *\n * This provider wraps the SessionManager from node-sdk-wasm to provide\n * cryptographic key operations required by the SharingService.\n *\n * @packageDocumentation\n */\n\nimport type { KeyProvider, JWK, ISessionManager } from \"@tinycloud/sdk-core\";\n\n/**\n * Extended session manager with optional key listing support.\n * The base ISessionManager doesn't include listSessionKeys(),\n * but concrete implementations (e.g., TCWSessionManager) may provide it.\n */\ninterface SessionManagerWithListing extends ISessionManager {\n listSessionKeys?(): string[];\n}\n\n/**\n * Configuration for WasmKeyProvider.\n */\nexport interface WasmKeyProviderConfig {\n /**\n * The WASM session manager instance.\n * Must be created before constructing the KeyProvider.\n */\n sessionManager: SessionManagerWithListing;\n}\n\n/**\n * KeyProvider implementation that wraps the WASM session manager.\n *\n * This allows the SharingService to create new session keys for sharing links\n * using the same cryptographic operations as the main session management.\n *\n * @example\n * ```typescript\n * // sessionManager from wasmBindings.createSessionManager()\n * import { WasmKeyProvider } from \"@tinycloud/node-sdk\";\n *\n * const sessionManager = new SessionManager();\n * const keyProvider = new WasmKeyProvider({ sessionManager });\n *\n * // Create a session key for a sharing link\n * const keyId = await keyProvider.createSessionKey(\"share:abc123\");\n * const jwk = keyProvider.getJWK(keyId);\n * const did = await keyProvider.getDID(keyId);\n * ```\n */\nexport class WasmKeyProvider implements KeyProvider {\n private sessionManager: SessionManagerWithListing;\n\n /**\n * Create a new WasmKeyProvider.\n *\n * @param config - Configuration with the WASM session manager\n */\n constructor(config: WasmKeyProviderConfig) {\n this.sessionManager = config.sessionManager;\n }\n\n /**\n * Generate a new session key with the given name.\n *\n * This creates a new Ed25519 key pair in the WASM session manager.\n * The key can then be used for signing delegations in sharing links.\n *\n * @param name - A unique name/ID for the key (e.g., \"share:timestamp:random\")\n * @returns The key ID (same as the name provided)\n */\n async createSessionKey(name: string): Promise<string> {\n // The WASM session manager's createSessionKey returns the key_id\n // and stores the key internally\n return this.sessionManager.createSessionKey(name);\n }\n\n /**\n * Get the JWK (JSON Web Key) for a key.\n *\n * Returns the full JWK including the private key (d parameter),\n * which is required for signing and for embedding in sharing links.\n *\n * @param keyId - The key ID to retrieve\n * @returns The JWK object with public and private key components\n * @throws Error if the key is not found\n */\n getJWK(keyId: string): JWK {\n // The WASM session manager returns the JWK as a JSON string\n const jwkJson = this.sessionManager.jwk(keyId);\n if (!jwkJson) {\n throw new Error(`Key not found: ${keyId}`);\n }\n // Parse the JSON string to get the JWK object\n return JSON.parse(jwkJson) as JWK;\n }\n\n /**\n * Get the DID (Decentralized Identifier) for a key.\n *\n * Returns the did:key format DID derived from the key's public key.\n * This DID can be used as the delegatee in delegations.\n *\n * @param keyId - The key ID to retrieve\n * @returns The DID in did:key format (e.g., \"did:key:z6Mk...\")\n */\n async getDID(keyId: string): Promise<string> {\n // The WASM session manager has a synchronous getDID method\n return this.sessionManager.getDID(keyId);\n }\n\n /**\n * List all session keys currently held by the provider.\n *\n * @returns Array of key IDs\n */\n listKeys(): string[] {\n const keys = this.sessionManager.listSessionKeys?.();\n return Array.isArray(keys) ? keys : [];\n }\n\n /**\n * Check if a key exists in the provider.\n *\n * @param keyId - The key ID to check\n * @returns True if the key exists\n */\n hasKey(keyId: string): boolean {\n const jwk = this.sessionManager.jwk(keyId);\n return jwk !== undefined;\n }\n}\n\n/**\n * Create a new WasmKeyProvider instance.\n *\n * @param sessionManager - The WASM session manager\n * @returns A new WasmKeyProvider instance\n */\nexport function createWasmKeyProvider(sessionManager: SessionManagerWithListing): WasmKeyProvider {\n return new WasmKeyProvider({ sessionManager });\n}\n","import { Delegation } from \"@tinycloud/sdk-core\";\n\n/**\n * A portable delegation that can be transported between users.\n * Extends the base Delegation type with fields required for transport.\n *\n * @remarks\n * PortableDelegation adds transport fields to Delegation:\n * - `delegationHeader`: Structured authorization header for API calls\n * - `ownerAddress`: Space owner's address for session creation\n * - `chainId`: Chain ID for session creation\n * - `host`: Optional server URL\n */\nexport interface PortableDelegation extends Omit<Delegation, \"isRevoked\"> {\n /** The authorization header for this delegation (structured format) */\n delegationHeader: { Authorization: string };\n\n /** The address of the space owner */\n ownerAddress: string;\n\n /** The chain ID */\n chainId: number;\n\n /** TinyCloud server URL where this delegation was created */\n host?: string;\n\n /** Whether the recipient is prevented from creating sub-delegations */\n disableSubDelegation?: boolean;\n\n /** Companion delegation for the user's public space (auto-created when includePublicSpace is true) */\n publicDelegation?: PortableDelegation;\n}\n\n/**\n * Serialize a PortableDelegation for transport (e.g., over network).\n */\nexport function serializeDelegation(delegation: PortableDelegation): string {\n return JSON.stringify({\n ...delegation,\n expiry: delegation.expiry.toISOString(),\n });\n}\n\n/**\n * Deserialize a PortableDelegation from transport.\n */\nexport function deserializeDelegation(data: string): PortableDelegation {\n const parsed = JSON.parse(data);\n return {\n ...parsed,\n cid: parsed.cid,\n expiry: new Date(parsed.expiry),\n };\n}\n"],"mappings":"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","names":["import_sdk_core","import_sdk_core","import_sdk_core","import_sdk_core","config","session","import_sdk_core"]}
1
+ {"version":3,"sources":["../src/core.ts","../src/storage/MemorySessionStorage.ts","../src/storage/FileSessionStorage.ts","../src/authorization/NodeUserAuthorization.ts","../src/authorization/strategies.ts","../src/TinyCloudNode.ts","../src/DelegatedAccess.ts","../src/keys/WasmKeyProvider.ts","../src/delegation.ts"],"sourcesContent":["/**\n * @tinycloud/node-sdk/core\n *\n * Platform-agnostic entry point for TinyCloud node-sdk.\n *\n * This entry point excludes Node.js-specific modules that depend on\n * @tinycloud/node-sdk-wasm (PrivateKeySigner, NodeWasmBindings), making it\n * safe to import in browser builds without webpack aliases or shims.\n *\n * Browser consumers (e.g., @tinycloud/web-sdk) should import from this\n * entry point instead of the root \"@tinycloud/node-sdk\".\n *\n * @packageDocumentation\n */\n\n// Re-export core values\nexport { TinyCloud } from \"@tinycloud/sdk-core\";\n\n// Re-export core types\nexport type {\n TinyCloudConfig,\n ISigner,\n ISessionStorage,\n IUserAuthorization,\n ClientSession,\n Extension,\n PersistedSessionData,\n TinyCloudSession,\n INotificationHandler,\n IENSResolver,\n IWasmBindings,\n ISessionManager,\n ISpaceCreationHandler,\n SpaceCreationContext,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export core values for extensibility\nexport {\n SilentNotificationHandler,\n AutoApproveSpaceCreationHandler,\n defaultSpaceCreationHandler,\n} from \"@tinycloud/sdk-core\";\n\n// Storage implementations\nexport { MemorySessionStorage } from \"./storage/MemorySessionStorage\";\nexport { FileSessionStorage } from \"./storage/FileSessionStorage\";\n\n// Authorization\nexport {\n NodeUserAuthorization,\n NodeUserAuthorizationConfig,\n} from \"./authorization/NodeUserAuthorization\";\n\n// Sign strategies — value exports\nexport { defaultSignStrategy } from \"./authorization/strategies\";\n\n// Sign strategies — type exports (re-exported from sdk-core + Node.js-specific types)\nexport type {\n SignRequest,\n SignResponse,\n SignCallback,\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n NodeEventEmitterStrategy,\n SignStrategy,\n} from \"./authorization/strategies\";\n\n// High-level API\nexport { TinyCloudNode, TinyCloudNodeConfig } from \"./TinyCloudNode\";\n\n// Delegation\nexport { DelegatedAccess } from \"./DelegatedAccess\";\nexport {\n PortableDelegation,\n serializeDelegation,\n deserializeDelegation,\n} from \"./delegation\";\n\n// Re-export KV service values\nexport { KVService, PrefixedKVService } from \"@tinycloud/sdk-core\";\n\n// Re-export KV service types\nexport type {\n IKVService,\n KVServiceConfig,\n KVResponse,\n IPrefixedKVService,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export SQL service values\nexport { SQLService, SQLAction, DatabaseHandle } from \"@tinycloud/sdk-core\";\n\n// Re-export SQL service types\nexport type {\n ISQLService,\n IDatabaseHandle,\n SQLServiceConfig,\n SqlValue,\n SqlStatement,\n QueryOptions,\n ExecuteOptions,\n BatchOptions,\n QueryResponse,\n ExecuteResponse,\n BatchResponse,\n SQLActionType,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export DuckDB service values\nexport { DuckDbService, DuckDbDatabaseHandle, DuckDbAction } from \"@tinycloud/sdk-core\";\n\n// Re-export DuckDB service types\nexport type {\n IDuckDbService,\n IDuckDbDatabaseHandle,\n DuckDbServiceConfig,\n DuckDbQueryOptions,\n DuckDbExecuteOptions,\n DuckDbBatchOptions,\n DuckDbOptions,\n DuckDbValue,\n DuckDbStatement,\n DuckDbQueryResponse,\n DuckDbExecuteResponse,\n DuckDbBatchResponse,\n DuckDbActionType,\n SchemaInfo,\n TableInfo,\n ColumnInfo,\n ViewInfo,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export Vault service values\nexport { DataVaultService, VaultHeaders, VaultPublicSpaceKVActions, createVaultCrypto } from \"@tinycloud/sdk-core\";\n\n// Re-export Vault service types\nexport type {\n IDataVaultService,\n VaultCrypto,\n WasmVaultFunctions,\n DataVaultConfig,\n VaultPutOptions,\n VaultGetOptions,\n VaultListOptions,\n VaultGrantOptions,\n VaultEntry,\n VaultError,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export v2 Delegation service values\nexport {\n DelegationManager,\n SharingService,\n createSharingService,\n DelegationErrorCodes,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export v2 Delegation types\nexport type {\n DelegationManagerConfig,\n ISharingService,\n SharingServiceConfig,\n EncodedShareData,\n ReceiveOptions,\n ShareAccess,\n Delegation,\n CreateDelegationParams,\n DelegationResult,\n DelegationError,\n DelegationErrorCode,\n JWK,\n KeyType,\n KeyInfo,\n CapabilityEntry,\n DelegationRecord,\n SpaceOwnership,\n SpaceInfo,\n ShareSchema,\n ShareLink,\n ShareLinkData,\n IngestOptions,\n GenerateShareParams,\n DelegationChain,\n DelegationChainV2,\n DelegationDirection,\n DelegationFilters,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export CapabilityKeyRegistry values (v2)\nexport {\n CapabilityKeyRegistry,\n createCapabilityKeyRegistry,\n CapabilityKeyRegistryErrorCodes,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export CapabilityKeyRegistry types (v2)\nexport type {\n ICapabilityKeyRegistry,\n StoredDelegationChain,\n CapabilityKeyRegistryErrorCode,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export SpaceService values (v2)\nexport {\n SpaceService,\n SpaceErrorCodes,\n createSpaceService,\n parseSpaceUri,\n buildSpaceUri,\n makePublicSpaceId,\n Space,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export SpaceService types (v2)\nexport type {\n ISpaceService,\n SpaceServiceConfig,\n SpaceErrorCode,\n ISpace,\n SpaceConfig,\n ISpaceScopedDelegations,\n ISpaceScopedSharing,\n} from \"@tinycloud/sdk-core\";\n\n// Protocol version checking\nexport {\n ProtocolMismatchError,\n VersionCheckError,\n UnsupportedFeatureError,\n checkNodeInfo,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export ServiceContext value for advanced usage\nexport { ServiceContext } from \"@tinycloud/sdk-core\";\n\n// Re-export ServiceContext types for advanced usage\nexport type {\n ServiceContextConfig,\n ServiceSession,\n InvokeFunction,\n FetchFunction,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export KeyProvider interface from sdk-core\nexport type { KeyProvider } from \"@tinycloud/sdk-core\";\n\n// Key management for node-sdk\nexport {\n WasmKeyProvider,\n WasmKeyProviderConfig,\n createWasmKeyProvider,\n} from \"./keys/WasmKeyProvider\";\n","import { ISessionStorage, PersistedSessionData } from \"@tinycloud/sdk-core\";\n\n/**\n * In-memory session storage for Node.js.\n *\n * Sessions are stored in memory and lost when the process exits.\n * Suitable for:\n * - Development and testing\n * - Stateless server deployments\n * - Short-lived processes\n *\n * @example\n * ```typescript\n * const storage = new MemorySessionStorage();\n * await storage.save(\"0x123...\", sessionData);\n * const session = await storage.load(\"0x123...\");\n * ```\n */\nexport class MemorySessionStorage implements ISessionStorage {\n private sessions: Map<string, PersistedSessionData> = new Map();\n\n /**\n * Save a session for an address.\n */\n async save(address: string, session: PersistedSessionData): Promise<void> {\n const normalizedAddress = address.toLowerCase();\n this.sessions.set(normalizedAddress, session);\n }\n\n /**\n * Load a session for an address.\n */\n async load(address: string): Promise<PersistedSessionData | null> {\n const normalizedAddress = address.toLowerCase();\n const session = this.sessions.get(normalizedAddress);\n\n if (!session) {\n return null;\n }\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n this.sessions.delete(normalizedAddress);\n return null;\n }\n\n return session;\n }\n\n /**\n * Clear a session for an address.\n */\n async clear(address: string): Promise<void> {\n const normalizedAddress = address.toLowerCase();\n this.sessions.delete(normalizedAddress);\n }\n\n /**\n * Check if a session exists for an address.\n */\n exists(address: string): boolean {\n const normalizedAddress = address.toLowerCase();\n const session = this.sessions.get(normalizedAddress);\n\n if (!session) {\n return false;\n }\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n this.sessions.delete(normalizedAddress);\n return false;\n }\n\n return true;\n }\n\n /**\n * Memory storage is always available.\n */\n isAvailable(): boolean {\n return true;\n }\n\n /**\n * Clear all sessions.\n */\n clearAll(): void {\n this.sessions.clear();\n }\n\n /**\n * Get the number of stored sessions.\n */\n size(): number {\n return this.sessions.size;\n }\n}\n","import { ISessionStorage, PersistedSessionData, validatePersistedSessionData } from \"@tinycloud/sdk-core\";\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n/**\n * File-based session storage for Node.js.\n *\n * Sessions are persisted to the file system and survive process restarts.\n * Suitable for:\n * - CLI applications\n * - Long-running server processes\n * - Development environments\n *\n * @example\n * ```typescript\n * const storage = new FileSessionStorage(\"/tmp/tinycloud-sessions\");\n * await storage.save(\"0x123...\", sessionData);\n * // Session persists across process restarts\n * ```\n */\nexport class FileSessionStorage implements ISessionStorage {\n private readonly baseDir: string;\n\n /**\n * Create a new FileSessionStorage.\n *\n * @param baseDir - Directory to store session files (default: ~/.tinycloud/sessions)\n */\n constructor(baseDir?: string) {\n this.baseDir = baseDir || this.getDefaultDir();\n this.ensureDirectoryExists();\n }\n\n /**\n * Get the default session storage directory.\n */\n private getDefaultDir(): string {\n const home = process.env.HOME || process.env.USERPROFILE || \"/tmp\";\n return join(home, \".tinycloud\", \"sessions\");\n }\n\n /**\n * Ensure the storage directory exists.\n */\n private ensureDirectoryExists(): void {\n if (!existsSync(this.baseDir)) {\n mkdirSync(this.baseDir, { recursive: true });\n }\n }\n\n /**\n * Get the file path for an address.\n */\n private getFilePath(address: string): string {\n const normalizedAddress = address.toLowerCase();\n // Use a hash of the address to avoid filesystem issues\n const filename = `${normalizedAddress.replace(\"0x\", \"\")}.json`;\n return join(this.baseDir, filename);\n }\n\n /**\n * Save a session for an address.\n */\n async save(address: string, session: PersistedSessionData): Promise<void> {\n const filePath = this.getFilePath(address);\n const data = JSON.stringify(session, null, 2);\n writeFileSync(filePath, data, \"utf-8\");\n }\n\n /**\n * Load a session for an address.\n */\n async load(address: string): Promise<PersistedSessionData | null> {\n const filePath = this.getFilePath(address);\n\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const data = readFileSync(filePath, \"utf-8\");\n const parsed = JSON.parse(data);\n\n // Validate loaded data against schema\n const validation = validatePersistedSessionData(parsed);\n if (!validation.ok) {\n console.warn(`Invalid session data for ${address}:`, validation.error.message);\n // Clean up invalid session\n unlinkSync(filePath);\n return null;\n }\n\n const session = validation.data;\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n // Clean up expired session\n unlinkSync(filePath);\n return null;\n }\n\n return session;\n } catch (error) {\n // Invalid JSON or read error - remove the file\n try {\n unlinkSync(filePath);\n } catch {\n // Ignore cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Clear a session for an address.\n */\n async clear(address: string): Promise<void> {\n const filePath = this.getFilePath(address);\n if (existsSync(filePath)) {\n unlinkSync(filePath);\n }\n }\n\n /**\n * Check if a session exists for an address.\n */\n exists(address: string): boolean {\n const filePath = this.getFilePath(address);\n if (!existsSync(filePath)) {\n return false;\n }\n\n try {\n const data = readFileSync(filePath, \"utf-8\");\n const session: PersistedSessionData = JSON.parse(data);\n\n // Check if session is expired\n const expiresAt = new Date(session.expiresAt);\n if (expiresAt < new Date()) {\n // Clean up expired session\n unlinkSync(filePath);\n return false;\n }\n\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if file system storage is available.\n */\n isAvailable(): boolean {\n try {\n this.ensureDirectoryExists();\n return existsSync(this.baseDir);\n } catch {\n return false;\n }\n }\n}\n","import { EventEmitter } from \"events\";\nimport {\n IUserAuthorization,\n ISigner,\n ISessionStorage,\n ClientSession,\n Extension,\n PersistedSessionData,\n TinyCloudSession,\n SiweConfig,\n fetchPeerId,\n submitHostDelegation,\n activateSessionWithHost,\n checkNodeInfo,\n ISpaceCreationHandler,\n AutoApproveSpaceCreationHandler,\n IWasmBindings,\n ISessionManager,\n} from \"@tinycloud/sdk-core\";\nimport {\n SignStrategy,\n SignRequest,\n SignResponse,\n defaultSignStrategy,\n} from \"./strategies\";\nimport { MemorySessionStorage } from \"../storage/MemorySessionStorage\";\n\n/**\n * Configuration for NodeUserAuthorization.\n */\nexport interface NodeUserAuthorizationConfig {\n /** The signer used for signing messages */\n signer: ISigner;\n /** Sign strategy for handling sign requests */\n signStrategy?: SignStrategy;\n /** Session storage implementation */\n sessionStorage?: ISessionStorage;\n /** Domain for SIWE messages */\n domain: string;\n /** URI for SIWE messages (default: domain) */\n uri?: string;\n /** Statement included in SIWE messages */\n statement?: string;\n /** Space prefix for new sessions */\n spacePrefix?: string;\n /** Default actions for sessions */\n defaultActions?: Record<string, Record<string, string[]>>;\n /** Session expiration time in milliseconds (default: 1 hour) */\n sessionExpirationMs?: number;\n /** Automatically create space if it doesn't exist (default: false) */\n autoCreateSpace?: boolean;\n /** Custom space creation handler. If provided, takes precedence over autoCreateSpace. */\n spaceCreationHandler?: ISpaceCreationHandler;\n /** TinyCloud server endpoints (default: [\"https://node.tinycloud.xyz\"]) */\n tinycloudHosts?: string[];\n /** Whether to include public space capabilities in the session (default: true) */\n enablePublicSpace?: boolean;\n /** WASM bindings for cryptographic operations. Required. */\n wasmBindings: IWasmBindings;\n /**\n * SIWE nonce override. If omitted, the WASM layer generates a random nonce.\n * If `siweConfig.nonce` is also provided, `siweConfig.nonce` wins.\n */\n nonce?: string;\n /** Optional SIWE configuration overrides (e.g., nonce for server-provided nonces) */\n siweConfig?: SiweConfig;\n}\n\n/**\n * Node.js implementation of IUserAuthorization.\n *\n * Supports multiple sign strategies for different use cases:\n * - auto-sign: Automatically approve all sign requests (trusted backends)\n * - auto-reject: Reject all sign requests (read-only mode)\n * - callback: Delegate to a custom callback function (CLI prompts)\n * - event-emitter: Emit sign requests as events (async workflows)\n *\n * @example\n * ```typescript\n * // Auto-sign for backend services\n * const auth = new NodeUserAuthorization({\n * signer: new PrivateKeySigner(process.env.PRIVATE_KEY),\n * signStrategy: { type: 'auto-sign' },\n * domain: 'api.myapp.com',\n * });\n *\n * // Callback for CLI prompts\n * const auth = new NodeUserAuthorization({\n * signer,\n * signStrategy: {\n * type: 'callback',\n * handler: async (req) => {\n * const approved = await promptUser(`Sign for ${req.address}?`);\n * return { approved };\n * }\n * },\n * domain: 'cli.myapp.com',\n * });\n * ```\n */\nexport class NodeUserAuthorization implements IUserAuthorization {\n private readonly signer: ISigner;\n private readonly signStrategy: SignStrategy;\n private readonly sessionStorage: ISessionStorage;\n private readonly domain: string;\n private readonly uri: string;\n private readonly statement?: string;\n private readonly spacePrefix: string;\n private readonly defaultActions: Record<string, Record<string, string[]>>;\n private readonly sessionExpirationMs: number;\n private readonly autoCreateSpace: boolean;\n private readonly spaceCreationHandler?: ISpaceCreationHandler;\n private readonly tinycloudHosts: string[];\n private readonly enablePublicSpace: boolean;\n private readonly nonce?: string;\n private readonly siweConfig?: SiweConfig;\n private readonly wasm: IWasmBindings;\n\n private sessionManager: ISessionManager;\n private extensions: Extension[] = [];\n private _session?: ClientSession;\n private _tinyCloudSession?: TinyCloudSession;\n private _address?: string;\n private _chainId?: number;\n private _nodeFeatures: string[] = [];\n\n constructor(config: NodeUserAuthorizationConfig) {\n this.wasm = config.wasmBindings;\n\n this.signer = config.signer;\n this.signStrategy = config.signStrategy ?? defaultSignStrategy;\n this.sessionStorage = config.sessionStorage ?? new MemorySessionStorage();\n this.domain = config.domain;\n this.uri = config.uri ?? `https://${config.domain}`;\n this.statement = config.statement;\n this.spacePrefix = config.spacePrefix ?? \"default\";\n this.defaultActions = config.defaultActions ?? {\n kv: {\n \"\": [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n ],\n },\n sql: {\n \"\": [\n \"tinycloud.sql/read\",\n \"tinycloud.sql/write\",\n \"tinycloud.sql/admin\",\n \"tinycloud.sql/export\",\n ],\n },\n duckdb: {\n \"\": [\n \"tinycloud.duckdb/read\",\n \"tinycloud.duckdb/write\",\n \"tinycloud.duckdb/admin\",\n \"tinycloud.duckdb/describe\",\n \"tinycloud.duckdb/export\",\n \"tinycloud.duckdb/import\",\n \"tinycloud.duckdb/execute\",\n ],\n },\n capabilities: {\n \"\": [\"tinycloud.capabilities/read\"],\n },\n };\n this.sessionExpirationMs = config.sessionExpirationMs ?? 60 * 60 * 1000;\n this.autoCreateSpace = config.autoCreateSpace ?? false;\n this.spaceCreationHandler = config.spaceCreationHandler;\n this.tinycloudHosts = config.tinycloudHosts ?? [\"https://node.tinycloud.xyz\"];\n this.enablePublicSpace = config.enablePublicSpace ?? true;\n this.nonce = config.nonce;\n this.siweConfig = config.siweConfig;\n\n // Initialize session manager via WASM bindings\n this.sessionManager = this.wasm.createSessionManager();\n }\n\n /**\n * The current active session (web-core compatible).\n */\n get session(): ClientSession | undefined {\n return this._session;\n }\n\n /**\n * The current TinyCloud session with full delegation data.\n * Includes spaceId, delegationHeader, and delegationCid.\n */\n get tinyCloudSession(): TinyCloudSession | undefined {\n return this._tinyCloudSession;\n }\n\n get nodeFeatures(): string[] {\n return this._nodeFeatures;\n }\n\n /**\n * Build SIWE overrides from the top-level nonce and siweConfig.\n * - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.\n * - statement is prepended to the default statement\n * - resources are appended to the default resources\n * - uri triggers a warning (overwriting delegation target)\n * - all other fields override directly\n */\n private buildSiweOverrides(): Record<string, unknown> {\n // Seed with top-level nonce; siweConfig fields layered on top take precedence.\n const base: Record<string, unknown> = { uri: this.uri };\n if (this.nonce !== undefined) {\n base.nonce = this.nonce;\n }\n\n if (!this.siweConfig) return base;\n\n const { statement, resources, uri, ...rest } = this.siweConfig;\n const overrides: Record<string, unknown> = { ...base, ...rest };\n\n if (statement) {\n overrides.statement = this.statement\n ? `${statement} ${this.statement}`\n : statement;\n }\n\n if (resources && resources.length > 0) {\n overrides.resources = resources;\n }\n\n if (uri) {\n console.warn(\n \"[tinycloud] siweConfig.uri is overwriting the delegation target URI. \" +\n \"This may break delegation chain validation if the URI does not match the session key DID.\",\n );\n overrides.uri = uri;\n }\n\n return overrides;\n }\n\n /**\n * Add an extension to the authorization flow.\n */\n extend(extension: Extension): void {\n this.extensions.push(extension);\n }\n\n /**\n * Get the space ID for the current session.\n */\n getSpaceId(): string | undefined {\n return this._tinyCloudSession?.spaceId;\n }\n\n /**\n * Create the space on the TinyCloud server (host delegation).\n * This registers the user as the owner of the space.\n */\n private async hostSpace(targetSpaceId?: string): Promise<boolean> {\n if (!this._tinyCloudSession || !this._address || !this._chainId) {\n throw new Error(\"Must be signed in to host space\");\n }\n\n const host = this.tinycloudHosts[0];\n const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;\n\n // Get peer ID from TinyCloud server\n const peerId = await fetchPeerId(host, spaceId);\n\n // Generate host SIWE message\n const siwe = this.wasm.generateHostSIWEMessage({\n address: this._address,\n chainId: this._chainId,\n domain: this.domain,\n issuedAt: new Date().toISOString(),\n spaceId,\n peerId,\n });\n\n // Sign the message\n const signature = await this.signMessage(siwe);\n\n // Convert to delegation headers and submit\n const headers = this.wasm.siweToDelegationHeaders({ siwe, signature });\n const result = await submitHostDelegation(host, headers);\n\n return result.success;\n }\n\n /**\n * Create a specific space on the server via host delegation.\n * Used for lazy creation of additional spaces (e.g., public).\n */\n async hostPublicSpace(spaceId: string): Promise<boolean> {\n return this.hostSpace(spaceId);\n }\n\n /**\n * Ensure the user's space exists on the TinyCloud server.\n * Creates the space if it doesn't exist and autoCreateSpace is enabled.\n * If autoCreateSpace is false and space doesn't exist, silently returns\n * (user may be using delegations to access other spaces).\n *\n * @throws Error if space creation fails\n */\n async ensureSpaceExists(): Promise<void> {\n if (!this._tinyCloudSession) {\n throw new Error(\"Must be signed in to ensure space exists\");\n }\n\n const host = this.tinycloudHosts[0];\n const primarySpaceId = this._tinyCloudSession.spaceId;\n\n // Try to activate the session\n const result = await activateSessionWithHost(\n host,\n this._tinyCloudSession.delegationHeader\n );\n\n // Determine the effective space creation handler:\n // 1. Explicit spaceCreationHandler takes precedence\n // 2. autoCreateSpace: true uses AutoApproveSpaceCreationHandler\n // 3. Otherwise, no handler (space creation skipped silently)\n const handler: ISpaceCreationHandler | undefined = this.spaceCreationHandler\n ?? (this.autoCreateSpace ? new AutoApproveSpaceCreationHandler() : undefined);\n\n const creationContext = {\n spaceId: primarySpaceId,\n address: this._address!,\n chainId: this._chainId!,\n host,\n };\n\n if (result.success) {\n // Check if primary space was actually activated or just skipped\n const primarySkipped = result.skipped?.includes(primarySpaceId);\n\n if (!primarySkipped) {\n // Primary space exists and session is activated\n return;\n }\n\n // Primary space was skipped (doesn't exist yet)\n if (!handler) {\n return;\n }\n\n const confirmed = await handler.confirmSpaceCreation(creationContext);\n if (!confirmed) {\n return;\n }\n\n // Create the primary space\n try {\n const created = await this.hostSpace();\n if (!created) {\n const err = new Error(`Failed to create space: ${primarySpaceId}`);\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n } catch (error) {\n handler.onSpaceCreationFailed?.(creationContext, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n\n // Small delay to allow space creation to propagate\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n // Retry activation\n const retryResult = await activateSessionWithHost(\n host,\n this._tinyCloudSession.delegationHeader\n );\n\n if (!retryResult.success) {\n const err = new Error(\n `Failed to activate session after creating space: ${retryResult.error}`\n );\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n\n handler.onSpaceCreated?.(creationContext);\n return;\n }\n\n // Handle 404 (backwards compat with older servers)\n if (result.status === 404) {\n if (!handler) {\n return;\n }\n\n const confirmed = await handler.confirmSpaceCreation(creationContext);\n if (!confirmed) {\n return;\n }\n\n try {\n const created = await this.hostSpace();\n if (!created) {\n const err = new Error(`Failed to create space: ${primarySpaceId}`);\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n } catch (error) {\n handler.onSpaceCreationFailed?.(creationContext, error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n\n const retryResult = await activateSessionWithHost(\n host,\n this._tinyCloudSession.delegationHeader\n );\n\n if (!retryResult.success) {\n const err = new Error(\n `Failed to activate session after creating space: ${retryResult.error}`\n );\n handler.onSpaceCreationFailed?.(creationContext, err);\n throw err;\n }\n\n handler.onSpaceCreated?.(creationContext);\n return;\n }\n\n throw new Error(`Failed to activate session: ${result.error}`);\n }\n\n /**\n * Sign in and create a new session.\n *\n * This follows the correct SIWE-ReCap flow:\n * 1. Create session key and get JWK\n * 2. Call prepareSession() which generates the SIWE with ReCap capabilities\n * 3. Sign the SIWE string from prepareSession\n * 4. Call completeSessionSetup() with the prepared session + signature\n */\n async signIn(): Promise<ClientSession> {\n // Get signer address and chain ID\n this._address = await this.signer.getAddress();\n this._chainId = await this.signer.getChainId();\n\n const address = this.wasm.ensureEip55(this._address);\n const chainId = this._chainId;\n\n // Create a session key\n const keyId = `session-${Date.now()}`;\n this.sessionManager.renameSessionKeyId(\"default\", keyId);\n\n // Get JWK for session key\n const jwkString = this.sessionManager.jwk(keyId);\n if (!jwkString) {\n throw new Error(\"Failed to create session key\");\n }\n const jwk = JSON.parse(jwkString);\n\n // Create space ID\n const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);\n\n const now = new Date();\n const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);\n\n // Prepare session - this creates the SIWE message with ReCap capabilities\n const prepared = this.wasm.prepareSession({\n abilities: this.defaultActions,\n address,\n chainId,\n domain: this.domain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId,\n jwk,\n ...this.buildSiweOverrides(),\n });\n\n // Sign the SIWE message from prepareSession (NOT a separately generated SIWE)\n const signature = await this.requestSignature({\n address,\n chainId,\n message: prepared.siwe,\n type: \"siwe\",\n });\n\n // Complete session setup with the prepared session + signature\n const session = this.wasm.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Create client session (web-core compatible)\n const clientSession: ClientSession = {\n address,\n walletAddress: address,\n chainId,\n sessionKey: keyId,\n siwe: prepared.siwe,\n signature,\n };\n\n // Compute additional spaces as metadata (not in the delegation itself).\n // The public space delegation is created lazily via ensurePublicSpace(),\n // not at signIn time, to avoid creating spaces the user may never use.\n const spacesMetadata: Record<string, string> | undefined =\n this.enablePublicSpace\n ? { public: this.wasm.makeSpaceId(address, chainId, \"public\") }\n : undefined;\n\n // Create TinyCloud session with full delegation data\n // Use sessionManager.getDID(keyId) for verificationMethod to get properly formatted DID URL\n // The prepared.verificationMethod from Rust WASM has a bug that doubles the DID fragment\n const tinyCloudSession: TinyCloudSession = {\n address,\n chainId,\n sessionKey: keyId,\n spaceId,\n spaces: spacesMetadata,\n delegationCid: session.delegationCid,\n delegationHeader: session.delegationHeader,\n verificationMethod: this.sessionManager.getDID(keyId),\n jwk,\n siwe: prepared.siwe,\n signature,\n };\n\n // Persist session with TinyCloud-specific data\n const persistedData: PersistedSessionData = {\n address,\n chainId,\n sessionKey: JSON.stringify(jwk),\n siwe: prepared.siwe,\n signature,\n tinycloudSession: {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId,\n spaces: spacesMetadata,\n verificationMethod: this.sessionManager.getDID(keyId),\n },\n expiresAt: expirationTime.toISOString(),\n createdAt: now.toISOString(),\n version: \"1.0\",\n };\n await this.sessionStorage.save(address, persistedData);\n\n // Set current session\n this._session = clientSession;\n this._tinyCloudSession = tinyCloudSession;\n this._address = address;\n this._chainId = chainId;\n\n // Verify SDK-node protocol compatibility and discover supported features\n const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], this.wasm.protocolVersion());\n this._nodeFeatures = nodeInfo.features;\n\n // Call extension hooks\n for (const ext of this.extensions) {\n if (ext.afterSignIn) {\n await ext.afterSignIn(clientSession);\n }\n }\n\n // Ensure space exists (creates if needed when autoCreateSpace is true)\n await this.ensureSpaceExists();\n\n return clientSession;\n }\n\n /**\n * Sign out and clear the current session.\n */\n async signOut(): Promise<void> {\n if (this._address) {\n await this.clearPersistedSession(this._address);\n }\n this._session = undefined;\n }\n\n /**\n * Get the current wallet/signer address.\n */\n address(): string | undefined {\n return this._address;\n }\n\n /**\n * Get the current chain ID.\n */\n chainId(): number | undefined {\n return this._chainId;\n }\n\n /**\n * Sign a message with the connected signer.\n */\n async signMessage(message: string): Promise<string> {\n if (!this._address) {\n this._address = await this.signer.getAddress();\n }\n if (!this._chainId) {\n this._chainId = await this.signer.getChainId();\n }\n\n return this.requestSignature({\n address: this._address,\n chainId: this._chainId,\n message,\n type: \"message\",\n });\n }\n\n\n /**\n * Prepare a session for external signing.\n *\n * Use this method when you need to sign the SIWE message externally (e.g., via\n * a hardware wallet, multi-sig, or external service). After obtaining the signature,\n * call `signInWithPreparedSession()` to complete the sign-in.\n *\n * @example\n * ```typescript\n * const { prepared, keyId, jwk } = await auth.prepareSessionForSigning();\n * const signature = await externalSigner.signMessage(prepared.siwe);\n * const session = await auth.signInWithPreparedSession(prepared, signature, keyId, jwk);\n * ```\n */\n async prepareSessionForSigning(): Promise<{\n prepared: {\n siwe: string;\n jwk: Record<string, unknown>;\n spaceId: string;\n verificationMethod: string;\n };\n keyId: string;\n jwk: Record<string, unknown>;\n address: string;\n chainId: number;\n }> {\n const address = this.wasm.ensureEip55(await this.signer.getAddress());\n const chainId = await this.signer.getChainId();\n\n // Create a session key\n const keyId = `session-${Date.now()}`;\n this.sessionManager.renameSessionKeyId(\"default\", keyId);\n\n // Get JWK for session key\n const jwkString = this.sessionManager.jwk(keyId);\n if (!jwkString) {\n throw new Error(\"Failed to create session key\");\n }\n const jwk = JSON.parse(jwkString);\n\n // Create space ID\n const spaceId = this.wasm.makeSpaceId(address, chainId, this.spacePrefix);\n\n const now = new Date();\n const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);\n\n // Prepare session - this creates the SIWE message with ReCap capabilities\n const prepared = this.wasm.prepareSession({\n abilities: this.defaultActions,\n address,\n chainId,\n domain: this.domain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId,\n jwk,\n ...this.buildSiweOverrides(),\n });\n\n return {\n prepared,\n keyId,\n jwk,\n address,\n chainId,\n };\n }\n\n /**\n * Complete sign-in with a prepared session and signature.\n *\n * Use this method after obtaining a signature for the SIWE message from\n * `prepareSessionForSigning()`. The signature MUST be over `prepared.siwe`.\n *\n * @param prepared - The prepared session from `prepareSessionForSigning()`\n * @param signature - The signature over `prepared.siwe`\n * @param keyId - The session key ID from `prepareSessionForSigning()`\n * @param jwk - The JWK from `prepareSessionForSigning()`\n */\n async signInWithPreparedSession(\n prepared: {\n siwe: string;\n jwk: Record<string, unknown>;\n spaceId: string;\n verificationMethod: string;\n },\n signature: string,\n keyId: string,\n jwk: Record<string, unknown>,\n ): Promise<ClientSession> {\n // Complete session setup with the prepared session + signature\n const session = this.wasm.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Parse address and chainId from the prepared session\n // The SIWE message contains this info, but we need to extract it\n // For now, we'll get it from the signer since it should match\n const address = this.wasm.ensureEip55(await this.signer.getAddress());\n const chainId = await this.signer.getChainId();\n\n // Create client session (web-core compatible)\n const clientSession: ClientSession = {\n address,\n walletAddress: address,\n chainId,\n sessionKey: keyId,\n siwe: prepared.siwe,\n signature,\n };\n\n // Compute additional spaces as metadata (not in the delegation itself).\n const spacesMetadata: Record<string, string> | undefined =\n this.enablePublicSpace\n ? { public: this.wasm.makeSpaceId(address, chainId, \"public\") }\n : undefined;\n\n // Create TinyCloud session with full delegation data\n // Use sessionManager.getDID(keyId) for properly formatted DID URL\n const tinyCloudSession: TinyCloudSession = {\n address,\n chainId,\n sessionKey: keyId,\n spaceId: prepared.spaceId,\n spaces: spacesMetadata,\n delegationCid: session.delegationCid,\n delegationHeader: session.delegationHeader,\n verificationMethod: this.sessionManager.getDID(keyId),\n jwk,\n siwe: prepared.siwe,\n signature,\n };\n\n // Extract expiration from SIWE message (parse the string)\n const expirationMatch = prepared.siwe.match(/Expiration Time: (.+)/);\n const issuedAtMatch = prepared.siwe.match(/Issued At: (.+)/);\n const expiresAt =\n expirationMatch?.[1] ??\n new Date(Date.now() + this.sessionExpirationMs).toISOString();\n const createdAt = issuedAtMatch?.[1] ?? new Date().toISOString();\n\n // Persist session with TinyCloud-specific data\n const persistedData: PersistedSessionData = {\n address,\n chainId,\n sessionKey: JSON.stringify(jwk),\n siwe: prepared.siwe,\n signature,\n tinycloudSession: {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: prepared.spaceId,\n spaces: spacesMetadata,\n verificationMethod: this.sessionManager.getDID(keyId),\n },\n expiresAt,\n createdAt,\n version: \"1.0\",\n };\n await this.sessionStorage.save(address, persistedData);\n\n // Set current session\n this._session = clientSession;\n this._tinyCloudSession = tinyCloudSession;\n this._address = address;\n this._chainId = chainId;\n\n // Verify SDK-node protocol compatibility and discover supported features\n const nodeInfo = await checkNodeInfo(this.tinycloudHosts[0], this.wasm.protocolVersion());\n this._nodeFeatures = nodeInfo.features;\n\n // Call extension hooks\n for (const ext of this.extensions) {\n if (ext.afterSignIn) {\n await ext.afterSignIn(clientSession);\n }\n }\n\n // Ensure space exists (creates if needed when autoCreateSpace is true)\n await this.ensureSpaceExists();\n\n return clientSession;\n }\n\n /**\n * Clear persisted session data.\n */\n async clearPersistedSession(address?: string): Promise<void> {\n const targetAddress = address ?? this._address;\n if (targetAddress) {\n await this.sessionStorage.clear(targetAddress);\n }\n }\n\n /**\n * Check if a session is persisted for an address.\n */\n isSessionPersisted(address: string): boolean {\n return this.sessionStorage.exists(address);\n }\n\n /**\n * Request a signature based on the configured strategy.\n */\n private async requestSignature(request: SignRequest): Promise<string> {\n switch (this.signStrategy.type) {\n case \"auto-sign\":\n return this.signer.signMessage(request.message);\n\n case \"auto-reject\":\n throw new Error(\"Sign request rejected by auto-reject strategy\");\n\n case \"callback\": {\n const response = await this.signStrategy.handler(request);\n if (!response.approved) {\n throw new Error(\n response.reason ?? \"Sign request rejected by callback\"\n );\n }\n // If callback provides signature, use it; otherwise sign with signer\n return (\n response.signature ?? (await this.signer.signMessage(request.message))\n );\n }\n\n case \"event-emitter\": {\n return this.requestSignatureViaEmitter(\n request,\n this.signStrategy.emitter,\n this.signStrategy.timeout ?? 60000\n );\n }\n\n default:\n throw new Error(`Unknown sign strategy: ${(this.signStrategy as any).type}`);\n }\n }\n\n /**\n * Request signature via event emitter with timeout.\n */\n private requestSignatureViaEmitter(\n request: SignRequest,\n emitter: EventEmitter,\n timeout: number\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(\"Sign request timed out\"));\n }, timeout);\n\n const respond = async (response: SignResponse) => {\n clearTimeout(timeoutId);\n if (!response.approved) {\n reject(\n new Error(response.reason ?? \"Sign request rejected via emitter\")\n );\n } else {\n // If response provides signature, use it; otherwise sign with signer\n const signature =\n response.signature ??\n (await this.signer.signMessage(request.message));\n resolve(signature);\n }\n };\n\n emitter.emit(\"sign-request\", request, respond);\n });\n }\n}\n","/**\n * Node.js-specific SignStrategy types for TinyCloud authorization.\n *\n * This module re-exports common types from sdk-core and provides\n * Node.js-specific implementations (e.g., NodeEventEmitterStrategy\n * using Node's EventEmitter instead of browser EventTarget).\n *\n * @packageDocumentation\n */\n\nimport { EventEmitter } from \"events\";\n\n// Import types for local use in SignStrategy union\nimport type {\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n} from \"@tinycloud/sdk-core\";\n\n// Re-export common types from sdk-core (type-only — erased at runtime in sdk-core dist)\nexport type {\n SignRequest,\n SignResponse,\n SignCallback,\n AutoSignStrategy,\n AutoRejectStrategy,\n CallbackStrategy,\n} from \"@tinycloud/sdk-core\";\n\n/**\n * Node.js event emitter strategy: emits sign requests as events.\n *\n * Uses Node.js EventEmitter for compatibility with Node.js applications.\n * For browser environments, use the EventEmitterStrategy from sdk-core\n * which uses EventTarget.\n *\n * Events emitted:\n * - 'sign-request': When a sign request is received\n *\n * Use cases:\n * - Async approval workflows in Node.js\n * - External signing services\n * - Multi-step authorization flows\n *\n * @example\n * ```typescript\n * const emitter = new EventEmitter();\n * const strategy: NodeEventEmitterStrategy = { type: 'event-emitter', emitter };\n *\n * emitter.on('sign-request', async (req, respond) => {\n * const approved = await externalApprovalService.check(req);\n * respond({ approved, signature: approved ? await sign(req.message) : undefined });\n * });\n * ```\n */\nexport interface NodeEventEmitterStrategy {\n type: \"event-emitter\";\n emitter: EventEmitter;\n /** Timeout in milliseconds for waiting on event response (default: 60000) */\n timeout?: number;\n}\n\n/**\n * Node.js sign strategy union type.\n *\n * Determines how sign requests are handled in NodeUserAuthorization.\n * Uses Node.js EventEmitter for the event-emitter strategy.\n */\nexport type SignStrategy =\n | AutoSignStrategy\n | AutoRejectStrategy\n | CallbackStrategy\n | NodeEventEmitterStrategy;\n\n/**\n * Default sign strategy is auto-sign for convenience.\n * This is the Node.js-specific version typed with SignStrategy.\n */\nexport const defaultSignStrategy: SignStrategy = { type: \"auto-sign\" };\n","/**\n * TinyCloudNode - High-level API for Node.js users.\n *\n * Each user has their own TinyCloudNode instance with their own key.\n * This class provides a simplified interface for:\n * - Signing in and managing sessions\n * - Key-value storage operations on own space\n * - Creating and using delegations\n *\n * @example\n * ```typescript\n * const alice = new TinyCloudNode({\n * privateKey: process.env.ALICE_PRIVATE_KEY,\n * host: \"https://node.tinycloud.xyz\",\n * prefix: \"myapp\",\n * });\n *\n * await alice.signIn();\n * await alice.kv.put(\"greeting\", \"Hello, world!\");\n *\n * // Delegate access to Bob\n * const delegation = await alice.createDelegation({\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * delegateDID: bob.did,\n * });\n *\n * // Bob uses the delegation\n * const access = await bob.useDelegation(delegation);\n * const data = await access.kv.get(\"shared/data\");\n * ```\n */\n\nimport {\n TinyCloud,\n TinyCloudSession,\n activateSessionWithHost,\n KVService,\n IKVService,\n SQLService,\n ISQLService,\n DuckDbService,\n IDuckDbService,\n DataVaultService,\n IDataVaultService,\n createVaultCrypto,\n ServiceSession,\n ServiceContext,\n ISessionStorage,\n ISigner,\n INotificationHandler,\n SilentNotificationHandler,\n IENSResolver,\n IWasmBindings,\n ISessionManager,\n ISpaceCreationHandler,\n // v2 services\n DelegationManager,\n SpaceService,\n ISpaceService,\n CapabilityKeyRegistry,\n ICapabilityKeyRegistry,\n SharingService,\n ISharingService,\n // v2 types\n SiweConfig,\n Delegation,\n CreateDelegationParams,\n KeyInfo,\n JWK,\n DelegationResult,\n CreateDelegationWasmParams,\n CreateDelegationWasmResult,\n UnsupportedFeatureError,\n makePublicSpaceId,\n} from \"@tinycloud/sdk-core\";\nimport { NodeUserAuthorization } from \"./authorization/NodeUserAuthorization\";\nimport { FileSessionStorage } from \"./storage/FileSessionStorage\";\nimport { MemorySessionStorage } from \"./storage/MemorySessionStorage\";\nimport { PortableDelegation } from \"./delegation\";\nimport { DelegatedAccess } from \"./DelegatedAccess\";\nimport { WasmKeyProvider } from \"./keys/WasmKeyProvider\";\n\n/** Default TinyCloud host */\nconst DEFAULT_HOST = \"https://node.tinycloud.xyz\";\n\n/**\n * Configuration for TinyCloudNode.\n * All fields are optional - TinyCloudNode can work with zero configuration.\n */\nexport interface TinyCloudNodeConfig {\n /** Hex-encoded private key (with or without 0x prefix). Optional - only needed for wallet mode and signIn() */\n privateKey?: string;\n /** Custom signer implementation. If provided, takes precedence over privateKey. */\n signer?: ISigner;\n /** TinyCloud server URL (default: \"https://node.tinycloud.xyz\") */\n host?: string;\n /** Space prefix for this user's space. Optional - only needed for signIn() */\n prefix?: string;\n /** Domain for SIWE messages (default: derived from host) */\n domain?: string;\n /** Session expiration time in milliseconds (default: 1 hour) */\n sessionExpirationMs?: number;\n /** Whether to automatically create space if it doesn't exist (default: false) */\n autoCreateSpace?: boolean;\n /** Custom session storage implementation (default: MemorySessionStorage) */\n sessionStorage?: ISessionStorage;\n /** Whether to include public space capabilities in the session (default: true).\n * When true, signIn() automatically includes capabilities for the user's public space,\n * accessible via spaces.get('public').kv */\n enablePublicSpace?: boolean;\n /** Custom WASM bindings (default: @tinycloud/node-sdk-wasm). Used by browser wrapper. */\n wasmBindings?: IWasmBindings;\n /** Notification handler for sign-in/sign-out/error events (default: SilentNotificationHandler) */\n notificationHandler?: INotificationHandler;\n /** ENS resolver for resolving .eth names in delegation methods */\n ensResolver?: IENSResolver;\n /** Custom space creation handler (default: auto-approve when autoCreateSpace is true) */\n spaceCreationHandler?: ISpaceCreationHandler;\n /**\n * SIWE nonce override. If omitted, the WASM layer generates a random nonce.\n * If `siweConfig.nonce` is also provided, `siweConfig.nonce` wins.\n */\n nonce?: string;\n /** Optional SIWE configuration overrides (e.g., nonce for server-provided nonces) */\n siweConfig?: SiweConfig;\n}\n\n/**\n * High-level TinyCloud API for Node.js environments.\n *\n * Each user creates their own TinyCloudNode instance with their private key.\n * The instance manages the user's session and provides access to their space.\n */\n/** @internal */\nexport interface NodeDefaults {\n createWasmBindings: () => IWasmBindings;\n createSigner: (privateKey: string, chainId?: number) => ISigner;\n}\n\nexport class TinyCloudNode {\n /** @internal Registered by importing @tinycloud/node-sdk (not /core) */\n private static nodeDefaults?: NodeDefaults;\n\n /** @internal Register Node.js-specific defaults (NodeWasmBindings, PrivateKeySigner) */\n static registerNodeDefaults(defaults: NodeDefaults): void {\n TinyCloudNode.nodeDefaults = defaults;\n }\n\n private config: TinyCloudNodeConfig;\n private signer: ISigner | null = null;\n private auth: NodeUserAuthorization | null = null;\n private tc: TinyCloud | null = null;\n private _address?: string;\n private _chainId: number = 1;\n private wasmBindings: IWasmBindings;\n private sessionManager: ISessionManager;\n private _serviceContext?: ServiceContext;\n private _kv?: KVService;\n private _sql?: SQLService;\n private _duckdb?: DuckDbService;\n private _vault?: DataVaultService;\n /** Cached public KV with proper delegation (set by ensurePublicSpace) */\n private _publicKV?: KVService;\n\n /** Session key ID - always available */\n private sessionKeyId: string;\n /** Session key JWK as object - always available */\n private sessionKeyJwk: object;\n\n /** Notification handler for user-facing events */\n private notificationHandler: INotificationHandler;\n\n // v2 services (initialized in constructor)\n private _capabilityRegistry: CapabilityKeyRegistry;\n private _keyProvider: WasmKeyProvider;\n private _sharingService: SharingService;\n // These are initialized after signIn()\n private _delegationManager?: DelegationManager;\n private _spaceService?: SpaceService;\n\n private get nodeFeatures(): string[] {\n return this.auth?.nodeFeatures ?? [];\n }\n\n /** SIWE domain — uses config override or defaults to app.tinycloud.xyz */\n private get siweDomain(): string {\n return this.config.domain ?? 'app.tinycloud.xyz';\n }\n\n /**\n * Create a new TinyCloudNode instance.\n *\n * All configuration is optional. Without a privateKey, the instance operates\n * in \"session-only\" mode where it can receive delegations but cannot create\n * its own space via signIn().\n *\n * @param config - Configuration options (all optional)\n *\n * @example\n * ```typescript\n * // Session-only mode - can receive delegations\n * const bob = new TinyCloudNode();\n * console.log(bob.did); // did:key:z6Mk... - available immediately\n *\n * // Wallet mode - can create own space\n * const alice = new TinyCloudNode({\n * privateKey: process.env.ALICE_PRIVATE_KEY,\n * prefix: \"myapp\",\n * });\n * await alice.signIn();\n * ```\n */\n constructor(config: TinyCloudNodeConfig = {}) {\n // Store config with default host\n this.config = {\n ...config,\n host: config.host ?? DEFAULT_HOST,\n };\n\n // Initialize WASM bindings (uses registered Node defaults if not provided)\n if (config.wasmBindings) {\n this.wasmBindings = config.wasmBindings;\n } else if (TinyCloudNode.nodeDefaults) {\n this.wasmBindings = TinyCloudNode.nodeDefaults.createWasmBindings();\n } else {\n throw new Error(\n \"wasmBindings must be provided in config. \" +\n \"Import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults.\"\n );\n }\n\n // Always create session manager and session key immediately\n this.sessionManager = this.wasmBindings.createSessionManager();\n\n // Try to use \"default\" key, create if it doesn't exist\n const defaultKeyId = \"default\";\n let jwkStr = this.sessionManager.jwk(defaultKeyId);\n if (jwkStr) {\n // Key already exists, reuse it\n this.sessionKeyId = defaultKeyId;\n } else {\n // Create new key\n this.sessionKeyId = this.sessionManager.createSessionKey(defaultKeyId);\n jwkStr = this.sessionManager.jwk(this.sessionKeyId);\n }\n\n if (!jwkStr) {\n throw new Error(\"Failed to get session key JWK\");\n }\n this.sessionKeyJwk = JSON.parse(jwkStr);\n\n // Initialize capability registry for all users (needed for tracking received delegations)\n this._capabilityRegistry = new CapabilityKeyRegistry();\n\n // Initialize KeyProvider for SharingService\n this._keyProvider = new WasmKeyProvider({\n sessionManager: this.sessionManager,\n });\n\n // Initialize notification handler\n this.notificationHandler = config.notificationHandler ?? new SilentNotificationHandler();\n\n // Initialize SharingService for receive-only access (no session required)\n // This allows session-only users to receive sharing links without signIn()\n // Full capabilities (generate) are added after signIn()\n this._sharingService = new SharingService({\n hosts: [this.config.host!],\n // session: undefined - not needed for receive()\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n keyProvider: this._keyProvider,\n registry: this._capabilityRegistry,\n // delegationManager: undefined - not needed for receive()\n createKVService: (config) => {\n // Use pathPrefix as the KV service prefix for sharing links\n // Strip trailing slash to match DelegatedAccess behavior\n const prefix = config.pathPrefix?.replace(/\\/$/, '');\n const kvService = new KVService({ prefix });\n // Create a new service context for the KV service\n const kvContext = new ServiceContext({\n invoke: config.invoke,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n hosts: config.hosts,\n });\n kvContext.setSession(config.session);\n kvService.initialize(kvContext);\n return kvService;\n },\n });\n\n // Set up wallet/auth if signer or privateKey is provided\n if (config.signer) {\n this.signer = config.signer;\n this.setupAuth(config);\n } else if (config.privateKey) {\n if (!TinyCloudNode.nodeDefaults) {\n throw new Error(\n \"privateKey requires PrivateKeySigner. Either provide a signer in config, \" +\n \"or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults.\"\n );\n }\n this.signer = TinyCloudNode.nodeDefaults.createSigner(config.privateKey, this._chainId);\n this.setupAuth(config);\n }\n }\n\n /**\n * Set up authorization handler and TinyCloud instance.\n * @internal\n */\n private setupAuth(config: TinyCloudNodeConfig): void {\n const host = this.config.host!;\n\n this.auth = new NodeUserAuthorization({\n signer: this.signer!,\n signStrategy: { type: \"auto-sign\" },\n wasmBindings: this.wasmBindings,\n sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),\n domain: this.siweDomain,\n spacePrefix: config.prefix,\n sessionExpirationMs: config.sessionExpirationMs ?? 60 * 60 * 1000,\n tinycloudHosts: [host],\n autoCreateSpace: config.autoCreateSpace,\n enablePublicSpace: config.enablePublicSpace ?? true,\n spaceCreationHandler: config.spaceCreationHandler,\n nonce: config.nonce,\n siweConfig: config.siweConfig,\n });\n\n this.tc = new TinyCloud(this.auth);\n }\n\n /**\n * Get the primary identity DID for this user.\n * - If wallet connected and signed in: returns PKH DID (did:pkh:eip155:{chainId}:{address})\n * - If session-only mode: returns session key DID (did:key:z6Mk...)\n *\n * Use this for delegations - it always returns the appropriate identity.\n */\n get did(): string {\n // If wallet is connected and signed in, return PKH (persistent identity)\n if (this._address) {\n return `did:pkh:eip155:${this._chainId}:${this._address}`;\n }\n // Session-only mode: return session key DID (ephemeral identity)\n return this.sessionManager.getDID(this.sessionKeyId);\n }\n\n /**\n * Get the session key DID. Always available.\n * Format: did:key:z6Mk...#z6Mk...\n *\n * Use this when you specifically need the session key, not the user identity.\n */\n get sessionDid(): string {\n return this.sessionManager.getDID(this.sessionKeyId);\n }\n\n /**\n * Get the Ethereum address for this user.\n */\n get address(): string | undefined {\n return this._address;\n }\n\n /**\n * Check if this instance is in session-only mode (no wallet).\n * In session-only mode, the instance can receive delegations but cannot\n * create its own space via signIn().\n */\n get isSessionOnly(): boolean {\n return this.signer === null;\n }\n\n /**\n * Get the space ID for this user.\n * Available after signIn().\n */\n get spaceId(): string | undefined {\n return this.auth?.tinyCloudSession?.spaceId;\n }\n\n /**\n * Get the current TinyCloud session.\n * Available after signIn().\n */\n get session(): TinyCloudSession | undefined {\n return this.auth?.tinyCloudSession;\n }\n\n /**\n * Sign in and create a new session.\n * This creates the user's space if it doesn't exist.\n * Requires wallet mode (privateKey in config).\n */\n async signIn(): Promise<void> {\n if (!this.signer || !this.tc) {\n throw new Error(\n \"Cannot signIn() in session-only mode. Provide a privateKey in config to create your own space.\"\n );\n }\n\n // Ensure WASM is ready (critical for browser where WASM loads asynchronously)\n await this.wasmBindings.ensureInitialized?.();\n\n this._address = await this.signer.getAddress();\n this._chainId = await this.signer.getChainId();\n\n // Reset services so they get recreated with new session\n this._kv = undefined;\n this._sql = undefined;\n this._duckdb = undefined;\n this._serviceContext = undefined;\n\n await this.tc.signIn();\n\n // Initialize service context with session\n this.initializeServices();\n\n this.notificationHandler.success(\"Successfully signed in\");\n }\n\n /**\n * Restore a previously established session from stored delegation data.\n *\n * This is used by the CLI to restore a session that was created via the\n * browser-based delegation flow (OpenKey `/delegate` page). Instead of\n * signing in with a private key, it injects the delegation data directly.\n *\n * @param sessionData - The stored delegation data from the browser flow\n */\n async restoreSession(sessionData: {\n delegationHeader: { Authorization: string };\n delegationCid: string;\n spaceId: string;\n jwk: object;\n verificationMethod: string;\n address?: string;\n chainId?: number;\n }): Promise<void> {\n // Ensure WASM is ready (critical for browser where WASM loads asynchronously)\n await this.wasmBindings.ensureInitialized?.();\n\n // Reset services so they get recreated with new session\n this._kv = undefined;\n this._sql = undefined;\n this._duckdb = undefined;\n this._serviceContext = undefined;\n\n if (sessionData.address) {\n this._address = sessionData.address;\n }\n if (sessionData.chainId) {\n this._chainId = sessionData.chainId;\n }\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n hosts: [this.config.host!],\n });\n\n // Create and register KV service\n this._kv = new KVService({});\n this._kv.initialize(this._serviceContext);\n this._serviceContext.registerService('kv', this._kv);\n\n // Create and register SQL service\n this._sql = new SQLService({});\n this._sql.initialize(this._serviceContext);\n this._serviceContext.registerService('sql', this._sql);\n\n // Create and register DuckDB service\n this._duckdb = new DuckDbService({});\n this._duckdb.initialize(this._serviceContext);\n this._serviceContext.registerService('duckdb', this._duckdb);\n\n // Set session on context\n const serviceSession: ServiceSession = {\n delegationHeader: sessionData.delegationHeader,\n delegationCid: sessionData.delegationCid,\n spaceId: sessionData.spaceId,\n verificationMethod: sessionData.verificationMethod,\n jwk: sessionData.jwk,\n };\n this._serviceContext.setSession(serviceSession);\n\n // Create and register Vault service (matches initializeServices behavior)\n const wasm = this.wasmBindings;\n const vaultCrypto = createVaultCrypto({\n vault_encrypt: wasm.vault_encrypt, vault_decrypt: wasm.vault_decrypt, vault_derive_key: wasm.vault_derive_key,\n vault_x25519_from_seed: wasm.vault_x25519_from_seed, vault_x25519_dh: wasm.vault_x25519_dh,\n vault_random_bytes: wasm.vault_random_bytes, vault_sha256: wasm.vault_sha256,\n });\n const self = this;\n this._vault = new DataVaultService({\n spaceId: sessionData.spaceId,\n crypto: vaultCrypto,\n tc: {\n kv: this._kv!,\n ensurePublicSpace: async () => {\n try {\n await self.ensurePublicSpace();\n return { ok: true as const, data: undefined };\n } catch (error) {\n return { ok: false as const, error: { code: \"STORAGE_ERROR\", message: error instanceof Error ? error.message : String(error), service: \"vault\" } };\n }\n },\n get publicKV() { return self._publicKV ?? self.tc!.publicKV; },\n readPublicSpace: <T>(host: string, spaceId: string, key: string) =>\n TinyCloud.readPublicSpace<T>(host, spaceId, key),\n makePublicSpaceId: TinyCloud.makePublicSpaceId,\n did: this.did,\n address: sessionData.address ?? this._address ?? \"\",\n chainId: sessionData.chainId ?? this._chainId,\n hosts: [this.config.host!],\n },\n });\n this._vault.initialize(this._serviceContext);\n this._serviceContext.registerService('vault', this._vault);\n\n // Initialize v2 services\n this.initializeV2Services(serviceSession);\n }\n\n /**\n * Connect a wallet to upgrade from session-only mode to wallet mode.\n *\n * This allows a user who started in session-only mode to later connect\n * a wallet and gain the ability to create their own space.\n *\n * Note: This does NOT automatically sign in. Call signIn() after connecting\n * the wallet to create your space.\n *\n * @param privateKey - The Ethereum private key (hex string, no 0x prefix)\n * @param options - Optional configuration\n * @param options.prefix - Space name prefix (defaults to \"default\")\n *\n * @example\n * ```typescript\n * // Start in session-only mode\n * const node = new TinyCloudNode({ host: \"https://node.tinycloud.xyz\" });\n * console.log(node.did); // did:key:z6Mk... (session key)\n *\n * // Later, connect a wallet\n * node.connectWallet(privateKey);\n * await node.signIn();\n * console.log(node.did); // did:pkh:eip155:1:0x... (PKH)\n * ```\n */\n connectWallet(privateKey: string, options?: { prefix?: string; sessionStorage?: ISessionStorage }): void {\n if (this.signer) {\n throw new Error(\"Wallet already connected. Cannot connect another wallet.\");\n }\n\n const prefix = options?.prefix ?? \"default\";\n const host = this.config.host!;\n\n // Create signer from private key\n if (!TinyCloudNode.nodeDefaults) {\n throw new Error(\n \"connectWallet() requires PrivateKeySigner. Use connectSigner() instead, \" +\n \"or import from '@tinycloud/node-sdk' (not '/core') for automatic Node.js defaults.\"\n );\n }\n this.signer = TinyCloudNode.nodeDefaults.createSigner(privateKey);\n\n // Create authorization handler\n this.auth = new NodeUserAuthorization({\n signer: this.signer,\n signStrategy: { type: \"auto-sign\" },\n wasmBindings: this.wasmBindings,\n sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),\n domain: this.siweDomain,\n spacePrefix: prefix,\n sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1000,\n tinycloudHosts: [host],\n autoCreateSpace: this.config.autoCreateSpace,\n enablePublicSpace: this.config.enablePublicSpace ?? true,\n spaceCreationHandler: this.config.spaceCreationHandler,\n nonce: this.config.nonce,\n siweConfig: this.config.siweConfig,\n });\n\n // Create TinyCloud instance\n this.tc = new TinyCloud(this.auth);\n\n // Update config with prefix\n this.config.prefix = prefix;\n }\n\n /**\n * Connect any ISigner to upgrade from session-only mode to wallet mode.\n *\n * Same as connectWallet() but accepts any ISigner implementation instead\n * of a raw private key string. Use this for browser wallets, hardware wallets,\n * or custom signing backends.\n *\n * Note: This does NOT automatically sign in. Call signIn() after connecting.\n *\n * @param signer - Any ISigner implementation\n * @param options - Optional configuration\n * @param options.prefix - Space name prefix (defaults to \"default\")\n */\n connectSigner(signer: ISigner, options?: { prefix?: string; sessionStorage?: ISessionStorage }): void {\n if (this.signer) {\n throw new Error(\"Signer already connected. Cannot connect another signer.\");\n }\n\n const prefix = options?.prefix ?? \"default\";\n const host = this.config.host!;\n\n this.signer = signer;\n\n this.auth = new NodeUserAuthorization({\n signer: this.signer,\n signStrategy: { type: \"auto-sign\" },\n wasmBindings: this.wasmBindings,\n sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),\n domain: this.siweDomain,\n spacePrefix: prefix,\n sessionExpirationMs: this.config.sessionExpirationMs ?? 60 * 60 * 1000,\n tinycloudHosts: [host],\n autoCreateSpace: this.config.autoCreateSpace,\n enablePublicSpace: this.config.enablePublicSpace ?? true,\n spaceCreationHandler: this.config.spaceCreationHandler,\n nonce: this.config.nonce,\n siweConfig: this.config.siweConfig,\n });\n\n this.tc = new TinyCloud(this.auth);\n this.config.prefix = prefix;\n }\n\n /**\n * Initialize the service context and KV service after sign-in.\n * @internal\n */\n private initializeServices(): void {\n const session = this.auth?.tinyCloudSession;\n if (!session) {\n return;\n }\n\n // Initialize TinyCloud core services (needed for publicKV, ensurePublicSpace)\n this.tc!.initializeServices(this.wasmBindings.invoke, [this.config.host!]);\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n hosts: [this.config.host!],\n });\n\n // Create and register KV service\n this._kv = new KVService({});\n this._kv.initialize(this._serviceContext);\n this._serviceContext.registerService('kv', this._kv);\n\n // Create and register SQL service (if supported)\n const features = this.nodeFeatures;\n if (features.length === 0 || features.includes(\"sql\")) {\n this._sql = new SQLService({});\n this._sql.initialize(this._serviceContext);\n this._serviceContext.registerService('sql', this._sql);\n }\n\n // Create and register DuckDB service (if supported)\n if (features.length === 0 || features.includes(\"duckdb\")) {\n this._duckdb = new DuckDbService({});\n this._duckdb.initialize(this._serviceContext);\n this._serviceContext.registerService('duckdb', this._duckdb);\n }\n\n // Set session on context\n const serviceSession: ServiceSession = {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: session.spaceId,\n verificationMethod: session.verificationMethod,\n jwk: session.jwk,\n };\n this._serviceContext.setSession(serviceSession);\n (this.tc!.serviceContext as ServiceContext).setSession(serviceSession);\n\n // Create and register Vault service\n const wasm = this.wasmBindings;\n const vaultCrypto = createVaultCrypto({\n vault_encrypt: wasm.vault_encrypt, vault_decrypt: wasm.vault_decrypt, vault_derive_key: wasm.vault_derive_key,\n vault_x25519_from_seed: wasm.vault_x25519_from_seed, vault_x25519_dh: wasm.vault_x25519_dh,\n vault_random_bytes: wasm.vault_random_bytes, vault_sha256: wasm.vault_sha256,\n });\n const self = this;\n this._vault = new DataVaultService({\n spaceId: session.spaceId,\n crypto: vaultCrypto,\n tc: {\n kv: this._kv!,\n ensurePublicSpace: async () => {\n try {\n await self.ensurePublicSpace();\n return { ok: true as const, data: undefined };\n } catch (error) {\n return { ok: false as const, error: { code: \"STORAGE_ERROR\", message: error instanceof Error ? error.message : String(error), service: \"vault\" } };\n }\n },\n get publicKV() { return self._publicKV ?? self.tc!.publicKV; },\n readPublicSpace: <T>(host: string, spaceId: string, key: string) =>\n TinyCloud.readPublicSpace<T>(host, spaceId, key),\n makePublicSpaceId: TinyCloud.makePublicSpaceId,\n did: this.did,\n address: this._address!,\n chainId: this._chainId,\n hosts: [this.config.host!],\n },\n });\n this._vault.initialize(this._serviceContext);\n this._serviceContext.registerService('vault', this._vault);\n\n // Initialize v2 services\n this.initializeV2Services(serviceSession);\n }\n\n /**\n * Initialize the v2 delegation system services.\n * @internal\n */\n private initializeV2Services(serviceSession: ServiceSession): void {\n // Initialize CapabilityKeyRegistry\n this._capabilityRegistry = new CapabilityKeyRegistry();\n\n const tcSession = this.auth?.tinyCloudSession;\n // Register the session key with its capabilities\n if (tcSession && this._address) {\n const sessionKey: KeyInfo = {\n id: tcSession.sessionKey,\n did: tcSession.verificationMethod,\n type: \"session\",\n // Cast jwk from generic object to JWK - we know it has the required structure\n jwk: tcSession.jwk as JWK,\n priority: 0, // Session keys have highest priority\n };\n\n // Create root delegation for the session\n const rootDelegation: Delegation = {\n cid: tcSession.delegationCid,\n delegateDID: tcSession.verificationMethod,\n spaceId: tcSession.spaceId,\n path: \"\", // Root access\n actions: [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n \"tinycloud.sql/read\",\n \"tinycloud.sql/write\",\n \"tinycloud.sql/admin\",\n \"tinycloud.sql/*\",\n \"tinycloud.duckdb/read\",\n \"tinycloud.duckdb/write\",\n \"tinycloud.duckdb/admin\",\n \"tinycloud.duckdb/describe\",\n \"tinycloud.duckdb/export\",\n \"tinycloud.duckdb/import\",\n \"tinycloud.duckdb/*\",\n ],\n expiry: this.getSessionExpiry(),\n isRevoked: false,\n allowSubDelegation: true,\n };\n\n // Register root delegations\n const delegations = [rootDelegation];\n\n // If session includes additional spaces (e.g., public), register delegations for those too\n if (tcSession.spaces) {\n for (const [spaceName, spaceId] of Object.entries(tcSession.spaces)) {\n delegations.push({\n cid: tcSession.delegationCid,\n delegateDID: tcSession.verificationMethod,\n spaceId,\n path: \"\",\n actions: [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n \"tinycloud.sql/read\",\n \"tinycloud.sql/write\",\n \"tinycloud.sql/admin\",\n \"tinycloud.sql/*\",\n \"tinycloud.duckdb/read\",\n \"tinycloud.duckdb/write\",\n \"tinycloud.duckdb/admin\",\n \"tinycloud.duckdb/describe\",\n \"tinycloud.duckdb/export\",\n \"tinycloud.duckdb/import\",\n \"tinycloud.duckdb/*\",\n ],\n expiry: this.getSessionExpiry(),\n isRevoked: false,\n allowSubDelegation: true,\n });\n }\n }\n\n this._capabilityRegistry.registerKey(sessionKey, delegations);\n }\n\n // Initialize DelegationManager\n this._delegationManager = new DelegationManager({\n hosts: [this.config.host!],\n session: serviceSession,\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n });\n\n // Initialize SpaceService\n this._spaceService = new SpaceService({\n hosts: [this.config.host!],\n session: serviceSession,\n invoke: this.wasmBindings.invoke,\n fetch: globalThis.fetch.bind(globalThis),\n capabilityRegistry: this._capabilityRegistry,\n userDid: this.did,\n createKVService: (spaceId: string) => {\n // Create a new KV service scoped to the specified space\n const kvService = new KVService({});\n if (this._serviceContext) {\n const spaceScopedContext = new ServiceContext({\n invoke: this._serviceContext.invoke,\n fetch: this._serviceContext.fetch,\n hosts: this._serviceContext.hosts,\n });\n const session = this._serviceContext.session;\n if (session) {\n spaceScopedContext.setSession({ ...session, spaceId });\n }\n kvService.initialize(spaceScopedContext);\n }\n return kvService;\n },\n // Enable space.delegations.create() via SIWE-based delegation\n createDelegation: async (params) => {\n try {\n // Use the existing createDelegation method which calls /delegate with SIWE\n const portableDelegation = await this.createDelegation({\n delegateDID: params.delegateDID,\n path: params.path,\n actions: params.actions,\n disableSubDelegation: params.disableSubDelegation,\n expiryMs: params.expiry\n ? params.expiry.getTime() - Date.now()\n : undefined,\n });\n\n // Convert PortableDelegation to Delegation type for Space API\n const delegation: Delegation = {\n cid: portableDelegation.cid,\n delegateDID: portableDelegation.delegateDID,\n delegatorDID: this.did,\n spaceId: portableDelegation.spaceId,\n path: portableDelegation.path,\n actions: portableDelegation.actions,\n expiry: portableDelegation.expiry,\n isRevoked: false,\n allowSubDelegation: !portableDelegation.disableSubDelegation,\n createdAt: new Date(),\n authHeader: portableDelegation.delegationHeader.Authorization,\n };\n\n return { ok: true, data: delegation };\n } catch (error) {\n return {\n ok: false,\n error: {\n code: \"CREATION_FAILED\",\n message: error instanceof Error ? error.message : String(error),\n service: \"delegation\",\n },\n };\n }\n },\n });\n\n // Update SharingService with full capabilities (session + createDelegation)\n // SharingService was initialized in constructor for receive-only access\n this._sharingService.updateConfig({\n session: serviceSession,\n delegationManager: this._delegationManager,\n sessionExpiry: this.getSessionExpiry(),\n // WASM-based delegation creation (preferred - no server roundtrip)\n createDelegationWasm: (params) => this.createDelegationWrapper(params),\n // Root delegation for long-lived share links (bypasses session expiry)\n // In node-sdk we have direct signer access, so no popup needed\n onRootDelegationNeeded: this.signer\n ? async (params) => this.createRootDelegationForSharing(params)\n : undefined,\n });\n\n // Wire up SharingService to SpaceService for space.sharing.generate()\n this._spaceService.updateConfig({\n sharingService: this._sharingService,\n });\n }\n\n /**\n * Get the session expiry time.\n * @internal\n */\n private getSessionExpiry(): Date {\n // Default to 1 hour from now if not explicitly set\n const expirationMs = this.config.sessionExpirationMs ?? 60 * 60 * 1000;\n return new Date(Date.now() + expirationMs);\n }\n\n /**\n * Wrapper for the WASM createDelegation function.\n * Adapts the WASM interface to what SharingService expects.\n * @internal\n */\n private createDelegationWrapper(params: CreateDelegationWasmParams): CreateDelegationWasmResult {\n // Convert ServiceSession to the format WASM expects\n const wasmSession = {\n delegationHeader: params.session.delegationHeader,\n delegationCid: params.session.delegationCid,\n jwk: params.session.jwk,\n spaceId: params.session.spaceId,\n verificationMethod: params.session.verificationMethod,\n };\n\n const result = this.wasmBindings.createDelegation(\n wasmSession,\n params.delegateDID,\n params.spaceId,\n params.path,\n params.actions,\n params.expirationSecs,\n params.notBeforeSecs\n );\n\n return {\n delegation: result.delegation,\n cid: result.cid,\n delegateDID: result.delegateDid,\n path: result.path,\n actions: result.actions,\n expiry: new Date(result.expiry * 1000),\n };\n }\n\n /**\n * Create a direct root delegation from the wallet to a share key.\n * This bypasses the session delegation chain, allowing share links\n * with expiry longer than the current session.\n * @internal\n */\n private async createRootDelegationForSharing(params: {\n shareKeyDID: string;\n spaceId: string;\n path: string;\n actions: string[];\n requestedExpiry: Date;\n }): Promise<Delegation | undefined> {\n if (!this.signer) {\n return undefined;\n }\n\n const session = this.auth?.tinyCloudSession;\n if (!session) {\n return undefined;\n }\n\n try {\n const host = this.config.host!;\n const now = new Date();\n\n // Build abilities for the share key\n const abilities: Record<string, Record<string, string[]>> = {\n kv: {\n [params.path]: params.actions,\n },\n };\n\n // Prepare a direct delegation to the share key (no parents = root delegation)\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(session.address),\n chainId: session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: params.requestedExpiry.toISOString(),\n spaceId: params.spaceId,\n delegateUri: params.shareKeyDID,\n });\n\n // Sign with the signer (no popup in node-sdk)\n const signature = await this.signer.signMessage(prepared.siwe);\n\n const delegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate the delegation with the server\n const activateResult = await activateSessionWithHost(\n host,\n delegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n return undefined;\n }\n\n return {\n cid: delegationSession.delegationCid,\n delegateDID: params.shareKeyDID,\n delegatorDID: `did:pkh:eip155:${session.chainId}:${session.address}`,\n spaceId: params.spaceId,\n path: params.path,\n actions: params.actions,\n expiry: params.requestedExpiry,\n isRevoked: false,\n allowSubDelegation: true,\n createdAt: now,\n authHeader: delegationSession.delegationHeader.Authorization,\n };\n } catch {\n return undefined;\n }\n }\n\n /**\n * Track a received delegation in the capability registry.\n * @internal\n */\n private trackReceivedDelegation(delegation: PortableDelegation, jwk: JWK): void {\n if (!this._capabilityRegistry) {\n return;\n }\n\n const keyInfo: KeyInfo = {\n id: `received:${delegation.cid}`,\n did: this.sessionDid,\n type: \"ingested\",\n jwk,\n priority: 2,\n };\n\n // Convert PortableDelegation to Delegation type\n const delegationRecord: Delegation = {\n cid: delegation.cid,\n delegateDID: delegation.delegateDID,\n spaceId: delegation.spaceId,\n path: delegation.path,\n actions: delegation.actions,\n expiry: delegation.expiry,\n isRevoked: false,\n allowSubDelegation: !delegation.disableSubDelegation,\n };\n\n this._capabilityRegistry.ingestKey(keyInfo, delegationRecord);\n }\n\n /**\n * Key-value storage operations on this user's space.\n */\n get kv(): IKVService {\n if (!this._kv) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._kv;\n }\n\n /**\n * SQL database operations on this user's space.\n */\n get sql(): ISQLService {\n if (!this._sql) {\n const features = this.nodeFeatures;\n if (features.length > 0 && !features.includes(\"sql\")) {\n throw new UnsupportedFeatureError(\"sql\", this.config.host!, features);\n }\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._sql;\n }\n\n /**\n * DuckDB database operations on this user's space.\n */\n get duckdb(): IDuckDbService {\n if (!this._duckdb) {\n const features = this.nodeFeatures;\n if (features.length > 0 && !features.includes(\"duckdb\")) {\n throw new UnsupportedFeatureError(\"duckdb\", this.config.host!, features);\n }\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._duckdb;\n }\n\n /**\n * Data Vault operations - client-side encrypted KV storage.\n * Call `vault.unlock(signer)` after signIn() to derive encryption keys.\n */\n get vault(): IDataVaultService {\n if (!this._vault) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._vault;\n }\n\n // ===========================================================================\n // v2 Service Accessors\n // ===========================================================================\n\n /**\n * Get the CapabilityKeyRegistry for managing keys and their capabilities.\n *\n * The registry tracks keys (session, main, ingested) and their associated\n * delegations, enabling automatic key selection for operations.\n *\n * @example\n * ```typescript\n * const registry = alice.capabilityRegistry;\n *\n * // Get the best key for an operation\n * const key = registry.getKeyForCapability(\n * \"tinycloud://my-space/kv/data\",\n * \"tinycloud.kv/get\"\n * );\n *\n * // List all capabilities\n * const capabilities = registry.getAllCapabilities();\n * ```\n */\n get capabilityRegistry(): ICapabilityKeyRegistry {\n if (!this._capabilityRegistry) {\n throw new Error(\"CapabilityKeyRegistry not initialized.\");\n }\n return this._capabilityRegistry;\n }\n\n /**\n * Access received delegations (recipient view).\n *\n * Use this to see what delegations have been received via useDelegation().\n *\n * @example\n * ```typescript\n * // List all received delegations\n * const received = bob.delegations.list();\n * console.log(\"I have access to:\", received.length, \"spaces\");\n *\n * // Get a specific delegation by CID\n * const delegation = bob.delegations.get(cid);\n * ```\n */\n get delegations(): {\n /** List all received delegations */\n list: () => Delegation[];\n /** Get a delegation by CID */\n get: (cid: string) => Delegation | undefined;\n } {\n const registry = this._capabilityRegistry;\n if (!registry) {\n return {\n list: () => [],\n get: () => undefined,\n };\n }\n\n return {\n list: () => registry.getAllCapabilities().map((entry) => entry.delegation),\n get: (cid: string) => {\n const capabilities = registry.getAllCapabilities();\n const entry = capabilities.find((e) => e.delegation.cid === cid);\n return entry?.delegation;\n },\n };\n }\n\n /**\n * Get the DelegationManager for delegation CRUD operations.\n *\n * This is the v2 delegation service providing a cleaner API than\n * the legacy createDelegation/useDelegation methods.\n *\n * @example\n * ```typescript\n * const delegations = alice.delegationManager;\n *\n * // Create a delegation\n * const result = await delegations.create({\n * delegateDID: bob.did,\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours\n * });\n *\n * // List delegations\n * const listResult = await delegations.list();\n *\n * // Revoke a delegation\n * await delegations.revoke(delegationCid);\n * ```\n */\n get delegationManager(): DelegationManager {\n if (!this._delegationManager) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._delegationManager;\n }\n\n /**\n * Get the SpaceService for managing spaces.\n *\n * The SpaceService provides access to owned and delegated spaces,\n * including space creation, listing, and scoped operations.\n *\n * @example\n * ```typescript\n * const spaces = alice.spaces;\n *\n * // List all accessible spaces\n * const result = await spaces.list();\n *\n * // Create a new space\n * const createResult = await spaces.create('photos');\n *\n * // Get a space object for operations\n * const mySpace = spaces.get('default');\n * await mySpace.kv.put('key', 'value');\n *\n * // Check if a space exists\n * const exists = await spaces.exists('photos');\n * ```\n */\n get spaces(): ISpaceService {\n if (!this._spaceService) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this._spaceService;\n }\n\n /**\n * Alias for `spaces` - get the SpaceService.\n * @see spaces\n */\n get spaceService(): ISpaceService {\n return this.spaces;\n }\n\n /**\n * Get the SharingService for creating and receiving v2 sharing links.\n *\n * The SharingService creates sharing links with embedded private keys,\n * allowing recipients to exercise delegations without prior session setup.\n *\n * @example\n * ```typescript\n * const sharing = alice.sharing;\n *\n * // Generate a sharing link\n * const result = await sharing.generate({\n * path: \"/kv/documents/report.pdf\",\n * actions: [\"tinycloud.kv/get\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000),\n * });\n *\n * if (result.ok) {\n * console.log(\"Share URL:\", result.data.url);\n * // Send the URL to the recipient\n * }\n *\n * // Receive a sharing link\n * const receiveResult = await sharing.receive(shareUrl);\n * if (receiveResult.ok) {\n * // Use the pre-configured KV service\n * const data = await receiveResult.data.kv.get(\"report.pdf\");\n * }\n * ```\n */\n get sharing(): ISharingService {\n // SharingService is initialized in constructor for receive-only access\n // Full capabilities (generate) are added after signIn()\n return this._sharingService;\n }\n\n /**\n * Alias for `sharing` - get the SharingService.\n * @see sharing\n */\n get sharingService(): ISharingService {\n return this.sharing;\n }\n\n // ===========================================================================\n // Public Space Methods\n // ===========================================================================\n\n /**\n * Ensure the user's public space exists and is accessible.\n * Creates the space and activates a session delegation for it.\n * This is the trigger for lazy public space creation — call it\n * before writing to spaces.get('public').kv.\n */\n async ensurePublicSpace() {\n if (!this.auth || !this.session || !this.signer) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n const publicSpaceId = this.session.spaces?.public;\n if (!publicSpaceId) {\n throw new Error(\"Public space not enabled. Set enablePublicSpace: true in config.\");\n }\n\n // Create the public space on the server (host SIWE)\n await (this.auth as NodeUserAuthorization).hostPublicSpace(publicSpaceId);\n\n // Create a session delegation for the public space using the session key JWK.\n // This mirrors the primary session flow (prepareSession with jwk), ensuring\n // the delegation targets the session key — not the PKH DID — so that\n // invoke() requests signed by the session key are properly authorized.\n const kvActions = [\n \"tinycloud.kv/put\",\n \"tinycloud.kv/get\",\n \"tinycloud.kv/del\",\n \"tinycloud.kv/list\",\n \"tinycloud.kv/metadata\",\n ];\n const abilities = { kv: { \"\": kvActions } };\n const now = new Date();\n const expiryMs = 60 * 60 * 1000;\n const expirationTime = new Date(now.getTime() + expiryMs);\n\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(this.session.address),\n chainId: this.session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: publicSpaceId,\n jwk: this.session.jwk,\n parents: [this.session.delegationCid],\n });\n\n const signature = await this.signer.signMessage(prepared.siwe);\n\n const delegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n const activateResult = await activateSessionWithHost(\n this.config.host!,\n delegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate public space delegation: ${activateResult.error}`);\n }\n\n // Register the delegation in the capability registry so\n // spaces.get('public').kv operations are authorized\n if (this._capabilityRegistry && this.session) {\n const sessionKey: KeyInfo = {\n id: this.session.sessionKey,\n did: this.session.verificationMethod,\n type: \"session\",\n jwk: this.session.jwk as JWK,\n priority: 0,\n };\n this._capabilityRegistry.registerKey(sessionKey, [{\n cid: delegationSession.delegationCid,\n delegateDID: this.session.verificationMethod,\n spaceId: publicSpaceId,\n path: \"\",\n actions: kvActions,\n expiry: expirationTime,\n isRevoked: false,\n allowSubDelegation: true,\n }]);\n }\n\n // Cache a properly authorized public KV service using the new delegation\n if (this._serviceContext) {\n const publicKV = new KVService({ prefix: \"\" });\n const publicContext = new ServiceContext({\n invoke: this.wasmBindings.invoke,\n fetch: this._serviceContext.fetch,\n hosts: this._serviceContext.hosts,\n });\n publicContext.setSession({\n delegationHeader: delegationSession.delegationHeader,\n delegationCid: delegationSession.delegationCid,\n spaceId: publicSpaceId,\n verificationMethod: this.session.verificationMethod,\n jwk: this.session.jwk,\n });\n publicKV.initialize(publicContext);\n this._publicKV = publicKV;\n }\n }\n\n /**\n * Get a KVService scoped to the user's own public space.\n * Writes require authentication (owner/delegate).\n */\n get publicKV(): IKVService {\n if (this._publicKV) {\n return this._publicKV;\n }\n if (!this.tc) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n return this.tc.publicKV;\n }\n\n // ===========================================================================\n // v2 Delegation Convenience Methods\n // ===========================================================================\n\n /**\n * Create a delegation using the v2 DelegationManager.\n *\n * This is a convenience method that wraps DelegationManager.create().\n * For more control, use `this.delegationManager` directly.\n *\n * @param params - Delegation parameters\n * @returns Result containing the created Delegation\n *\n * @example\n * ```typescript\n * const result = await alice.delegate({\n * delegateDID: bob.did,\n * path: \"shared/\",\n * actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\"],\n * expiry: new Date(Date.now() + 24 * 60 * 60 * 1000),\n * });\n *\n * if (result.ok) {\n * console.log(\"Delegation created:\", result.data.cid);\n * }\n * ```\n */\n async delegate(params: CreateDelegationParams): Promise<DelegationResult<Delegation>> {\n return this.delegationManager.create(params);\n }\n\n /**\n * Revoke a delegation using the v2 DelegationManager.\n *\n * @param cid - The CID of the delegation to revoke\n * @returns Result indicating success or failure\n */\n async revokeDelegation(cid: string): Promise<DelegationResult<void>> {\n return this.delegationManager.revoke(cid);\n }\n\n /**\n * List all delegations for the current session's space.\n *\n * @returns Result containing an array of Delegations\n */\n async listDelegations(): Promise<DelegationResult<Delegation[]>> {\n return this.delegationManager.list();\n }\n\n /**\n * Check if the current session has permission for a path and action.\n *\n * @param path - The resource path to check\n * @param action - The action to check (e.g., \"tinycloud.kv/get\")\n * @returns Result containing boolean permission status\n */\n async checkPermission(path: string, action: string): Promise<DelegationResult<boolean>> {\n return this.delegationManager.checkPermission(path, action);\n }\n\n /**\n * Create a delegation from this user to another user.\n *\n * The delegation grants the recipient access to a specific path and actions\n * within this user's space.\n *\n * @param params - Delegation parameters\n * @returns A portable delegation that can be sent to the recipient\n */\n async createDelegation(params: {\n /** Path within the space to delegate access to */\n path: string;\n /** Actions to allow (e.g., [\"tinycloud.kv/get\", \"tinycloud.kv/put\"]) */\n actions: string[];\n /** DID of the recipient (from their TinyCloudNode.did) */\n delegateDID: string;\n /** Whether to prevent the recipient from creating sub-delegations (default: false) */\n disableSubDelegation?: boolean;\n /** Expiration time in milliseconds from now (default: 1 hour) */\n expiryMs?: number;\n /** Override space ID (for creating delegations to non-primary spaces like public) */\n spaceIdOverride?: string;\n /** Include a companion delegation for the user's public space (default: true) */\n includePublicSpace?: boolean;\n }): Promise<PortableDelegation> {\n if (!this.signer) {\n throw new Error(\"Cannot createDelegation() in session-only mode. Requires wallet mode.\");\n }\n const session = this.auth?.tinyCloudSession;\n if (!session) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n // Resolve ENS names to PKH DIDs\n if (params.delegateDID.endsWith('.eth') && this.config.ensResolver) {\n const address = await this.config.ensResolver.resolveAddress(params.delegateDID);\n if (!address) throw new Error(`Could not resolve ENS name: ${params.delegateDID}`);\n params = { ...params, delegateDID: `did:pkh:eip155:1:${address}` };\n }\n\n // Build abilities for the delegation\n const abilities: Record<string, Record<string, string[]>> = {};\n const kvActions = params.actions.filter(a => a.startsWith(\"tinycloud.kv/\"));\n const sqlActions = params.actions.filter(a => a.startsWith(\"tinycloud.sql/\"));\n const duckdbActions = params.actions.filter(a => a.startsWith(\"tinycloud.duckdb/\"));\n if (kvActions.length > 0) {\n abilities.kv = { [params.path]: kvActions };\n }\n if (sqlActions.length > 0) {\n abilities.sql = { [params.path]: sqlActions };\n }\n if (duckdbActions.length > 0) {\n abilities.duckdb = { [params.path]: duckdbActions };\n }\n\n const now = new Date();\n const expiryMs = params.expiryMs ?? 60 * 60 * 1000; // Default 1 hour\n const expirationTime = new Date(now.getTime() + expiryMs);\n\n // Prepare the delegation session with:\n // - delegateUri: target the recipient's DID directly (for user-to-user delegation)\n // - parents: reference our session CID for chain validation\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(session.address),\n chainId: session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: params.spaceIdOverride ?? session.spaceId,\n delegateUri: params.delegateDID,\n parents: [session.delegationCid],\n });\n\n // Sign the SIWE message with this user's signer\n const signature = await this.signer.signMessage(prepared.siwe);\n\n // Complete the session setup\n const delegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate the delegation with the server\n const activateResult = await activateSessionWithHost(\n this.config.host!,\n delegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate delegation: ${activateResult.error}`);\n }\n\n const result: PortableDelegation = {\n cid: delegationSession.delegationCid,\n delegationHeader: delegationSession.delegationHeader,\n spaceId: params.spaceIdOverride ?? session.spaceId,\n path: params.path,\n actions: params.actions,\n disableSubDelegation: params.disableSubDelegation ?? false,\n expiry: expirationTime,\n delegateDID: params.delegateDID,\n ownerAddress: session.address,\n chainId: session.chainId,\n host: this.config.host,\n };\n\n // Auto-create public-space delegation for vault key publishing\n const hasKvActions = params.actions.some(a => a.startsWith(\"tinycloud.kv/\"));\n if (hasKvActions && params.includePublicSpace !== false) {\n const publicSpaceId = makePublicSpaceId(\n this.wasmBindings.ensureEip55(session.address), session.chainId\n );\n const publicAbilities: Record<string, Record<string, string[]>> = {\n kv: { \"\": [\"tinycloud.kv/get\", \"tinycloud.kv/put\", \"tinycloud.kv/metadata\"] },\n };\n const publicPrepared = this.wasmBindings.prepareSession({\n abilities: publicAbilities,\n address: this.wasmBindings.ensureEip55(session.address),\n chainId: session.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: publicSpaceId,\n delegateUri: params.delegateDID,\n parents: [session.delegationCid],\n });\n const publicSignature = await this.signer.signMessage(publicPrepared.siwe);\n const publicSession = this.wasmBindings.completeSessionSetup({\n ...publicPrepared,\n signature: publicSignature,\n });\n\n const publicActivateResult = await activateSessionWithHost(\n this.config.host!,\n publicSession.delegationHeader\n );\n\n if (publicActivateResult.success) {\n result.publicDelegation = {\n cid: publicSession.delegationCid,\n delegationHeader: publicSession.delegationHeader,\n spaceId: publicSpaceId,\n path: \"\",\n actions: [\"tinycloud.kv/get\", \"tinycloud.kv/put\", \"tinycloud.kv/metadata\"],\n disableSubDelegation: params.disableSubDelegation ?? false,\n expiry: expirationTime,\n delegateDID: params.delegateDID,\n ownerAddress: session.address,\n chainId: session.chainId,\n host: this.config.host,\n };\n }\n }\n\n return result;\n }\n\n /**\n * Use a delegation received from another user.\n *\n * This creates a new session key for this user that chains from the\n * received delegation, allowing operations on the delegator's space.\n *\n * Works in both modes:\n * - **Wallet mode**: Creates a SIWE sub-delegation from PKH to session key\n * - **Session-only mode**: Uses the delegation directly (must target session key DID)\n *\n * @param delegation - The PortableDelegation to use (from createDelegation or transport)\n * @returns A DelegatedAccess instance for performing operations\n */\n async useDelegation(delegation: PortableDelegation): Promise<DelegatedAccess> {\n const delegationHeader = delegation.delegationHeader;\n\n // Use the host from the delegation if provided, otherwise fall back to config\n const targetHost = delegation.host ?? this.config.host!;\n\n // Session-only mode: use the delegation directly\n // The delegation must target this user's session key DID\n if (this.isSessionOnly) {\n // Verify the delegation targets our session key DID\n const myDid = this.did; // In session-only mode, this is the session key DID\n if (delegation.delegateDID !== myDid) {\n throw new Error(\n `Delegation targets ${delegation.delegateDID} but this user's DID is ${myDid}. ` +\n `The delegation must target this user's DID.`\n );\n }\n\n // Create a session using the delegation directly\n // In session-only mode, we use the received delegation as-is\n const session: TinyCloudSession = {\n address: delegation.ownerAddress,\n chainId: delegation.chainId,\n sessionKey: JSON.stringify(this.sessionKeyJwk),\n spaceId: delegation.spaceId,\n delegationCid: delegation.cid,\n delegationHeader,\n verificationMethod: this.sessionDid,\n jwk: this.sessionKeyJwk as unknown as JWK,\n siwe: \"\", // Not used in session-only mode\n signature: \"\", // Not used in session-only mode\n };\n\n // Track received delegation in registry\n this.trackReceivedDelegation(delegation, this.sessionKeyJwk as unknown as JWK);\n\n return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);\n }\n\n // Wallet mode: create a SIWE sub-delegation\n const mySession = this.auth?.tinyCloudSession;\n if (!mySession) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n // Use our existing session key - the delegation targets our DID from signIn\n // We must use the same key that the delegation was created for\n const jwk = mySession.jwk;\n\n // Build abilities from the delegation\n const abilities: Record<string, Record<string, string[]>> = {};\n const kvActions = delegation.actions.filter(a => a.startsWith(\"tinycloud.kv/\"));\n const sqlActions = delegation.actions.filter(a => a.startsWith(\"tinycloud.sql/\"));\n const duckdbActions = delegation.actions.filter(a => a.startsWith(\"tinycloud.duckdb/\"));\n if (kvActions.length > 0) {\n abilities.kv = { [delegation.path]: kvActions };\n }\n if (sqlActions.length > 0) {\n abilities.sql = { [delegation.path]: sqlActions };\n }\n if (duckdbActions.length > 0) {\n abilities.duckdb = { [delegation.path]: duckdbActions };\n }\n\n const now = new Date();\n // Use delegation expiry or 1 hour, whichever is sooner\n const maxExpiry = new Date(now.getTime() + 60 * 60 * 1000);\n const expirationTime = delegation.expiry < maxExpiry ? delegation.expiry : maxExpiry;\n\n // Prepare the session with:\n // - THIS user's address (we are the invoker)\n // - The delegation owner's space (where we're accessing data)\n // - Our existing session key (must match the DID the delegation targets)\n // - Parent reference to the received delegation\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(mySession.address),\n chainId: mySession.chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: expirationTime.toISOString(),\n spaceId: delegation.spaceId,\n jwk,\n parents: [delegation.cid],\n });\n\n // Sign with THIS user's signer\n const signature = await this.signer!.signMessage(prepared.siwe);\n\n // Complete the session setup\n const invokerSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate with server\n const activateResult = await activateSessionWithHost(\n targetHost,\n invokerSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate delegated session: ${activateResult.error}`);\n }\n\n // Create TinyCloudSession for the delegated access\n const session: TinyCloudSession = {\n address: mySession.address,\n chainId: mySession.chainId,\n sessionKey: mySession.sessionKey,\n spaceId: delegation.spaceId,\n delegationCid: invokerSession.delegationCid,\n delegationHeader: invokerSession.delegationHeader,\n verificationMethod: mySession.verificationMethod,\n jwk,\n siwe: prepared.siwe,\n signature,\n };\n\n // Track received delegation in registry\n this.trackReceivedDelegation(delegation, jwk as unknown as JWK);\n\n return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);\n }\n\n /**\n * Create a sub-delegation from a received delegation.\n *\n * This allows further delegating access that was received from another user,\n * if the original delegation allows sub-delegation.\n *\n * @param parentDelegation - The delegation received from another user\n * @param params - Sub-delegation parameters (must be within parent's scope)\n * @returns A portable delegation for the sub-delegate\n */\n async createSubDelegation(\n parentDelegation: PortableDelegation,\n params: {\n /** Path within the delegated path to sub-delegate */\n path: string;\n /** Actions to allow (must be subset of parent's actions) */\n actions: string[];\n /** DID of the recipient */\n delegateDID: string;\n /** Whether to prevent the recipient from creating further sub-delegations */\n disableSubDelegation?: boolean;\n /** Expiration time in milliseconds from now (must be before parent's expiry) */\n expiryMs?: number;\n }\n ): Promise<PortableDelegation> {\n if (!this.signer) {\n throw new Error(\"Cannot createSubDelegation() in session-only mode. Requires wallet mode.\");\n }\n if (!this._address) {\n throw new Error(\"Not signed in. Call signIn() first.\");\n }\n\n // Validate sub-delegation is allowed\n if (parentDelegation.disableSubDelegation) {\n throw new Error(\"Parent delegation does not allow sub-delegation\");\n }\n\n // Validate path is within parent's path\n if (!params.path.startsWith(parentDelegation.path)) {\n throw new Error(\n `Sub-delegation path \"${params.path}\" must be within parent path \"${parentDelegation.path}\"`\n );\n }\n\n // Validate actions are subset of parent's actions\n const parentActions = new Set(parentDelegation.actions);\n for (const action of params.actions) {\n if (!parentActions.has(action)) {\n throw new Error(\n `Sub-delegation action \"${action}\" is not in parent's actions: ${parentDelegation.actions.join(\", \")}`\n );\n }\n }\n\n // Calculate expiry - cap at parent's expiry\n const now = new Date();\n const expiryMs = params.expiryMs ?? 60 * 60 * 1000;\n const requestedExpiry = new Date(now.getTime() + expiryMs);\n // Sub-delegation cannot outlive parent, so cap at parent's expiry\n const actualExpiry =\n requestedExpiry > parentDelegation.expiry ? parentDelegation.expiry : requestedExpiry;\n\n // Build abilities for the sub-delegation\n const abilities: Record<string, Record<string, string[]>> = {};\n const kvActions = params.actions.filter(a => a.startsWith(\"tinycloud.kv/\"));\n const sqlActions = params.actions.filter(a => a.startsWith(\"tinycloud.sql/\"));\n const duckdbActions = params.actions.filter(a => a.startsWith(\"tinycloud.duckdb/\"));\n if (kvActions.length > 0) {\n abilities.kv = { [params.path]: kvActions };\n }\n if (sqlActions.length > 0) {\n abilities.sql = { [params.path]: sqlActions };\n }\n if (duckdbActions.length > 0) {\n abilities.duckdb = { [params.path]: duckdbActions };\n }\n\n // Use parent's host or fall back to config\n const targetHost = parentDelegation.host ?? this.config.host!;\n\n // Prepare the sub-delegation session\n // Uses THIS user's address (who received the delegation and is now sub-delegating)\n // Targets the recipient's PKH DID (delegateUri)\n // References the parent delegation as the chain\n const prepared = this.wasmBindings.prepareSession({\n abilities,\n address: this.wasmBindings.ensureEip55(this._address),\n chainId: this._chainId,\n domain: this.siweDomain,\n issuedAt: now.toISOString(),\n expirationTime: actualExpiry.toISOString(),\n spaceId: parentDelegation.spaceId,\n delegateUri: params.delegateDID,\n parents: [parentDelegation.cid],\n });\n\n // Sign with THIS user's signer\n const signature = await this.signer.signMessage(prepared.siwe);\n\n // Complete the session setup\n const subDelegationSession = this.wasmBindings.completeSessionSetup({\n ...prepared,\n signature,\n });\n\n // Activate the sub-delegation with the server\n const activateResult = await activateSessionWithHost(\n targetHost,\n subDelegationSession.delegationHeader\n );\n\n if (!activateResult.success) {\n throw new Error(`Failed to activate sub-delegation: ${activateResult.error}`);\n }\n\n // Return the portable sub-delegation\n return {\n cid: subDelegationSession.delegationCid,\n delegationHeader: subDelegationSession.delegationHeader,\n spaceId: parentDelegation.spaceId,\n path: params.path,\n actions: params.actions,\n disableSubDelegation: params.disableSubDelegation ?? false,\n expiry: actualExpiry,\n delegateDID: params.delegateDID,\n ownerAddress: parentDelegation.ownerAddress!,\n chainId: parentDelegation.chainId!,\n host: targetHost,\n };\n }\n}\n","import {\n TinyCloudSession,\n KVService,\n IKVService,\n SQLService,\n ISQLService,\n DuckDbService,\n IDuckDbService,\n ServiceSession,\n ServiceContext,\n} from \"@tinycloud/sdk-core\";\nimport type { InvokeFunction } from \"@tinycloud/sdk-services\";\nimport { PortableDelegation } from \"./delegation\";\n\n/**\n * Provides access to a space via a received delegation.\n *\n * This is returned by TinyCloudNode.useDelegation() and provides\n * KV operations on the delegated space.\n */\nexport class DelegatedAccess {\n private session: TinyCloudSession;\n private _delegation: PortableDelegation;\n private host: string;\n private _serviceContext: ServiceContext;\n private _kv: KVService;\n private _sql: SQLService;\n private _duckdb: DuckDbService;\n\n constructor(\n session: TinyCloudSession,\n delegation: PortableDelegation,\n host: string,\n invoke: InvokeFunction,\n ) {\n this.session = session;\n this._delegation = delegation;\n this.host = host;\n\n // Create service context\n this._serviceContext = new ServiceContext({\n invoke,\n fetch: globalThis.fetch.bind(globalThis),\n hosts: [host],\n });\n\n // Create and initialize KV service with path prefix from delegation\n // Strip trailing slash to avoid double-slash in paths\n const prefix = this._delegation.path.replace(/\\/$/, '');\n this._kv = new KVService({ prefix });\n this._kv.initialize(this._serviceContext);\n this._serviceContext.registerService('kv', this._kv);\n\n // Create and initialize SQL service with same delegation context\n this._sql = new SQLService({});\n this._sql.initialize(this._serviceContext);\n this._serviceContext.registerService('sql', this._sql);\n\n // Create and initialize DuckDB service with same delegation context\n this._duckdb = new DuckDbService({});\n this._duckdb.initialize(this._serviceContext);\n this._serviceContext.registerService('duckdb', this._duckdb);\n\n // Set session on context\n const serviceSession: ServiceSession = {\n delegationHeader: session.delegationHeader,\n delegationCid: session.delegationCid,\n spaceId: session.spaceId,\n verificationMethod: session.verificationMethod,\n jwk: session.jwk,\n };\n this._serviceContext.setSession(serviceSession);\n }\n\n /**\n * Get the delegation this access was created from.\n */\n get delegation(): PortableDelegation {\n return this._delegation;\n }\n\n /**\n * The space ID this access is for.\n */\n get spaceId(): string {\n return this._delegation.spaceId;\n }\n\n /**\n * The path this access is scoped to.\n */\n get path(): string {\n return this._delegation.path;\n }\n\n /**\n * KV operations on the delegated space.\n */\n get kv(): IKVService {\n return this._kv;\n }\n\n /**\n * SQL operations on the delegated space.\n */\n get sql(): ISQLService {\n return this._sql;\n }\n\n /**\n * DuckDB operations on the delegated space.\n */\n get duckdb(): IDuckDbService {\n return this._duckdb;\n }\n}\n","/**\n * WasmKeyProvider - KeyProvider implementation using WASM session manager.\n *\n * This provider wraps the SessionManager from node-sdk-wasm to provide\n * cryptographic key operations required by the SharingService.\n *\n * @packageDocumentation\n */\n\nimport type { KeyProvider, JWK, ISessionManager } from \"@tinycloud/sdk-core\";\n\n/**\n * Extended session manager with optional key listing support.\n * The base ISessionManager doesn't include listSessionKeys(),\n * but concrete implementations (e.g., TCWSessionManager) may provide it.\n */\ninterface SessionManagerWithListing extends ISessionManager {\n listSessionKeys?(): string[];\n}\n\n/**\n * Configuration for WasmKeyProvider.\n */\nexport interface WasmKeyProviderConfig {\n /**\n * The WASM session manager instance.\n * Must be created before constructing the KeyProvider.\n */\n sessionManager: SessionManagerWithListing;\n}\n\n/**\n * KeyProvider implementation that wraps the WASM session manager.\n *\n * This allows the SharingService to create new session keys for sharing links\n * using the same cryptographic operations as the main session management.\n *\n * @example\n * ```typescript\n * // sessionManager from wasmBindings.createSessionManager()\n * import { WasmKeyProvider } from \"@tinycloud/node-sdk\";\n *\n * const sessionManager = new SessionManager();\n * const keyProvider = new WasmKeyProvider({ sessionManager });\n *\n * // Create a session key for a sharing link\n * const keyId = await keyProvider.createSessionKey(\"share:abc123\");\n * const jwk = keyProvider.getJWK(keyId);\n * const did = await keyProvider.getDID(keyId);\n * ```\n */\nexport class WasmKeyProvider implements KeyProvider {\n private sessionManager: SessionManagerWithListing;\n\n /**\n * Create a new WasmKeyProvider.\n *\n * @param config - Configuration with the WASM session manager\n */\n constructor(config: WasmKeyProviderConfig) {\n this.sessionManager = config.sessionManager;\n }\n\n /**\n * Generate a new session key with the given name.\n *\n * This creates a new Ed25519 key pair in the WASM session manager.\n * The key can then be used for signing delegations in sharing links.\n *\n * @param name - A unique name/ID for the key (e.g., \"share:timestamp:random\")\n * @returns The key ID (same as the name provided)\n */\n async createSessionKey(name: string): Promise<string> {\n // The WASM session manager's createSessionKey returns the key_id\n // and stores the key internally\n return this.sessionManager.createSessionKey(name);\n }\n\n /**\n * Get the JWK (JSON Web Key) for a key.\n *\n * Returns the full JWK including the private key (d parameter),\n * which is required for signing and for embedding in sharing links.\n *\n * @param keyId - The key ID to retrieve\n * @returns The JWK object with public and private key components\n * @throws Error if the key is not found\n */\n getJWK(keyId: string): JWK {\n // The WASM session manager returns the JWK as a JSON string\n const jwkJson = this.sessionManager.jwk(keyId);\n if (!jwkJson) {\n throw new Error(`Key not found: ${keyId}`);\n }\n // Parse the JSON string to get the JWK object\n return JSON.parse(jwkJson) as JWK;\n }\n\n /**\n * Get the DID (Decentralized Identifier) for a key.\n *\n * Returns the did:key format DID derived from the key's public key.\n * This DID can be used as the delegatee in delegations.\n *\n * @param keyId - The key ID to retrieve\n * @returns The DID in did:key format (e.g., \"did:key:z6Mk...\")\n */\n async getDID(keyId: string): Promise<string> {\n // The WASM session manager has a synchronous getDID method\n return this.sessionManager.getDID(keyId);\n }\n\n /**\n * List all session keys currently held by the provider.\n *\n * @returns Array of key IDs\n */\n listKeys(): string[] {\n const keys = this.sessionManager.listSessionKeys?.();\n return Array.isArray(keys) ? keys : [];\n }\n\n /**\n * Check if a key exists in the provider.\n *\n * @param keyId - The key ID to check\n * @returns True if the key exists\n */\n hasKey(keyId: string): boolean {\n const jwk = this.sessionManager.jwk(keyId);\n return jwk !== undefined;\n }\n}\n\n/**\n * Create a new WasmKeyProvider instance.\n *\n * @param sessionManager - The WASM session manager\n * @returns A new WasmKeyProvider instance\n */\nexport function createWasmKeyProvider(sessionManager: SessionManagerWithListing): WasmKeyProvider {\n return new WasmKeyProvider({ sessionManager });\n}\n","import { Delegation } from \"@tinycloud/sdk-core\";\n\n/**\n * A portable delegation that can be transported between users.\n * Extends the base Delegation type with fields required for transport.\n *\n * @remarks\n * PortableDelegation adds transport fields to Delegation:\n * - `delegationHeader`: Structured authorization header for API calls\n * - `ownerAddress`: Space owner's address for session creation\n * - `chainId`: Chain ID for session creation\n * - `host`: Optional server URL\n */\nexport interface PortableDelegation extends Omit<Delegation, \"isRevoked\"> {\n /** The authorization header for this delegation (structured format) */\n delegationHeader: { Authorization: string };\n\n /** The address of the space owner */\n ownerAddress: string;\n\n /** The chain ID */\n chainId: number;\n\n /** TinyCloud server URL where this delegation was created */\n host?: string;\n\n /** Whether the recipient is prevented from creating sub-delegations */\n disableSubDelegation?: boolean;\n\n /** Companion delegation for the user's public space (auto-created when includePublicSpace is true) */\n publicDelegation?: PortableDelegation;\n}\n\n/**\n * Serialize a PortableDelegation for transport (e.g., over network).\n */\nexport function serializeDelegation(delegation: PortableDelegation): string {\n return JSON.stringify({\n ...delegation,\n expiry: delegation.expiry.toISOString(),\n });\n}\n\n/**\n * Deserialize a PortableDelegation from transport.\n */\nexport function deserializeDelegation(data: string): PortableDelegation {\n const parsed = JSON.parse(data);\n return {\n ...parsed,\n cid: parsed.cid,\n expiry: new Date(parsed.expiry),\n };\n}\n"],"mappings":"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","names":["import_sdk_core","import_sdk_core","import_sdk_core","import_sdk_core","config","session","import_sdk_core"]}