@moltlaunch/sdk 2.2.0 → 2.4.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 (3) hide show
  1. package/README.md +264 -338
  2. package/package.json +1 -1
  3. package/src/index.js +289 -0
package/README.md CHANGED
@@ -1,462 +1,388 @@
1
- # @moltlaunch/sdk
1
+ <p align="center">
2
+ <h1 align="center">@moltlaunch/sdk</h1>
3
+ </p>
2
4
 
3
- On-chain AI verification for AI agents on Solana.
5
+ <p align="center">
6
+ <strong>Hardware-anchored identity, STARK proofs, and Sybil detection for AI agents on Solana</strong>
7
+ </p>
4
8
 
5
- ## Installation
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@moltlaunch/sdk"><img src="https://img.shields.io/npm/v/@moltlaunch/sdk" alt="npm" /></a>
11
+ <a href="https://web-production-419d9.up.railway.app"><img src="https://img.shields.io/badge/API-live-brightgreen" alt="API" /></a>
12
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="MIT" /></a>
13
+ </p>
14
+
15
+ ---
16
+
17
+ ## Install
6
18
 
7
19
  ```bash
8
20
  npm install @moltlaunch/sdk
9
21
  ```
10
22
 
11
- ## Quick Start
23
+ ## What It Does
12
24
 
13
- ```javascript
14
- const { MoltLaunch } = require('@moltlaunch/sdk');
25
+ | Feature | Description |
26
+ |---------|-------------|
27
+ | **Hardware Identity** | Tie agent identity to physical hardware — CPU, TPM, DePIN devices |
28
+ | **Sybil Detection** | Detect duplicate agents sharing the same infrastructure |
29
+ | **Agent Verification** | Score agents 0-100 with on-chain AI |
30
+ | **STARK Proofs** | Prove "score ≥ 60" without revealing the actual score |
31
+ | **Behavioral Scoring** | Track agent behavior over time via execution traces |
32
+ | **On-Chain Anchoring** | Write attestations to Solana (Memo program) |
33
+ | **DePIN Integration** | Link identity to io.net, Akash, Render, Helium, Nosana |
34
+
35
+ ---
36
+
37
+ ## Quick Start
15
38
 
39
+ ```typescript
40
+ import { MoltLaunch } from "@moltlaunch/sdk";
16
41
  const ml = new MoltLaunch();
17
42
 
18
43
  // Verify an agent
19
44
  const result = await ml.verify({
20
- agentId: 'my-trading-agent',
21
- capabilities: ['trading', 'analysis'],
22
- codeUrl: 'https://github.com/org/agent',
23
- documentation: true,
24
- testCoverage: 85,
25
- codeLines: 3000
45
+ agentId: "my-agent",
46
+ capabilities: ["trading"],
47
+ codeUrl: "https://github.com/org/repo"
26
48
  });
27
49
 
28
50
  console.log(result.score); // 78
29
- console.log(result.tier); // 'good'
51
+ console.log(result.tier); // "good"
30
52
  console.log(result.verified); // true
31
53
  ```
32
54
 
33
- ## On-Chain AI
34
-
35
- MoltLaunch runs verification scoring **on Solana** via Cauldron/Frostbite RISC-V VM.
36
-
37
- ```
38
- Network: Solana Devnet
39
- VM: FHcy35f4NGZK9b6j5TGMYstfB6PXEtmNbMLvjfR1y2Li
40
- Program: FRsToriMLgDc1Ud53ngzHUZvCRoazCaGeGUuzkwoha7m
41
- ```
42
-
43
- ## API Reference
44
-
45
- ### Constructor
55
+ ---
46
56
 
47
- ```javascript
48
- const ml = new MoltLaunch({
49
- baseUrl: 'https://web-production-419d9.up.railway.app', // default
50
- apiKey: 'optional-api-key'
51
- });
52
- ```
57
+ ## 🔑 Hardware-Anchored Identity (Anti-Sybil)
53
58
 
54
- ### verify(options)
59
+ The core feature. Tie agent identity to physical hardware so Sybil attacks cost real money.
55
60
 
56
- Run on-chain AI verification for an agent.
61
+ ### Generate Identity
57
62
 
58
- ```javascript
59
- const result = await ml.verify({
60
- agentId: 'my-agent', // required
61
- wallet: 'SolanaAddress', // optional
62
- capabilities: ['trading'], // optional
63
- codeUrl: 'https://github.com/...', // optional
64
- documentation: true, // optional
65
- testCoverage: 80, // optional, 0-100
66
- codeLines: 5000 // optional
63
+ ```typescript
64
+ const identity = await ml.generateIdentity({
65
+ includeHardware: true, // CPU, memory, hostname
66
+ includeRuntime: true, // Node version, OS
67
+ includeCode: true, // SHA-256 of agent's main file
68
+ includeTPM: true, // TPM endorsement key (if available)
69
+ codeEntry: "./index.js",
70
+ agentId: "my-agent",
71
+ anchor: true // Write to Solana
67
72
  });
68
- ```
69
73
 
70
- Returns:
71
- ```javascript
72
- {
73
- agentId: 'my-agent',
74
- verified: true, // score >= 60
75
- score: 78,
76
- tier: 'good', // 'excellent'|'good'|'needs_work'|'poor'
77
- features: { ... },
78
- onChainAI: {
79
- enabled: true,
80
- executedOnChain: true,
81
- vm: 'FHcy35f...',
82
- program: 'FRsTo...'
83
- },
84
- attestation: {
85
- type: 'deep-verification-onchain',
86
- timestamp: '2026-02-07T...',
87
- hash: 'abc123...'
88
- }
89
- }
74
+ console.log(identity.hash); // "7f04b937d885..."
75
+ console.log(identity.trustLevel); // 3 (hardware-anchored)
76
+ console.log(identity.anchored); // true
77
+ console.log(identity.anchorExplorer); // Solana explorer link
90
78
  ```
91
79
 
92
- ### getStatus(agentId)
80
+ Same machine + same code = **same identity hash**. Can't fake 10 different agents on one server.
93
81
 
94
- Check existing verification status.
82
+ ### Trust Levels
95
83
 
96
- ```javascript
97
- const status = await ml.getStatus('my-agent');
98
- console.log(status.verified); // true
99
- console.log(status.score); // 78
100
- console.log(status.expiresAt); // '2026-03-09T...'
101
- ```
84
+ | Level | Method | Sybil Cost |
85
+ |-------|--------|------------|
86
+ | 0 | None | $0 |
87
+ | 1 | API key | $0 |
88
+ | 2 | Code hash | $0 |
89
+ | 3 | **Hardware fingerprint** | **$100/mo** |
90
+ | 4 | **TPM attestation** | **$200+/mo** |
91
+ | 5 | **DePIN device** | **$500+/mo** |
102
92
 
103
- ### getStatusBatch(agentIds)
93
+ ### Check Two Agents for Sybil
104
94
 
105
- Check multiple agents at once.
95
+ ```typescript
96
+ const result = await ml.checkSybil("agent-1", "agent-2");
106
97
 
107
- ```javascript
108
- const batch = await ml.getStatusBatch(['agent-1', 'agent-2', 'agent-3']);
109
- console.log(batch.verified); // 2 (count of verified)
110
- console.log(batch.results); // [{ agentId, verified, score, tier }, ...]
98
+ // {
99
+ // sameIdentity: true,
100
+ // sybilRisk: "HIGH",
101
+ // reason: "Same hardware fingerprint likely same operator",
102
+ // recommendation: "Do not seat at same table"
103
+ // }
111
104
  ```
112
105
 
113
- ### getOnChainInfo()
106
+ ### Check a Table (Multi-Agent)
114
107
 
115
- Get on-chain AI deployment information.
108
+ ```typescript
109
+ const table = await ml.checkTableSybils([
110
+ "BluffMaster", "TightBot", "AggroAlice",
111
+ "SuspiciousBot", "FishBot", "NitNancy"
112
+ ]);
116
113
 
117
- ```javascript
118
- const info = await ml.getOnChainInfo();
119
- console.log(info.deployment.vm); // VM address
120
- console.log(info.features); // Scoring features
114
+ // {
115
+ // safe: false,
116
+ // sybilClusters: [["BluffMaster", "SuspiciousBot"]],
117
+ // flaggedAgents: ["BluffMaster", "SuspiciousBot"],
118
+ // recommendation: "1 Sybil cluster — 2 agents share hardware"
119
+ // }
121
120
  ```
122
121
 
123
- ### applyToPool(options)
122
+ ### DePIN Device Registration
124
123
 
125
- Apply an agent to a staking pool.
126
-
127
- ```javascript
128
- const result = await ml.applyToPool({
129
- agentId: 'my-agent',
130
- wallet: 'SolanaAddress',
131
- topic: 'trading',
132
- strategy: 'momentum'
124
+ ```typescript
125
+ await ml.registerDePINDevice({
126
+ provider: "io.net", // or: akash, render, helium, hivemapper, nosana
127
+ deviceId: "device_abc123",
128
+ agentId: "my-agent"
133
129
  });
130
+ // Trust level → 5 (highest)
134
131
  ```
135
132
 
136
- ### getPools(topic?)
137
-
138
- Get pool information.
139
-
140
- ```javascript
141
- const pools = await ml.getPools(); // all pools
142
- const trading = await ml.getPools('trading'); // specific topic
143
- ```
144
-
145
- ### getLeaderboard()
146
-
147
- Get agent leaderboard by efficiency.
148
-
149
- ```javascript
150
- const leaderboard = await ml.getLeaderboard();
151
- ```
152
-
153
- ### isHealthy()
154
-
155
- Check API health.
156
-
157
- ```javascript
158
- const healthy = await ml.isHealthy(); // true or false
159
- ```
160
-
161
- ## Scoring
162
-
163
- ### Features
164
-
165
- | Feature | Weight | Max Points |
166
- |---------|--------|------------|
167
- | hasGithub | +15 | 15 |
168
- | hasApiEndpoint | +20 | 20 |
169
- | capabilityCount | +5 each | 25 |
170
- | codeLines | +0.3/100 | 15 |
171
- | hasDocumentation | +10 | 10 |
172
- | testCoverage | +0.2/% | 20 |
173
-
174
- ### Tiers
175
-
176
- | Tier | Score | Meaning |
177
- |------|-------|---------|
178
- | excellent | 80-100 | Production ready |
179
- | good | 60-79 | Verified |
180
- | needs_work | 40-59 | Needs improvement |
181
- | poor | 0-39 | Not ready |
182
-
183
- ### Helper Functions
184
-
185
- ```javascript
186
- const { getTier, isVerified } = require('@moltlaunch/sdk');
187
-
188
- getTier(85); // 'excellent'
189
- getTier(65); // 'good'
190
- isVerified(75); // true
191
- isVerified(55); // false
192
- ```
193
-
194
- ## Constants
195
-
196
- ```javascript
197
- const { DEPLOYMENT, SCORE_TIERS, DEFAULT_BASE_URL } = require('@moltlaunch/sdk');
198
-
199
- console.log(DEPLOYMENT.vm); // VM address
200
- console.log(SCORE_TIERS.good); // { min: 60, max: 79, label: 'Verified' }
201
- ```
202
-
203
- ## Integration Examples
204
-
205
- ### TUNA Agent Launchpad
206
-
207
- ```javascript
208
- // Before allowing agent to trade
209
- const { verified, score } = await ml.getStatus(agentId);
210
- if (!verified) {
211
- throw new Error(`Agent must be verified. Current score: ${score}`);
212
- }
213
- ```
214
-
215
- ### AIoOS State Machine
133
+ ### Identity Report
216
134
 
217
- ```javascript
218
- // Trigger VERIFIED state transition
219
- const result = await ml.verify({ agentId, capabilities });
220
- if (result.verified) {
221
- await aioos.transitionState(agentId, 'VERIFIED');
222
- }
223
- ```
224
-
225
- ### Staking Pool Gateway
135
+ ```typescript
136
+ const report = await ml.getIdentityReport("my-agent");
226
137
 
227
- ```javascript
228
- // Require verification before pool access
229
- app.post('/pool/join', async (req, res) => {
230
- const status = await ml.getStatus(req.body.agentId);
231
- if (!status.verified) {
232
- return res.status(403).json({ error: 'Verification required' });
233
- }
234
- // Allow access...
235
- });
138
+ // {
139
+ // trustLevel: 3,
140
+ // trustLadder: {
141
+ // level0: { status: "passed" },
142
+ // level1: { status: "passed" },
143
+ // level2: { status: "passed" },
144
+ // level3: { status: "passed", description: "Hardware fingerprint" },
145
+ // level4: { status: "missing", description: "TPM attestation" },
146
+ // level5: { status: "missing", description: "DePIN device" }
147
+ // },
148
+ // sybilResistance: { current: "$100/mo", level: 3, maxLevel: 5 }
149
+ // }
236
150
  ```
237
151
 
238
- ## STARK Proofs (v2.1+)
152
+ ---
239
153
 
240
- Privacy-preserving proofs that prove properties without revealing exact values.
154
+ ## 🔐 STARK Proofs (Privacy-Preserving)
241
155
 
242
- ### generateProof(agentId, options)
156
+ Prove properties about your agent without revealing the underlying data.
243
157
 
244
- Generate a threshold proof: proves "score >= X" without revealing exact score.
158
+ ### Threshold Proof
245
159
 
246
- ```javascript
247
- const proof = await ml.generateProof('my-agent', { threshold: 60 });
160
+ ```typescript
161
+ // Prove "score >= 60" without revealing exact score
162
+ const proof = await ml.generateProof("my-agent", { threshold: 60 });
248
163
 
249
- console.log(proof.valid); // true
250
- console.log(proof.claim); // "Score >= 60"
251
- console.log(proof.proof.commitment); // cryptographic commitment
252
- // Verifier knows: agent passed 60
253
- // Verifier doesn't know: actual score (could be 61 or 99)
164
+ console.log(proof.valid); // true
165
+ console.log(proof.claim); // "Score >= 60"
166
+ console.log(proof.proof.commitment); // cryptographic commitment
167
+ // Verifier knows: passed 60. Doesn't know: scored 61 or 99.
254
168
  ```
255
169
 
256
- ### generateConsistencyProof(agentId, options)
257
-
258
- Prove "maintained >= threshold for N periods" without revealing individual scores.
170
+ ### Consistency Proof
259
171
 
260
- ```javascript
261
- const proof = await ml.generateConsistencyProof('my-agent', {
172
+ ```typescript
173
+ // Prove "maintained >= 60 for 30 days"
174
+ const proof = await ml.generateConsistencyProof("my-agent", {
262
175
  threshold: 60,
263
176
  days: 30
264
177
  });
265
-
266
- console.log(proof.periodCount); // 30
267
- console.log(proof.timeRange); // { start: '...', end: '...' }
268
- console.log(proof.valid); // true if ALL periods met threshold
178
+ // Hides individual daily scores
269
179
  ```
270
180
 
271
- ### generateStreakProof(agentId, options)
181
+ ### Streak Proof
272
182
 
273
- Prove "N+ consecutive periods at >= threshold".
274
-
275
- ```javascript
276
- const proof = await ml.generateStreakProof('my-agent', {
183
+ ```typescript
184
+ // Prove "7+ consecutive periods above threshold"
185
+ const proof = await ml.generateStreakProof("my-agent", {
277
186
  threshold: 60,
278
187
  minStreak: 7
279
188
  });
280
-
281
- // Proves agent maintained 7+ consecutive good periods
282
- // Without revealing actual streak length
283
189
  ```
284
190
 
285
- ### generateStabilityProof(agentId, options)
286
-
287
- Prove "score variance stayed below threshold".
191
+ ### Stability Proof
288
192
 
289
- ```javascript
290
- const proof = await ml.generateStabilityProof('my-agent', {
193
+ ```typescript
194
+ // Prove "score variance stayed below 100"
195
+ const proof = await ml.generateStabilityProof("my-agent", {
291
196
  maxVariance: 100
292
197
  });
293
-
294
- // Proves consistent performance without volatility
295
- // Without revealing actual variance
296
- ```
297
-
298
- ### Proof Cost Estimate
299
-
300
- ```javascript
301
- const cost = await ml.getProofCost('consistency');
302
- console.log(cost.computeMs); // 120
303
- console.log(cost.estimatedCost); // '$0.002'
304
198
  ```
305
199
 
306
- ## Execution Traces (Behavioral Scoring)
200
+ ---
307
201
 
308
- Submit and query behavioral traces for continuous reputation.
202
+ ## 📊 Execution Traces (Behavioral Scoring)
309
203
 
310
- ### submitTrace(agentId, data)
204
+ Submit behavioral data to build continuous reputation.
311
205
 
312
- Submit execution data for behavioral scoring.
206
+ ### Submit a Trace
313
207
 
314
- ```javascript
315
- const trace = await ml.submitTrace('my-agent', {
316
- period: {
317
- start: '2026-02-01T00:00:00Z',
318
- end: '2026-02-07T23:59:59Z'
208
+ ```typescript
209
+ const trace = await ml.submitTrace("my-agent", {
210
+ period: {
211
+ start: "2026-02-01T00:00:00Z",
212
+ end: "2026-02-07T23:59:59Z"
319
213
  },
320
214
  summary: {
321
215
  totalActions: 150,
322
216
  successRate: 0.92,
323
- errorRate: 0.03,
324
- avgResponseTime: 120,
325
- // Domain-specific metrics
326
217
  tradesExecuted: 45,
327
218
  winRate: 0.73
328
219
  }
329
220
  });
330
221
 
331
- console.log(trace.traceId); // 'trace_abc123'
332
- console.log(trace.commitment); // Merkle root
333
- console.log(trace.behavioralScore); // +15 points
222
+ console.log(trace.traceId); // "trace_abc123"
223
+ console.log(trace.commitment); // Merkle root
224
+ console.log(trace.onChainAnchor); // { signature, explorer } (auto-anchored)
334
225
  ```
335
226
 
336
- ### getBehavioralScore(agentId)
337
-
338
- Get current behavioral score from all traces.
339
-
340
- ```javascript
341
- const score = await ml.getBehavioralScore('my-agent');
227
+ ### Get Behavioral Score
342
228
 
343
- console.log(score.score); // 22
344
- console.log(score.breakdown); // { hasTraces: 5, verified: 5, history7d: 5, ... }
345
- console.log(score.traceCount); // 12
229
+ ```typescript
230
+ const score = await ml.getBehavioralScore("my-agent");
231
+ // { score: 22, breakdown: { hasTraces: 5, verified: 5, ... }, traceCount: 12 }
346
232
  ```
347
233
 
348
- ### anchorTrace(traceId)
234
+ ### Anchor Trace On-Chain
349
235
 
350
- Anchor a trace commitment on-chain for tamper-proof audit.
351
-
352
- ```javascript
353
- const anchor = await ml.anchorTrace('trace_abc123');
354
-
355
- console.log(anchor.anchored); // true
356
- console.log(anchor.txSignature); // Solana transaction signature
357
- console.log(anchor.slot); // 12345678
236
+ ```typescript
237
+ const anchor = await ml.anchorTrace("trace_abc123");
238
+ // { anchored: true, txSignature: "4EXao...", slot: 12345678 }
358
239
  ```
359
240
 
360
- ## Helper Methods
241
+ ---
242
+
243
+ ## 🧠 Agent Verification
361
244
 
362
- ### isVerified(agentId)
245
+ ### Deep Verification
363
246
 
364
- Quick boolean check.
247
+ ```typescript
248
+ const result = await ml.verify({
249
+ agentId: "my-agent",
250
+ wallet: "SolanaAddress",
251
+ capabilities: ["trading", "analysis"],
252
+ codeUrl: "https://github.com/org/repo",
253
+ documentation: true,
254
+ testCoverage: 85,
255
+ codeLines: 3000
256
+ });
365
257
 
366
- ```javascript
367
- if (await ml.isVerified('suspicious-agent')) {
368
- allowAccess();
369
- }
258
+ // {
259
+ // verified: true,
260
+ // score: 78,
261
+ // tier: "good", // excellent (80+) | good (60+) | needs_work (40+) | poor
262
+ // onChainAI: { enabled: true, executedOnChain: true },
263
+ // attestation: { hash: "abc123...", expiresAt: "2026-03-10" }
264
+ // }
370
265
  ```
371
266
 
372
- ### checkCapability(agentId, capability, minScore)
267
+ ### Quick Checks
373
268
 
374
- Check if agent has a capability at a minimum score.
269
+ ```typescript
270
+ // Boolean check
271
+ if (await ml.isVerified("agent-id")) { ... }
375
272
 
376
- ```javascript
377
- // Check if agent can handle escrow at score >= 70
378
- const canEscrow = await ml.checkCapability('my-agent', 'escrow', 70);
273
+ // Capability check with minimum score
274
+ const canTrade = await ml.checkCapability("agent-id", "trading", 70);
379
275
 
380
- if (canEscrow) {
381
- // Allow high-value escrow transactions
382
- }
276
+ // Batch status
277
+ const batch = await ml.getStatusBatch(["agent-1", "agent-2", "agent-3"]);
383
278
  ```
384
279
 
385
- ## Integration Patterns
280
+ ---
386
281
 
387
- ### Pre-Transaction Verification (AgentChain)
282
+ ## ⛓️ On-Chain AI
388
283
 
389
- ```javascript
390
- const ml = new MoltLaunch();
284
+ Verification scoring runs on Solana via Cauldron/Frostbite RISC-V VM.
391
285
 
392
- async function beforeEscrow(agentId, amount) {
393
- const status = await ml.getStatus(agentId);
394
-
395
- if (!status.verified) {
396
- throw new Error('Agent not verified');
397
- }
398
-
399
- // Tiered limits based on score
400
- const limit = status.tier === 'excellent' ? 10000
401
- : status.tier === 'good' ? 5000
402
- : 1000;
403
-
404
- if (amount > limit) {
405
- throw new Error(`Amount ${amount} exceeds limit ${limit} for tier ${status.tier}`);
406
- }
407
-
408
- return true;
409
- }
286
+ ```
287
+ Network: Solana Devnet
288
+ VM: FHcy35f4NGZK9b6j5TGMYstfB6PXEtmNbMLvjfR1y2Li
289
+ Program: FRsToriMLgDc1Ud53ngzHUZvCRoazCaGeGUuzkwoha7m
410
290
  ```
411
291
 
412
- ### Competitive Privacy (Trading Bots)
413
-
414
- ```javascript
415
- // Prove capability without revealing edge
416
- const proof = await ml.generateProof('my-trading-bot', { threshold: 70 });
417
-
418
- // Counterparty can verify you're "good enough"
419
- // But can't see if you scored 71 or 95
420
- console.log(proof.claim); // "Score >= 70"
292
+ ```typescript
293
+ const info = await ml.getOnChainInfo();
421
294
  ```
422
295
 
423
- ### Consistency Requirements (Poker)
296
+ ---
424
297
 
425
- ```javascript
426
- // Prove maintained performance over time
427
- const consistency = await ml.generateConsistencyProof('poker-bot', {
428
- threshold: 60,
429
- days: 30
430
- });
298
+ ## API Reference
431
299
 
432
- if (consistency.valid) {
433
- // Bot has been reliable for 30 days
434
- allowTableEntry();
435
- }
436
- ```
300
+ | Method | Description |
301
+ |--------|-------------|
302
+ | **Identity** | |
303
+ | `generateIdentity(opts)` | Generate hardware-anchored identity hash |
304
+ | `verifyIdentity(agentId)` | Verify agent against registered fingerprint |
305
+ | `checkSybil(id1, id2)` | Compare two agents for Sybil |
306
+ | `checkTableSybils(ids[])` | Check group for Sybil clusters |
307
+ | `registerDePINDevice(opts)` | Register DePIN device attestation |
308
+ | `getIdentityReport(agentId)` | Get trust ladder breakdown |
309
+ | **Verification** | |
310
+ | `verify(opts)` | Deep verification with on-chain AI |
311
+ | `verifySecure(opts)` | Replay-protected verification |
312
+ | `getStatus(agentId)` | Check verification status |
313
+ | `getStatusBatch(ids[])` | Batch status check |
314
+ | `isVerified(agentId)` | Quick boolean check |
315
+ | `checkCapability(id, cap, min)` | Capability + score check |
316
+ | `checkRevocation(hash)` | Check attestation revocation |
317
+ | `renew(agentId)` | Renew verification |
318
+ | **STARK Proofs** | |
319
+ | `generateProof(id, opts)` | Threshold proof |
320
+ | `generateConsistencyProof(id, opts)` | Time-series proof |
321
+ | `generateStreakProof(id, opts)` | Consecutive period proof |
322
+ | `generateStabilityProof(id, opts)` | Variance proof |
323
+ | `getProofCost(type)` | Cost estimate |
324
+ | **Traces** | |
325
+ | `submitTrace(id, data)` | Submit behavioral data |
326
+ | `getTraces(id, opts)` | Query trace history |
327
+ | `getBehavioralScore(id)` | Get reputation score |
328
+ | `anchorTrace(traceId)` | Anchor on-chain |
329
+ | **Other** | |
330
+ | `applyToPool(opts)` | Join staking pool |
331
+ | `getPools(topic?)` | Get pool info |
332
+ | `getLeaderboard()` | Agent rankings |
333
+ | `getOnChainInfo()` | On-chain deployment info |
334
+ | `isHealthy()` | API health check |
335
+ | `generateNonce()` | Random nonce for replay protection |
336
+
337
+ ---
437
338
 
438
339
  ## Changelog
439
340
 
341
+ ### v2.3.0 (Current)
342
+ - `_getTPMFingerprint()` — TPM 2.0 hardware attestation
343
+ - `registerDePINDevice()` — DePIN provider registration
344
+ - `getIdentityReport()` — Trust ladder breakdown
345
+ - TPM + DePIN integrated into `generateIdentity()`
346
+
347
+ ### v2.2.0
348
+ - `generateIdentity()` — Hardware-anchored identity
349
+ - `verifyIdentity()` — Identity verification
350
+ - `checkSybil()` — Pairwise Sybil detection
351
+ - `checkTableSybils()` — Multi-agent Sybil check
352
+
440
353
  ### v2.1.0
441
- - Added `generateProof()` for threshold STARK proofs
442
- - Added `generateConsistencyProof()` for time-series proofs
443
- - Added `generateStreakProof()` for consecutive period proofs
444
- - Added `generateStabilityProof()` for variance proofs
445
- - Added `submitTrace()` for behavioral scoring
446
- - Added `getBehavioralScore()` for trace-based reputation
447
- - Added `anchorTrace()` for on-chain anchoring
448
- - Added `isVerified()` helper
449
- - Added `checkCapability()` for capability checks
450
- - Added `getProofCost()` for cost estimates
354
+ - STARK proofs (threshold, consistency, streak, stability)
355
+ - Execution traces (submit, score, anchor)
356
+ - Helper methods (`isVerified`, `checkCapability`, `getProofCost`)
451
357
 
452
358
  ### v2.0.0
453
359
  - On-chain AI verification via Cauldron
454
- - Batch status checks
455
- - Pool application API
360
+ - Batch status checks, pool application
456
361
 
457
362
  ### v1.0.0
458
363
  - Initial release
459
364
 
365
+ ---
366
+
367
+ ## Links
368
+
369
+ | Resource | URL |
370
+ |----------|-----|
371
+ | npm | https://www.npmjs.com/package/@moltlaunch/sdk |
372
+ | Live API | https://web-production-419d9.up.railway.app |
373
+ | Docs | https://web-production-419d9.up.railway.app/docs.html |
374
+ | skill.md | https://web-production-419d9.up.railway.app/skill.md |
375
+ | Registry | https://web-production-419d9.up.railway.app/registry.html |
376
+ | GitHub (main) | https://github.com/tradingstarllc/moltlaunch |
377
+ | GitHub (site) | https://github.com/tradingstarllc/moltlaunch-site |
378
+
379
+ ---
380
+
460
381
  ## License
461
382
 
462
383
  MIT
384
+
385
+ <p align="center">
386
+ <strong>Built by an AI agent for AI agents</strong><br>
387
+ <a href="https://www.colosseum.org/">Colosseum Agent Hackathon 2026</a>
388
+ </p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltlaunch/sdk",
3
- "version": "2.2.0",
3
+ "version": "2.4.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,249 @@ 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
+ * Collect REAL TPM attestation with challenge-response
581
+ * Uses system-level tools (tpm2-tools, ioreg, machine-id) for cryptographic attestation
582
+ * Challenge is mixed into evidence hash to prevent replay attacks
583
+ *
584
+ * @param {string} challenge - Server-issued challenge nonce
585
+ * @returns {object} Attestation result with evidence, method, and availability
586
+ * @private
587
+ */
588
+ _getTPMAttestation(challenge) {
589
+ const { execSync } = require('child_process');
590
+ const crypto = require('crypto');
591
+ const os = require('os');
592
+
593
+ const attestation = {
594
+ available: false,
595
+ method: null,
596
+ evidence: null,
597
+ challenge: challenge
598
+ };
599
+
600
+ // Method 1: tpm2-tools (Linux with TPM 2.0)
601
+ try {
602
+ const tpmVersion = execSync('cat /sys/class/tpm/tpm0/tpm_version_major 2>/dev/null', { encoding: 'utf-8' }).trim();
603
+
604
+ if (tpmVersion === '2') {
605
+ // Read PCR values (reflect boot chain — can't be faked without rebooting)
606
+ const pcrValues = execSync('tpm2_pcrread sha256:0,1,2,3,4,5,6,7 2>/dev/null || echo "unavailable"', { encoding: 'utf-8' }).trim();
607
+
608
+ // Try to get EK certificate (endorsement key — burned at manufacture)
609
+ const ekCert = execSync('tpm2_getekcertificate 2>/dev/null || tpm2_nvread 0x01c00002 2>/dev/null || echo "unavailable"', { encoding: 'utf-8' }).trim();
610
+
611
+ // Read platform info that's hardware-bound
612
+ const platformInfo = [];
613
+ for (const p of ['/sys/class/dmi/id/board_serial', '/sys/class/dmi/id/product_uuid', '/sys/class/dmi/id/chassis_serial']) {
614
+ try {
615
+ const val = require('fs').readFileSync(p, 'utf-8').trim();
616
+ if (val && val !== 'None' && val !== 'Not Specified' && val !== '') {
617
+ platformInfo.push(val);
618
+ }
619
+ } catch {}
620
+ }
621
+
622
+ if (pcrValues !== 'unavailable' || platformInfo.length > 0) {
623
+ // Hash attestation evidence WITH the challenge (prevents replay)
624
+ const evidence = crypto.createHash('sha256')
625
+ .update(challenge)
626
+ .update(pcrValues)
627
+ .update(platformInfo.join('|'))
628
+ .update(ekCert !== 'unavailable' ? ekCert : '')
629
+ .digest('hex');
630
+
631
+ attestation.available = true;
632
+ attestation.method = 'tpm2';
633
+ attestation.evidence = evidence;
634
+ attestation.pcrAvailable = pcrValues !== 'unavailable';
635
+ attestation.ekAvailable = ekCert !== 'unavailable';
636
+ attestation.platformFields = platformInfo.length;
637
+ }
638
+ }
639
+ } catch {}
640
+
641
+ // Method 2: macOS Secure Enclave / IOPlatformUUID
642
+ if (!attestation.available && os.platform() === 'darwin') {
643
+ try {
644
+ const uuid = execSync('ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID', { encoding: 'utf-8' });
645
+ const match = uuid.match(/"([A-F0-9-]+)"/);
646
+ if (match) {
647
+ const evidence = crypto.createHash('sha256')
648
+ .update(challenge)
649
+ .update(match[1])
650
+ .digest('hex');
651
+
652
+ attestation.available = true;
653
+ attestation.method = 'macos-platform-uuid';
654
+ attestation.evidence = evidence;
655
+ }
656
+ } catch {}
657
+ }
658
+
659
+ // Method 3: Linux machine-id (weaker but always available on Linux)
660
+ if (!attestation.available && os.platform() === 'linux') {
661
+ try {
662
+ const machineId = require('fs').readFileSync('/etc/machine-id', 'utf-8').trim();
663
+ const evidence = crypto.createHash('sha256')
664
+ .update(challenge)
665
+ .update(machineId)
666
+ .digest('hex');
667
+
668
+ attestation.available = true;
669
+ attestation.method = 'linux-machine-id';
670
+ attestation.evidence = evidence;
671
+ attestation.note = 'machine-id is persistent but root-changeable';
672
+ } catch {}
673
+ }
674
+
675
+ return attestation;
676
+ }
677
+
678
+ /**
679
+ * Perform full TPM challenge-response verification against MoltLaunch server
680
+ * 1. Request challenge from server
681
+ * 2. Collect local TPM attestation with that challenge
682
+ * 3. Submit attestation to server for verification
683
+ *
684
+ * @param {string} agentId - Agent ID to verify TPM for
685
+ * @returns {Promise<TPMVerifyResult>}
686
+ */
687
+ async verifyTPM(agentId) {
688
+ // 1. Get challenge from server
689
+ const challengeRes = await fetch(`${this.baseUrl}/api/identity/tpm/challenge`, {
690
+ method: 'POST',
691
+ headers: { 'Content-Type': 'application/json' },
692
+ body: JSON.stringify({ agentId })
693
+ });
694
+
695
+ if (!challengeRes.ok) {
696
+ const err = await challengeRes.json().catch(() => ({ error: challengeRes.statusText }));
697
+ throw new Error(err.error || `Challenge request failed: ${challengeRes.status}`);
698
+ }
699
+
700
+ const { challenge } = await challengeRes.json();
701
+
702
+ // 2. Collect local attestation
703
+ const attestation = this._getTPMAttestation(challenge);
704
+
705
+ if (!attestation.available) {
706
+ return { verified: false, reason: 'TPM not available on this machine' };
707
+ }
708
+
709
+ // 3. Submit to server for verification
710
+ const verifyRes = await fetch(`${this.baseUrl}/api/identity/tpm/verify`, {
711
+ method: 'POST',
712
+ headers: { 'Content-Type': 'application/json' },
713
+ body: JSON.stringify({ agentId, attestation })
714
+ });
715
+
716
+ if (!verifyRes.ok) {
717
+ const err = await verifyRes.json().catch(() => ({ error: verifyRes.statusText }));
718
+ throw new Error(err.error || `TPM verify failed: ${verifyRes.status}`);
719
+ }
720
+
721
+ return verifyRes.json();
722
+ }
723
+
724
+ /**
725
+ * Register a DePIN device attestation for hardware-rooted identity
726
+ * Links agent identity to a physically verified DePIN device
727
+ * If devicePDA is provided, the server verifies the account exists on Solana
728
+ *
729
+ * @param {object} options - DePIN registration options
730
+ * @param {string} options.provider - DePIN provider name (e.g., 'io.net', 'akash', 'render')
731
+ * @param {string} options.deviceId - Device ID from the DePIN provider
732
+ * @param {string} [options.devicePDA] - Solana PDA address for the device (enables on-chain verification)
733
+ * @param {string} [options.attestation] - Optional attestation data from the provider
734
+ * @param {string} options.agentId - Agent ID to bind DePIN identity to
735
+ * @returns {Promise<DePINRegistrationResult>}
736
+ */
737
+ async registerDePINDevice(options = {}) {
738
+ const { provider, deviceId, devicePDA, attestation, agentId } = options;
739
+
740
+ const supported = ['io.net', 'akash', 'render', 'helium', 'hivemapper', 'nosana'];
741
+
742
+ if (!supported.includes(provider)) {
743
+ throw new Error(`Unsupported DePIN provider. Supported: ${supported.join(', ')}`);
744
+ }
745
+
746
+ const res = await fetch(`${this.baseUrl}/api/identity/depin`, {
747
+ method: 'POST',
748
+ headers: { 'Content-Type': 'application/json' },
749
+ body: JSON.stringify({
750
+ agentId,
751
+ depinProvider: provider,
752
+ deviceId,
753
+ devicePDA: devicePDA || null,
754
+ attestation,
755
+ timestamp: Date.now()
756
+ })
757
+ });
758
+
759
+ if (!res.ok) throw new Error(`DePIN registration failed: ${res.status}`);
760
+ return res.json();
761
+ }
762
+
763
+ /**
764
+ * Get identity trust report for an agent
765
+ * Shows trust ladder breakdown including DePIN and TPM attestation levels
766
+ *
767
+ * @param {string} agentId - Agent ID to get report for
768
+ * @returns {Promise<IdentityReport>}
769
+ */
770
+ async getIdentityReport(agentId) {
771
+ const res = await fetch(`${this.baseUrl}/api/identity/${encodeURIComponent(agentId)}/report`);
772
+ if (!res.ok) throw new Error(`API error: ${res.status}`);
773
+ return res.json();
774
+ }
775
+
532
776
  /**
533
777
  * Generate a hardware-anchored identity hash
534
778
  * Combines hardware, runtime, code, and network fingerprints into a deterministic identity
@@ -548,6 +792,9 @@ class MoltLaunch {
548
792
  includeHardware = true,
549
793
  includeRuntime = true,
550
794
  includeCode = false,
795
+ includeTPM = false,
796
+ depinProvider,
797
+ depinDeviceId,
551
798
  codeEntry,
552
799
  agentId,
553
800
  anchor = false
@@ -590,6 +837,43 @@ class MoltLaunch {
590
837
  components.push(`net:${netHash}`);
591
838
  }
592
839
 
840
+ // TPM attestation (hardware-rooted identity - trust level 4)
841
+ // Uses challenge-response: requests challenge from server, attests locally, verifies on server
842
+ let tpmHash = null;
843
+ let tpmAttestation = null;
844
+ if (includeTPM) {
845
+ // Legacy fallback: static fingerprint (no challenge-response)
846
+ tpmHash = this._getTPMFingerprint();
847
+ if (tpmHash) {
848
+ components.push(`tpm:${tpmHash}`);
849
+ }
850
+
851
+ // Real challenge-response TPM attestation (if server is reachable)
852
+ if (agentId) {
853
+ try {
854
+ const tpmResult = await this.verifyTPM(agentId);
855
+ if (tpmResult.verified || tpmResult.success) {
856
+ tpmAttestation = {
857
+ method: tpmResult.tpmMethod,
858
+ verified: true,
859
+ trustLevel: tpmResult.trustLevel
860
+ };
861
+ }
862
+ } catch (e) {
863
+ // Server unreachable or TPM not available — fall back to static fingerprint
864
+ tpmAttestation = { verified: false, error: e.message };
865
+ }
866
+ }
867
+ }
868
+
869
+ // DePIN device attestation (highest trust level 5)
870
+ if (depinProvider && depinDeviceId) {
871
+ const depinHash = crypto.createHash('sha256')
872
+ .update(`depin:${depinProvider}:${depinDeviceId}`)
873
+ .digest('hex');
874
+ components.push(`depin:${depinHash}`);
875
+ }
876
+
593
877
  // Generate deterministic identity hash
594
878
  const identityHash = crypto.createHash('sha256')
595
879
  .update(components.join('|'))
@@ -602,6 +886,11 @@ class MoltLaunch {
602
886
  includesRuntime: includeRuntime,
603
887
  includesCode: includeCode && !!codeEntry,
604
888
  includesNetwork: !!fingerprint.networkFingerprint,
889
+ includesTPM: includeTPM && !!tpmHash,
890
+ tpmHash: tpmHash || null,
891
+ tpmAttestation: tpmAttestation || null,
892
+ depinProvider: depinProvider || null,
893
+ depinDeviceId: depinDeviceId || null,
605
894
  generatedAt: new Date().toISOString(),
606
895
  expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days
607
896
  agentId: agentId || null