Official JavaScript SDK for LicenseChain - Secure license management for web applications.
Note: This is the browser/isomorphic LicenseChain-JavaScript-SDK. For server-only Node.js, use LicenseChain-NodeJS-SDK. See docs.licensechain.app.
- Canonical API base:
https://api.licensechain.app/v1 - API docs: docs.licensechain.app
Root exports match licensechain-node-sdk: verifyLicenseAssertionJwt, LICENSE_TOKEN_USE_CLAIM, and VerifyLicenseAssertionOptions (TypeScript). Use them after LicenseService.verifyWithDetails when the API returns license_token and license_jwks_uri.
import{verifyLicenseAssertionJwt}from'@licensechain/javascript-sdk';// or: const { verifyLicenseAssertionJwt } = require('@licensechain/javascript-sdk');jose is a runtime dependency (listed in package.json); CJS/ESM builds load it from node_modules. Legacy require('@licensechain/javascript-sdk/license-assertion.cjs') still works and delegates to the same implementation.
UMD / CDN:dist/index.umd.js treats jose as external; browser bundles that call verifyLicenseAssertionJwt must load a compatible jose build or use ESM with a bundler that resolves jose. Prefer Node or bundled ESM for JWT verification in production.
- 🔐 Secure Authentication - User registration, login, and session management
- 📜 License Management - Create, validate, update, and revoke licenses
- 🛡️ Hardware ID Validation - Prevent license sharing and unauthorized access
- 🔔 Webhook Support - Real-time license events and notifications
- 📊 Analytics Integration - Track license usage and performance metrics
- ⚡ High Performance - Optimized for production workloads
- 🔄 Async Operations - Non-blocking HTTP requests and data processing
- 🛠️ Easy Integration - Simple API with comprehensive documentation
# Install via npm
npm install @licensechain/javascript-sdk
# Or via yarn
yarn add licensechain-sdk<!-- ES6 Module --><scripttype="module">importLicenseChainfrom'https://cdn.skypack.dev/licensechain-sdk';</script><!-- UMD --><scriptsrc="https://unpkg.com/licensechain-sdk/dist/index.umd.js"></script>- Download the latest release from GitHub Releases
- Include the script in your HTML
- Use the global
LicenseChainobject
importLicenseChainfrom'licensechain-sdk';// Initialize the clientconstclient=newLicenseChain({apiKey: 'your-api-key',appName: 'your-app-name',version: '1.0.0',baseUrl: 'https://api.licensechain.app/v1'});// Connect to LicenseChaintry{awaitclient.connect();console.log('Connected to LicenseChain successfully!');}catch(error){console.error('Failed to connect:',error.message);}// Register a new usertry{constuser=awaitclient.register('username','password','email@example.com');console.log('User registered successfully!');console.log('User ID:',user.id);}catch(error){console.error('Registration failed:',error.message);}// Login existing usertry{constuser=awaitclient.login('username','password');console.log('User logged in successfully!');console.log('Session ID:',user.sessionId);}catch(error){console.error('Login failed:',error.message);}// Validate a licensetry{constlicense=awaitclient.validateLicense('LICENSE-KEY-HERE');console.log('License is valid!');console.log('License Key:',license.key);console.log('Status:',license.status);console.log('Expires:',license.expires);console.log('Features:',license.features.join(', '));console.log('User:',license.user);}catch(error){console.error('License validation failed:',error.message);}// Get user's licensestry{constlicenses=awaitclient.getUserLicenses();console.log(`Found ${licenses.length} licenses:`);licenses.forEach((license,index)=>{console.log(` ${index+1}. ${license.key} - ${license.status} (Expires: ${license.expires})`);});}catch(error){console.error('Failed to get licenses:',error.message);}// Get hardware ID (automatically generated)consthardwareId=client.getHardwareId();console.log('Hardware ID:',hardwareId);// Validate hardware ID with licensetry{constisValid=awaitclient.validateHardwareId('LICENSE-KEY-HERE',hardwareId);if(isValid){console.log('Hardware ID is valid for this license!');}else{console.log('Hardware ID is not valid for this license.');}}catch(error){console.error('Hardware ID validation failed:',error.message);}// Set up webhook handlerclient.setWebhookHandler((event,data)=>{console.log('Webhook received:',event);switch(event){case'license.created':
console.log('New license created:',data.licenseKey);break;case'license.updated':
console.log('License updated:',data.licenseKey);break;case'license.revoked':
console.log('License revoked:',data.licenseKey);break;}});// Start webhook listenerawaitclient.startWebhookListener();All endpoints target the LicenseChain HTTP API at https://api.licensechain.app/v1. The client accepts either the canonical /v1 base or the root host and normalizes requests to the same API version.
- Production:
https://api.licensechain.app/v1 - Development:
https://api.licensechain.app/v1
| Method | Endpoint | Description |
|---|---|---|
GET | /v1/health | Health check |
POST | /v1/auth/login | User login |
POST | /v1/auth/register | User registration |
GET | /v1/apps | List applications |
POST | /v1/apps | Create application |
GET | /v1/licenses | List licenses |
POST | /v1/licenses/verify | Verify license |
GET | /v1/webhooks | List webhooks |
POST | /v1/webhooks | Create webhook |
GET | /v1/analytics | Get analytics |
Note: The SDK automatically prepends /v1 to all endpoints, so you only need to specify the path (e.g., /auth/login instead of /v1/auth/login).
constclient=newLicenseChain({apiKey: 'your-api-key',appName: 'your-app-name',version: '1.0.0',baseUrl: 'https://api.licensechain.app/v1'// Optional});// Connect to LicenseChainawaitclient.connect();// Disconnect from LicenseChainawaitclient.disconnect();// Check connection statusconstisConnected=client.isConnected();// Register a new userconstuser=awaitclient.register(username,password,email);// Login existing userconstuser=awaitclient.login(username,password);// Logout current userawaitclient.logout();// Get current user infoconstuser=awaitclient.getCurrentUser();// Validate a licenseconstlicense=awaitclient.validateLicense(licenseKey);// Get user's licensesconstlicenses=awaitclient.getUserLicenses();// Create a new licenseconstlicense=awaitclient.createLicense(userId,features,expires);// Update a licenseconstlicense=awaitclient.updateLicense(licenseKey,updates);// Revoke a licenseawaitclient.revokeLicense(licenseKey);// Extend a licenseconstlicense=awaitclient.extendLicense(licenseKey,days);// Get hardware IDconsthardwareId=client.getHardwareId();// Validate hardware IDconstisValid=awaitclient.validateHardwareId(licenseKey,hardwareId);// Bind hardware ID to licenseawaitclient.bindHardwareId(licenseKey,hardwareId);// Set webhook handlerclient.setWebhookHandler(handler);// Start webhook listenerawaitclient.startWebhookListener();// Stop webhook listenerawaitclient.stopWebhookListener();// Track eventawaitclient.trackEvent(eventName,properties);// Get analytics dataconstanalytics=awaitclient.getAnalytics(timeRange);Set these in your environment or through your build process:
# Requiredexport LICENSECHAIN_API_KEY=your-api-key
export LICENSECHAIN_APP_NAME=your-app-name
export LICENSECHAIN_APP_VERSION=1.0.0
# Optionalexport LICENSECHAIN_BASE_URL=https://api.licensechain.app/v1
export LICENSECHAIN_DEBUG=trueconstclient=newLicenseChain({apiKey: 'your-api-key',appName: 'your-app-name',version: '1.0.0',baseUrl: 'https://api.licensechain.app/v1',timeout: 30000,// Request timeout in millisecondsretries: 3,// Number of retry attemptsdebug: false,// Enable debug logginguserAgent: 'MyApp/1.0.0'// Custom user agent});The SDK automatically generates and manages hardware IDs to prevent license sharing:
// Hardware ID is automatically generated and storedconsthardwareId=client.getHardwareId();// Validate against licenseconstisValid=awaitclient.validateHardwareId(licenseKey,hardwareId);- All API requests use HTTPS
- API keys are securely stored and transmitted
- Session tokens are automatically managed
- Webhook signatures are verified
- Real-time license validation
- Hardware ID binding
- Expiration checking
- Feature-based access control
// Track custom eventsawaitclient.trackEvent('app.started',{level: 1,playerCount: 10});// Track license eventsawaitclient.trackEvent('license.validated',{licenseKey: 'LICENSE-KEY',features: 'premium,unlimited'});// Get performance metricsconstmetrics=awaitclient.getPerformanceMetrics();console.log('API Response Time:',metrics.averageResponseTime+'ms');console.log('Success Rate:',(metrics.successRate*100).toFixed(2)+'%');console.log('Error Count:',metrics.errorCount);try{constlicense=awaitclient.validateLicense('invalid-key');}catch(error){if(errorinstanceofLicenseChainError){switch(error.type){case'INVALID_LICENSE':
console.error('License key is invalid');break;case'EXPIRED_LICENSE':
console.error('License has expired');break;case'NETWORK_ERROR':
console.error('Network connection failed');break;default:
console.error('LicenseChain error:',error.message);}}}// Automatic retry for network errorsconstclient=newLicenseChain({apiKey: 'your-api-key',appName: 'your-app-name',version: '1.0.0',retries: 3,// Retry up to 3 timestimeout: 30000// Wait 30 seconds for each request});# Run tests
npm test# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch# Test with real API
npm run test:integrationSee the examples/ directory for complete examples:
basic-usage.js- Basic SDK usageadvanced-features.js- Advanced features and configurationwebhook-integration.js- Webhook handling
We welcome contributions! Please see our Contributing Guide for details.
- Clone the repository
- Install Node.js 16 or later
- Install dependencies:
npm install - Build:
npm run build - Test:
npm test
This project is licensed under the Elastic License 2.0 (ELv2) — see the LICENSE file for details.
- Documentation: https://docs.licensechain.app/sdks/javascript
- Issues: GitHub Issues
- Discord: LicenseChain Discord
- Email: support@licensechain.app
Made with ❤️ for the JavaScript community
This SDK targets the LicenseChain HTTP API v1 implemented by the LicenseChain API service.
- Production base URL:https://api.licensechain.app/v1
- API reference:docs.licensechain.app
- Baseline REST mapping (documented for integrators):
- GET /health
- POST /auth/register
- POST /licenses/verify
- PATCH /licenses/:id/revoke
- PATCH /licenses/:id/activate
- PATCH /licenses/:id/extend
- GET /analytics/stats