@licensechain/javascript-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +518 -0
- package/dist/index.d.ts +763 -0
- package/dist/index.esm.js +1484 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1595 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/license-assertion.cjs +12 -0
- package/package.json +85 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 LicenseChain LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
# LicenseChain JavaScript SDK
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
|
|
5
|
+
[](https://www.npmjs.com/package/licensechain-sdk)
|
|
6
|
+
[](https://bundlephobia.com/result?p=licensechain-sdk)
|
|
7
|
+
|
|
8
|
+
Official JavaScript SDK for LicenseChain - Secure license management for web applications.
|
|
9
|
+
|
|
10
|
+
> Note: This is the browser/isomorphic **LicenseChain-JavaScript-SDK**. For server-only Node.js, use **LicenseChain-NodeJS-SDK**. See [docs.licensechain.app](https://docs.licensechain.app/).
|
|
11
|
+
## API Base
|
|
12
|
+
|
|
13
|
+
- Canonical API base: `https://api.licensechain.app/v1`
|
|
14
|
+
- API docs: [docs.licensechain.app](https://docs.licensechain.app/)
|
|
15
|
+
## License assertion JWT (RS256 + JWKS)
|
|
16
|
+
|
|
17
|
+
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`.
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
import { verifyLicenseAssertionJwt } from '@licensechain/javascript-sdk';
|
|
21
|
+
// or: const { verifyLicenseAssertionJwt } = require('@licensechain/javascript-sdk');
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`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.
|
|
25
|
+
|
|
26
|
+
**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.
|
|
27
|
+
|
|
28
|
+
## ๐ Features
|
|
29
|
+
|
|
30
|
+
- **๐ Secure Authentication** - User registration, login, and session management
|
|
31
|
+
- **๐ License Management** - Create, validate, update, and revoke licenses
|
|
32
|
+
- **๐ก๏ธ Hardware ID Validation** - Prevent license sharing and unauthorized access
|
|
33
|
+
- **๐ Webhook Support** - Real-time license events and notifications
|
|
34
|
+
- **๐ Analytics Integration** - Track license usage and performance metrics
|
|
35
|
+
- **โก High Performance** - Optimized for production workloads
|
|
36
|
+
- **๐ Async Operations** - Non-blocking HTTP requests and data processing
|
|
37
|
+
- **๐ ๏ธ Easy Integration** - Simple API with comprehensive documentation
|
|
38
|
+
|
|
39
|
+
## ๐ฆ Installation
|
|
40
|
+
|
|
41
|
+
### Method 1: npm (Recommended)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Install via npm
|
|
45
|
+
npm install @licensechain/javascript-sdk
|
|
46
|
+
|
|
47
|
+
# Or via yarn
|
|
48
|
+
yarn add licensechain-sdk
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Method 2: CDN
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<!-- ES6 Module -->
|
|
55
|
+
<script type="module">
|
|
56
|
+
import LicenseChain from 'https://cdn.skypack.dev/licensechain-sdk';
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<!-- UMD -->
|
|
60
|
+
<script src="https://unpkg.com/licensechain-sdk/dist/index.umd.js"></script>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Method 3: Manual Installation
|
|
64
|
+
|
|
65
|
+
1. Download the latest release from [GitHub Releases](https://github.com/LicenseChain/LicenseChain-JavaScript-SDK/releases)
|
|
66
|
+
2. Include the script in your HTML
|
|
67
|
+
3. Use the global `LicenseChain` object
|
|
68
|
+
|
|
69
|
+
## ๐ Quick Start
|
|
70
|
+
|
|
71
|
+
### Basic Setup
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
import LicenseChain from 'licensechain-sdk';
|
|
75
|
+
|
|
76
|
+
// Initialize the client
|
|
77
|
+
const client = new LicenseChain({
|
|
78
|
+
apiKey: 'your-api-key',
|
|
79
|
+
appName: 'your-app-name',
|
|
80
|
+
version: '1.0.0',
|
|
81
|
+
baseUrl: 'https://api.licensechain.app/v1'
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Connect to LicenseChain
|
|
85
|
+
try {
|
|
86
|
+
await client.connect();
|
|
87
|
+
console.log('Connected to LicenseChain successfully!');
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('Failed to connect:', error.message);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### User Authentication
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
// Register a new user
|
|
97
|
+
try {
|
|
98
|
+
const user = await client.register('username', 'password', 'email@example.com');
|
|
99
|
+
console.log('User registered successfully!');
|
|
100
|
+
console.log('User ID:', user.id);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('Registration failed:', error.message);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Login existing user
|
|
106
|
+
try {
|
|
107
|
+
const user = await client.login('username', 'password');
|
|
108
|
+
console.log('User logged in successfully!');
|
|
109
|
+
console.log('Session ID:', user.sessionId);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error('Login failed:', error.message);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### License Management
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
// Validate a license
|
|
119
|
+
try {
|
|
120
|
+
const license = await client.validateLicense('LICENSE-KEY-HERE');
|
|
121
|
+
console.log('License is valid!');
|
|
122
|
+
console.log('License Key:', license.key);
|
|
123
|
+
console.log('Status:', license.status);
|
|
124
|
+
console.log('Expires:', license.expires);
|
|
125
|
+
console.log('Features:', license.features.join(', '));
|
|
126
|
+
console.log('User:', license.user);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('License validation failed:', error.message);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Get user's licenses
|
|
132
|
+
try {
|
|
133
|
+
const licenses = await client.getUserLicenses();
|
|
134
|
+
console.log(`Found ${licenses.length} licenses:`);
|
|
135
|
+
licenses.forEach((license, index) => {
|
|
136
|
+
console.log(` ${index + 1}. ${license.key} - ${license.status} (Expires: ${license.expires})`);
|
|
137
|
+
});
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.error('Failed to get licenses:', error.message);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Hardware ID Validation
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
// Get hardware ID (automatically generated)
|
|
147
|
+
const hardwareId = client.getHardwareId();
|
|
148
|
+
console.log('Hardware ID:', hardwareId);
|
|
149
|
+
|
|
150
|
+
// Validate hardware ID with license
|
|
151
|
+
try {
|
|
152
|
+
const isValid = await client.validateHardwareId('LICENSE-KEY-HERE', hardwareId);
|
|
153
|
+
if (isValid) {
|
|
154
|
+
console.log('Hardware ID is valid for this license!');
|
|
155
|
+
} else {
|
|
156
|
+
console.log('Hardware ID is not valid for this license.');
|
|
157
|
+
}
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.error('Hardware ID validation failed:', error.message);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Webhook Integration
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
// Set up webhook handler
|
|
167
|
+
client.setWebhookHandler((event, data) => {
|
|
168
|
+
console.log('Webhook received:', event);
|
|
169
|
+
|
|
170
|
+
switch (event) {
|
|
171
|
+
case 'license.created':
|
|
172
|
+
console.log('New license created:', data.licenseKey);
|
|
173
|
+
break;
|
|
174
|
+
case 'license.updated':
|
|
175
|
+
console.log('License updated:', data.licenseKey);
|
|
176
|
+
break;
|
|
177
|
+
case 'license.revoked':
|
|
178
|
+
console.log('License revoked:', data.licenseKey);
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Start webhook listener
|
|
184
|
+
await client.startWebhookListener();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## ๐ API Endpoints
|
|
188
|
+
|
|
189
|
+
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.
|
|
190
|
+
|
|
191
|
+
### Base URL
|
|
192
|
+
- **Production**: `https://api.licensechain.app/v1`
|
|
193
|
+
- **Development**: `https://api.licensechain.app/v1`
|
|
194
|
+
|
|
195
|
+
### Available Endpoints
|
|
196
|
+
|
|
197
|
+
| Method | Endpoint | Description |
|
|
198
|
+
|--------|----------|-------------|
|
|
199
|
+
| `GET` | `/v1/health` | Health check |
|
|
200
|
+
| `POST` | `/v1/auth/login` | User login |
|
|
201
|
+
| `POST` | `/v1/auth/register` | User registration |
|
|
202
|
+
| `GET` | `/v1/apps` | List applications |
|
|
203
|
+
| `POST` | `/v1/apps` | Create application |
|
|
204
|
+
| `GET` | `/v1/licenses` | List licenses |
|
|
205
|
+
| `POST` | `/v1/licenses/verify` | Verify license |
|
|
206
|
+
| `GET` | `/v1/webhooks` | List webhooks |
|
|
207
|
+
| `POST` | `/v1/webhooks` | Create webhook |
|
|
208
|
+
| `GET` | `/v1/analytics` | Get analytics |
|
|
209
|
+
|
|
210
|
+
**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`).
|
|
211
|
+
|
|
212
|
+
## ๐ API Reference
|
|
213
|
+
|
|
214
|
+
### LicenseChain Client
|
|
215
|
+
|
|
216
|
+
#### Constructor
|
|
217
|
+
|
|
218
|
+
```javascript
|
|
219
|
+
const client = new LicenseChain({
|
|
220
|
+
apiKey: 'your-api-key',
|
|
221
|
+
appName: 'your-app-name',
|
|
222
|
+
version: '1.0.0',
|
|
223
|
+
baseUrl: 'https://api.licensechain.app/v1' // Optional
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Methods
|
|
228
|
+
|
|
229
|
+
##### Connection Management
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
// Connect to LicenseChain
|
|
233
|
+
await client.connect();
|
|
234
|
+
|
|
235
|
+
// Disconnect from LicenseChain
|
|
236
|
+
await client.disconnect();
|
|
237
|
+
|
|
238
|
+
// Check connection status
|
|
239
|
+
const isConnected = client.isConnected();
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
##### User Authentication
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// Register a new user
|
|
246
|
+
const user = await client.register(username, password, email);
|
|
247
|
+
|
|
248
|
+
// Login existing user
|
|
249
|
+
const user = await client.login(username, password);
|
|
250
|
+
|
|
251
|
+
// Logout current user
|
|
252
|
+
await client.logout();
|
|
253
|
+
|
|
254
|
+
// Get current user info
|
|
255
|
+
const user = await client.getCurrentUser();
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
##### License Management
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
// Validate a license
|
|
262
|
+
const license = await client.validateLicense(licenseKey);
|
|
263
|
+
|
|
264
|
+
// Get user's licenses
|
|
265
|
+
const licenses = await client.getUserLicenses();
|
|
266
|
+
|
|
267
|
+
// Create a new license
|
|
268
|
+
const license = await client.createLicense(userId, features, expires);
|
|
269
|
+
|
|
270
|
+
// Update a license
|
|
271
|
+
const license = await client.updateLicense(licenseKey, updates);
|
|
272
|
+
|
|
273
|
+
// Revoke a license
|
|
274
|
+
await client.revokeLicense(licenseKey);
|
|
275
|
+
|
|
276
|
+
// Extend a license
|
|
277
|
+
const license = await client.extendLicense(licenseKey, days);
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
##### Hardware ID Management
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
// Get hardware ID
|
|
284
|
+
const hardwareId = client.getHardwareId();
|
|
285
|
+
|
|
286
|
+
// Validate hardware ID
|
|
287
|
+
const isValid = await client.validateHardwareId(licenseKey, hardwareId);
|
|
288
|
+
|
|
289
|
+
// Bind hardware ID to license
|
|
290
|
+
await client.bindHardwareId(licenseKey, hardwareId);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
##### Webhook Management
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
// Set webhook handler
|
|
297
|
+
client.setWebhookHandler(handler);
|
|
298
|
+
|
|
299
|
+
// Start webhook listener
|
|
300
|
+
await client.startWebhookListener();
|
|
301
|
+
|
|
302
|
+
// Stop webhook listener
|
|
303
|
+
await client.stopWebhookListener();
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
##### Analytics
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
// Track event
|
|
310
|
+
await client.trackEvent(eventName, properties);
|
|
311
|
+
|
|
312
|
+
// Get analytics data
|
|
313
|
+
const analytics = await client.getAnalytics(timeRange);
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## ๐ง Configuration
|
|
317
|
+
|
|
318
|
+
### Environment Variables
|
|
319
|
+
|
|
320
|
+
Set these in your environment or through your build process:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Required
|
|
324
|
+
export LICENSECHAIN_API_KEY=your-api-key
|
|
325
|
+
export LICENSECHAIN_APP_NAME=your-app-name
|
|
326
|
+
export LICENSECHAIN_APP_VERSION=1.0.0
|
|
327
|
+
|
|
328
|
+
# Optional
|
|
329
|
+
export LICENSECHAIN_BASE_URL=https://api.licensechain.app/v1
|
|
330
|
+
export LICENSECHAIN_DEBUG=true
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Advanced Configuration
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
const client = new LicenseChain({
|
|
337
|
+
apiKey: 'your-api-key',
|
|
338
|
+
appName: 'your-app-name',
|
|
339
|
+
version: '1.0.0',
|
|
340
|
+
baseUrl: 'https://api.licensechain.app/v1',
|
|
341
|
+
timeout: 30000, // Request timeout in milliseconds
|
|
342
|
+
retries: 3, // Number of retry attempts
|
|
343
|
+
debug: false, // Enable debug logging
|
|
344
|
+
userAgent: 'MyApp/1.0.0' // Custom user agent
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## ๐ก๏ธ Security Features
|
|
349
|
+
|
|
350
|
+
### Hardware ID Protection
|
|
351
|
+
|
|
352
|
+
The SDK automatically generates and manages hardware IDs to prevent license sharing:
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
// Hardware ID is automatically generated and stored
|
|
356
|
+
const hardwareId = client.getHardwareId();
|
|
357
|
+
|
|
358
|
+
// Validate against license
|
|
359
|
+
const isValid = await client.validateHardwareId(licenseKey, hardwareId);
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Secure Communication
|
|
363
|
+
|
|
364
|
+
- All API requests use HTTPS
|
|
365
|
+
- API keys are securely stored and transmitted
|
|
366
|
+
- Session tokens are automatically managed
|
|
367
|
+
- Webhook signatures are verified
|
|
368
|
+
|
|
369
|
+
### License Validation
|
|
370
|
+
|
|
371
|
+
- Real-time license validation
|
|
372
|
+
- Hardware ID binding
|
|
373
|
+
- Expiration checking
|
|
374
|
+
- Feature-based access control
|
|
375
|
+
|
|
376
|
+
## ๐ Analytics and Monitoring
|
|
377
|
+
|
|
378
|
+
### Event Tracking
|
|
379
|
+
|
|
380
|
+
```javascript
|
|
381
|
+
// Track custom events
|
|
382
|
+
await client.trackEvent('app.started', {
|
|
383
|
+
level: 1,
|
|
384
|
+
playerCount: 10
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Track license events
|
|
388
|
+
await client.trackEvent('license.validated', {
|
|
389
|
+
licenseKey: 'LICENSE-KEY',
|
|
390
|
+
features: 'premium,unlimited'
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Performance Monitoring
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
// Get performance metrics
|
|
398
|
+
const metrics = await client.getPerformanceMetrics();
|
|
399
|
+
console.log('API Response Time:', metrics.averageResponseTime + 'ms');
|
|
400
|
+
console.log('Success Rate:', (metrics.successRate * 100).toFixed(2) + '%');
|
|
401
|
+
console.log('Error Count:', metrics.errorCount);
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## ๐ Error Handling
|
|
405
|
+
|
|
406
|
+
### Custom Error Types
|
|
407
|
+
|
|
408
|
+
```javascript
|
|
409
|
+
try {
|
|
410
|
+
const license = await client.validateLicense('invalid-key');
|
|
411
|
+
} catch (error) {
|
|
412
|
+
if (error instanceof LicenseChainError) {
|
|
413
|
+
switch (error.type) {
|
|
414
|
+
case 'INVALID_LICENSE':
|
|
415
|
+
console.error('License key is invalid');
|
|
416
|
+
break;
|
|
417
|
+
case 'EXPIRED_LICENSE':
|
|
418
|
+
console.error('License has expired');
|
|
419
|
+
break;
|
|
420
|
+
case 'NETWORK_ERROR':
|
|
421
|
+
console.error('Network connection failed');
|
|
422
|
+
break;
|
|
423
|
+
default:
|
|
424
|
+
console.error('LicenseChain error:', error.message);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Retry Logic
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
// Automatic retry for network errors
|
|
434
|
+
const client = new LicenseChain({
|
|
435
|
+
apiKey: 'your-api-key',
|
|
436
|
+
appName: 'your-app-name',
|
|
437
|
+
version: '1.0.0',
|
|
438
|
+
retries: 3, // Retry up to 3 times
|
|
439
|
+
timeout: 30000 // Wait 30 seconds for each request
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## ๐งช Testing
|
|
444
|
+
|
|
445
|
+
### Unit Tests
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
# Run tests
|
|
449
|
+
npm test
|
|
450
|
+
|
|
451
|
+
# Run tests with coverage
|
|
452
|
+
npm run test:coverage
|
|
453
|
+
|
|
454
|
+
# Run tests in watch mode
|
|
455
|
+
npm run test:watch
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Integration Tests
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
# Test with real API
|
|
462
|
+
npm run test:integration
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## ๐ Examples
|
|
466
|
+
|
|
467
|
+
See the `examples/` directory for complete examples:
|
|
468
|
+
|
|
469
|
+
- `basic-usage.js` - Basic SDK usage
|
|
470
|
+
- `advanced-features.js` - Advanced features and configuration
|
|
471
|
+
- `webhook-integration.js` - Webhook handling
|
|
472
|
+
|
|
473
|
+
## ๐ค Contributing
|
|
474
|
+
|
|
475
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
476
|
+
|
|
477
|
+
### Development Setup
|
|
478
|
+
|
|
479
|
+
1. Clone the repository
|
|
480
|
+
2. Install Node.js 16 or later
|
|
481
|
+
3. Install dependencies: `npm install`
|
|
482
|
+
4. Build: `npm run build`
|
|
483
|
+
5. Test: `npm test`
|
|
484
|
+
|
|
485
|
+
## ๐ License
|
|
486
|
+
|
|
487
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
488
|
+
|
|
489
|
+
## ๐ Support
|
|
490
|
+
|
|
491
|
+
- **Documentation**: [https://docs.licensechain.app/sdks/javascript](https://docs.licensechain.app/sdks/javascript)
|
|
492
|
+
- **Issues**: [GitHub Issues](https://github.com/LicenseChain/LicenseChain-JavaScript-SDK/issues)
|
|
493
|
+
- **Discord**: [LicenseChain Discord](https://discord.gg/licensechain)
|
|
494
|
+
- **Email**: support@licensechain.app
|
|
495
|
+
|
|
496
|
+
## ๐ Related Projects
|
|
497
|
+
|
|
498
|
+
- [LicenseChain Python SDK](https://github.com/LicenseChain/LicenseChain-Python-SDK)
|
|
499
|
+
- [LicenseChain Node.js SDK](https://github.com/LicenseChain/LicenseChain-NodeJS-SDK)
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
**Made with โค๏ธ for the JavaScript community**
|
|
503
|
+
|
|
504
|
+
## LicenseChain API (v1)
|
|
505
|
+
|
|
506
|
+
This SDK targets the **LicenseChain HTTP API v1** implemented by the LicenseChain API service.
|
|
507
|
+
|
|
508
|
+
- **Production base URL:** https://api.licensechain.app/v1
|
|
509
|
+
- **API reference:** [docs.licensechain.app](https://docs.licensechain.app/)
|
|
510
|
+
- **Baseline REST mapping (documented for integrators):**
|
|
511
|
+
- GET /health
|
|
512
|
+
- POST /auth/register
|
|
513
|
+
- POST /licenses/verify
|
|
514
|
+
- PATCH /licenses/:id/revoke
|
|
515
|
+
- PATCH /licenses/:id/activate
|
|
516
|
+
- PATCH /licenses/:id/extend
|
|
517
|
+
- GET /analytics/stats
|
|
518
|
+
|