arroba package

Reference documentation.

did

Utilities to create and resolve did:plcs, did:webs, and handles.

class DidPlc(did, signing_key, rotation_key, doc)

Bases: tuple

resolve(did, **kwargs)[source]

Resolves a did:plc or did:web.

Parameters:
Returns:

JSON DID document

Return type:

dict

Raises:
resolve_plc(did, get_fn=<bound method Session.get of <requests_hardened.client.HTTPSession object>>)[source]

Resolves a did:plc by fetching its DID document from a PLC directory.

The PLC directory hostname is specified in the PLC_HOST environment variable.

did:plc background:

Parameters:
  • did (str)

  • get_fn (callable) – for making HTTP GET requests

Returns:

JSON DID document

Return type:

dict

Raises:
create_plc(handle, **kwargs)[source]

Creates a new did:plc in a PLC directory.

Args are documented in write_plc().

update_plc(did, handle=None, get_fn=<bound method Session.get of <requests_hardened.client.HTTPSession object>>, **kwargs)[source]

Updates an existing did:plc in a PLC directory.

Args are documented in write_plc().

write_plc(did=None, handle=None, signing_key=None, rotation_key=None, new_rotation_key=None, pds_url=None, also_known_as=None, prev=None, get_fn=<bound method Session.get of <requests_hardened.client.HTTPSession object>>, post_fn=<bound method Session.post of <requests_hardened.client.HTTPSession object>>)[source]

Writes a PLC operation to a PLC directory.

Generally used to create a new did:plc or update an existing one.

The PLC directory hostname is specified in the PLC_HOST environment variable.

did:plc background:

The DID document in the returned value is the new format DID doc, with the fully qualified verificationMethod.id and Multikey key encoding, ie did:key without the prefix. Details: https://github.com/bluesky-social/atproto/discussions/1510

Parameters:
  • did (str) – if provided, updates an existing DID, otherwise creates a new one.

  • handle (str) – domain handle to associate with this DID

  • signing_key (ec.EllipticCurvePrivateKey or ec.EllipticCurvePublicKey) – The curve must be SECP256K1. If omitted, a new keypair will be created.

  • rotation_key (ec.EllipticCurvePrivateKey) – The curve must be SECP256K1. Used for signing the operation. If omitted, a new keypair will be created.

  • new_rotation_key (ec.EllipticCurvePrivateKey or ec.EllipticCurvePublicKey) – optional. If provided, populated into the rotationKeys field instead of rotation_key.

  • pds_url (str) – PDS base URL to associate with this DID. If omitted, defaults to https://[$PDS_HOST]

  • also_known_as (str or sequence of str) – additional URI or URIs to add to alsoKnownAs

  • prev (str) – if an update, the CID of the previous operation for this DID

  • get_fn (callable) – for making HTTP GET requests

  • post_fn (callable) – for making HTTP POST requests

Returns:

with the DID, keys, and DID document

Return type:

DidPlc

Raises:
write_plc_operation(op, rotation_key, did=None, post_fn=<bound method Session.post of <requests_hardened.client.HTTPSession object>>)[source]

Signs and sends a PLC operation to the directory.

Parameters:
  • op (dict) – PLC operation

  • rotation_key (ec.EllipticCurvePrivateKey) – The curve must be SECP256K1. Must match the DID’s current rotation key in the PLC directory.

  • did (str) – if provided, updates an existing DID, otherwise creates a new one.

  • post_fn (callable) – for making HTTP POST requests

Returns:

with the DID and DID document, but not keys

Return type:

DidPlc

rollback_plc(did, rotation_key, num_operations=1, get_fn=<bound method Session.get of <requests_hardened.client.HTTPSession object>>, post_fn=<bound method Session.post of <requests_hardened.client.HTTPSession object>>)[source]

Reverts a DID PLC document to its last version.

Reads a did:plc’s audit log from the directory, extracts its previous operation, and re-applies that operation. Reverts the DID to its last document, before the current one.

Parameters:
  • did (str)

  • rotation_key (ec.EllipticCurvePrivateKey) – The curve must be SECP256K1. Must match the DID’s current rotation key in the PLC directory.

  • num_operations (int) – how many operations back to revert. Defaults to 1.

  • get_fn (callable) – for making HTTP GET requests

  • post_fn (callable) – for making HTTP POST requests

Returns:

with the DID and DID document, but not keys

Return type:

DidPlc

encode_did_key(pubkey)[source]

Encodes an ec.EllipticCurvePublicKey into a did:key string.

https://atproto.com/specs/did#public-key-encoding

Parameters:

pubkey (ec.EllipticCurvePublicKey)

Returns:

encoded did:key

Return type:

str

decode_did_key(did_key)[source]

Decodes a did:key string into an ec.EllipticCurvePublicKey.

https://atproto.com/specs/did#public-key-encoding

Parameters:

did_key (str)

Returns:

ec.EllipticCurvePublicKey

get_handle(did_doc)[source]

Extracts and returns a DID’s handle.

Doesn’t do bidirectional handle resolution! Just returns the handle in the first at:// URI in alsoKnownAs.

Parameters:

did_doc (dict) – DID document

Returns:

handle, or None if the DID doc doens’t have one

Return type:

str

get_signing_key(did_doc)[source]

Extracts and returns a DID’s signing key.

Parameters:

did_doc (dict) – DID document

Returns:

ec.EllipticCurvePublicKey, or None if the DID doc has no ATProto signing key

plc_operation_to_did_doc(op)[source]

Converts a PLC directory operation to a DID document.

https://github.com/bluesky-social/did-method-plc#presentation-as-did-document

The DID document in the returned value is the new format DID doc, with the fully qualified verificationMethod.id and Multikey key encoding, ie did:key without the prefix. Details: https://github.com/bluesky-social/atproto/discussions/1510

Parameters:

op – dict, PLC operation, https://github.com/did-method-plc/did-method-plc#operation-serialization-signing-and-validation

Returns:

DID document, https://www.w3.org/TR/did-core/#data-model

Return type:

dict

resolve_web(did, get_fn=<bound method Session.get of <requests_hardened.client.HTTPSession object>>)[source]

Resolves a did:web by fetching its DID document.

did:web spec: https://w3c-ccg.github.io/did-method-web/

Parameters:
  • did (str)

  • get_fn (callable) – for making HTTP GET requests

Returns:

JSON DID document

Return type:

dict

Raises:
resolve_handle(handle, get_fn=<bound method Session.get of <requests_hardened.client.HTTPSession object>>)[source]

Resolves an ATProto handle to a DID.

Supports the DNS TXT record and HTTPS well-known methods.

https://atproto.com/specs/handle#handle-resolution

Parameters:
  • handle (str)

  • get_fn (callable) – for making HTTP GET requests

Returns:

DID, or None if the handle can’t be resolved

Return type:

str or None

Raises:

ValueError – if handle is not a valid handle

diff

mst

repo

Bluesky / AT Protocol repo implementation.

https://atproto.com/guides/data-repos

Heavily based on: https://github.com/bluesky-social/atproto/blob/main/packages/repo/src/repo.ts

Huge thanks to the Bluesky team for working in the public, in open source, and to Daniel Holmgren and Devin Ivy for this code specifically!

class Write(action, collection, rkey, record)

Bases: tuple

class Repo(*, storage=None, mst=None, head=None, handle=None, status=None, callback=None, signing_key=None, rotation_key=None, created=None)[source]

Bases: object

AT Protocol data repo implementation, storage agnostic.

did

repo DID (dynamic property)

Type:

str

version

AT Protocol version (dynamic property)

Type:

int

storage
Type:

Storage

mst
Type:

MST

head

head commit

Type:

Block

handle
Type:

str

status

None (if active) or 'deactivated', 'deleted', or 'tombstoned' (deprecated)

Type:

str

created
Type:

datetime

callback (callable

(data=CommitData | dict, lost_seq=int) => None): called on new commits and other repo events. May be set directly by clients. None means no callback. Both kwargs are optional. data is a CommitData for commits, or a dict record with $type for other com.atproto.sync.subscribeRepos messages. lost_seq is an integer sequence number that we allocated but then didn’t use, ie “lost.”

get_record(collection, rkey)[source]
Parameters:
Returns:

node, record or commit or serialized MST

Return type:

dict

get_contents()[source]
Return type:

dict mapping str collection to dict mapping str rkey to dict record

classmethod create(storage, did, *, signing_key, rotation_key=None, **kwargs)[source]
Parameters:
  • did (str)

  • storage (Storage)

  • signing_key (ec.EllipticCurvePrivateKey)

  • rotation_key (ec.EllipticCurvePrivateKey)

  • kwargs – passed through to Repo constructor

Return type:

Repo

classmethod load(storage, cid=None, **kwargs)[source]
Parameters:
  • storage (Storage)

  • cid (CID) – optional

  • kwargs – passed through to Repo constructor

Return type:

Repo

storage

datastore_storage

util

Misc AT Protocol utils. TIDs, CIDs, etc.

exception InactiveRepo(did, status, *args, **kwargs)[source]

Bases: ValueError

Raised when loading a repo that’s not active.

status
Type:

str

time_ns()[source]

Wrapper for time.time_ns() that lets us mock it out in tests.

dag_cbor_cid(obj)[source]

Returns the DAG-CBOR CID for a given object.

Parameters:

obj – CBOR-compatible native object or value

Return type:

CID

s32encode(num)[source]

Base32 encode with encoding variant sort.

Based on https://github.com/bluesky-social/atproto/blob/main/packages/common-web/src/tid.ts

Parameters:

num (int or Integral)

Return type:

str

s32decode(val)[source]

Base32 decode with encoding variant sort.

Based on https://github.com/bluesky-social/atproto/blob/main/packages/common-web/src/tid.ts

Parameters:

val (str)

Return type:

int or Integral

datetime_to_tid(dt, clock_id=None)[source]

Converts a datetime to a TID.

https://atproto.com/specs/record-key#record-key-type-tid

Parameters:
  • dt (datetime)

  • clock_id – 0, optional. If not specified, uses this runtime’s clock id

Returns:

base32-encoded TID

Return type:

str

int_to_tid(num, clock_id=None)[source]

Converts an integer to a TID.

https://atproto.com/specs/record-key#record-key-type-tid

Parameters:
  • seq (int)

  • clock_id (int) – optional. If not specified, uses this runtime’s clock id

Returns:

base32-encoded TID

Return type:

str

tid_to_datetime(tid)[source]

Converts an TID to a datetime.

https://atproto.com/specs/record-key#record-key-type-tid

Parameters:

tid (bytes) – base32-encoded TID

Return type:

datetime

Raises:

ValueError – if tid is not bytes or not 13 characters long

tid_to_int(tid)[source]

Converts an TID to an integer.

https://atproto.com/specs/record-key#record-key-type-tid

Parameters:

tid (bytes) – base32-encoded TID

Return type:

int

Raises:

ValueError – if tid is not bytes or not 13 characters long

next_tid()[source]

Returns the TID corresponding to the current time.

A TID is a base32-sortable-encoded UNIX timestamp (ie time since the epoch) in microseconds. Returned tids are guaranteed to monotonically increase across calls.

https://atproto.com/specs/atp#timestamp-ids-tid https://atproto.com/specs/record-key#record-key-type-tid https://github.com/bluesky-social/atproto/blob/main/packages/common-web/src/tid.ts

Returns:

TID

Return type:

str

at_uri(did, collection, rkey)[source]

Returns the at:// URI for a given DID, collection, and rkey.

https://atproto.com/specs/at-uri-scheme

Parameters:
Returns:

at:// URI

Return type:

str

parse_at_uri(uri)[source]

Parses the repo DID, collection, and rkey out of an at:// URI.

https://atproto.com/specs/at-uri-scheme

Parameters:

uri (str)

Returns:

(did, collection, rkey)

Return type:

tuple of str

new_key(seed=None)[source]

Generates a new ECC K-256 keypair.

https://atproto.com/specs/cryptography

Parameters:

seed (int) – optional deterministic value to derive private key from. Don’t use in production!

Return type:

ec.EllipticCurvePrivateKey

sign(obj, private_key)[source]

Signs an object, eg a repo commit or DID document.

Adds the signature in the sig field.

https://atproto.com/specs/cryptography

The signature is ECDSA around SHA-256 of the input, including a custom second pass to enforce that it’s the “low-S” variant: https://atproto.com/specs/cryptography#ecdsa-signature-malleability

Parameters:
Returns:

obj with new sig field

Return type:

dict

apply_low_s_mitigation(signature, curve)[source]

Low-S signature mitigation.

This prevents signature malleability. (It doesn’t guarantee deterministic signatures though!)

https://atproto.com/specs/cryptography#ecdsa-signature-malleability

From picopds. Thank you David! https://github.com/DavidBuchanan314/picopds/blob/main/signing.py

Parameters:
  • signature (bytes)

  • curve (ec.EllipticCurve)

Return type:

bytes

verify_sig(obj, public_key)[source]

Returns True if obj’s signature is valid, False otherwise.

See sign() for more background.

Parameters:
  • obj (dict) – repo commit

  • public_key (ec.EllipticCurvePublicKey)

Raises:

KeyError – if obj isn’t signed, ie doesn’t have a sig field

service_jwt(host, repo_did, privkey, expiration=datetime.timedelta(seconds=600), aud=None, **claims)[source]

Generates an inter-service JWT, eg for a relay or AppView.

https://atproto.com/specs/xrpc#inter-service-authentication-temporary-specification

Parameters:
  • host (str) – hostname of the service this JWT is for, eg bsky.network

  • repo_did (str) – DID of the repo this JWT is for

  • privkey (ec.EllipticCurvePrivateKey) – repo’s signing key

  • expiration (timedelta) – length of time this JWT will be valid, defaults to 10m

  • aud (str) – JWT audience. Default is did:web:[host], which works for relays and AppViews, but others (eg mod services) have did:plc instead.

  • claims (dict) – additional claims to include in the JWT, eg lxm

Returns:

JWT

Return type:

str

xrpc_repo

xrpc_server

xrpc_sync