# atproto-plc [![Crates.io](https://img.shields.io/crates/v/atproto-plc.svg)](https://crates.io/crates/atproto-plc) [![Documentation](https://docs.rs/atproto-plc/badge.svg)](https://docs.rs/atproto-plc) [![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE-MIT) [did-method-plc](https://web.plc.directory/spec/v0.1/did-plc) implementation for ATProtocol with WASM support. ## Features - ✅ Validate did:plc identifiers - ✅ Parse and validate DID documents - ✅ Create new did:plc identities - ✅ Validate operation chains - ✅ Native Rust and WASM support - ✅ Recovery mechanism with 72-hour window - ✅ Support for both P-256 and secp256k1 keys - ✅ DAG-CBOR encoding for operations - ✅ Comprehensive test suite ## Quick Start ### Rust Add this to your `Cargo.toml`: ```toml [dependencies] atproto-plc = "0.1" ``` #### Validate a DID ```rust use atproto_plc::Did; let did = Did::parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz")?; println!("Valid DID: {}", did); ``` #### Create a new DID ```rust use atproto_plc::{DidBuilder, SigningKey, ServiceEndpoint}; // Generate keys let rotation_key = SigningKey::generate_p256(); let signing_key = SigningKey::generate_k256(); // Build the DID let (did, operation, keys) = DidBuilder::new() .add_rotation_key(rotation_key) .add_verification_method("atproto".into(), signing_key) .add_also_known_as("at://alice.example.com".into()) .add_service( "atproto_pds".into(), ServiceEndpoint::new( "AtprotoPersonalDataServer".into(), "https://pds.example.com".into(), ), ) .build()?; println!("Created DID: {}", did); ``` ### JavaScript/WASM #### Installation ```bash npm install atproto-plc ``` #### Usage ```javascript import { parseDid, createDidBuilder, generateP256Key, generateK256Key } from 'atproto-plc'; // Validate a DID const did = await parseDid('did:plc:ewvi7nxzyoun6zhxrhs64oiz'); console.log('Valid DID:', did.identifier); // Create a new DID const rotationKey = await generateP256Key(); const signingKey = await generateK256Key(); const builder = await createDidBuilder(); const result = builder .addRotationKey(rotationKey) .addVerificationMethod('atproto', signingKey) .build(); console.log('Created DID:', result.did); ``` ## DID Format A did:plc identifier consists of: - Prefix: `did:plc:` - Identifier: 24 lowercase base32 characters (alphabet: `abcdefghijklmnopqrstuvwxyz234567`) Example: `did:plc:ewvi7nxzyoun6zhxrhs64oiz` ### Valid Characters The identifier uses a restricted base32 alphabet that excludes confusing characters: - ✅ Allowed: `a-z`, `2-7` - ❌ Excluded: `0`, `1`, `8`, `9` (avoid confusion with letters) - ❌ No uppercase letters ## Architecture ### Core Components - **DID Validation** (`src/did.rs`): Parse and validate did:plc identifiers - **Cryptography** (`src/crypto.rs`): Signing and verification with P-256 and secp256k1 - **Documents** (`src/document.rs`): DID document structures (PLC state and W3C format) - **Operations** (`src/operations.rs`): Genesis, update, and tombstone operations - **Validation** (`src/validation.rs`): Operation chain validation and recovery - **Builder** (`src/builder.rs`): Convenient API for creating DIDs - **Encoding** (`src/encoding.rs`): Base32, base64url, and DAG-CBOR utilities - **WASM** (`src/wasm.rs`): WebAssembly bindings for JavaScript ### Key Concepts #### Rotation Keys (1-5 required) Rotation keys are used to: - Sign operations that modify the DID - Recover control within a 72-hour window - Establish a priority order for fork resolution #### Verification Methods (up to 10) Verification methods are used for: - Authentication - Signing application data (e.g., ATProto records) - General cryptographic operations #### Recovery Mechanism If a higher-priority rotation key (lower array index) signs a conflicting operation within 72 hours, it can invalidate operations signed by lower-priority keys. ## Command-Line Tools ### plc-audit: DID Audit Log Validator The `plc-audit` binary fetches and validates DID audit logs from plc.directory: ```bash # Build the tool cargo build --release --features cli --bin plc-audit # Validate a DID ./target/release/plc-audit did:plc:z72i7hdynmk6r22z27h6tvur # Verbose mode (shows all operations) ./target/release/plc-audit did:plc:z72i7hdynmk6r22z27h6tvur --verbose # Quiet mode (only shows VALID/INVALID) ./target/release/plc-audit did:plc:z72i7hdynmk6r22z27h6tvur --quiet # Custom PLC directory ./target/release/plc-audit did:plc:example --plc-url https://custom.plc.directory ``` The tool performs comprehensive validation: - ✅ Chain linkage verification (prev references) - ✅ Cryptographic signature verification - ✅ Operation ordering and consistency Example output: ``` 🔍 Fetching audit log for: did:plc:z72i7hdynmk6r22z27h6tvur Source: https://plc.directory 📊 Audit Log Summary: Total operations: 4 Genesis operation: bafyreigp6shzy6dlcxuowwoxz7u5nemdrkad2my5zwzpwilcnhih7bw6zm Latest operation: bafyreifn4pkect7nymne3sxkdg7tn7534msyxcjkshmzqtijmn3enyxm3q 🔐 Validating operation chain... ✅ Validation successful! 📄 Final DID State: Rotation keys: 2 Verification methods: 1 Also known as: 1 Services: 1 ``` ## Examples ### Validate DIDs ```bash cargo run --example validate_did ``` ### Create a New DID ```bash cargo run --example create_did ``` ### Parse DID Documents ```bash cargo run --example parse_document ``` ## Building ### Native ```bash # Build cargo build --release # Run tests cargo test --all-features # Run benchmarks cargo bench # Generate documentation cargo doc --open --no-deps --all-features ``` ### WASM ```bash # Install wasm-pack cargo install wasm-pack # Build for web wasm-pack build --target web --out-dir wasm/pkg # Run WASM tests wasm-pack test --headless --chrome ``` ## Testing The library includes comprehensive tests: ```bash # Run all tests cargo test --all-features # Run specific test suites cargo test --test did_validation cargo test --test crypto_operations cargo test --test document_parsing cargo test --test operation_chain ``` ## Specification This library implements the did:plc specification: - Specification: - PLC Directory: ## Performance Run benchmarks: ```bash cargo bench ``` ## Contributing Contributions are welcome! Please: 1. Fork the repository 2. Create a feature branch 3. Add tests for new functionality 4. Ensure all tests pass: `cargo test --all-features` 5. Run formatter: `cargo fmt` 6. Run clippy: `cargo clippy --all-targets --all-features -- -D warnings` 7. Submit a pull request ## License Licensed under either of: - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) - MIT license ([LICENSE-MIT](LICENSE-MIT) or ) at your option. ### Contribution Unless 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. ## Related Projects - [ATProto](https://github.com/bluesky-social/atproto) - The AT Protocol specification - [plc-directory](https://github.com/did-method-plc/did-method-plc) - Reference implementation - [did-web](https://w3c-ccg.github.io/did-method-web/) - Alternative DID method