/** * Credential management for Vana CLI authentication. * * Stores and retrieves auth credentials from ~/.vana/auth.json. * Supports the device code flow for browser-based login and * env var overrides for CI/automation. */ import type { ExportOwner } from "../core/source-export.js"; export interface VanaCredentials { account: { address: string; session_token: string; expires_at: string; }; personal_server: { url: string; session_token: string; expires_at: string; /** * "vana-server-start" when the CLI runs this server itself. Such a URL is * where `connect` writes, never a server to log in to. */ started_by?: "vana-server-start"; } | null; } /** * One login per Account deployment. Production keeps ~/.vana/auth.json; any * other Account (VANA_ENV=dev, or VANA_ACCOUNT_URL) gets its own file, so a * login and the Personal Server session saved with it are never sent to the * other environment, and switching back and forth needs no new login. */ export declare function getAuthFilePath(): string; /** * The line login prints after saving: the file this login actually went to, * which follows VANA_HOME and the Account environment, home-shortened. */ export declare function credentialsSavedLine(): string; /** * Load credentials from disk or env vars. * * Priority: * 1. Env vars (VANA_SESSION_TOKEN, VANA_PS_TOKEN, VANA_PS_URL) * 2. File (~/.vana/auth.json) * * Returns null if no credentials are available or if they are expired. */ export declare function loadCredentials(): VanaCredentials | null; /** * The account address stored in auth.json, expired or not. Login uses it to * detect an account switch; loadCredentials() cannot serve that purpose * because it filters expired credentials to null, and re-login happens * precisely because the token expired. */ export declare function readStoredAccountAddress(): string | null; /** * The saved account for Personal Server ownership checks, even after expiry. * An env token has unknown identity and overrides the saved account. This * address is never authorization; tokens keep their own validity checks. */ export declare function loadAccountAddressForOwnership(): string | null; /** Capture identity independently of token expiry, never from a destination server. */ export declare function loadExportOwner(): ExportOwner; /** * Raw peek at auth.json ignoring expiry: the previous address and the * previous personal_server block. Login uses it to detect an account switch * and to carry a still-useful PS session across a same-account cloud * re-login (the cloud flow cannot mint PS tokens, so overwriting the block * with null would discard a working session for nothing). */ export declare function readStoredAuthFile(): { address: string | null; personalServer: VanaCredentials["personal_server"]; } | null; /** Whether two account addresses name the same account (case-insensitive). */ export declare function sameAccountAddress(a: string | null | undefined, b: string | null | undefined): boolean; /** * Personal Server sessions of accounts that are not signed in right now, * keyed by lowercase address, next to the auth file they came from. * * auth.json holds one account. Signing in as another one used to drop the * previous account's PS session, which only that server can mint again (a * browser approval at the server), so switching back meant re-approving. * Login parks it here instead and restores it when that account returns. */ export declare function getStashedSessionsPath(): string; /** * Park `address`'s Personal Server session while another account is signed * in. Returns false when there was nothing worth keeping. */ export declare function stashPersonalServerSession(address: string, session: VanaCredentials["personal_server"]): Promise; /** * The parked Personal Server session of `address`, removed from the stash, * or null when there is none still valid. */ export declare function takeStashedPersonalServerSession(address: string): Promise; /** * Save credentials to ~/.vana/auth.json with 0600 permissions. */ export declare function saveCredentials(creds: VanaCredentials): Promise; /** * Delete ~/.vana/auth.json. */ export declare function clearCredentials(): Promise; /** * Check if the account session token has expired. */ export declare function isExpired(creds: VanaCredentials): boolean; /** * The saved Personal Server session, checked against its own expiry. The PS * token (30 days) usually outlives the Account session (hours to days), and * the server still accepts it after the Account login lapses, so syncs and * reads must not drop it when loadCredentials() returns null. * * With VANA_SESSION_TOKEN set, the env credentials win, as in * loadCredentials(). A block without a parseable expires_at is returned as * is: the server is the judge of a token whose lifetime we do not know. */ export declare function loadPersonalServerSession(): VanaCredentials["personal_server"]; /** * Format an address for display: 0x2Ab3...fa1 */ export declare function formatAddress(address: string): string; /** * Return human-readable time until expiry: "29 days", "3 hours", etc. */ export declare function formatExpiresIn(expiresAt: string): string; export interface DeviceCodeResponse { device_code: string; user_code: string; verification_uri: string; verification_uri_complete?: string; expires_in: number; interval: number; } export interface DeviceCodePollAuthorized { status: "authorized"; session_token: string; personal_server_url?: string; personal_server_session_token?: string; ps_access_token?: string; address: string; expires_in?: number; expires_at?: string; } export interface DeviceCodePollPending { status: "pending"; } export interface DeviceCodePollSlowDown { status: "slow_down"; } export interface DeviceCodePollExpired { status: "expired"; } export type DeviceCodePollResponse = DeviceCodePollAuthorized | DeviceCodePollPending | DeviceCodePollSlowDown | DeviceCodePollExpired; export interface DeviceCodeFlowOptions { clientId?: string; /** * Whether this run may take over the user's browser. False for * `--no-input`, `--json`, `--quiet` and anything without a TTY: those * callers asked for a URL to hand somewhere else, and opening a tab there * also starts a second attempt on the same one-time code, which makes * whichever tab finishes second fail. */ openBrowser?: boolean; } interface DeviceCodeFlowCallbacks { onCode: (code: string, verificationUri: string) => void; onWaiting: () => void; onAuthorized: (creds: VanaCredentials) => void | Promise; onExpired: () => void; onError: (error: Error) => void; } /** The Vana Account the CLI signs in to; `VANA_ACCOUNT_URL` overrides it. */ export declare function getAccountUrl(): string; export declare function resolveOAuthClientId(accountUrl?: string): string; /** * Request a device code from the auth server. */ export declare function requestDeviceCode(): Promise; /** * Poll for device code authorization. */ export declare function pollDeviceCode(deviceCode: string): Promise; /** * Open a URL in the user's default browser. * Best-effort — failures are silently ignored. */ export declare function openBrowser(url: string): void; /** * Run the full device code login flow. * * Returns credentials on success, or null if the code expired. * Calls the provided callbacks for UI updates. */ export declare function runDeviceCodeFlow(callbacks: DeviceCodeFlowCallbacks, options?: DeviceCodeFlowOptions): Promise; export type AuthTarget = "cloud" | "self-hosted"; export declare function getAuthTarget(psUrl: string | null): AuthTarget; /** * The account session to carry across a Personal Server login, or null when * there is nothing worth keeping. * * `saveCredentials` rewrites the whole auth file, so a server login must not * be allowed to blank a live account token or replace the CLI identity with * the server owner's address. An env-sourced session is not ours to persist. */ export declare function accountSessionToPreserve(stored: VanaCredentials["account"] | undefined): VanaCredentials["account"] | null; /** * The self-hosted server `vana login` logs in to, only when one is named: * `--server` on the command line, or VANA_PS_URL. A URL saved in auth.json * never changes who you log in to; without one, login is Vana Account. */ export declare function resolveLoginServerUrl(): string | undefined; export declare function resolvePersonalServerUrl(): string | undefined; export declare function runSelfHostedLoginFlow(serverUrl: string, onLoginUrl: (url: string) => void): Promise<{ server: string; address: string; session_token: string; expires_at: string; }>; export {}; //# sourceMappingURL=auth.d.ts.map