@moltlaunch/sdk 2.2.0 → 2.3.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/package.json +1 -1
- package/src/index.js +120 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -487,6 +487,7 @@ class MoltLaunch {
|
|
|
487
487
|
|
|
488
488
|
// ==========================================
|
|
489
489
|
// HARDWARE-ANCHORED IDENTITY (Anti-Sybil)
|
|
490
|
+
// DePIN-Rooted Device Identity
|
|
490
491
|
// ==========================================
|
|
491
492
|
|
|
492
493
|
/**
|
|
@@ -529,6 +530,101 @@ class MoltLaunch {
|
|
|
529
530
|
return { hardware, runtime, networkFingerprint };
|
|
530
531
|
}
|
|
531
532
|
|
|
533
|
+
/**
|
|
534
|
+
* Try to read TPM endorsement key hash for hardware-rooted identity
|
|
535
|
+
* @returns {string|null} SHA-256 hash of TPM data, or null if unavailable
|
|
536
|
+
* @private
|
|
537
|
+
*/
|
|
538
|
+
_getTPMFingerprint() {
|
|
539
|
+
const crypto = require('crypto');
|
|
540
|
+
const fs = require('fs');
|
|
541
|
+
const os = require('os');
|
|
542
|
+
|
|
543
|
+
// TPM 2.0 paths (Linux)
|
|
544
|
+
const tpmPaths = [
|
|
545
|
+
'/sys/class/tpm/tpm0/device/description',
|
|
546
|
+
'/sys/class/tpm/tpm0/tpm_version_major',
|
|
547
|
+
'/sys/class/dmi/id/board_serial',
|
|
548
|
+
'/sys/class/dmi/id/product_uuid',
|
|
549
|
+
'/sys/class/dmi/id/chassis_serial',
|
|
550
|
+
];
|
|
551
|
+
|
|
552
|
+
const tpmData = [];
|
|
553
|
+
for (const p of tpmPaths) {
|
|
554
|
+
try {
|
|
555
|
+
const data = fs.readFileSync(p, 'utf-8').trim();
|
|
556
|
+
if (data && data !== 'None' && data !== '') {
|
|
557
|
+
tpmData.push(data);
|
|
558
|
+
}
|
|
559
|
+
} catch {}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// macOS: use IOPlatformUUID
|
|
563
|
+
if (os.platform() === 'darwin') {
|
|
564
|
+
try {
|
|
565
|
+
const { execSync } = require('child_process');
|
|
566
|
+
const uuid = execSync('ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID', { encoding: 'utf-8' });
|
|
567
|
+
const match = uuid.match(/"([A-F0-9-]+)"/);
|
|
568
|
+
if (match) tpmData.push(match[1]);
|
|
569
|
+
} catch {}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (tpmData.length === 0) return null;
|
|
573
|
+
|
|
574
|
+
return crypto.createHash('sha256')
|
|
575
|
+
.update(tpmData.join('|'))
|
|
576
|
+
.digest('hex');
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Register a DePIN device attestation for hardware-rooted identity
|
|
581
|
+
* Links agent identity to a physically verified DePIN device
|
|
582
|
+
*
|
|
583
|
+
* @param {object} options - DePIN registration options
|
|
584
|
+
* @param {string} options.provider - DePIN provider name (e.g., 'io.net', 'akash', 'render')
|
|
585
|
+
* @param {string} options.deviceId - Device ID from the DePIN provider
|
|
586
|
+
* @param {string} [options.attestation] - Optional attestation data from the provider
|
|
587
|
+
* @param {string} options.agentId - Agent ID to bind DePIN identity to
|
|
588
|
+
* @returns {Promise<DePINRegistrationResult>}
|
|
589
|
+
*/
|
|
590
|
+
async registerDePINDevice(options = {}) {
|
|
591
|
+
const { provider, deviceId, attestation, agentId } = options;
|
|
592
|
+
|
|
593
|
+
const supported = ['io.net', 'akash', 'render', 'helium', 'hivemapper', 'nosana'];
|
|
594
|
+
|
|
595
|
+
if (!supported.includes(provider)) {
|
|
596
|
+
throw new Error(`Unsupported DePIN provider. Supported: ${supported.join(', ')}`);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const res = await fetch(`${this.baseUrl}/api/identity/depin`, {
|
|
600
|
+
method: 'POST',
|
|
601
|
+
headers: { 'Content-Type': 'application/json' },
|
|
602
|
+
body: JSON.stringify({
|
|
603
|
+
agentId,
|
|
604
|
+
depinProvider: provider,
|
|
605
|
+
deviceId,
|
|
606
|
+
attestation,
|
|
607
|
+
timestamp: Date.now()
|
|
608
|
+
})
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
if (!res.ok) throw new Error(`DePIN registration failed: ${res.status}`);
|
|
612
|
+
return res.json();
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Get identity trust report for an agent
|
|
617
|
+
* Shows trust ladder breakdown including DePIN and TPM attestation levels
|
|
618
|
+
*
|
|
619
|
+
* @param {string} agentId - Agent ID to get report for
|
|
620
|
+
* @returns {Promise<IdentityReport>}
|
|
621
|
+
*/
|
|
622
|
+
async getIdentityReport(agentId) {
|
|
623
|
+
const res = await fetch(`${this.baseUrl}/api/identity/${encodeURIComponent(agentId)}/report`);
|
|
624
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
625
|
+
return res.json();
|
|
626
|
+
}
|
|
627
|
+
|
|
532
628
|
/**
|
|
533
629
|
* Generate a hardware-anchored identity hash
|
|
534
630
|
* Combines hardware, runtime, code, and network fingerprints into a deterministic identity
|
|
@@ -548,6 +644,9 @@ class MoltLaunch {
|
|
|
548
644
|
includeHardware = true,
|
|
549
645
|
includeRuntime = true,
|
|
550
646
|
includeCode = false,
|
|
647
|
+
includeTPM = false,
|
|
648
|
+
depinProvider,
|
|
649
|
+
depinDeviceId,
|
|
551
650
|
codeEntry,
|
|
552
651
|
agentId,
|
|
553
652
|
anchor = false
|
|
@@ -590,6 +689,23 @@ class MoltLaunch {
|
|
|
590
689
|
components.push(`net:${netHash}`);
|
|
591
690
|
}
|
|
592
691
|
|
|
692
|
+
// TPM attestation (hardware-rooted identity - trust level 4)
|
|
693
|
+
let tpmHash = null;
|
|
694
|
+
if (includeTPM) {
|
|
695
|
+
tpmHash = this._getTPMFingerprint();
|
|
696
|
+
if (tpmHash) {
|
|
697
|
+
components.push(`tpm:${tpmHash}`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// DePIN device attestation (highest trust level 5)
|
|
702
|
+
if (depinProvider && depinDeviceId) {
|
|
703
|
+
const depinHash = crypto.createHash('sha256')
|
|
704
|
+
.update(`depin:${depinProvider}:${depinDeviceId}`)
|
|
705
|
+
.digest('hex');
|
|
706
|
+
components.push(`depin:${depinHash}`);
|
|
707
|
+
}
|
|
708
|
+
|
|
593
709
|
// Generate deterministic identity hash
|
|
594
710
|
const identityHash = crypto.createHash('sha256')
|
|
595
711
|
.update(components.join('|'))
|
|
@@ -602,6 +718,10 @@ class MoltLaunch {
|
|
|
602
718
|
includesRuntime: includeRuntime,
|
|
603
719
|
includesCode: includeCode && !!codeEntry,
|
|
604
720
|
includesNetwork: !!fingerprint.networkFingerprint,
|
|
721
|
+
includesTPM: includeTPM && !!tpmHash,
|
|
722
|
+
tpmHash: tpmHash || null,
|
|
723
|
+
depinProvider: depinProvider || null,
|
|
724
|
+
depinDeviceId: depinDeviceId || null,
|
|
605
725
|
generatedAt: new Date().toISOString(),
|
|
606
726
|
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days
|
|
607
727
|
agentId: agentId || null
|