open source is social v-it.org
1#!/usr/bin/env bun
2// SPDX-License-Identifier: MIT
3// Copyright (c) 2026 sol pbc
4
5import { Command } from 'commander';
6
7const program = new Command();
8program
9 .name('plc-verify')
10 .description('Verify PLC directory entry for a DID')
11 .requiredOption('--did <did>', 'DID to check (required)')
12 .option('-v, --verbose', 'Show full API responses')
13 .action(async (opts) => {
14 try {
15 const did = opts.did;
16
17 if (!did.startsWith('did:plc:')) {
18 throw new Error(`Expected a did:plc: identifier, got: ${did}`);
19 }
20
21 console.log(`Checking DID: ${did}\n`);
22
23 const docUrl = `https://plc.directory/${did}`;
24 const docRes = await fetch(docUrl);
25 if (!docRes.ok) {
26 throw new Error(`PLC directory returned ${docRes.status} for ${docUrl}`);
27 }
28 const doc = await docRes.json();
29
30 if (opts.verbose) {
31 console.log('[verbose] DID document:');
32 console.log(JSON.stringify(doc, null, 2));
33 console.log();
34 }
35
36 const handles = doc.alsoKnownAs ?? [];
37 const services = doc.service ?? [];
38 const verificationMethods = doc.verificationMethod ?? [];
39
40 console.log(`DID document:`);
41 console.log(` id: ${doc.id}`);
42 console.log(` handles: ${handles.join(', ') || '(none)'}`);
43 console.log(` services: ${services.map(s => `${s.id} (${s.type})`).join(', ') || '(none)'}`);
44 console.log(` verification methods: ${verificationMethods.length}`);
45 console.log();
46
47 const auditUrl = `https://plc.directory/${did}/log/audit`;
48 const auditRes = await fetch(auditUrl);
49 if (!auditRes.ok) {
50 throw new Error(`PLC directory returned ${auditRes.status} for ${auditUrl}`);
51 }
52 const auditLog = await auditRes.json();
53
54 if (opts.verbose) {
55 console.log('[verbose] Audit log:');
56 console.log(JSON.stringify(auditLog, null, 2));
57 console.log();
58 }
59
60 console.log(`Audit log: ${auditLog.length} operation(s)`);
61 if (auditLog.length > 0) {
62 const first = auditLog[0];
63 const last = auditLog[auditLog.length - 1];
64 console.log(` first: ${first.createdAt}`);
65 if (auditLog.length > 1) {
66 console.log(` latest: ${last.createdAt}`);
67 }
68 }
69 console.log();
70
71 console.log('All checks passed.');
72 } catch (err) {
73 console.error(err instanceof Error ? err.message : String(err));
74 process.exitCode = 1;
75 }
76 });
77
78program.parse();