Rust and WASM did-method-plc tools and structures
1# plc-audit WASM Implementation
2
3This is a JavaScript implementation of the `plc-audit` binary that uses WebAssembly for cryptographic operations. It fetches and validates DID audit logs from plc.directory.
4
5## Prerequisites
6
7- **Rust** (stable toolchain)
8- **wasm-pack** - Install with: `cargo install wasm-pack`
9- **Node.js** (v18 or later) - For running the JavaScript tool
10
11## Building
12
13### 1. Build the WASM Module
14
15From the project root directory:
16
17```bash
18# Build WASM module with wasm feature
19wasm-pack build --target nodejs --out-dir wasm/pkg --features wasm
20
21# Or use the provided build script
22./wasm/build.sh
23```
24
25This will:
26- Compile the Rust library to WebAssembly
27- Generate JavaScript bindings
28- Create a `wasm/pkg/` directory with the WASM module and TypeScript definitions
29
30### 2. Install Node.js Dependencies
31
32```bash
33cd wasm
34npm install
35```
36
37## Usage
38
39The JavaScript version supports the same command-line interface as the Rust binary:
40
41### Basic Validation
42
43Validate a DID and show detailed output:
44
45```bash
46node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur
47```
48
49### Verbose Mode
50
51Show all operations and detailed cryptographic validation steps:
52
53```bash
54node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur --verbose
55# or
56node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur -v
57```
58
59Output includes:
60- Operation index and CID
61- Creation timestamp
62- Operation type (Genesis/Update)
63- Previous operation reference
64- Step-by-step chain linkage validation
65- Detailed signature verification with rotation key tracking
66
67### Quiet Mode
68
69Only show validation result (useful for scripts):
70
71```bash
72node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur --quiet
73# or
74node plc-audit.js did:plc:z72i7hdynmk6r22z27h6tvur -q
75```
76
77Output: `✅ VALID` or error message
78
79### Custom PLC Directory
80
81Use a custom PLC directory server:
82
83```bash
84node plc-audit.js did:plc:example --plc-url https://custom.plc.directory
85```
86
87## What is Validated?
88
89The WASM version performs the same comprehensive validation as the Rust binary:
90
911. **DID Format Validation**
92 - Checks prefix is `did:plc:`
93 - Verifies identifier is exactly 24 characters
94 - Ensures only valid base32 characters (a-z, 2-7)
95
962. **Chain Linkage Verification**
97 - First operation must be genesis (prev = null)
98 - Each subsequent operation's `prev` field must match previous operation's CID
99 - No breaks in the chain
100
1013. **Cryptographic Signature Verification**
102 - Each operation's signature is verified using rotation keys
103 - Genesis operation establishes initial rotation keys
104 - Later operations can rotate keys
105 - Identifies which specific rotation key verified each signature
106
107## Example Output
108
109### Standard Mode
110
111```
112🔍 Fetching audit log for: did:plc:z72i7hdynmk6r22z27h6tvur
113 Source: https://plc.directory
114
115📊 Audit Log Summary:
116 Total operations: 4
117 Genesis operation: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm
118 Latest operation: bafyreifn4pkect7nymne3sxkdg7tn7534msyxcjkshmzqtijmn3enyxm3q
119
120🔐 Validating operation chain...
121✅ Validation successful!
122
123📄 Final DID State:
124 Rotation keys: 2
125 [0] did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg
126 [1] did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK
127```
128
129### Verbose Mode
130
131Shows detailed step-by-step validation:
132
133```
134Step 1: Chain Linkage Validation
135================================
136 [1] Checking prev reference...
137 Expected: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm
138 Actual: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm
139 ✅ Match - chain link valid
140 [2] Checking prev reference...
141 Expected: bafyreihmuvr3frdvd6vmdhucih277prdcfcezf67lasg5oekxoimnunjoq
142 Actual: bafyreihmuvr3frdvd6vmdhucih277prdcfcezf67lasg5oekxoimnunjoq
143 ✅ Match - chain link valid
144 ...
145
146✅ Chain linkage validation complete
147
148Step 2: Cryptographic Signature Validation
149==========================================
150 [0] Genesis operation - extracting rotation keys
151 Rotation keys: 2
152 [0] did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg
153 [1] did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK
154 ⚠️ Genesis signature cannot be verified (bootstrapping trust)
155 [1] Validating signature...
156 CID: bafyreihmuvr3frdvd6vmdhucih277prdcfcezf67lasg5oekxoimnunjoq
157 Signature: 1mEWzRtFOgeRXH-YCSPTxb990JOXxa__n8Qw6BOKl7Ndm6OFFmwYKiiMqMCpAbxpnGjF5abfIsKc7u3a77Cbnw
158 Available rotation keys: 2
159 [0] did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg
160 [1] did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK
161 Parsed verifying keys: 2/2
162 ✅ Signature verified with rotation key [1]
163 did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK
164 ...
165
166✅ Cryptographic signature validation complete
167```
168
169## Architecture
170
171The WASM implementation divides responsibilities:
172
173- **JavaScript** (`plc-audit.js`):
174 - Command-line argument parsing
175 - HTTP requests to plc.directory
176 - Console output formatting
177 - Control flow and orchestration
178
179- **WASM** (Rust compiled to WebAssembly):
180 - DID parsing and validation
181 - Operation parsing from JSON
182 - Cryptographic signature verification (P-256 and secp256k1)
183 - Rotation key management
184 - All security-critical operations
185
186## Performance
187
188The WASM version has comparable performance to the native Rust binary:
189
190- **WASM module size**: ~200KB (optimized)
191- **Validation time**: ~200-500ms for typical DIDs (4-10 operations)
192- **Startup overhead**: ~50-100ms for WASM initialization
193
194## Troubleshooting
195
196### Build Errors
197
198If you encounter build errors:
199
200```bash
201# Ensure wasm32-unknown-unknown target is installed
202rustup target add wasm32-unknown-unknown
203
204# Clean and rebuild
205rm -rf wasm/pkg
206wasm-pack build --target nodejs --out-dir wasm/pkg --features wasm
207```
208
209### Runtime Errors
210
211If you get "Module not found" errors:
212
213```bash
214# Ensure the WASM module is built
215ls wasm/pkg/atproto_plc_bg.wasm
216
217# If missing, rebuild
218wasm-pack build --target nodejs --out-dir wasm/pkg --features wasm
219```
220
221### Node.js Version
222
223Ensure you're using Node.js v18 or later:
224
225```bash
226node --version # Should be v18.0.0 or higher
227```
228
229## Comparison with Rust Binary
230
231| Feature | Rust Binary | WASM/JavaScript |
232|---------|-------------|-----------------|
233| Performance | Native speed | ~2-3x slower |
234| Binary Size | 1.5MB | ~200KB WASM |
235| Dependencies | None (static) | Node.js runtime |
236| Platform | Per-platform compilation | Universal (runs anywhere with Node.js) |
237| Use Case | Production servers, CLI | Cross-platform, web integration |
238
239## Integration Examples
240
241### Use in a Node.js Application
242
243```javascript
244import { WasmDid, WasmOperation, WasmVerifyingKey } from './pkg/atproto_plc.js';
245
246async function validateDid(didString) {
247 // Parse DID
248 const did = WasmDid.parse(didString);
249
250 // Fetch audit log
251 const response = await fetch(`https://plc.directory/${did.did}/log/audit`);
252 const auditLog = await response.json();
253
254 // Parse operations
255 const operations = auditLog.map(entry => ({
256 operation: WasmOperation.fromJson(JSON.stringify(entry.operation)),
257 cid: entry.cid,
258 }));
259
260 // Validate chain
261 for (let i = 1; i < operations.length; i++) {
262 const prev = operations[i].operation.prev();
263 if (prev !== operations[i - 1].cid) {
264 throw new Error('Chain linkage broken');
265 }
266 }
267
268 return true;
269}
270```
271
272### Use in Browser (with bundler)
273
274```javascript
275// Build with web target instead
276// wasm-pack build --target web --out-dir wasm/pkg --features wasm
277
278import init, { WasmDid } from './pkg/atproto_plc.js';
279
280await init(); // Initialize WASM
281
282const did = WasmDid.parse('did:plc:ewvi7nxzyoun6zhxrhs64oiz');
283console.log('Valid DID:', did.did);
284```
285
286## License
287
288Dual-licensed under MIT or Apache-2.0, same as the parent library.