/**
 * TinyCloudWeb — thin browser wrapper around TinyCloudNode.
 *
 * All core logic (auth, services, delegations) is handled by TinyCloudNode.
 * This wrapper provides:
 * - Browser-specific adapters (wallet signer, notifications, WASM bindings)
 * - The familiar TinyCloudWeb public API surface
 * - Static receiveShare() using browser WASM
 *
 * @packageDocumentation
 */
import { type DelegateToOptions, type DelegateToResult, type ISessionStorage, type SignStrategy } from "@tinycloud/node-sdk/core";
import { IKVService, ISQLService, IDuckDbService, IDataVaultService, ISecretsService, ISpaceService, ISpace, ISharingService, ICapabilityKeyRegistry, IHooksService, IEncryptionService, DelegationManager, Delegation, CreateDelegationParams, Result, DelegationError, ClientSession, Extension, type TelemetryConfig, ISpaceCreationHandler, type Manifest, type ComposedManifestRequest, type AccountService, type ResolvedDelegate, type PermissionEntry, type NetworkDescriptor, SignInOptions } from "@tinycloud/sdk-core";
import type { providers } from "ethers";
import { RPCProviders, ClientConfig } from "../providers";
import type { NotificationConfig } from "../notifications/types";
import type { PortableDelegation, DelegatedAccess } from "@tinycloud/node-sdk/core";
declare global {
    interface Window {
        ethereum?: any;
    }
}
/**
 * Configuration for TinyCloudWeb.
 *
 * Extends ClientConfig with browser-specific options.
 */
export interface Config extends ClientConfig {
    /** Notification configuration for error popups and toasts */
    notifications?: NotificationConfig;
    /** Optional prefix for KV service keys */
    kvPrefix?: string;
    /** Prefix for space names when creating spaces */
    spacePrefix?: string;
    /** Explicit TinyCloud server hosts. When omitted, signIn resolves the user's host. */
    tinycloudHosts?: string[];
    /** TinyCloud location registry URL. Default: https://registry.tinycloud.xyz. */
    tinycloudRegistryUrl?: string | null;
    /** Fallback TinyCloud hosts. Default: hosted TinyCloud node. */
    tinycloudFallbackHosts?: string[] | null;
    /** Whether to auto-create space on sign-in (default: true) */
    autoCreateSpace?: boolean;
    /** Space creation handler (default: ModalSpaceCreationHandler) */
    spaceCreationHandler?: ISpaceCreationHandler;
    /** Session expiration time in milliseconds (default: 1 hour) */
    sessionExpirationMs?: number;
    /** Persist browser sessions so signIn() can restore before prompting. Default true. */
    persistSession?: boolean;
    /** Custom session storage implementation. */
    sessionStorage?: ISessionStorage;
    /** Browser storage key prefix for isolating apps/environments. */
    sessionStorageKeyPrefix?: string;
    /** SIWE domain (default: window.location.hostname in browser, app.tinycloud.xyz otherwise) */
    domain?: string;
    /** Shorthand for passing a Web3 provider */
    provider?: any;
    /**
     * App manifest used for sign-in and escalation flows. When set,
     * the SIWE recap issued at sign-in covers the union of the app's
     * own permissions and every manifest-declared delegation's
     * permissions — which is what enables
     * `tcw.delegateTo(manifestDeclaredDid, permissions)` to run via
     * the session-key UCAN path (no wallet prompt).
     *
     * When provided, {@link TinyCloudWeb.requestPermissions} uses the
     * manifest's `name` and `icon` to title the permission modal. The
     * manifest is forwarded into the underlying {@link TinyCloudNode}
     * so `signIn()` drives its SIWE recap from it directly.
     */
    manifest?: Manifest | Manifest[];
    /** Pre-composed manifest request. Takes precedence over `manifest`. */
    capabilityRequest?: ComposedManifestRequest;
    /** Strategy for TinyCloud root signature requests. */
    signStrategy?: SignStrategy;
    /** Include implicit account registry permissions when composing `manifest`. Default true. */
    includeAccountRegistryPermissions?: boolean;
    /** Default-off service telemetry. */
    telemetry?: TelemetryConfig;
}
/**
 * Result of {@link TinyCloudWeb.requestPermissions}. On approve, `session`
 * is the current session that received the runtime permission delegation.
 * On decline, `session` is omitted so callers can branch on `approved`.
 */
export interface RequestPermissionsResult {
    approved: boolean;
    session?: ClientSession;
    delegations?: readonly PortableDelegation[];
}
export type SessionRestoreStatus = "idle" | "disabled" | "restoring" | "restored" | "missing" | "expired" | "corrupt" | "storage-unavailable" | "restore-failed" | "stale" | "logging-in";
export interface SessionRestoreResult {
    status: Exclude<SessionRestoreStatus, "idle" | "restoring" | "logging-in">;
    session?: ClientSession;
    error?: Error;
}
/**
 * Result of receiving a share link.
 */
export interface ShareReceiveResult<T = unknown> {
    data: T;
    delegation: Delegation;
    path: string;
    spaceId: string;
}
export declare class TinyCloudWeb {
    /** The Ethereum provider */
    provider: providers.Web3Provider;
    /** Supported RPC Providers */
    static RPCProviders: typeof RPCProviders;
    /** Underlying TinyCloudNode (created after WASM init) */
    private _node;
    /** Browser notification handler */
    private notificationHandler;
    /** Browser WASM bindings */
    private wasmBindings;
    /** Browser wallet signer */
    private walletSigner?;
    private sessionStorage?;
    private _sessionRestoreStatus;
    private _secrets;
    /** Promise that resolves when WASM + node are ready */
    private _initPromise;
    /** User config */
    private config;
    /**
     * App manifest stored from config (or updated via `setManifest`).
     *
     * `requestPermissions` reads this for the modal title/icon. `_init`
     * forwards this value into the underlying {@link TinyCloudNode} so
     * `signIn()` drives its SIWE recap from the manifest. `setManifest`
     * mirrors any post-construction updates onto the node so the next
     * sign-in picks them up.
     */
    private _manifest?;
    private _capabilityRequest?;
    private resetSessionScopedCaches;
    /**
     * Test hook — override the modal shower and sign-in function used by
     * {@link requestPermissions}. Not part of the public API. Tests set
     * these via `(tcw as any)._testHooks = { ... }` so they can exercise
     * the escalation control flow without a real DOM or wallet.
     *
     * @internal
     */
    private _testHooks?;
    constructor(config?: Config);
    /**
     * Async initialization: ensure WASM is ready, then create TinyCloudNode.
     * @internal
     */
    private _init;
    /**
     * Get the TinyCloudNode instance, awaiting init if necessary.
     * @internal
     */
    private ensureNode;
    /**
     * Get the TinyCloudNode instance synchronously.
     * Throws if called before WASM initialization completes.
     * @internal
     */
    private get node();
    /**
     * Factory method for guaranteed correct initialization.
     * Awaits WASM loading before returning the instance.
     */
    static create(config?: Config): Promise<TinyCloudWeb>;
    get kv(): IKVService;
    get sql(): ISQLService;
    /** Whether the last signIn() skipped client-side account bootstrap. */
    get bootstrapSkipped(): boolean;
    /** Outcome of the last signIn()'s account-bootstrap attempt. */
    get bootstrapStatus(): {
        skipped: boolean;
        reason?: string;
    };
    /** Space-scoped SQL service for a non-primary space (e.g. the owner's `applications` space). */
    sqlForSpace(spaceId: string): ISQLService;
    /** Space-scoped KV service for a non-primary space (e.g. the owner's `applications` space). */
    kvForSpace(spaceId: string): IKVService;
    get duckdb(): IDuckDbService;
    get hooks(): IHooksService;
    get encryption(): IEncryptionService;
    get vault(): IDataVaultService;
    get secrets(): ISecretsService;
    secretsForSpace(spaceId: string): ISecretsService;
    get spaces(): ISpaceService;
    get sharing(): ISharingService;
    get delegations(): DelegationManager;
    get capabilityRegistry(): ICapabilityKeyRegistry;
    get spaceId(): string | undefined;
    get accountSpaceId(): string | undefined;
    get account(): AccountService;
    get hosts(): string[];
    get sessionRestoreStatus(): SessionRestoreStatus;
    space(nameOrUri: string): ISpace;
    get kvPrefix(): string;
    getEncryptionNetwork(nameOrNetworkId?: string): Promise<NetworkDescriptor | null>;
    createEncryptionNetwork(name?: string): Promise<NetworkDescriptor>;
    ensureEncryptionNetwork(name?: string): Promise<NetworkDescriptor>;
    /**
     * Ensure one of this user's owned spaces (e.g. `"secrets"`) is hosted on the
     * server.
     *
     * A full-authority sign-in auto-hosts the owner's `secrets` space, but a
     * session created with a manifest / capabilityRequest does not. Such a
     * session can hold valid `tinycloud.kv/*` capabilities for the owned
     * `secrets` space yet still fail its first scoped `secrets.put(...)` with
     * `404 Space not found`, because the space was never registered on the node.
     *
     * Calling this resolves `name` to the owner's owned-space URI. It first
     * consults the account spaces registry and, if the space is already
     * registered/hosted, returns without prompting for a host signature; only
     * when the space is absent (or the registry check fails) does it host via the
     * host-SIWE delegation flow (one signature, idempotent server-side). Must be
     * called after {@link signIn}.
     *
     * @param name - The owned space name (e.g. `"secrets"`).
     * @returns The hosted owned-space URI.
     */
    ensureOwnedSpaceHosted(name: string): Promise<string>;
    private resolveRestoreAddress;
    private loadPersistedSession;
    restoreSession(address?: string): Promise<SessionRestoreResult>;
    clearPersistedSession(address?: string): Promise<void>;
    private configuredManifestPermissions;
    private restoredSessionCoversConfiguredManifest;
    signIn: (options?: SignInOptions) => Promise<ClientSession>;
    signOut: () => Promise<void>;
    session: () => ClientSession | undefined;
    address: () => string | undefined;
    chainId: () => number | undefined;
    get did(): string;
    get sessionDid(): string;
    get isSessionOnly(): boolean;
    get isWalletConnected(): boolean;
    extend(_extension: Extension): void;
    cleanup(): void;
    connectWallet(provider: providers.ExternalProvider | providers.Web3Provider, options?: {
        spacePrefix?: string;
    }): void;
    createDelegation(params: {
        path: string;
        actions: string[];
        delegateDID: string;
        disableSubDelegation?: boolean;
        expiryMs?: number;
    }): Promise<PortableDelegation>;
    /**
     * Issue a delegation using the capability-chain flow (spec:
     * `.claude/specs/capability-chain.md`). When the requested permissions
     * are a subset of the current session's recap, no wallet prompt is
     * shown — the delegation is signed by the session key via WASM. When
     * they are not, this throws `PermissionNotInManifestError` so callers
     * can trigger an escalation flow via {@link requestPermissions}.
     *
     * Pass `{ forceWalletSign: true }` to bypass the derivability check and
     * always use the wallet-signed SIWE path.
     */
    delegateTo: (did: string, permissions: PermissionEntry[], options?: DelegateToOptions) => Promise<DelegateToResult>;
    materializeDelegation: (did: string, request?: ComposedManifestRequest) => Promise<DelegateToResult & {
        target: ResolvedDelegate;
    }>;
    materializeDelegations: (request?: ComposedManifestRequest) => Promise<Array<DelegateToResult & {
        target: ResolvedDelegate;
    }>>;
    /**
     * Get the stored manifest (if any). Returns a shallow clone so callers
     * can't accidentally mutate our internal state.
     */
    getManifest(): Manifest | Manifest[] | undefined;
    /**
     * Install or replace the stored manifest. Used by apps that compose
     * their manifest at runtime (e.g. after fetching a backend's advertised
     * permissions) and by the escalation flow inside
     * {@link requestPermissions}.
     *
     * The manifest is forwarded to the underlying TinyCloudNode so the
     * next `signIn()` picks it up. If the node has not been constructed
     * yet (pre-init), the manifest is stored locally and forwarded
     * later inside `_init`.
     */
    setManifest(manifest: Manifest | Manifest[]): void;
    setCapabilityRequest(request: ComposedManifestRequest): void;
    /**
     * Request additional permissions on top of the currently-signed
     * session. Shows a confirmation modal; on approve, stores a narrow
     * runtime delegation that matching service calls can use. On decline,
     * returns `{ approved: false }` with no state changes.
     *
     * Spec: `.claude/specs/capability-chain.md` §requestPermissions.
     *
     * On approve, this does not mutate the manifest or force a new sign-in.
     * The underlying node creates a secondary delegation to the current
     * session key and records it in the invocation permission map.
     */
    requestPermissions(additional: PermissionEntry[]): Promise<RequestPermissionsResult>;
    getRuntimePermissionDelegations(permissions?: PermissionEntry[]): readonly PortableDelegation[];
    useRuntimeDelegation(delegation: PortableDelegation): Promise<void>;
    useDelegation(delegation: PortableDelegation): Promise<DelegatedAccess>;
    createSubDelegation(parentDelegation: PortableDelegation, params: {
        path: string;
        actions: string[];
        delegateDID: string;
        disableSubDelegation?: boolean;
        expiryMs?: number;
    }): Promise<PortableDelegation>;
    delegate(params: CreateDelegationParams): Promise<Result<Delegation, DelegationError>>;
    revokeDelegation(cid: string): Promise<Result<void, DelegationError>>;
    listDelegations(): Promise<Result<Delegation[], DelegationError>>;
    checkPermission(path: string, action: string): Promise<Result<boolean, DelegationError>>;
    /**
     * Receive and retrieve data from a v2 share link.
     * Static method — no auth required. Uses browser WASM.
     */
    static receiveShare<T = unknown>(link: string, key?: string): Promise<Result<ShareReceiveResult<T>, DelegationError>>;
}
//# sourceMappingURL=tcw.d.ts.map