API reference
import {
LicenseError,
LicenseManager,
type LicenseErrorCode,
type LicenseManagerOptions,
type LicenseState,
type LicenseStateListener,
type MachineFingerprint,
type OfflineState,
} from "@licenseman/electron";LicenseManager
new LicenseManager(options)
Creates the manager, and starts the startup validation and the clock check in the background. Create one per product, in the main process. Throws only when productId or publicKey is empty. See installation and setup.
ready(): Promise<LicenseState>
Resolves with the state on startup. With a valid stored token, right away with ACTIVE, and the online validation runs in the background. Otherwise, once the startup validation is done. Always the same promise. Never rejects. See what happens on construction.
getState(): LicenseState
The current state. See license states.
onStateChange(listener): () => void
Calls listener(state) on every change of state, not with the current state. Returns a function that removes the listener. Errors thrown by the listener are ignored.
setLicenseKey(input: string): Promise<LicenseState>
Validates the key online, trimmed, case kept, retrying transient failures for up to 30 seconds. On success, stores it with its token, and resolves with ACTIVE. On any failure, throws a LicenseError and changes nothing. See activating a license.
refresh(): Promise<LicenseState>
Waits for ready(), then validates the stored key now, retrying transient failures for up to 30 seconds. Resolves with the new state. Never throws. Without a stored key, resolves with the current state. See refresh().
getLicenseKey(): string | null
The stored key, or null when none was activated. Still returns the key in the locked states.
getPortalUrl(): string
The link to your product’s customer portal, like https://app.licensemanager.dev/portal/x7Kp2QaZ. See linking to the customer portal.
getLatestAllowedVersion(): string | null | undefined
In VERSION_NOT_ALLOWED, refused by LicenseManager: the latest version the license allows, or null when it allows none. undefined in every other state, and when the refusal comes from the stored token offline.
getOfflineState(): OfflineState
Whether the last validation reached LicenseManager, and how long the stored token remains valid. See offline state.
getFingerprint(): Promise<string>
This computer’s fingerprint for your product, computed once, then cached. See machine fingerprint.
isClockTampered(): boolean
The result of the latest clock check. See clock tampering.
dispose(): void
Stops the scheduled renewals, the pending retries and the hourly clock check. A request already running completes. Call it when the app quits.
LicenseManagerOptions
interface LicenseManagerOptions {
productId: string;
publicKey: string;
fingerprint?: MachineFingerprint;
version?: string;
machineName?: string;
platform?: string;
minOfflineDurationMs?: number;
apiBaseUrl?: string;
storageDirs?: string[];
}| Option | Default | |
|---|---|---|
productId | Required | Your product’s id. |
publicKey | Required | Your organization’s Ed25519 public key, as PEM, from the Security page. |
fingerprint | The system’s machine id | The machine part of the fingerprint. |
version | app.getVersion() | Your app’s version. Required outside Electron. |
machineName | The hostname | The machine’s name on LicenseManager. |
platform | macOS, Windows or Linux | The machine’s platform on LicenseManager. |
minOfflineDurationMs | 0 | The minimum validity left after a renewal. See minOfflineDurationMs. |
apiBaseUrl | https://api.licensemanager.dev | For tests. |
storageDirs | Per system | For tests: the folders of the file fallback. |
See options for details.
LicenseState
type LicenseState =
| "LOADING"
| "MISSING_KEY"
| "ACTIVE"
| "INVALID_KEY"
| "EXPIRED"
| "VERSION_NOT_ALLOWED"
| "MACHINE_LIMIT_REACHED"
| "OFFLINE_EXPIRED"
| "CLOCK_TAMPERED";LicenseStateListener
type LicenseStateListener = (state: LicenseState) => void;OfflineState
type OfflineState =
| { mode: "online" }
| {
mode: "offline";
/** Expiration of the stored token, or null without a valid token. */
validUntil: Date | null;
/** Time left before validUntil, in milliseconds. 0 without a valid token. */
remainingMs: number;
};MachineFingerprint
type MachineFingerprint = string | (() => string | Promise<string>);LicenseError
Extends Error, with name set to "LicenseError".
| Property | Type | |
|---|---|---|
code | LicenseErrorCode | What failed. Branch on it, not on message. |
message | string | For logs. |
status | number | undefined | The HTTP status, when LicenseManager answered. |
latestAllowedVersion | string | null | undefined | For version_not_allowed only. |
isLocking | boolean | true when the license itself was refused. |
cause | unknown | The original error, when there is one. |
LicenseErrorCode
| Code | Locking | Source |
|---|---|---|
not_found | Yes | LicenseManager, 404. |
license_expired | Yes | LicenseManager, 403. |
version_not_allowed | Yes | LicenseManager, 403. |
machine_limit_reached | Yes | LicenseManager, 403. |
plan_limit_exceeded | No | LicenseManager, 402. |
validation_error | No | LicenseManager, 422, or an empty key. |
internal_error | No | LicenseManager, 500. |
network_error | No | The SDK: no answer, a timeout after 10 seconds, or an unknown error code, after the retries. |
invalid_response | No | The SDK: no token in the answer, or a token that failed verification. |
See the errors for what to show for each one.