Rust and WASM did-method-plc tools and structures
1# atproto-plc 2 3[![Crates.io](https://img.shields.io/crates/v/atproto-plc.svg)](https://crates.io/crates/atproto-plc) 4[![Documentation](https://docs.rs/atproto-plc/badge.svg)](https://docs.rs/atproto-plc) 5[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](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