# IronLicensing SDK for JavaScript/TypeScript Software licensing and activation SDK for JavaScript/TypeScript applications. Validate licenses, manage activations, check features, and handle trials. [![npm](https://img.shields.io/npm/v/@ironservices/licensing.svg)](https://www.npmjs.com/package/@ironservices/licensing) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## Installation ```bash npm install @ironservices/licensing ``` ## Quick Start ### Validate a License ```typescript import { LicenseClient } from '@ironservices/licensing'; const client = new LicenseClient({ publicKey: 'pk_live_xxxxx', productSlug: 'my-app', }); // Validate a license key const result = await client.validate('IRON-XXXX-XXXX-XXXX-XXXX'); if (result.valid) { console.log('License is valid!'); console.log('Expires:', result.license?.expiresAt); } ``` ### Activate a License ```typescript import { LicenseClient } from '@ironservices/licensing'; const client = new LicenseClient({ publicKey: 'pk_live_xxxxx', productSlug: 'my-app', }); // Activate on this machine const result = await client.activate('IRON-XXXX-XXXX-XXXX-XXXX'); if (result.valid) { console.log('License activated!'); console.log('Activations:', result.activations?.length); } ``` ### Check Features ```typescript import { LicenseClient, LicenseRequiredError } from '@ironservices/licensing'; const client = new LicenseClient({ publicKey: 'pk_live_xxxxx', productSlug: 'my-app', }); await client.validate('IRON-XXXX-XXXX-XXXX-XXXX'); // Check if feature is enabled if (client.hasFeature('premium')) { // Enable premium features } // Or require a feature (throws if not available) try { client.requireFeature('enterprise'); // Enterprise code here } catch (e) { if (e instanceof LicenseRequiredError) { console.log('Enterprise license required'); } } ``` ### Using the Global Client ```typescript import * as licensing from '@ironservices/licensing'; // Initialize once licensing.init({ publicKey: 'pk_live_xxxxx', productSlug: 'my-app', }); // Use anywhere await licensing.validate('IRON-XXXX-XXXX-XXXX-XXXX'); if (licensing.hasFeature('premium')) { // Premium features } console.log('Status:', licensing.getStatus()); console.log('Licensed:', licensing.isLicensed()); ``` ## Configuration ```typescript import { LicenseClient } from '@ironservices/licensing'; const client = new LicenseClient({ publicKey: 'pk_live_xxxxx', // Required productSlug: 'my-app', // Required apiBaseUrl: 'https://api.ironlicensing.com', debug: false, enableOfflineCache: true, cacheValidationMinutes: 60, offlineGraceDays: 7, storageKeyPrefix: 'ironlicensing', }); ``` ### Configuration Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `publicKey` | string | required | Your public key (pk_live_xxx or pk_test_xxx) | | `productSlug` | string | required | Your product slug | | `apiBaseUrl` | string | https://api.ironlicensing.com | API base URL | | `debug` | boolean | false | Enable debug logging | | `enableOfflineCache` | boolean | true | Cache validation results | | `cacheValidationMinutes` | number | 60 | Cache validity in minutes | | `offlineGraceDays` | number | 7 | Offline grace period in days | | `storageKeyPrefix` | string | 'ironlicensing' | Storage key prefix | ## License Status ```typescript type LicenseStatus = | 'valid' // License is valid | 'expired' // License has expired | 'suspended' // License is suspended | 'revoked' // License is revoked | 'invalid' // License key is invalid | 'trial' // Trial license | 'trial_expired' // Trial has expired | 'not_activated' // No license activated | 'unknown'; // Unknown status ``` ## Features ### Check Features ```typescript // Check if feature is enabled if (client.hasFeature('premium')) { enablePremiumFeatures(); } // Get feature details const feature = client.getFeature('max-users'); if (feature?.enabled) { console.log('Max users:', feature.metadata?.limit); } // Get all features const features = client.getFeatures(); features.forEach(f => { console.log(`${f.name}: ${f.enabled ? 'enabled' : 'disabled'}`); }); ``` ### Require Features ```typescript import { LicenseRequiredError } from '@ironservices/licensing'; try { client.requireFeature('enterprise'); // This code only runs if feature is available } catch (e) { if (e instanceof LicenseRequiredError) { showUpgradeDialog(); } } ``` ## Trial Management ```typescript // Start a trial const result = await client.startTrial('user@example.com'); if (result.valid) { console.log('Trial started!'); console.log('Expires:', result.license?.expiresAt); } // Check if trial if (client.isTrial) { showTrialBanner(client.expiresAt); } ``` ## Purchase Flow ```typescript // Get available tiers const tiers = await client.getTiers(); tiers.forEach(tier => { console.log(`${tier.name}: ${tier.price} ${tier.currency}/${tier.billingPeriod}`); }); // Start checkout const checkout = await client.startPurchase('tier-pro', 'user@example.com'); if (checkout.success) { // Redirect to checkout URL window.location.href = checkout.checkoutUrl!; } ``` ## Deactivation ```typescript // Deactivate on this machine const success = await client.deactivate(); if (success) { console.log('License deactivated'); } ``` ## License Change Events ```typescript // Listen for license changes const unsubscribe = client.onLicenseChange((license) => { if (license) { console.log('License updated:', license.status); } else { console.log('License removed'); } }); // Later: unsubscribe unsubscribe(); ``` ## Offline Support The SDK automatically caches validation results and supports offline usage: ```typescript const client = new LicenseClient({ publicKey: 'pk_live_xxxxx', productSlug: 'my-app', enableOfflineCache: true, cacheValidationMinutes: 60, // Use cache for 60 minutes offlineGraceDays: 7, // Allow 7 days offline }); // This will use cache if available const result = await client.validate(); if (result.cached) { console.log('Using cached validation'); } ``` ## Custom Storage ```typescript import { LicenseClient, StorageAdapter, LicenseCache } from '@ironservices/licensing'; // Implement custom storage class MyStorage implements StorageAdapter { get(key: string): string | null { return myDatabase.get(key); } set(key: string, value: string): void { myDatabase.set(key, value); } remove(key: string): void { myDatabase.delete(key); } } ``` ## TypeScript Support Full TypeScript support with exported types: ```typescript import type { LicenseOptions, License, LicenseResult, LicenseStatus, LicenseType, Feature, Activation, CheckoutResult, ProductTier, } from '@ironservices/licensing'; ``` ## Browser & Node.js The SDK works in both browser and Node.js environments: - **Browser**: Uses `localStorage` for caching - **Node.js**: Uses in-memory storage by default ## License MIT License - see [LICENSE](LICENSE) for details.