/** * @module registries/session * @description Unified session lifecycle manager. * * Wraps the vault + ledger modules into a single cohesive API * that manages the full memory session lifecycle: * 1. Ensure vault exists (create if needed) * 2. Open a named session * 3. Initialize a ledger for the session * 4. Write data (ring buffer + TX log) * 5. Read latest entries from ring buffer * 6. Seal the ring buffer into permanent archive pages * 7. Close ledger + session when done * * This is the RECOMMENDED way to manage agent memory. * * @category Registries * @since v0.1.0 * * @example * ```ts * const session = client.session; * * // Start a new conversation session * const ctx = await session.start("conversation-123"); * * // Write messages * await session.write(ctx, "Hello from the agent"); * await session.write(ctx, "Processing your request..."); * * // Read latest messages from ring buffer * const messages = await session.readLatest(ctx); * * // Seal into permanent archive * await session.seal(ctx); * * // Close when done * await session.close(ctx); * ``` */ import { type PublicKey, type TransactionSignature } from "@solana/web3.js"; import type { SapProgram } from "../modules/base"; /** * @interface SessionContext * @name SessionContext * @description Resolved session context with all derived PDAs. * Created by {@link SessionManager.deriveContext} or {@link SessionManager.start}. * Contains the human-readable session ID, SHA-256 hash, and all * PDA addresses needed for session operations. * @category Registries * @since v0.1.0 */ export interface SessionContext { /** Human-readable session identifier. */ readonly sessionId: string; /** SHA-256 of the session ID. */ readonly sessionHash: Uint8Array; /** Session hash as number[] for instruction args. */ readonly sessionHashArray: number[]; /** Agent PDA. */ readonly agentPda: PublicKey; /** Memory vault PDA. */ readonly vaultPda: PublicKey; /** Session ledger PDA. */ readonly sessionPda: PublicKey; /** Memory ledger PDA (unified ring buffer). */ readonly ledgerPda: PublicKey; /** Wallet public key. */ readonly wallet: PublicKey; } /** * @interface WriteResult * @name WriteResult * @description Result of writing data to a session via {@link SessionManager.write}. * Contains the transaction signature, content hash, and data size. * @category Registries * @since v0.1.0 */ export interface WriteResult { /** Transaction signature. */ readonly txSignature: TransactionSignature; /** Content hash of the written data. */ readonly contentHash: number[]; /** Data size in bytes. */ readonly dataSize: number; } /** * @interface SealResult * @name SealResult * @description Result of sealing the ring buffer into a permanent archive page * via {@link SessionManager.seal}. * @category Registries * @since v0.1.0 */ export interface SealResult { /** Transaction signature. */ readonly txSignature: TransactionSignature; /** Page index of the sealed archive. */ readonly pageIndex: number; } /** * @interface RingBufferEntry * @name RingBufferEntry * @description Decoded ring buffer entry from the on-chain memory ledger. * Contains raw bytes, UTF-8 text representation, and byte size. * @category Registries * @since v0.1.0 */ export interface RingBufferEntry { /** Raw data bytes. */ readonly data: Uint8Array; /** Data decoded as UTF-8 string (if applicable). */ readonly text: string; /** Size in bytes. */ readonly size: number; } /** * @interface SessionStatus * @name SessionStatus * @description Full session status including vault, session, and ledger state. * Returned by {@link SessionManager.getStatus}. * @category Registries * @since v0.1.0 */ export interface SessionStatus { /** Whether the vault exists. */ readonly vaultExists: boolean; /** Whether the session exists. */ readonly sessionExists: boolean; /** Whether the ledger exists. */ readonly ledgerExists: boolean; /** Whether the session is closed. */ readonly isClosed: boolean; /** Total entries written to the ledger. */ readonly totalEntries: number; /** Total data size in bytes. */ readonly totalDataSize: string; /** Number of sealed archive pages. */ readonly numPages: number; /** Merkle root hex string. */ readonly merkleRoot: string; } /** * @name SessionManager * @description Unified session lifecycle manager for agent memory. * * Wraps vault + ledger modules into a single API that manages * the full memory session lifecycle: create vault, open session, * write data, read ring buffer, seal archives, and close sessions. * * @category Registries * @since v0.1.0 * * @example * ```ts * const session = client.session; * const ctx = await session.start("conversation-123"); * await session.write(ctx, "Hello from the agent"); * const entries = await session.readLatest(ctx); * await session.seal(ctx); * await session.close(ctx); * ``` */ export declare class SessionManager { private readonly program; private readonly wallet; constructor(program: SapProgram); /** * @name deriveContext * @description Derive all PDAs for a session without creating anything. * Pure computation — no network calls. * * @param sessionId - Human-readable session identifier (hashed for PDA derivation). * @returns A {@link SessionContext} with all resolved PDAs. * @since v0.1.0 */ deriveContext(sessionId: string): SessionContext; /** * @name start * @description Start a new session: ensures vault exists, opens session, * and initializes a ledger. Idempotent — skips any step * that’s already done. * * @param sessionId - Human-readable session name (hashed for PDA). * @param vaultNonce - Optional 32-byte nonce for vault init (only used if vault doesn’t exist). * @returns A {@link SessionContext} with all resolved PDAs. * @since v0.1.0 */ start(sessionId: string, vaultNonce?: number[]): Promise; /** * @name write * @description Write data to a session (ring buffer + permanent TX log). * Cost: TX fee only (~0.000005 SOL per write). * * @param ctx - Session context from {@link SessionManager.start} or {@link SessionManager.deriveContext}. * @param data - UTF-8 string or raw bytes to write. * @returns A {@link WriteResult} with the transaction signature, content hash, and data size. * @since v0.1.0 */ write(ctx: SessionContext, data: string | Buffer | Uint8Array): Promise; /** * @name readLatest * @description Read the latest entries from the ring buffer. * FREE — uses `getAccountInfo()` on any RPC (no archival needed). * * @param ctx - Session context. * @returns An array of {@link RingBufferEntry} from the current ring buffer. * @since v0.1.0 */ readLatest(ctx: SessionContext): Promise; /** * @name seal * @description Seal the ring buffer into a permanent LedgerPage. * Creates a write-once, never-delete archive (~0.031 SOL per page). * * @param ctx - Session context. * @returns A {@link SealResult} with the transaction signature and page index. * @since v0.1.0 */ seal(ctx: SessionContext): Promise; /** * @name closeLedger * @description Close the ledger and reclaim ~0.032 SOL rent. * * @param ctx - Session context. * @returns The transaction signature. * @since v0.1.0 */ closeLedger(ctx: SessionContext): Promise; /** * @name closeSession * @description Close the session (no more writes allowed). * * @param ctx - Session context. * @returns The transaction signature. * @since v0.1.0 */ closeSession(ctx: SessionContext): Promise; /** * @name close * @description Full session teardown: close ledger → close session. * Reclaims all rent. Idempotent — skips steps already done. * * @param ctx - Session context. * @returns Resolves when the session is fully closed. * @since v0.1.0 */ close(ctx: SessionContext): Promise; /** * @name getStatus * @description Get the full status of a session. * Returns vault/session/ledger existence, closure state, and metrics. * * @param ctx - Session context. * @returns A {@link SessionStatus} with all session state information. * @since v0.1.0 */ getStatus(ctx: SessionContext): Promise; /** * @name readPage * @description Read a sealed archive page by index. * * @param ctx - Session context. * @param pageIndex - Zero-based index of the sealed page. * @returns An array of {@link RingBufferEntry} from the sealed page. * @since v0.1.0 */ readPage(ctx: SessionContext, pageIndex: number): Promise; /** * @name readAll * @description Read ALL data: ring buffer (latest) + all sealed pages (history). * Returns entries in chronological order (oldest first). * * @param ctx - Session context. * @returns An array of all {@link RingBufferEntry} in chronological order. * @since v0.1.0 */ readAll(ctx: SessionContext): Promise; /** * @name decodeRingBuffer * @description Decode a raw ring buffer byte array into structured entries. * Parses length-prefixed (u16 LE) entries from the byte stream. * @param ring - Raw ring buffer bytes. * @returns An array of decoded {@link RingBufferEntry}. * @private */ private decodeRingBuffer; /** * @name accountExists * @description Check if an on-chain account exists at the given PDA. * @param pda - Account public key to check. * @returns `true` if the account exists, `false` otherwise. * @private */ private accountExists; /** * @name methods * @description Accessor for the Anchor program methods namespace. * @returns The program methods object for building RPC calls. * @private */ private get methods(); /** * @name fetch * @description Fetch an on-chain account by name and PDA. Throws if not found. * @param name - Anchor account discriminator name. * @param pda - Account public key to fetch. * @returns The deserialized account data. * @throws If the account does not exist. * @private */ private fetch; /** * @name fetchNullable * @description Fetch an on-chain account by name and PDA. Returns `null` if not found. * @param name - Anchor account discriminator name. * @param pda - Account public key to fetch. * @returns The deserialized account data, or `null` if the account does not exist. * @private */ private fetchNullable; } //# sourceMappingURL=session.d.ts.map