Client integration
Integrate Hiphops product keys into your applications using the Hook client libraries for license validation.
Hook client library
The @hiphops/hook
client library provides a simple interface for license validation in JavaScript/TypeScript applications.
📖 View on GitHub
Installation
npm install @hiphops/hook
Basic usage
import { license } from '@hiphops/hook';
const getLicenseInfo = async () => {
try {
const info = await license();
if (info.verified) {
console.log('License is valid:', info.license);
// Access specific license fields
const maxSeats = info.license.seats;
console.log(`License valid for ${maxSeats} users`);
} else {
console.warn('License verification failed:', info.verify_failures);
// Your app should decide what to do here - typically exit or disable features
process.exit(1);
}
return info;
} catch (error) {
console.error('Error getting license info:', error);
// Handle missing LICENSE_TOKEN or other errors
process.exit(1);
}
};
License response structure
Valid license:
{
"verified": true,
"verify_failures": [],
"license": {
"seats": 10
},
"hiphops": {
"identity": "c_01jz3b9bz4ka7stedds7g3fjb7",
"project_id": "my-project-1234"
}
}
Invalid license:
{
"verified": false,
"verify_failures": ["invalid_license_token"],
"license": null,
"hiphops": {
"identity": "",
"project_id": ""
}
}
Setting up the license token
Hook reads the license token from the LICENSE_TOKEN
environment variable.
Local development
export LICENSE_TOKEN="your_jwt_token_here"
node your-app.js
Docker
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
# Set the license token
ENV LICENSE_TOKEN=""
CMD ["npm", "start"]
Docker Compose
version: '3.8'
services:
app:
build: .
environment:
- LICENSE_TOKEN=${LICENSE_TOKEN}
ports:
- '3000:3000'
Express.js integration
import { license } from '@hiphops/hook';
import express from 'express';
const app = express();
// License validation middleware
const validateLicense = async (req, res, next) => {
try {
const licenseInfo = await license();
if (!licenseInfo.verified) {
return res.status(403).json({
error: 'Invalid license',
failures: licenseInfo.verify_failures,
});
}
req.license = licenseInfo.license;
next();
} catch (error) {
res.status(500).json({ error: 'License validation failed' });
}
};
// Protected route
app.get('/api/protected', validateLicense, (req, res) => {
res.json({
message: 'Access granted',
license: req.license,
});
});
Feature gating
Use license fields to control application features:
const checkFeatureAccess = async (feature) => {
const licenseInfo = await license();
if (!licenseInfo.verified) {
return { allowed: false, reason: 'Invalid license' };
}
const config = licenseInfo.license;
switch (feature) {
case 'premium_features':
return {
allowed: config.tier === 'premium',
reason: config.tier !== 'premium' ? 'Premium tier required' : null,
};
case 'user_limit':
const currentUsers = getCurrentUserCount();
return {
allowed: currentUsers < config.seats,
reason: currentUsers >= config.seats ? 'User limit exceeded' : null,
};
default:
return { allowed: true };
}
};
Registry authentication
Product keys also provide Docker registry access. Customers can use their JWT token as Docker credentials:
docker login your-project.ctr.dev -u customer -p <jwt-token>
docker pull your-project.ctr.dev/your-image:latest
Error handling
Common failure scenarios
Missing license token:
// Hook will fail if LICENSE_TOKEN is not set
try {
const info = await license();
} catch (error) {
console.error('License check failed:', error.message);
// Handle gracefully - exit, show error, or disable features
}
Invalid or expired token:
const info = await license();
if (!info.verified) {
info.verify_failures.forEach((failure) => {
switch (failure) {
case 'invalid_license_token':
console.error('License token is invalid');
break;
case 'token_expired':
console.error('License token has expired');
break;
default:
console.error('License verification failed:', failure);
}
});
}
Handling license validation failures
Important: Your application must decide what to do when license validation fails. Common approaches include:
const info = await license();
if (!info.verified) {
// Option 1: Exit the application
console.error('Invalid license - application cannot start');
process.exit(1);
// Option 2: Disable premium features
enablePremiumFeatures = false;
// Option 3: Show error and continue in limited mode
showLicenseError('License validation failed');
enableLimitedMode = true;
}
Accessing license fields
License fields contain custom data defined in your product configuration:
const info = await license();
if (info.verified) {
// Access any custom field defined in your product
const seats = info.license.seats; // Number field
const expires = info.license.expires_at; // Date field
// Use fields to control application behavior
if (getCurrentUserCount() > seats) {
throw new Error(`User limit exceeded. Licensed for ${seats} users.`);
}
}
Custom binary path
Hook automatically manages the license validation binary, but you can specify a custom path:
export HIPHOPS_HOOK_BIN=/path/to/custom/hook-binary
Platform support
The Hook client works on:
- Node.js (16+)
- Deno (via npm compatibility)
- Bun
- Docker containers (Linux, macOS, Windows)