Teal CLI#
A comprehensive management tool for Teal AT Protocol services, featuring cryptographic key management and CAR (Content Addressable aRchive) file exploration.
Installation#
From the project root:
cargo build --release --bin teal
The binary will be available at target/release/teal.
Usage#
CAR File Explorer#
Explore and analyze CAR files containing AT Protocol and Teal records.
Fetch CAR file from the internet#
# Fetch from AT Protocol handle
teal car fetch --identity alice.bsky.social
# Fetch from DID
teal car fetch --identity did:plc:vdjlpwlhbnug4fnjodwr3vzh
# Fetch and save to specific file
teal car fetch --identity mmatt.net --output mmatt.car
# Fetch and immediately explore
teal car fetch --identity mmatt.net --explore
Explore a CAR file#
# Basic exploration
teal car explore --file path/to/archive.car
# Verbose output with detailed information
teal car explore --file path/to/archive.car --verbose
Search for specific content#
# Search for records containing "play"
teal car search --file path/to/archive.car --query "play"
# Search with verbose JSON output
teal car search --file path/to/archive.car --query "queen" --verbose
Export Teal records to JSON#
# Export to default directory (./teal_exports)
teal car export --file path/to/archive.car
# Export to custom directory
teal car export --file path/to/archive.car --output ./my_exports
Generate a new K256 key pair#
# Generate with default settings (saves to ~/.teal/keys/)
teal gen-key
# Generate with custom name
teal gen-key --name production
# Generate with custom output directory
teal gen-key --output ./keys
# Overwrite existing keys
teal gen-key --force
# Output only the multibase (useful for scripts)
teal gen-key --format multibase
# Output as JSON
teal gen-key --format json
Extract public key from existing private key#
# Extract as multibase (default)
teal extract-pubkey --private-key ./keys/repo.key
# Extract as hex
teal extract-pubkey --private-key ./keys/repo.key --format hex
# Extract as JSON with both formats
teal extract-pubkey --private-key ./keys/repo.key --format json
List available keys#
# List keys in default directory
teal list
# List keys in custom directory
teal list --directory ./keys
Rotate keys (backup old, generate new)#
# Rotate the default 'repo' key
teal rotate --name repo
# Rotate with custom backup directory
teal rotate --name repo --backup-dir ./backups
CAR File Analysis#
The CAR explorer can analyze AT Protocol archives and identify:
- Teal Records: Music plays (
fm.teal.alpha.feed.play), profiles (fm.teal.alpha.actor.profile), and status updates - AT Protocol Records: BlueSky posts, likes, follows, and other social data
- Commit Operations: Repository changes and metadata
- IPLD Structure: Content addressing and linking
Example Output#
📊 CAR Analysis Results
==================================================
📁 File Overview:
File size: 10267026 bytes
Total blocks: 30195
Root CIDs: 1
📋 Record Types:
app.bsky.feed.like: 11034
app.bsky.feed.post: 7510
fm.teal.alpha.feed.play: 2605
fm.teal.alpha.actor.profile: 1
🎵 Teal Records Found:
fm.teal.alpha.feed.play: 2605
fm.teal.alpha.actor.profile: 1
🔍 Sample Teal Records:
1. fm.teal.alpha.feed.play (bafyreigmu...)
🎵 Track: Bohemian Rhapsody
🎤 Artists: Queen
⏱️ Duration: 355000ms
Exported JSON Structure#
[
{
"cid": "bafyreigmuwliezhxczoxgxq5hjtsdzaj3jl54kg...",
"data": {
"$type": "fm.teal.alpha.feed.play",
"track_name": "Bohemian Rhapsody",
"artist_names": ["Queen"],
"duration": 355000,
"played_time": "2024-01-15T14:30:00Z"
}
}
]
Key Management#
The tool generates K256 (secp256k1) keys compatible with AT Protocol:
- Private Key: 32-byte secp256k1 private key stored as binary
- Public Key: Base58-encoded multibase of the compressed public key
- Default Location:
~/.teal/keys/
File Structure#
~/.teal/keys/
├── repo.key # Private key (32 bytes, binary)
├── repo.pub # Public key multibase (text)
├── production.key # Another private key
└── production.pub # Another public key multibase
Integration#
Replace the hardcoded multibase in your DID document:
// Before (hardcoded)
"publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
// After (using generated key)
let pubkey = std::fs::read_to_string("~/.teal/keys/repo.pub")?;
// Use pubkey in your DID document
Examples#
CAR File Analysis#
# Fetch CAR file from a user's handle
teal car fetch --identity mmatt.net --output mmatt.car
# Fetch and immediately explore
teal car fetch --identity alice.bsky.social --explore
# Analyze a local CAR export
teal car explore --file nat.car
# Search for specific tracks
teal car search --file nat.car --query "bohemian rhapsody"
# Export all Teal records for data analysis
teal car export --file nat.car --output ./music_data
# View exported play records
cat ./music_data/fm_teal_alpha_feed_play.json | jq '.[0]'
Quick setup#
# Generate a key for development
teal gen-key --name dev
# Get the multibase for your DID document
teal extract-pubkey --private-key ~/.teal/keys/dev.key
Production deployment#
# Generate production keys in a secure location
teal gen-key --name production --output /secure/keys
# Extract multibase for configuration
PUBKEY=$(teal extract-pubkey --private-key /secure/keys/production.key)
echo "Public key: $PUBKEY"
Security Notes#
- Private keys are stored as raw 32-byte files with restrictive permissions (600 on Unix)
- Keys are generated using cryptographically secure random number generation
- Never commit private keys to version control
- Consider using secure key management systems in production