/**
 * License-key parsing. Matches the service's wire format exactly.
 *
 * ## Wire format
 *
 * A key string looks like `LIC1-<payload_b32>-<signature_b32>`. Both halves
 * are Crockford base32 (no padding) of the raw bytes.
 *
 * ### v1 payload (74 bytes, fixed)
 *
 * ```text
 * offset  size  field
 *      0     1  version = 1
 *      1     1  flags
 *      2    16  product_id (UUID bytes)
 *     18    16  license_id (UUID bytes)
 *     34     8  issued_at   (i64 unix seconds, big-endian)
 *     42    32  fingerprint_hash (SHA-256, or all-zero)
 * ```
 *
 * ### v2 payload (83 bytes + variable entitlements)
 *
 * ```text
 * offset  size  field
 *      0     1  version = 2
 *      1     1  flags
 *      2    16  product_id
 *     18    16  license_id
 *     34     8  issued_at
 *     42     8  expires_at  (i64, 0 = perpetual)
 *     50    32  fingerprint_hash
 *     82     1  num_entitlements (u8)
 *     83     *  entitlements — each: [u8 len][len utf-8 bytes]
 * ```
 *
 * Clients verifying a v1 key treat `expiresAt` as 0 and `entitlements` as
 * empty, so application code can branch on flags / fields uniformly.
 */
declare const KEY_PREFIX = "LIC1";
/** v1 format identifier. */
declare const KEY_VERSION_V1 = 1;
/** v2 format identifier. */
declare const KEY_VERSION_V2 = 2;
/** Highest format version this client understands. */
declare const KEY_VERSION = 2;
/** Set when the key is bound to a specific machine fingerprint hash. */
declare const FLAG_FINGERPRINT_BOUND = 1;
/** Set on trial keys. */
declare const FLAG_TRIAL = 2;
/** Decoded fields of the signed payload. */
interface LicensePayload {
    /** Format version (1 or 2). */
    version: number;
    /** Feature flags. */
    flags: number;
    /** Raw 16-byte product id (UUID). */
    productId: Uint8Array;
    /** Raw 16-byte license id (UUID). */
    licenseId: Uint8Array;
    /** Unix seconds issued. */
    issuedAt: number;
    /** Unix seconds expiry; `0` for perpetual. Always `0` on v1 keys. */
    expiresAt: number;
    /** SHA-256 hash of the bound machine fingerprint, or all-zero. */
    fingerprintHash: Uint8Array;
    /** Entitlement slugs granted by this license. Empty on v1 keys. */
    entitlements: string[];
    /** Product UUID in canonical string form. */
    productUuid: string;
    /** License UUID in canonical string form. */
    licenseUuid: string;
    /** True if the key is fingerprint-bound. */
    isFingerprintBound: boolean;
    /** True if the key is flagged as a trial. */
    isTrial: boolean;
}
/** A parsed (not yet verified) license key. */
interface LicenseKey {
    payload: LicensePayload;
    /**
     * Raw payload bytes (what the server signed over). Length is 74 on v1,
     * `>= 83` on v2.
     */
    signedBytes: Uint8Array;
    /** Raw 64-byte signature. */
    signature: Uint8Array;
}
/** True if `nowUnixSeconds` is at or after the key's `expiresAt`. */
declare function isExpiredAt(payload: LicensePayload, nowUnixSeconds: number): boolean;
/** True if the license grants the given entitlement slug. */
declare function hasEntitlement(payload: LicensePayload, slug: string): boolean;
/** Parse a `LIC1-...-...` string. Does NOT verify. */
declare function parseLicenseKey(raw: string): LicenseKey;

/**
 * Issuer public key. Accepts either raw 32-byte Ed25519 key material or a
 * PEM-encoded SubjectPublicKeyInfo blob (which is what the service returns
 * from `/v1/pubkey`).
 */
/** Parsed Ed25519 public key, ready for signature verification. */
declare class PublicKey {
    /** Raw 32-byte Ed25519 public key material. */
    readonly raw: Uint8Array;
    constructor(raw: Uint8Array);
    /** Parse a PEM blob as emitted by the service. */
    static fromPem(pem: string): PublicKey;
    /** Construct from raw bytes (no PEM envelope). */
    static fromBytes(bytes: Uint8Array): PublicKey;
}

/** Offline Ed25519 signature verification. */

interface VerifyOk {
    /** Parsed payload fields. */
    payload: LicensePayload;
    /** License UUID as a canonical string. */
    licenseId: string;
    /** Product UUID as a canonical string. */
    productId: string;
}
/** Verifies license keys against a single issuing server's public key. */
declare class Verifier {
    private pubkey;
    constructor(pubkey: PublicKey);
    /** Verify a license key string. Throws on any failure. */
    verify(keyStr: string): VerifyOk;
    /**
     * Verify AND enforce that, if the key is fingerprint-bound, the given
     * fingerprint matches. If the key is not bound, the fingerprint is
     * ignored. Throws on any failure.
     */
    verifyWithFingerprint(keyStr: string, fingerprint: string): VerifyOk;
    /**
     * Verify a key and additionally reject it with an `expired` error if
     * `nowUnixSeconds` is at or past its `expiresAt`. Perpetual keys
     * (`expiresAt === 0`) are accepted regardless of `nowUnixSeconds`. This is
     * offline-only — no grace window logic; use `Client.validate` for that.
     */
    verifyWithTime(keyStr: string, nowUnixSeconds: number): VerifyOk;
}

/**
 * Online operations against a running `licensing-service` instance.
 *
 * All methods use the global `fetch` available in Node 18+ and every modern
 * browser. No additional runtime required.
 */
interface ValidateResponse {
    ok: boolean;
    /**
     * Machine-readable reason on failure. One of:
     * `bad_format`, `bad_signature`, `not_found`, `revoked`, `suspended`,
     * `expired`, `product_mismatch`, `fingerprint_mismatch`,
     * `too_many_machines`, `rate_limited`, `invalid_state`.
     */
    reason?: string;
    licenseId?: string;
    productId?: string;
    productSlug?: string;
    issuedAt?: string;
    /** Expiry timestamp (RFC 3339) if the license has one. */
    expiresAt?: string;
    /** End of the grace window (RFC 3339) when in a grace period. */
    graceUntil?: string;
    /** True when the key is past `expiresAt` but still inside the grace window. */
    inGracePeriod?: boolean;
    /** True if this license is flagged as a trial. */
    isTrial?: boolean;
    /** Entitlement slugs granted by the license. */
    entitlements?: string[];
    /** License status string: `active`, `suspended`, `revoked`. */
    status?: string;
    /** Machine id created or matched by this call (when fingerprint was sent). */
    machineId?: string;
    /** Seat cap: `0` unlimited, `1` single-seat, `n` n-seat. */
    maxMachines?: number;
}
interface ValidateOptions {
    /** Product slug the caller expects the key to cover. */
    productSlug?: string;
    /** Raw machine fingerprint; enables seat binding / cap enforcement. */
    fingerprint?: string;
    /** Client-supplied hostname, stored against the machine row on activation. */
    hostname?: string;
    /** Client-supplied platform descriptor, e.g. `'linux-x86_64'`. */
    platform?: string;
}
interface MachineResponse {
    ok: boolean;
    reason?: string;
    machineId?: string;
    activeCount?: number;
    maxMachines?: number;
}
interface PurchaseSession {
    /** Our internal invoice id — use with `pollPurchase`. */
    invoiceId: string;
    /** BTCPay's invoice id (opaque). */
    btcpayInvoiceId: string;
    /** URL to open in the buyer's browser to pay. */
    checkoutUrl: string;
    /** Price in satoshis. */
    amountSats: number;
    /** Where the service recommends polling. */
    pollUrl: string;
}
interface PollResponse {
    invoiceId: string;
    /** `pending | settled | expired | invalid`. */
    status: string;
    productId: string;
    amountSats: number;
    /** Populated once the license has been issued. */
    licenseKey?: string;
    licenseId?: string;
}
interface StartPurchaseOptions {
    /** Optional email for the receipt. */
    buyerEmail?: string;
    /** Optional URL the buyer should be returned to after payment. */
    redirectUrl?: string;
    /** Optional discount / referral code. */
    code?: string;
    /** Optional buyer note recorded on the invoice (admin-visible). */
    buyerNote?: string;
}
interface RedeemFreeOptions {
    /** Optional email recorded on the synthetic invoice + license. */
    buyerEmail?: string;
    /** Optional buyer note. */
    buyerNote?: string;
}
interface RedeemFreeResponse {
    licenseId: string;
    /** The fully-signed license key, ready for offline verification. */
    licenseKey: string;
    invoiceId: string;
    redemptionId: string;
}
/** An HTTP client pinned to one licensing-service base URL. */
declare class Client {
    private base;
    constructor(baseUrl: string);
    /** The normalized base URL this client is pinned to. */
    baseUrl(): string;
    /** Fetch the server's PEM-encoded public key. */
    fetchPubkeyPem(): Promise<string>;
    /**
     * Server-authoritative validation. Returns the full response including
     * expiry / entitlements / seat fields introduced in v2.
     *
     * Two-argument form kept for call-site compatibility with earlier SDK
     * versions; pass an options object for the full set of fields.
     */
    validate(key: string, productSlugOrOptions?: string | ValidateOptions, fingerprint?: string): Promise<ValidateResponse>;
    /** Lightweight heartbeat. Server updates `last_heartbeat_at`. */
    heartbeat(key: string, fingerprint: string): Promise<MachineResponse>;
    /** Explicitly activate a seat for the given fingerprint. */
    activate(key: string, fingerprint: string, opts?: {
        hostname?: string;
        platform?: string;
    }): Promise<MachineResponse>;
    /** Free a seat held by the given fingerprint. */
    deactivate(key: string, fingerprint: string, reason?: string): Promise<MachineResponse>;
    /** Start a purchase. Returns the checkout URL and invoice id. */
    startPurchase(productSlug: string, opts?: StartPurchaseOptions): Promise<PurchaseSession>;
    /**
     * Redeem a `free_license` code: bypass BTCPay entirely and receive the
     * signed license key directly. Throws if the code is unknown / disabled
     * / expired / wrong product / not a free_license code, or if the cap
     * has been reached.
     */
    redeemFreeLicense(productSlug: string, code: string, opts?: RedeemFreeOptions): Promise<RedeemFreeResponse>;
    /** Poll a purchase by its invoice id. */
    pollPurchase(invoiceId: string): Promise<PollResponse>;
    /**
     * Convenience: open the checkout, poll until a license key is issued,
     * then return it. Suitable for CLI usage or for an app UI that shows a
     * spinner while the buyer pays.
     */
    waitForLicense(invoiceId: string, options?: {
        intervalMs?: number;
        timeoutMs?: number;
    }): Promise<string>;
    private toValidateResponse;
    private toMachineResponse;
    private get;
    private post;
    private request;
}

/** Hash a raw fingerprint string to the 32-byte form embedded in keys. */
declare function hashFingerprint(raw: string): Uint8Array;

/** All errors thrown by this library inherit from `LicensingError`. */
declare class LicensingError extends Error {
    /**
     * Machine-readable reason code. Common values:
     * `"bad_format"`, `"bad_encoding"`, `"bad_version"`, `"bad_signature"`,
     * `"expired"`, `"server_error"`, `"http_error"`, `"other"`.
     */
    readonly code: string;
    constructor(code: string, message: string);
}

export { Client, FLAG_FINGERPRINT_BOUND, FLAG_TRIAL, KEY_PREFIX, KEY_VERSION, KEY_VERSION_V1, KEY_VERSION_V2, type LicenseKey, type LicensePayload, LicensingError, type MachineResponse, type PollResponse, PublicKey, type PurchaseSession, type RedeemFreeOptions, type RedeemFreeResponse, type StartPurchaseOptions, type ValidateOptions, type ValidateResponse, Verifier, type VerifyOk, hasEntitlement, hashFingerprint, isExpiredAt, parseLicenseKey };
