npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@substrate-system/at

v0.0.6

Published

At protocol CLI

Readme

at

tests types semantic versioning Common Changelog install size license

A typescript/node CLI client for at protocol (bluesky).

This exposes a CLI tool, at, that you can use to make requests to your DID document.

Install

npm i @substrate-system/at

Use

aka command

Add a URL to your DID's alsoKnownAs property.

The aka command lets you link external URLs, like Github, to your Bluesky DID document. See verify.aviary.domains to lookup your DID document and see the also known as values.

If you did not install this glabally via npm i -g @substrate-system/at, then use npx to execute it.

npx at aka <handle> <URL> [--pds <custom-pds>]

Arguments

  • <handle> - Your Bluesky handle (e.g., alice.bsky.social)
  • <URL> - The URL to link (e.g., https://github.com/alice)
  • --pds - (Optional) Custom PDS server URL. Defaults to https://bsky.social

Example

Link to your github profile.

at aka alice.bsky.social https://github.com/alice

This command will:

  1. Prompt you for your Bluesky password
  2. Send a verification code to your email
  3. Ask you to enter the verification code
  4. Update your DID document so that it includes your GitHub URL in the alsoKnownAs property

The resulting alsoKnownAs array in your DID document will contain:

[
  "at://alice.bsky.social",
  "https://github.com/alice"
]

Using a custom PDS

Pass in the --pds argument with PDS URL.

at aka alice.example.com https://alice.com --pds https://pds.example.com

did command

Fetch the DID document for a handle.

npx at did <handle> [--pds <custom-pds>] [--log]

Arguments

  • <handle> - A Bluesky handle (e.g., alice.bsky.social or @alice.bsky.social)
  • --pds - (Optional) Custom PDS server URL for handle resolution. Defaults to https://bsky.social
  • --log, -l - (Optional) Fetch the audit log instead of the DID document. Only available for did:plc: identifiers, not did:web.

Example

Get a DID document for @nichoth.com:

npx at did @nichoth.com
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/multikey/v1",
    "https://w3id.org/security/suites/secp256k1-2019/v1"
  ],
  "id": "did:plc:s53e6k6sirobjtz5s6vdddwr",
  "alsoKnownAs": [
    "at://nichoth.com",
    "https://github.com/nichoth/"
  ],
  "verificationMethod": [
    {
      "id": "did:plc:s53e6k6sirobjtz5s6vdddwr#atproto",
      "type": "Multikey",
      "controller": "did:plc:s53e6k6sirobjtz5s6vdddwr",
      "publicKeyMultibase": "zQ3shnSayXqCvnetx9S5BaHVEXPovHqpKcXwK2oRwAWPVKmdz"
    }
  ],
  "service": [
    {
      "id": "#atproto_pds",
      "type": "AtprotoPersonalDataServer",
      "serviceEndpoint": "https://lionsmane.us-east.host.bsky.network"
    }
  ]
}

Extract fields using jq:

# Get the DID string
npx at did alice.bsky.social | jq -r '.id'
# => did:plc:vdjlpwlhbnug4fnjodwr3vzh

# Get the alsoKnownAs array
npx at did alice.bsky.social | jq '.alsoKnownAs'

# Get the PDS endpoint
npx at did alice.bsky.social | jq -r '.service[] | select(.type == "AtprotoPersonalDataServer") | .serviceEndpoint'

Output

Returns a JSON object containing:

  • id - The DID identifier
  • alsoKnownAs - Array of alternative identifiers
  • verificationMethod - Cryptographic keys for the identity
  • service - Service endpoints (like the PDS server)

Audit Log

Use the --log or -l flag to fetch the audit log for a DID from the PLC directory. This shows the history of changes to the DID document:

npx at did @nichoth.com --log

The audit log returns an array of operations with their CIDs and timestamps:

[
  {
    "cid": "bafyreid...",
    "nullified": false,
    "operation": {
      "type": "plc_operation",
      "services": { ... },
      "alsoKnownAs": [...],
      // ... other operation details
    },
    "createdAt": "2024-01-15T10:30:00.000Z"
  },
  // ... previous operations
]

rotation command

Add or remove a rotation key.

npx at rotation <handle> [key] [--pds <custom-pds>] [--format <format>] [--remove <key-to-remove>]

Arguments

  • <handle> - Your Bluesky handle (e.g., alice.bsky.social)
  • [key] - (Optional) The private key (in hex format) for the new rotation key. If not provided, a new keypair will be generated.
  • --pds - (Optional) Custom PDS server URL. Defaults to https://bsky.social
  • --format, -f - (Optional) Output format for the generated keypair: json (default), hex, or jwk.
  • --remove, -rm - (Optional) Remove the given rotation key. Pass the public key in multikey format (e.g., did:key:z...) or just the key part (e.g., z...).

Example: Add a key

Generate a new keypair and add it as a rotation key:

at rotation alice.bsky.social

This will:

  1. Generate a new secp256k1 keypair
  2. Log in and request email verification
  3. Add the new public key to your DID document's rotationKeys
  4. Print the new private key (save this securely!)

You can also provide an existing private key in hex format:

at rotation alice.bsky.social <private-key-hex>

Example: Remove a key

Remove an existing rotation key from your account:

at rotation alice.bsky.social --remove "did:key:zQ3sh..."

You can also pass just the key part:

at rotation alice.bsky.social --remove "zQ3sh..."

This command will:

  1. Log in and request email verification
  2. Fetch the current rotation keys from the PLC directory
  3. Remove the specified key from the list
  4. Update your DID with the new list of rotation keys

How it works

The AT Protocol uses DID (Decentralized Identifier) documents as user identity. Each DID can include an alsoKnownAs field that links to other identifiers or URLs.

This uses the @atproto/api client.