CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-atproto

Comprehensive Python SDK for the AT Protocol, providing client interfaces, authentication, and real-time streaming for decentralized social networks.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

cryptographic-operations.mddocs/

Cryptographic Operations

Cryptographic key management, signature verification, multibase encoding/decoding, and DID key generation for secure AT Protocol communications. These operations ensure data integrity, authentication, and secure communication within the AT Protocol ecosystem.

Capabilities

Key Management

Multikey

Cryptographic key representation supporting multiple key types and algorithms for AT Protocol operations.

class Multikey:
    """
    Cryptographic key representation with algorithm specification.
    
    Attributes:
        jwt_alg (str): JWT algorithm identifier (e.g., 'ES256K', 'Ed25519')
        key_bytes (bytes): Raw key material
    """
    jwt_alg: str
    key_bytes: bytes
    
    @classmethod
    def from_str(cls, multikey: str) -> 'Multikey':
        """
        Parse Multikey from string representation.
        
        Args:
            multikey (str): Multikey string (e.g., multibase encoded)
            
        Returns:
            Multikey: Parsed key object
            
        Raises:
            ValueError: If multikey format is invalid
        """
    
    def to_str(self) -> str:
        """
        Format Multikey as string.
        
        Returns:
            str: Multikey string representation
        """
    
    @property
    def algorithm(self) -> str:
        """Get the cryptographic algorithm."""
    
    @property
    def key_type(self) -> str:
        """Get the key type (e.g., 'secp256k1', 'ed25519')."""
    
    def public_key_bytes(self) -> bytes:
        """
        Extract public key bytes.
        
        Returns:
            bytes: Public key material
        """

Usage example:

from atproto import Multikey

# Parse multikey from string
multikey_str = "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
multikey = Multikey.from_str(multikey_str)

print(f"Algorithm: {multikey.jwt_alg}")
print(f"Key type: {multikey.key_type}")
print(f"Key bytes length: {len(multikey.key_bytes)}")

# Convert back to string
key_str = multikey.to_str()
assert key_str == multikey_str

DID Key Generation

Generate DID keys from cryptographic key material for decentralized identity operations.

def get_did_key(key: Union[Multikey, bytes, str]) -> str:
    """
    Generate DID key from cryptographic key material.
    
    Args:
        key (Union[Multikey, bytes, str]): Key material in various formats
        
    Returns:
        str: DID key string (e.g., "did:key:z6MkhaXgB...")
        
    Raises:
        ValueError: If key format is unsupported
    """

Usage example:

from atproto import get_did_key, Multikey

# Generate DID key from Multikey
multikey = Multikey.from_str("z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK")
did_key = get_did_key(multikey)
print(f"DID key: {did_key}")

# Generate DID key from raw bytes
key_bytes = b'\x01\x02\x03...'  # Your key bytes
did_key = get_did_key(key_bytes)
print(f"DID key from bytes: {did_key}")

Multibase Encoding

Multibase provides self-describing base encodings for binary data, enabling interoperability across different encoding schemes.

Encoding to Multibase

def bytes_to_multibase(encoding: str, data: bytes) -> str:
    """
    Encode bytes to multibase format.
    
    Args:
        encoding (str): Multibase encoding character:
            - 'z' for base58btc
            - 'f' for base16 (hex)
            - 'b' for base32
            - 'u' for base64url
            - 'm' for base64
        data (bytes): Data to encode
        
    Returns:
        str: Multibase encoded string
        
    Raises:
        ValueError: If encoding is unsupported
    """

Decoding from Multibase

def multibase_to_bytes(data: str) -> bytes:
    """
    Decode multibase string to bytes.
    
    Args:
        data (str): Multibase encoded string (first character indicates encoding)
        
    Returns:
        bytes: Decoded data
        
    Raises:
        ValueError: If multibase format is invalid or encoding unsupported
    """

Usage examples:

from atproto import bytes_to_multibase, multibase_to_bytes

# Original data
original_data = b"Hello, AT Protocol!"

# Encode to different multibase formats
base58_encoded = bytes_to_multibase('z', original_data)
print(f"Base58: {base58_encoded}")

base32_encoded = bytes_to_multibase('b', original_data)
print(f"Base32: {base32_encoded}")

base64_encoded = bytes_to_multibase('m', original_data)
print(f"Base64: {base64_encoded}")

# Decode back to bytes
decoded_from_base58 = multibase_to_bytes(base58_encoded)
decoded_from_base32 = multibase_to_bytes(base32_encoded)
decoded_from_base64 = multibase_to_bytes(base64_encoded)

# All should equal original data
assert decoded_from_base58 == original_data
assert decoded_from_base32 == original_data
assert decoded_from_base64 == original_data

# The encoding is self-describing
print(f"Base58 prefix: {base58_encoded[0]}")  # 'z'
print(f"Base32 prefix: {base32_encoded[0]}")  # 'b'
print(f"Base64 prefix: {base64_encoded[0]}")  # 'm'

Signature Verification

Verify cryptographic signatures using DID keys to ensure message authenticity and integrity.

def verify_signature(did_key: str, signing_input: bytes, signature: bytes) -> bool:
    """
    Verify cryptographic signature using DID key.
    
    Args:
        did_key (str): DID key for verification (e.g., "did:key:z6Mk...")
        signing_input (bytes): Original data that was signed
        signature (bytes): Signature to verify
        
    Returns:
        bool: True if signature is valid, False otherwise
        
    Raises:
        ValueError: If DID key format is invalid
        UnsupportedAlgorithmError: If key algorithm is not supported
    """

Usage example:

from atproto import verify_signature, get_did_key

# Example verification scenario
did_key = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
message = b"This message was signed"
signature = b"\x01\x02\x03..."  # Actual signature bytes

# Verify the signature
is_valid = verify_signature(did_key, message, signature)

if is_valid:
    print("✓ Signature is valid - message is authentic")
else:
    print("✗ Signature is invalid - message may be tampered")

# Common use case: JWT signature verification
jwt_header = b'{"alg":"ES256K","typ":"JWT"}'
jwt_payload = b'{"iss":"did:plc:alice","sub":"did:plc:alice"}'
jwt_signing_input = base64_encode(jwt_header) + b'.' + base64_encode(jwt_payload)

jwt_signature = b"\x30\x45..."  # JWT signature bytes
is_jwt_valid = verify_signature(did_key, jwt_signing_input, jwt_signature)

Key Format Conversion

Utilities for converting between different key formats used in AT Protocol.

def multikey_to_did_key(multikey: Union[str, Multikey]) -> str:
    """
    Convert Multikey to DID key format.
    
    Args:
        multikey (Union[str, Multikey]): Multikey to convert
        
    Returns:
        str: DID key string
    """

def did_key_to_multikey(did_key: str) -> Multikey:
    """
    Extract Multikey from DID key.
    
    Args:
        did_key (str): DID key string
        
    Returns:
        Multikey: Extracted multikey
        
    Raises:
        ValueError: If DID key format is invalid
    """

def public_key_to_multikey(public_key: bytes, algorithm: str) -> Multikey:
    """
    Create Multikey from raw public key bytes.
    
    Args:
        public_key (bytes): Raw public key bytes
        algorithm (str): Key algorithm ('secp256k1', 'ed25519', etc.)
        
    Returns:
        Multikey: Constructed multikey
        
    Raises:
        ValueError: If algorithm is unsupported
    """

Usage examples:

from atproto import (
    Multikey, multikey_to_did_key, did_key_to_multikey, 
    public_key_to_multikey
)

# Convert between formats
multikey_str = "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
multikey = Multikey.from_str(multikey_str)

# Multikey to DID key
did_key = multikey_to_did_key(multikey)
print(f"DID key: {did_key}")

# DID key back to Multikey
recovered_multikey = did_key_to_multikey(did_key)
assert recovered_multikey.to_str() == multikey_str

# Create Multikey from raw key bytes
raw_public_key = b'\x04\x01\x02\x03...'  # secp256k1 public key
multikey_from_raw = public_key_to_multikey(raw_public_key, 'secp256k1')
print(f"Multikey from raw: {multikey_from_raw.to_str()}")

Cryptographic Algorithms

The SDK supports multiple cryptographic algorithms for different use cases:

class SupportedAlgorithms:
    """Supported cryptographic algorithms."""
    SECP256K1 = 'secp256k1'    # Bitcoin/Ethereum style keys
    ED25519 = 'ed25519'        # High-performance EdDSA
    P256 = 'p256'              # NIST P-256 curve

class JWTAlgorithms:
    """JWT algorithm identifiers."""
    ES256K = 'ES256K'          # ECDSA using secp256k1
    EDDSA = 'EdDSA'           # EdDSA using Ed25519
    ES256 = 'ES256'           # ECDSA using P-256

Algorithm selection example:

from atproto import Multikey, SupportedAlgorithms, JWTAlgorithms

# Create keys for different algorithms
algorithms = [
    (SupportedAlgorithms.SECP256K1, JWTAlgorithms.ES256K),
    (SupportedAlgorithms.ED25519, JWTAlgorithms.EDDSA),
    (SupportedAlgorithms.P256, JWTAlgorithms.ES256)
]

for key_type, jwt_alg in algorithms:
    # In practice, you would generate actual key material
    mock_key_bytes = b'\x01' * 32  # Placeholder
    
    multikey = Multikey(jwt_alg=jwt_alg, key_bytes=mock_key_bytes)
    did_key = get_did_key(multikey)
    
    print(f"Algorithm: {key_type}")
    print(f"JWT Algorithm: {jwt_alg}")
    print(f"DID Key: {did_key[:50]}...")
    print()

Error Handling

class CryptographicError(Exception):
    """Base exception for cryptographic operations."""

class InvalidKeyError(CryptographicError):
    """Raised when key format or content is invalid."""

class UnsupportedAlgorithmError(CryptographicError):
    """Raised when algorithm is not supported."""

class SignatureVerificationError(CryptographicError):
    """Raised when signature verification fails."""

class MultibaseError(CryptographicError):
    """Raised for multibase encoding/decoding errors."""

Error handling patterns:

from atproto import (
    verify_signature, multibase_to_bytes,
    InvalidKeyError, UnsupportedAlgorithmError, MultibaseError
)

# Handle key errors
try:
    invalid_did_key = "did:key:invalid"
    verify_signature(invalid_did_key, b"data", b"signature")
except InvalidKeyError as e:
    print(f"Invalid key format: {e}")

# Handle algorithm errors
try:
    unsupported_multikey = "unsupported_format_key"
    multikey = Multikey.from_str(unsupported_multikey)
except UnsupportedAlgorithmError as e:
    print(f"Unsupported algorithm: {e}")

# Handle multibase errors
try:
    invalid_multibase = "invalid_multibase_string"
    decoded = multibase_to_bytes(invalid_multibase)
except MultibaseError as e:
    print(f"Multibase decoding failed: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-atproto

docs

client-operations.md

core-functionality.md

cryptographic-operations.md

identity-resolution.md

index.md

jwt-operations.md

real-time-streaming.md

tile.json