atproto-plc#
did-method-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:
[dependencies]
atproto-plc = "0.1"
Validate a DID#
use atproto_plc::Did;
let did = Did::parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz")?;
println!("Valid DID: {}", did);
Create a new DID#
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#
npm install atproto-plc
Usage#
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:
# 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#
cargo run --example validate_did
Create a New DID#
cargo run --example create_did
Parse DID Documents#
cargo run --example parse_document
Building#
Native#
# Build
cargo build --release
# Run tests
cargo test --all-features
# Run benchmarks
cargo bench
# Generate documentation
cargo doc --open --no-deps --all-features
WASM#
# 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:
# 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: https://web.plc.directory/spec/v0.1/did-plc
- PLC Directory: https://plc.directory
Performance#
Run benchmarks:
cargo bench
Contributing#
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass:
cargo test --all-features - Run formatter:
cargo fmt - Run clippy:
cargo clippy --all-targets --all-features -- -D warnings - Submit a pull request
License#
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
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 - The AT Protocol specification
- plc-directory - Reference implementation
- did-web - Alternative DID method