tauri-plugin-keylight-api
v0.7.0
Published
JavaScript/TypeScript bindings for the Keylight Tauri v2 plugin — license activation, validation, and entitlement checks.
Maintainers
Readme
tauri-plugin-keylight
Tauri v2 plugin for the Keylight licensing SDK — activate and validate license keys and gate features on entitlements from a Tauri desktop app.
This crate is the Rust side of the plugin; the matching JavaScript/TypeScript bindings are
published as tauri-plugin-keylight-api.
Install
Rust (src-tauri/Cargo.toml):
[dependencies]
tauri-plugin-keylight = { git = "https://github.com/keylight-dev/keylight-rust" }
keylight = { git = "https://github.com/keylight-dev/keylight-rust" }JavaScript:
npm add tauri-plugin-keylight-apiRegister the plugin
Fetch https://api.keylight.dev/your-tenant/.well-known/keylight-keys during setup,
using your tenant ID. Find the entry in keys whose kid matches primary_kid.
Use its kid and base64 public_key as the two .trusted_key(...) arguments
below. The public signing key is separate from your SDK key.
// src-tauri/src/main.rs
use keylight::KeylightConfig;
fn main() {
let cfg = KeylightConfig::builder("your-tenant", "your-product", "sdk_live_…")
.trusted_key("your-key-id", "<raw ed25519 public key, base64>")
.build();
tauri::Builder::default()
.plugin(tauri_plugin_keylight::init(cfg))
.run(tauri::generate_context!())
.expect("error while running tauri application");
}Permissions
The plugin does not fetch signing keys automatically. Configure them in Rust, then rebuild and restart the app before retrying activation. The SDK key authenticates the API request; the public signing key verifies the returned lease.
Add the plugin's default permission set to your capability file:
// src-tauri/capabilities/default.json
{
"permissions": ["keylight:default"]
}keylight:default allows activate, validate, has_entitlement, check_on_launch,
refresh_if_needed, active_revalidate, refresh_after_upgrade, and report_keyless_state. You
can also grant the per-command permissions individually (keylight:allow-activate,
keylight:allow-validate, keylight:allow-has-entitlement, etc.).
Use from the frontend
import { activate, validate, hasEntitlement } from 'tauri-plugin-keylight-api';
await activate('USER-LICENSE-KEY');
const ok = await validate();
if (await hasEntitlement('pro')) {
// unlock pro features
}Foreground revalidation
Wire activeRevalidate() to your window's focus event so a dashboard revoke lands within minutes
of the user next touching the app, instead of waiting for the normal refresh cadence or a
relaunch. It's debounced to 60s on the Rust side, so a hammered focus event is safe to call
directly.
From the frontend (idiomatic Tauri v2 pattern, using @tauri-apps/api/window):
import { getCurrentWindow } from '@tauri-apps/api/window';
import { activeRevalidate } from 'tauri-plugin-keylight-api';
getCurrentWindow().onFocusChanged(({ payload: focused }) => {
if (focused) {
activeRevalidate();
}
});From Rust, the equivalent is handling WindowEvent::Focused(true) in setup() or via
on_window_event on the app builder — call Keylight::active_revalidate() directly on the
Arc<Keylight> you already manage as plugin state, rather than round-tripping through the
active_revalidate command.
Post-upgrade refresh
After a customer completes an upgrade (e.g. returning from a hosted billing portal), call
refreshAfterUpgrade() to poll-revalidate briefly so the new entitlements unlock in the running
app without waiting for the normal refresh cadence:
import { refreshAfterUpgrade } from 'tauri-plugin-keylight-api';
const changed = await refreshAfterUpgrade(); // polls up to 30s, every 2s by default
if (changed) {
// re-check hasEntitlement(...) / refresh UI state
}This call can take up to the timeout to resolve. It is declared #[tauri::command(async)], so Tauri
runs it on its blocking thread pool rather than the main thread and the UI stays responsive while it
polls — but still await it once from a deliberate trigger (e.g. when the app regains focus after an
upgrade flow), not from a hot path such as every render.
License
MIT
