Rust and WASM did-method-plc tools and structures
1# atproto-plc
2
3[](https://crates.io/crates/atproto-plc)
4[](https://docs.rs/atproto-plc)
5[](LICENSE-MIT)
6
7[did-method-plc](https://web.plc.directory/spec/v0.1/did-plc) implementation for ATProtocol with WASM support.
8
9## Features
10
11- ✅ Validate did:plc identifiers
12- ✅ Parse and validate DID documents
13- ✅ Create new did:plc identities
14- ✅ Validate operation chains
15- ✅ Native Rust and WASM support
16- ✅ Recovery mechanism with 72-hour window
17- ✅ Support for both P-256 and secp256k1 keys
18- ✅ DAG-CBOR encoding for operations
19- ✅ Comprehensive test suite
20
21## Quick Start
22
23### Rust
24
25Add this to your `Cargo.toml`:
26
27```toml
28[dependencies]
29atproto-plc = "0.1"
30```
31
32#### Validate a DID
33
34```rust
35use atproto_plc::Did;
36
37let did = Did::parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz")?;
38println!("Valid DID: {}", did);
39```
40
41#### Create a new DID
42
43```rust
44use atproto_plc::{DidBuilder, SigningKey, ServiceEndpoint};
45
46// Generate keys
47let rotation_key = SigningKey::generate_p256();
48let signing_key = SigningKey::generate_k256();
49
50// Build the DID
51let (did, operation, keys) = DidBuilder::new()
52 .add_rotation_key(rotation_key)
53 .add_verification_method("atproto".into(), signing_key)
54 .add_also_known_as("at://alice.example.com".into())
55 .add_service(
56 "atproto_pds".into(),
57 ServiceEndpoint::new(
58 "AtprotoPersonalDataServer".into(),
59 "https://pds.example.com".into(),
60 ),
61 )
62 .build()?;
63
64println!("Created DID: {}", did);
65```
66
67### JavaScript/WASM
68
69#### Installation
70
71```bash
72npm install atproto-plc
73```
74
75#### Usage
76
77```javascript
78import { parseDid, createDidBuilder, generateP256Key, generateK256Key } from 'atproto-plc';
79
80// Validate a DID
81const did = await parseDid('did:plc:ewvi7nxzyoun6zhxrhs64oiz');
82console.log('Valid DID:', did.identifier);
83
84// Create a new DID
85const rotationKey = await generateP256Key();
86const signingKey = await generateK256Key();
87
88const builder = await createDidBuilder();
89const result = builder
90 .addRotationKey(rotationKey)
91 .addVerificationMethod('atproto', signingKey)
92 .build();
93
94console.log('Created DID:', result.did);
95```
96
97## DID Format
98
99A did:plc identifier consists of:
100- Prefix: `did:plc:`
101- Identifier: 24 lowercase base32 characters (alphabet: `abcdefghijklmnopqrstuvwxyz234567`)
102
103Example: `did:plc:ewvi7nxzyoun6zhxrhs64oiz`
104
105### Valid Characters
106
107The identifier uses a restricted base32 alphabet that excludes confusing characters:
108- ✅ Allowed: `a-z`, `2-7`
109- ❌ Excluded: `0`, `1`, `8`, `9` (avoid confusion with letters)
110- ❌ No uppercase letters
111
112## Architecture
113
114### Core Components
115
116- **DID Validation** (`src/did.rs`): Parse and validate did:plc identifiers
117- **Cryptography** (`src/crypto.rs`): Signing and verification with P-256 and secp256k1
118- **Documents** (`src/document.rs`): DID document structures (PLC state and W3C format)
119- **Operations** (`src/operations.rs`): Genesis, update, and tombstone operations
120- **Validation** (`src/validation.rs`): Operation chain validation and recovery
121- **Builder** (`src/builder.rs`): Convenient API for creating DIDs
122- **Encoding** (`src/encoding.rs`): Base32, base64url, and DAG-CBOR utilities
123- **WASM** (`src/wasm.rs`): WebAssembly bindings for JavaScript
124
125### Key Concepts
126
127#### Rotation Keys (1-5 required)
128
129Rotation keys are used to:
130- Sign operations that modify the DID
131- Recover control within a 72-hour window
132- Establish a priority order for fork resolution
133
134#### Verification Methods (up to 10)
135
136Verification methods are used for:
137- Authentication
138- Signing application data (e.g., ATProto records)
139- General cryptographic operations
140
141#### Recovery Mechanism
142
143If a higher-priority rotation key (lower array index) signs a conflicting operation within 72 hours, it can invalidate operations signed by lower-priority keys.
144
145## Command-Line Tools
146
147### plc-audit: DID Audit Log Validator
148
149The `plc-audit` binary fetches and validates DID audit logs from plc.directory:
150
151```bash
152# Build the tool
153cargo build --release --features cli --bin plc-audit
154
155# Validate a DID
156./target/release/plc-audit did:plc:z72i7hdynmk6r22z27h6tvur
157
158# Verbose mode (shows all operations)
159./target/release/plc-audit did:plc:z72i7hdynmk6r22z27h6tvur --verbose
160
161# Quiet mode (only shows VALID/INVALID)
162./target/release/plc-audit did:plc:z72i7hdynmk6r22z27h6tvur --quiet
163
164# Custom PLC directory
165./target/release/plc-audit did:plc:example --plc-url https://custom.plc.directory
166```
167
168The tool performs comprehensive validation:
169- ✅ Chain linkage verification (prev references)
170- ✅ Cryptographic signature verification
171- ✅ Operation ordering and consistency
172
173Example output:
174```
175🔍 Fetching audit log for: did:plc:z72i7hdynmk6r22z27h6tvur
176 Source: https://plc.directory
177
178📊 Audit Log Summary:
179 Total operations: 4
180 Genesis operation: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm
181 Latest operation: bafyreifn4pkect7nymne3sxkdg7tn7534msyxcjkshmzqtijmn3enyxm3q
182
183🔐 Validating operation chain...
184✅ Validation successful!
185
186📄 Final DID State:
187 Rotation keys: 2
188 Verification methods: 1
189 Also known as: 1
190 Services: 1
191```
192
193## Examples
194
195### Validate DIDs
196
197```bash
198cargo run --example validate_did
199```
200
201### Create a New DID
202
203```bash
204cargo run --example create_did
205```
206
207### Parse DID Documents
208
209```bash
210cargo run --example parse_document
211```
212
213## Building
214
215### Native
216
217```bash
218# Build
219cargo build --release
220
221# Run tests
222cargo test --all-features
223
224# Run benchmarks
225cargo bench
226
227# Generate documentation
228cargo doc --open --no-deps --all-features
229```
230
231### WASM
232
233```bash
234# Install wasm-pack
235cargo install wasm-pack
236
237# Build for web
238wasm-pack build --target web --out-dir wasm/pkg
239
240# Run WASM tests
241wasm-pack test --headless --chrome
242```
243
244## Testing
245
246The library includes comprehensive tests:
247
248```bash
249# Run all tests
250cargo test --all-features
251
252# Run specific test suites
253cargo test --test did_validation
254cargo test --test crypto_operations
255cargo test --test document_parsing
256cargo test --test operation_chain
257```
258
259## Specification
260
261This library implements the did:plc specification:
262- Specification: <https://web.plc.directory/spec/v0.1/did-plc>
263- PLC Directory: <https://plc.directory>
264
265## Performance
266
267Run benchmarks:
268
269```bash
270cargo bench
271```
272
273## Contributing
274
275Contributions are welcome! Please:
276
2771. Fork the repository
2782. Create a feature branch
2793. Add tests for new functionality
2804. Ensure all tests pass: `cargo test --all-features`
2815. Run formatter: `cargo fmt`
2826. Run clippy: `cargo clippy --all-targets --all-features -- -D warnings`
2837. Submit a pull request
284
285## License
286
287Licensed under either of:
288
289- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
290- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
291
292at your option.
293
294### Contribution
295
296Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
297
298## Related Projects
299
300- [ATProto](https://github.com/bluesky-social/atproto) - The AT Protocol specification
301- [plc-directory](https://github.com/did-method-plc/did-method-plc) - Reference implementation
302- [did-web](https://w3c-ccg.github.io/did-method-web/) - Alternative DID method