@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +120 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltlaunch/sdk",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "MoltLaunch SDK - On-chain AI verification for AI agents",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
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