chainlesschain 0.51.0 → 0.81.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/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AppLayout-Rvi759IS.js → AppLayout-6SPt_8Y_.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-DBhFxXYQ.js → Dashboard-Br7kCwKJ.js} +2 -2
- package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +1 -0
- package/src/assets/web-panel/assets/{index-uL0cZ8N_.js → index-tN-8TosE.js} +2 -2
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/a2a.js +380 -0
- package/src/commands/agent-network.js +785 -0
- package/src/commands/automation.js +654 -0
- package/src/commands/bi.js +348 -0
- package/src/commands/crosschain.js +218 -0
- package/src/commands/dao.js +565 -0
- package/src/commands/did-v2.js +620 -0
- package/src/commands/dlp.js +341 -0
- package/src/commands/economy.js +578 -0
- package/src/commands/evolution.js +391 -0
- package/src/commands/evomap.js +394 -0
- package/src/commands/federation.js +283 -0
- package/src/commands/hmemory.js +442 -0
- package/src/commands/inference.js +318 -0
- package/src/commands/lowcode.js +356 -0
- package/src/commands/marketplace.js +256 -0
- package/src/commands/perf.js +433 -0
- package/src/commands/pipeline.js +449 -0
- package/src/commands/plugin-ecosystem.js +517 -0
- package/src/commands/privacy.js +321 -0
- package/src/commands/reputation.js +261 -0
- package/src/commands/sandbox.js +401 -0
- package/src/commands/siem.js +246 -0
- package/src/commands/sla.js +259 -0
- package/src/commands/social.js +311 -0
- package/src/commands/sso.js +798 -0
- package/src/commands/stress.js +230 -0
- package/src/commands/terraform.js +245 -0
- package/src/commands/workflow.js +320 -0
- package/src/commands/zkp.js +562 -1
- package/src/index.js +21 -0
- package/src/lib/a2a-protocol.js +451 -0
- package/src/lib/agent-economy.js +479 -0
- package/src/lib/agent-network.js +1121 -0
- package/src/lib/app-builder.js +239 -0
- package/src/lib/automation-engine.js +948 -0
- package/src/lib/bi-engine.js +338 -0
- package/src/lib/cross-chain.js +345 -0
- package/src/lib/dao-governance.js +569 -0
- package/src/lib/did-v2-manager.js +1127 -0
- package/src/lib/dlp-engine.js +389 -0
- package/src/lib/evolution-system.js +453 -0
- package/src/lib/evomap-federation.js +177 -0
- package/src/lib/evomap-governance.js +276 -0
- package/src/lib/federation-hardening.js +259 -0
- package/src/lib/hierarchical-memory.js +481 -0
- package/src/lib/inference-network.js +330 -0
- package/src/lib/perf-tuning.js +734 -0
- package/src/lib/pipeline-orchestrator.js +928 -0
- package/src/lib/plugin-ecosystem.js +1109 -0
- package/src/lib/privacy-computing.js +427 -0
- package/src/lib/reputation-optimizer.js +299 -0
- package/src/lib/sandbox-v2.js +306 -0
- package/src/lib/siem-exporter.js +333 -0
- package/src/lib/skill-marketplace.js +325 -0
- package/src/lib/sla-manager.js +275 -0
- package/src/lib/social-graph-analytics.js +707 -0
- package/src/lib/sso-manager.js +841 -0
- package/src/lib/stress-tester.js +330 -0
- package/src/lib/terraform-manager.js +363 -0
- package/src/lib/workflow-engine.js +454 -1
- package/src/lib/zkp-engine.js +523 -20
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +0 -1
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cc did-v2` (alias `didv2`) — CLI port of Phase 55 去中心化身份2.0.
|
|
3
|
+
*
|
|
4
|
+
* W3C DID v2.0 with did:key / did:web / did:chain methods, Verifiable
|
|
5
|
+
* Presentations with selective disclosure, social recovery via k-of-n
|
|
6
|
+
* guardian shards, identity roaming, and multi-source reputation
|
|
7
|
+
* aggregation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Command } from "commander";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
DID_METHOD,
|
|
14
|
+
CREDENTIAL_STATUS,
|
|
15
|
+
RECOVERY_STATUS,
|
|
16
|
+
DID_STATUS,
|
|
17
|
+
ensureDIDv2Tables,
|
|
18
|
+
createDID,
|
|
19
|
+
resolveDID,
|
|
20
|
+
listDIDs,
|
|
21
|
+
updateDIDStatus,
|
|
22
|
+
issueCredential,
|
|
23
|
+
getCredential,
|
|
24
|
+
listCredentials,
|
|
25
|
+
revokeCredential,
|
|
26
|
+
createPresentation,
|
|
27
|
+
getPresentation,
|
|
28
|
+
listPresentations,
|
|
29
|
+
verifyPresentation,
|
|
30
|
+
startRecovery,
|
|
31
|
+
completeRecovery,
|
|
32
|
+
getRecovery,
|
|
33
|
+
listRecoveries,
|
|
34
|
+
roamIdentity,
|
|
35
|
+
listRoamingLog,
|
|
36
|
+
recordReputationSource,
|
|
37
|
+
aggregateReputation,
|
|
38
|
+
exportDID,
|
|
39
|
+
getStats,
|
|
40
|
+
getConfig,
|
|
41
|
+
} from "../lib/did-v2-manager.js";
|
|
42
|
+
|
|
43
|
+
function _dbFromCtx(cmd) {
|
|
44
|
+
const root = cmd?.parent?.parent ?? cmd?.parent;
|
|
45
|
+
return root?._db;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function _json(v) {
|
|
49
|
+
console.log(JSON.stringify(v, null, 2));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function _fmtTs(ts) {
|
|
53
|
+
if (!ts) return "—";
|
|
54
|
+
return new Date(ts).toISOString();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function _parseJsonArg(s, fallback) {
|
|
58
|
+
if (s == null) return fallback;
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(s);
|
|
61
|
+
} catch {
|
|
62
|
+
return fallback;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function registerDIDv2Command(program) {
|
|
67
|
+
const didv2 = new Command("did-v2")
|
|
68
|
+
.alias("didv2")
|
|
69
|
+
.description(
|
|
70
|
+
"Decentralized Identity 2.0 (Phase 55) — W3C DID v2.0 + VP + social recovery + roaming",
|
|
71
|
+
)
|
|
72
|
+
.hook("preAction", (thisCmd) => {
|
|
73
|
+
const db = _dbFromCtx(thisCmd);
|
|
74
|
+
if (db) ensureDIDv2Tables(db);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
/* ── Catalogs ────────────────────────────────────── */
|
|
78
|
+
|
|
79
|
+
didv2
|
|
80
|
+
.command("config")
|
|
81
|
+
.description("Show DID v2.0 constants and defaults")
|
|
82
|
+
.option("--json", "JSON output")
|
|
83
|
+
.action((opts) => {
|
|
84
|
+
const cfg = getConfig();
|
|
85
|
+
if (opts.json) return _json(cfg);
|
|
86
|
+
console.log(`Methods: ${cfg.methods.join(", ")}`);
|
|
87
|
+
console.log(
|
|
88
|
+
`Default recovery threshold: ${cfg.defaultRecoveryThreshold} of ${cfg.defaultGuardianCount}`,
|
|
89
|
+
);
|
|
90
|
+
console.log(`VP default TTL: ${cfg.vpDefaultTTLMs}ms`);
|
|
91
|
+
console.log("Reputation source weights:");
|
|
92
|
+
for (const [source, weight] of Object.entries(
|
|
93
|
+
cfg.reputationSourceWeights,
|
|
94
|
+
)) {
|
|
95
|
+
console.log(` ${source.padEnd(14)} ${weight}`);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
didv2
|
|
100
|
+
.command("methods")
|
|
101
|
+
.description("List supported DID methods")
|
|
102
|
+
.option("--json", "JSON output")
|
|
103
|
+
.action((opts) => {
|
|
104
|
+
const rows = Object.values(DID_METHOD);
|
|
105
|
+
if (opts.json) return _json(rows);
|
|
106
|
+
for (const m of rows) console.log(` ${m}`);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
didv2
|
|
110
|
+
.command("cred-statuses")
|
|
111
|
+
.description("List credential statuses")
|
|
112
|
+
.option("--json", "JSON output")
|
|
113
|
+
.action((opts) => {
|
|
114
|
+
const rows = Object.values(CREDENTIAL_STATUS);
|
|
115
|
+
if (opts.json) return _json(rows);
|
|
116
|
+
for (const s of rows) console.log(` ${s}`);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
didv2
|
|
120
|
+
.command("recovery-statuses")
|
|
121
|
+
.description("List recovery lifecycle statuses")
|
|
122
|
+
.option("--json", "JSON output")
|
|
123
|
+
.action((opts) => {
|
|
124
|
+
const rows = Object.values(RECOVERY_STATUS);
|
|
125
|
+
if (opts.json) return _json(rows);
|
|
126
|
+
for (const s of rows) console.log(` ${s}`);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
/* ── DID lifecycle ───────────────────────────────── */
|
|
130
|
+
|
|
131
|
+
didv2
|
|
132
|
+
.command("create")
|
|
133
|
+
.description("Create a new DID v2.0 (Ed25519 keypair + document)")
|
|
134
|
+
.option("-m, --method <method>", "did:key | did:web | did:chain", "key")
|
|
135
|
+
.option("-d, --domain <domain>", "Domain for did:web")
|
|
136
|
+
.option(
|
|
137
|
+
"-s, --services <json>",
|
|
138
|
+
"Service endpoints JSON array",
|
|
139
|
+
(v) => _parseJsonArg(v, []),
|
|
140
|
+
[],
|
|
141
|
+
)
|
|
142
|
+
.option(
|
|
143
|
+
"-g, --guardians <json>",
|
|
144
|
+
"Guardian DIDs JSON array for social recovery",
|
|
145
|
+
(v) => _parseJsonArg(v, []),
|
|
146
|
+
[],
|
|
147
|
+
)
|
|
148
|
+
.option(
|
|
149
|
+
"-t, --threshold <n>",
|
|
150
|
+
"Recovery threshold",
|
|
151
|
+
(v) => parseInt(v, 10),
|
|
152
|
+
3,
|
|
153
|
+
)
|
|
154
|
+
.option("--json", "JSON output")
|
|
155
|
+
.action((opts) => {
|
|
156
|
+
const db = _dbFromCtx(didv2);
|
|
157
|
+
const r = createDID(db, {
|
|
158
|
+
method: opts.method,
|
|
159
|
+
domain: opts.domain,
|
|
160
|
+
services: opts.services,
|
|
161
|
+
guardians: opts.guardians,
|
|
162
|
+
threshold: opts.threshold,
|
|
163
|
+
});
|
|
164
|
+
if (opts.json) return _json(r);
|
|
165
|
+
console.log(`Created ${r.did}`);
|
|
166
|
+
console.log(` method: ${r.method}`);
|
|
167
|
+
console.log(` publicKey: ${r.publicKey}`);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
didv2
|
|
171
|
+
.command("resolve")
|
|
172
|
+
.argument("<did>", "DID URI")
|
|
173
|
+
.description("Resolve DID → DID document")
|
|
174
|
+
.option("--json", "JSON output")
|
|
175
|
+
.action((did, opts) => {
|
|
176
|
+
const db = _dbFromCtx(didv2);
|
|
177
|
+
const r = resolveDID(db, did);
|
|
178
|
+
if (!r) {
|
|
179
|
+
console.error(`Unknown DID: ${did}`);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
if (opts.json) return _json(r);
|
|
183
|
+
console.log(`DID: ${r.did} method=${r.method} status=${r.status}`);
|
|
184
|
+
console.log(` publicKey: ${r.publicKey}`);
|
|
185
|
+
console.log(` reputation: ${r.reputationScore.toFixed(3)}`);
|
|
186
|
+
console.log(
|
|
187
|
+
` guardians: ${r.recoveryGuardians.length} (threshold ${r.recoveryThreshold})`,
|
|
188
|
+
);
|
|
189
|
+
console.log(` services: ${r.serviceEndpoints.length}`);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
didv2
|
|
193
|
+
.command("list")
|
|
194
|
+
.description("List all DIDs")
|
|
195
|
+
.option("-m, --method <method>", "Filter by method")
|
|
196
|
+
.option("-s, --status <status>", "Filter by status")
|
|
197
|
+
.option("--json", "JSON output")
|
|
198
|
+
.action((opts) => {
|
|
199
|
+
const db = _dbFromCtx(didv2);
|
|
200
|
+
const rows = listDIDs(db, { method: opts.method, status: opts.status });
|
|
201
|
+
if (opts.json) return _json(rows);
|
|
202
|
+
for (const r of rows) {
|
|
203
|
+
console.log(
|
|
204
|
+
` ${r.did} [${r.status}] method=${r.method} rep=${r.reputationScore.toFixed(2)}`,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
console.log(`(${rows.length} DIDs)`);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
didv2
|
|
211
|
+
.command("revoke")
|
|
212
|
+
.argument("<did>", "DID URI")
|
|
213
|
+
.description("Revoke a DID (sets status=revoked)")
|
|
214
|
+
.option("--json", "JSON output")
|
|
215
|
+
.action((did, opts) => {
|
|
216
|
+
const db = _dbFromCtx(didv2);
|
|
217
|
+
const changed = updateDIDStatus(db, did, DID_STATUS.REVOKED);
|
|
218
|
+
if (opts.json) return _json({ changed });
|
|
219
|
+
console.log(changed ? `Revoked ${did}` : `No change for ${did}`);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
/* ── Credentials ─────────────────────────────────── */
|
|
223
|
+
|
|
224
|
+
didv2
|
|
225
|
+
.command("cred-issue")
|
|
226
|
+
.description("Issue a Verifiable Credential")
|
|
227
|
+
.requiredOption("-h, --holder <did>", "Holder DID")
|
|
228
|
+
.requiredOption("-i, --issuer <did>", "Issuer DID")
|
|
229
|
+
.requiredOption("-t, --type <type>", "Credential type")
|
|
230
|
+
.option(
|
|
231
|
+
"-s, --subject <json>",
|
|
232
|
+
"credentialSubject JSON",
|
|
233
|
+
(v) => _parseJsonArg(v, {}),
|
|
234
|
+
{},
|
|
235
|
+
)
|
|
236
|
+
.option("-e, --expires-in <ms>", "Expires in ms", (v) => parseInt(v, 10))
|
|
237
|
+
.option("--json", "JSON output")
|
|
238
|
+
.action((opts) => {
|
|
239
|
+
const db = _dbFromCtx(didv2);
|
|
240
|
+
const r = issueCredential(db, {
|
|
241
|
+
holderDid: opts.holder,
|
|
242
|
+
issuerDid: opts.issuer,
|
|
243
|
+
type: opts.type,
|
|
244
|
+
credentialSubject: opts.subject,
|
|
245
|
+
expiresInMs: opts.expiresIn,
|
|
246
|
+
});
|
|
247
|
+
if (opts.json) return _json(r);
|
|
248
|
+
console.log(`Issued ${r.id}`);
|
|
249
|
+
console.log(` type: ${opts.type}`);
|
|
250
|
+
console.log(` issuer → holder: ${opts.issuer} → ${opts.holder}`);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
didv2
|
|
254
|
+
.command("cred-show")
|
|
255
|
+
.argument("<id>", "Credential id")
|
|
256
|
+
.description("Show a credential")
|
|
257
|
+
.option("--json", "JSON output")
|
|
258
|
+
.action((id, opts) => {
|
|
259
|
+
const db = _dbFromCtx(didv2);
|
|
260
|
+
const r = getCredential(db, id);
|
|
261
|
+
if (!r) {
|
|
262
|
+
console.error(`Unknown credential: ${id}`);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
if (opts.json) return _json(r);
|
|
266
|
+
console.log(`${r.id} [${r.status}] ${r.type}`);
|
|
267
|
+
console.log(` holder: ${r.holderDid}`);
|
|
268
|
+
console.log(` issuer: ${r.issuerDid}`);
|
|
269
|
+
console.log(` issued: ${_fmtTs(r.issuanceDate)}`);
|
|
270
|
+
console.log(` expires: ${_fmtTs(r.expirationDate)}`);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
didv2
|
|
274
|
+
.command("creds")
|
|
275
|
+
.description("List credentials")
|
|
276
|
+
.option("-h, --holder <did>", "Filter by holder")
|
|
277
|
+
.option("-i, --issuer <did>", "Filter by issuer")
|
|
278
|
+
.option("-s, --status <status>", "Filter by status")
|
|
279
|
+
.option("--json", "JSON output")
|
|
280
|
+
.action((opts) => {
|
|
281
|
+
const db = _dbFromCtx(didv2);
|
|
282
|
+
const rows = listCredentials(db, {
|
|
283
|
+
holderDid: opts.holder,
|
|
284
|
+
issuerDid: opts.issuer,
|
|
285
|
+
status: opts.status,
|
|
286
|
+
});
|
|
287
|
+
if (opts.json) return _json(rows);
|
|
288
|
+
for (const r of rows) {
|
|
289
|
+
console.log(
|
|
290
|
+
` ${r.id} [${r.status}] ${r.type} holder=${r.holderDid}`,
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
console.log(`(${rows.length} credentials)`);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
didv2
|
|
297
|
+
.command("cred-revoke")
|
|
298
|
+
.argument("<id>", "Credential id")
|
|
299
|
+
.description("Revoke a credential")
|
|
300
|
+
.option("-r, --reason <reason>", "Revocation reason")
|
|
301
|
+
.option("--json", "JSON output")
|
|
302
|
+
.action((id, opts) => {
|
|
303
|
+
const db = _dbFromCtx(didv2);
|
|
304
|
+
const changed = revokeCredential(db, id, opts.reason);
|
|
305
|
+
if (opts.json) return _json({ changed });
|
|
306
|
+
console.log(changed ? `Revoked ${id}` : `No change for ${id}`);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
/* ── Verifiable Presentations ────────────────────── */
|
|
310
|
+
|
|
311
|
+
didv2
|
|
312
|
+
.command("present")
|
|
313
|
+
.description("Build a Verifiable Presentation from credentials")
|
|
314
|
+
.requiredOption("-h, --holder <did>", "Holder DID")
|
|
315
|
+
.requiredOption("-c, --creds <csv>", "Credential ids CSV", (v) =>
|
|
316
|
+
v
|
|
317
|
+
.split(",")
|
|
318
|
+
.map((s) => s.trim())
|
|
319
|
+
.filter(Boolean),
|
|
320
|
+
)
|
|
321
|
+
.option("-r, --recipient <did>", "Recipient DID")
|
|
322
|
+
.option(
|
|
323
|
+
"-d, --disclose <csv>",
|
|
324
|
+
"Fields to selectively disclose (CSV)",
|
|
325
|
+
(v) =>
|
|
326
|
+
v
|
|
327
|
+
.split(",")
|
|
328
|
+
.map((s) => s.trim())
|
|
329
|
+
.filter(Boolean),
|
|
330
|
+
[],
|
|
331
|
+
)
|
|
332
|
+
.option("--ttl <ms>", "TTL in ms", (v) => parseInt(v, 10))
|
|
333
|
+
.option("--zkp", "Enable ZKP proof placeholder")
|
|
334
|
+
.option("--json", "JSON output")
|
|
335
|
+
.action((opts) => {
|
|
336
|
+
const db = _dbFromCtx(didv2);
|
|
337
|
+
const r = createPresentation(db, {
|
|
338
|
+
holderDid: opts.holder,
|
|
339
|
+
credentialIds: opts.creds,
|
|
340
|
+
recipientDid: opts.recipient,
|
|
341
|
+
disclosedFields: opts.disclose,
|
|
342
|
+
ttlMs: opts.ttl,
|
|
343
|
+
zkpEnabled: !!opts.zkp,
|
|
344
|
+
});
|
|
345
|
+
if (opts.json) return _json(r);
|
|
346
|
+
console.log(`VP ${r.id}`);
|
|
347
|
+
console.log(` credentials: ${r.credentialIds.length}`);
|
|
348
|
+
console.log(` expiresAt: ${_fmtTs(r.expiresAt)}`);
|
|
349
|
+
if (r.zkpProofId) console.log(` zkpProofId: ${r.zkpProofId}`);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
didv2
|
|
353
|
+
.command("verify")
|
|
354
|
+
.argument("<id>", "Presentation id")
|
|
355
|
+
.description("Verify a Verifiable Presentation")
|
|
356
|
+
.option("--json", "JSON output")
|
|
357
|
+
.action((id, opts) => {
|
|
358
|
+
const db = _dbFromCtx(didv2);
|
|
359
|
+
const r = verifyPresentation(db, id);
|
|
360
|
+
if (opts.json) return _json(r);
|
|
361
|
+
if (r.ok) {
|
|
362
|
+
console.log(`✓ VP ${id} valid (${r.verificationTimeMs}ms)`);
|
|
363
|
+
} else {
|
|
364
|
+
console.log(`✗ VP ${id} invalid: ${r.reason}`);
|
|
365
|
+
process.exitCode = 1;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
didv2
|
|
370
|
+
.command("vp-show")
|
|
371
|
+
.argument("<id>", "Presentation id")
|
|
372
|
+
.description("Show a presentation")
|
|
373
|
+
.option("--json", "JSON output")
|
|
374
|
+
.action((id, opts) => {
|
|
375
|
+
const db = _dbFromCtx(didv2);
|
|
376
|
+
const r = getPresentation(db, id);
|
|
377
|
+
if (!r) {
|
|
378
|
+
console.error(`Unknown presentation: ${id}`);
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
if (opts.json) return _json(r);
|
|
382
|
+
console.log(`VP ${r.id}`);
|
|
383
|
+
console.log(` holder: ${r.holderDid}`);
|
|
384
|
+
console.log(` recipient: ${r.recipientDid || "—"}`);
|
|
385
|
+
console.log(` credentials: ${r.credentialIds.length}`);
|
|
386
|
+
console.log(` disclosed: ${r.disclosedFields.join(", ") || "(all)"}`);
|
|
387
|
+
console.log(
|
|
388
|
+
` verified: ${r.verified} (${r.verificationTimeMs ?? 0}ms)`,
|
|
389
|
+
);
|
|
390
|
+
console.log(` expiresAt: ${_fmtTs(r.expiresAt)}`);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
didv2
|
|
394
|
+
.command("presentations")
|
|
395
|
+
.description("List presentations")
|
|
396
|
+
.option("-h, --holder <did>", "Filter by holder")
|
|
397
|
+
.option("--json", "JSON output")
|
|
398
|
+
.action((opts) => {
|
|
399
|
+
const db = _dbFromCtx(didv2);
|
|
400
|
+
const rows = listPresentations(db, { holderDid: opts.holder });
|
|
401
|
+
if (opts.json) return _json(rows);
|
|
402
|
+
for (const r of rows) {
|
|
403
|
+
console.log(
|
|
404
|
+
` ${r.id} verified=${r.verified} holder=${r.holderDid} expires=${_fmtTs(r.expiresAt)}`,
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
console.log(`(${rows.length} presentations)`);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
/* ── Social recovery ─────────────────────────────── */
|
|
411
|
+
|
|
412
|
+
didv2
|
|
413
|
+
.command("recover-start")
|
|
414
|
+
.description("Start social recovery (submit guardian shares)")
|
|
415
|
+
.requiredOption("-d, --did <did>", "DID to recover")
|
|
416
|
+
.requiredOption(
|
|
417
|
+
"-s, --shares <json>",
|
|
418
|
+
"Shares JSON array of {guardian, share}",
|
|
419
|
+
(v) => _parseJsonArg(v, []),
|
|
420
|
+
)
|
|
421
|
+
.option("--json", "JSON output")
|
|
422
|
+
.action((opts) => {
|
|
423
|
+
const db = _dbFromCtx(didv2);
|
|
424
|
+
const r = startRecovery(db, { did: opts.did, shares: opts.shares });
|
|
425
|
+
if (opts.json) return _json(r);
|
|
426
|
+
console.log(`Recovery ${r.id} status=${r.status}`);
|
|
427
|
+
console.log(` valid shares: ${r.validShares}/${r.threshold}`);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
didv2
|
|
431
|
+
.command("recover-complete")
|
|
432
|
+
.argument("<recoveryId>", "Recovery attempt id")
|
|
433
|
+
.description("Complete recovery (rotate keypair when threshold met)")
|
|
434
|
+
.option("--json", "JSON output")
|
|
435
|
+
.action((recoveryId, opts) => {
|
|
436
|
+
const db = _dbFromCtx(didv2);
|
|
437
|
+
const r = completeRecovery(db, recoveryId);
|
|
438
|
+
if (opts.json) return _json(r);
|
|
439
|
+
console.log(`Recovered ${r.did}`);
|
|
440
|
+
console.log(` new publicKey: ${r.newPublicKey}`);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
didv2
|
|
444
|
+
.command("recoveries")
|
|
445
|
+
.description("List recovery attempts")
|
|
446
|
+
.option("-d, --did <did>", "Filter by DID")
|
|
447
|
+
.option("--json", "JSON output")
|
|
448
|
+
.action((opts) => {
|
|
449
|
+
const db = _dbFromCtx(didv2);
|
|
450
|
+
const rows = listRecoveries(db, { did: opts.did });
|
|
451
|
+
if (opts.json) return _json(rows);
|
|
452
|
+
for (const r of rows) {
|
|
453
|
+
console.log(
|
|
454
|
+
` ${r.id} [${r.status}] did=${r.did} shares=${r.sharesSubmitted.length}/${r.threshold}`,
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
console.log(`(${rows.length} attempts)`);
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
didv2
|
|
461
|
+
.command("recovery-show")
|
|
462
|
+
.argument("<id>", "Recovery id")
|
|
463
|
+
.description("Show a recovery attempt")
|
|
464
|
+
.option("--json", "JSON output")
|
|
465
|
+
.action((id, opts) => {
|
|
466
|
+
const db = _dbFromCtx(didv2);
|
|
467
|
+
const r = getRecovery(db, id);
|
|
468
|
+
if (!r) {
|
|
469
|
+
console.error(`Unknown recovery: ${id}`);
|
|
470
|
+
process.exit(1);
|
|
471
|
+
}
|
|
472
|
+
if (opts.json) return _json(r);
|
|
473
|
+
console.log(`Recovery ${r.id} status=${r.status}`);
|
|
474
|
+
console.log(` did: ${r.did}`);
|
|
475
|
+
console.log(` threshold: ${r.threshold}`);
|
|
476
|
+
console.log(` shares: ${r.sharesSubmitted.length}`);
|
|
477
|
+
if (r.newPublicKey) console.log(` new pubkey: ${r.newPublicKey}`);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
/* ── Identity roaming ────────────────────────────── */
|
|
481
|
+
|
|
482
|
+
didv2
|
|
483
|
+
.command("roam")
|
|
484
|
+
.description("Roam identity to a new platform (cross-platform migration)")
|
|
485
|
+
.requiredOption("-d, --did <did>", "DID URI")
|
|
486
|
+
.requiredOption("-t, --target <platform>", "Target platform identifier")
|
|
487
|
+
.option("-s, --source <platform>", "Source platform identifier")
|
|
488
|
+
.option("-p, --proof <proof>", "Migration proof (opaque)")
|
|
489
|
+
.option("--json", "JSON output")
|
|
490
|
+
.action((opts) => {
|
|
491
|
+
const db = _dbFromCtx(didv2);
|
|
492
|
+
const r = roamIdentity(db, {
|
|
493
|
+
did: opts.did,
|
|
494
|
+
targetPlatform: opts.target,
|
|
495
|
+
sourcePlatform: opts.source,
|
|
496
|
+
migrationProof: opts.proof,
|
|
497
|
+
});
|
|
498
|
+
if (opts.json) return _json(r);
|
|
499
|
+
console.log(`Roamed ${r.did} → ${r.targetPlatform}`);
|
|
500
|
+
console.log(` credentials migrated: ${r.credentialsMigrated}`);
|
|
501
|
+
console.log(
|
|
502
|
+
` reputation transferred: ${r.reputationTransferred.toFixed(3)}`,
|
|
503
|
+
);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
didv2
|
|
507
|
+
.command("roaming-log")
|
|
508
|
+
.description("List roaming log entries")
|
|
509
|
+
.option("-d, --did <did>", "Filter by DID")
|
|
510
|
+
.option("--json", "JSON output")
|
|
511
|
+
.action((opts) => {
|
|
512
|
+
const db = _dbFromCtx(didv2);
|
|
513
|
+
const rows = listRoamingLog(db, { did: opts.did });
|
|
514
|
+
if (opts.json) return _json(rows);
|
|
515
|
+
for (const r of rows) {
|
|
516
|
+
console.log(
|
|
517
|
+
` ${r.id} ${r.did} ${r.sourcePlatform || "?"} → ${r.targetPlatform} creds=${r.credentialsMigrated}`,
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
console.log(`(${rows.length} entries)`);
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
/* ── Reputation aggregation ──────────────────────── */
|
|
524
|
+
|
|
525
|
+
didv2
|
|
526
|
+
.command("rep-record")
|
|
527
|
+
.description("Record a reputation sample from a source")
|
|
528
|
+
.requiredOption("-d, --did <did>", "DID")
|
|
529
|
+
.requiredOption(
|
|
530
|
+
"-s, --source <source>",
|
|
531
|
+
"on-chain | social | marketplace | custom",
|
|
532
|
+
)
|
|
533
|
+
.requiredOption("--score <n>", "Score", (v) => parseFloat(v))
|
|
534
|
+
.option(
|
|
535
|
+
"-e, --evidence <json>",
|
|
536
|
+
"Evidence JSON",
|
|
537
|
+
(v) => _parseJsonArg(v, null),
|
|
538
|
+
null,
|
|
539
|
+
)
|
|
540
|
+
.option("--json", "JSON output")
|
|
541
|
+
.action((opts) => {
|
|
542
|
+
const db = _dbFromCtx(didv2);
|
|
543
|
+
const r = recordReputationSource(db, {
|
|
544
|
+
did: opts.did,
|
|
545
|
+
source: opts.source,
|
|
546
|
+
score: opts.score,
|
|
547
|
+
evidence: opts.evidence,
|
|
548
|
+
});
|
|
549
|
+
if (opts.json) return _json(r);
|
|
550
|
+
console.log(
|
|
551
|
+
`Recorded ${opts.source} score=${opts.score} (weight ${r.weight})`,
|
|
552
|
+
);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
didv2
|
|
556
|
+
.command("rep-aggregate")
|
|
557
|
+
.argument("<did>", "DID URI")
|
|
558
|
+
.description("Aggregate reputation across sources")
|
|
559
|
+
.option("-s, --sources <csv>", "Filter to these sources (CSV)", (v) =>
|
|
560
|
+
v
|
|
561
|
+
.split(",")
|
|
562
|
+
.map((s) => s.trim())
|
|
563
|
+
.filter(Boolean),
|
|
564
|
+
)
|
|
565
|
+
.option("--json", "JSON output")
|
|
566
|
+
.action((did, opts) => {
|
|
567
|
+
const db = _dbFromCtx(didv2);
|
|
568
|
+
const r = aggregateReputation(db, did, { sources: opts.sources });
|
|
569
|
+
if (opts.json) return _json(r);
|
|
570
|
+
console.log(
|
|
571
|
+
`Aggregated score: ${r.aggregatedScore.toFixed(3)} (${r.sourceCount} samples)`,
|
|
572
|
+
);
|
|
573
|
+
for (const s of r.sources) {
|
|
574
|
+
console.log(
|
|
575
|
+
` ${s.source.padEnd(14)} avg=${s.avgScore.toFixed(2)} weight=${s.weight} n=${s.sampleCount}`,
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
/* ── Export ──────────────────────────────────────── */
|
|
581
|
+
|
|
582
|
+
didv2
|
|
583
|
+
.command("export")
|
|
584
|
+
.argument("<did>", "DID URI")
|
|
585
|
+
.description("Export DID document + credentials")
|
|
586
|
+
.option("-f, --format <format>", "json-ld | jwt", "json-ld")
|
|
587
|
+
.option("--json", "JSON output")
|
|
588
|
+
.action((did, opts) => {
|
|
589
|
+
const db = _dbFromCtx(didv2);
|
|
590
|
+
const r = exportDID(db, did, { format: opts.format });
|
|
591
|
+
if (opts.json || opts.format === "jwt") return _json(r);
|
|
592
|
+
console.log(`Format: ${r.format}`);
|
|
593
|
+
console.log(`Document: ${JSON.stringify(r.document, null, 2)}`);
|
|
594
|
+
console.log(`Credentials: ${r.credentials.length}`);
|
|
595
|
+
console.log(`Reputation: ${r.reputationScore} Status: ${r.status}`);
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
/* ── Stats ───────────────────────────────────────── */
|
|
599
|
+
|
|
600
|
+
didv2
|
|
601
|
+
.command("stats")
|
|
602
|
+
.description("DID v2.0 stats")
|
|
603
|
+
.option("--json", "JSON output")
|
|
604
|
+
.action((opts) => {
|
|
605
|
+
const db = _dbFromCtx(didv2);
|
|
606
|
+
const s = getStats(db);
|
|
607
|
+
if (opts.json) return _json(s);
|
|
608
|
+
console.log(`DIDs: ${s.didCount} (${s.activeDIDs} active)`);
|
|
609
|
+
console.log(
|
|
610
|
+
`Credentials: ${s.credentialCount} (${s.activeCredentials} active)`,
|
|
611
|
+
);
|
|
612
|
+
console.log(
|
|
613
|
+
`Presentations: ${s.presentationCount} (${s.verifiedPresentations} verified)`,
|
|
614
|
+
);
|
|
615
|
+
console.log(`Recoveries: ${s.recoveryCount}`);
|
|
616
|
+
console.log(`Roaming log: ${s.roamingCount}`);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
program.addCommand(didv2);
|
|
620
|
+
}
|