/**
 * src/security/license.ts
 *
 * Al Moasis · المؤسس — License + machine-fingerprint gate (v3.0).
 *
 * Business model: Al Moasis is sold as a one-time 999 SAR perpetual download
 * (.dmg / .msi / AppImage). To prevent casual sharing — torrents, "send me
 * your install" between coworkers, etc. — this module enforces:
 *
 *   1. **Activation:** on first launch, the user pastes a license key. Gateway
 *      calls https://license.almoasis.ai/activate, which binds the key to this
 *      machine's fingerprint server-side. Returns a signed license file.
 *
 *   2. **Heartbeat:** every 24h the gateway re-validates with the license
 *      server. Server can revoke (refund, abuse, key shared) → revocation
 *      propagates within 24h.
 *
 *   3. **Offline grace:** if the license server is unreachable, the gateway
 *      continues running for 7 days using the cached signed file. After
 *      7 days offline the gateway enters read-only mode (incoming messages
 *      logged but no replies sent) until heartbeat succeeds.
 *
 *   4. **Machine fingerprint:** sha256(hostname + platform.uuid + cpu.model).
 *      Stable across reboots, changes on hardware swap → forces re-activation.
 *
 * Honest disclaimer: this is a speed-bump, not a vault. A determined attacker
 * who decompiles the binary can patch out the checks. The bar is "non-technical
 * pirates give up; technical pirates spend 2 weeks." For 999 SAR, that's enough.
 *
 * NEVER hardcode the public key here — load from the build manifest at startup.
 */
export interface MachineFingerprint {
    /** Stable SHA-256 hex digest of {hostname, platform, arch, cpu model}. */
    fingerprint: string;
    hostname: string;
    platform: string;
    arch: string;
    cpu_model: string;
}
export interface SignedLicense {
    /** License key the user entered. */
    key: string;
    /** Machine fingerprint the key is bound to. */
    fingerprint: string;
    /** ISO timestamp when activation happened. */
    activated_at: string;
    /** ISO timestamp of last successful heartbeat. */
    last_heartbeat_at: string;
    /** Server-issued expiry (null = perpetual). */
    expires_at: string | null;
    /** Server-issued plan tier — currently 'individual' only. */
    plan: 'individual' | 'team' | 'enterprise';
    /** Ed25519 signature over the canonical JSON of all above fields. */
    signature: string;
}
export interface LicenseStatus {
    ok: boolean;
    state: 'unactivated' | 'active' | 'expired' | 'offline_grace' | 'revoked' | 'read_only';
    message: string;
    fingerprint: string;
    last_heartbeat_at: string | null;
    days_offline: number;
}
/**
 * Compute the machine fingerprint. Stable across reboots, changes on
 * hardware swap (which is what we want — a license keyed to "this device").
 *
 * Components:
 *   - hostname (changes if user renames their Mac; rare)
 *   - platform + arch (darwin/arm64, win32/x64, linux/x64)
 *   - CPU model name (changes only on actual hardware replacement)
 *
 * NOT used: MAC address (changes per network interface, can be spoofed easily),
 * disk serial (requires platform-specific calls), Apple UUID (privacy-sensitive).
 * The chosen components are stable enough and don't require elevated permissions.
 */
export declare function getMachineFingerprint(): MachineFingerprint;
/**
 * Persist the machine fingerprint to <dataDir>/machine.fp. First-write only —
 * subsequent reads return the originally-stored fingerprint so a hardware
 * change doesn't silently invalidate the license (the server will reject the
 * heartbeat instead, with a clearer error).
 */
export declare function getStoredFingerprint(dataDir: string): string;
/**
 * Load the signed license file from disk and verify its signature against
 * the embedded public key. Returns null if absent or signature fails.
 *
 * Verification path: canonical-JSON-stringify(license without signature)
 * → Ed25519.verify(message, signature) using the embedded public key.
 */
export declare function loadAndVerifyLicense(dataDir: string, pubKeyPem?: string): SignedLicense | null;
/**
 * Persist a signed license file (mode 0600). Caller is responsible for
 * receiving the signed payload from the license server before calling this.
 */
export declare function storeSignedLicense(dataDir: string, license: SignedLicense): void;
/**
 * Get the current license state. Combines the on-disk license file, the
 * last heartbeat timestamp, and offline-grace policy into a single answer
 * the gateway can use to decide "should I serve requests."
 *
 * Returns:
 *   - state='unactivated': no license file, user must paste a key
 *   - state='active':      license verified, last heartbeat <24h ago
 *   - state='offline_grace': license verified but heartbeat stale 1-7d (still serving)
 *   - state='read_only':   heartbeat stale >7d (block outbound replies)
 *   - state='expired':     server-issued expires_at is in the past
 *   - state='revoked':     heartbeat returned revocation in last 24h
 */
export declare function getLicenseStatus(dataDir: string, pubKeyPem?: string): LicenseStatus;
/**
 * Call the license server to activate a key against this machine's fingerprint.
 * Returns the signed license payload on success. The caller persists it via
 * storeSignedLicense.
 *
 * Network failure → throws. The gateway treats that as "user can't activate
 * right now, try again." We do NOT fall back to a permissive default — the
 * whole point of the gate is that activation requires network reach.
 */
export declare function activateLicense(licenseKey: string, fingerprint: MachineFingerprint, serverUrl?: string): Promise<SignedLicense>;
/**
 * Heartbeat ping — server confirms the license is still valid for this
 * machine and refreshes the cached `last_heartbeat_at`. Server may also
 * issue a revoke response that the gateway honors immediately.
 */
export declare function heartbeat(license: SignedLicense, serverUrl?: string): Promise<SignedLicense>;
//# sourceMappingURL=license.d.ts.map