import { Effect } from 'effect'; import { Tag } from 'effect/Context'; import { VoidIfEmpty } from 'effect/Types'; import { VoltroPlugin } from '@voltro/protocol'; import { YieldableError } from 'effect/Cause'; /** A numeric cap, or `'unlimited'` for no cap. */ export declare type EntitlementLimit = number | 'unlimited'; export declare const entitlementResolver: (tenantId: string | null | undefined, key: string) => Effect.Effect; /** Whether the current license grants `plugin` (name without the * `@voltro/plugin-` prefix) for production use. Reads the in-memory snapshot; * no license / no grant → false (fail-closed). */ export declare const licenseAllowsPlugin: (plugin: string) => boolean; /** The entitlement + feature grant a license carries. */ export declare interface LicenseClaims { /** If set, the license applies ONLY to this tenant id; unset = deployment-wide. */ readonly tenant?: string; /** Edition label (e.g. `'pro'`, `'enterprise'`). */ readonly edition: string; /** Per-key numeric limits. */ readonly entitlements: Readonly>; /** Boolean feature flags granted. */ readonly features: ReadonlyArray; /** Plugins licensed for production use (the "installed ≠ billable" gate — * a plugin can be present in the bundle but only run under a license grant). * Names without the `@voltro/plugin-` prefix, e.g. `['storage','search']`. */ readonly plugins: ReadonlyArray; /** Unix-seconds expiry (from the JWT `exp`). */ readonly exp: number; /** Unix-seconds issued-at (from the JWT `iat`), if present. */ readonly iat?: number; /** Key id from the JWS header — supports public-key rotation. */ readonly kid?: string; } export declare const LicenseService: Tag; /** The service handlers can `yield*` to read the current license directly (for * feature checks beyond billing's metered entitlements). */ export declare interface LicenseServiceShape { readonly snapshot: () => LicenseSnapshot | undefined; readonly limitFor: (tenantId: string | null | undefined, key: string) => number | undefined; readonly hasFeature: (feature: string) => boolean; readonly allowsPlugin: (plugin: string) => boolean; readonly edition: () => string | undefined; } export declare interface LicenseSnapshot { readonly claims: LicenseClaims; /** * Numeric limit for a `(tenant, key)` pair: a finite cap, `Infinity` for an * `'unlimited'` entitlement, or `undefined` when this license doesn't cover * the key (or is scoped to a different tenant) — the caller then falls back to * its own defaults (billing's static plan registry). */ readonly limitFor: (tenantId: string | null | undefined, key: string) => number | undefined; /** Whether a boolean feature is granted by the license. */ readonly hasFeature: (feature: string) => boolean; /** Whether a plugin is licensed for production use (name without the * `@voltro/plugin-` prefix, e.g. `'storage'`). The "installed ≠ billable" gate. */ readonly allowsPlugin: (plugin: string) => boolean; } export declare class LicenseVerifyError extends LicenseVerifyError_base<{ /** `expired` — past `exp`; `invalid` — bad signature; `key` — unusable public * key; `malformed` — verified but the payload isn't a license. */ readonly reason: 'expired' | 'invalid' | 'key' | 'malformed'; readonly message: string; }> { } declare const LicenseVerifyError_base: new = {}>(args: VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & { readonly _tag: "LicenseVerifyError"; } & Readonly; export declare const licensingPlugin: (options?: LicensingPluginOptions) => VoltroPlugin; export declare interface LicensingPluginOptions { /** Ed25519 public key (SPKI/PEM) that verifies the license. Falls back to * `VOLTRO_LICENSE_PUBLIC_KEY`. Safe to embed — it is a PUBLIC key. */ readonly publicKey?: string; /** The signed license token. Falls back to `VOLTRO_LICENSE_KEY`. */ readonly licenseKey?: string; /** URL to periodically re-fetch a fresh signed license (entitlement sync). * With `refreshMs`, a cluster-coordinated refresh re-verifies + re-installs * the snapshot. (The cloud endpoint that serves it ships in a later milestone.) */ readonly snapshotUrl?: string; /** Refresh interval (ms) for `snapshotUrl`. Default 15 minutes. */ readonly refreshMs?: number; /** Seconds an expired license is still honored (grace) before it goes dark. * Default 0. */ readonly graceSeconds?: number; /** Alias suffix when running more than one instance. */ readonly name?: string; } /** Thrown when a plugin's production use requires a license grant the current * license doesn't carry (the "installed ≠ billable" gate). */ export declare class PluginNotLicensed extends PluginNotLicensed_base<{ readonly plugin: string; }> { } declare const PluginNotLicensed_base: new = {}>(args: VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => YieldableError & { readonly _tag: "PluginNotLicensed"; } & Readonly; /** Gate a handler (or a plugin interceptor) on a plugin being licensed. Fails * `PluginNotLicensed` when it isn't. */ export declare const requireLicensedPlugin: (plugin: string) => Effect.Effect; /** * Verify a license token against an Ed25519 public key (SPKI/PEM), OFFLINE. * Returns the decoded {@link LicenseClaims} or a typed {@link LicenseVerifyError} * (expiry is enforced by `jose`). No network access. */ export declare const verifyLicense: (token: string, publicKeyPem: string) => Effect.Effect; export { }