PHPackages                             socialdept/atp-support - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. socialdept/atp-support

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

socialdept/atp-support
======================

Foundational utilities for AT Protocol packages in Laravel

v0.3.0(3mo ago)02424MITPHPPHP ^8.2

Since Feb 7Pushed 2mo agoCompare

[ Source](https://github.com/socialdept/atp-support)[ Packagist](https://packagist.org/packages/socialdept/atp-support)[ RSS](/packages/socialdept-atp-support/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (12)Versions (6)Used By (4)

ATP Support
===========

[](#atp-support)

###  Resolve DIDs, handles, and identities for AT Protocol in Laravel.

[](#----resolve-dids-handles-and-identities-for-at-protocol-in-laravel)

 [![](https://camo.githubusercontent.com/763dc7bf4285a259e810bfc8c4e94abe7cc46d16f24352977840006b808d26a0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6369616c646570742f6174702d737570706f72742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/socialdept/atp-support "Latest Version on Packagist") [![](https://camo.githubusercontent.com/a64f467ff2b385b4391cec9aeffa0a4f39eda91d0670372a57a3362db2145831/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736f6369616c646570742f6174702d737570706f72742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/socialdept/atp-support "Total Downloads") [![](https://camo.githubusercontent.com/1b0dcf67e28b0c49ecdfe0588a4c84a6b2f5e4e01a96fb60f2813987a13e7868/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736f6369616c646570742f6174702d737570706f72742f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/socialdept/atp-support/actions/workflows/tests.yml "GitHub Tests Action Status") [![](https://camo.githubusercontent.com/dcc89969f41d1c8bb31af5c84a9ade91168ee77c59f08790f32a7569e2cd39d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f736f6369616c646570742f6174702d737570706f72743f7374796c653d666c61742d737175617265)](LICENSE "Software License")

---

What is ATP Support?
--------------------

[](#what-is-atp-support)

**ATP Support** is the foundational Laravel package for the SocialDept AT Protocol ecosystem. It provides DID and handle resolution, identity validation, AT-URI parsing, NSID utilities, and shared configuration used by all other `atp-*` packages.

If you're building anything on AT Protocol with Laravel, this is your starting point.

Why use ATP Support?
--------------------

[](#why-use-atp-support)

- **Identity resolution** - Resolve DIDs, handles, and PDS endpoints with intelligent caching
- **Validation utilities** - Validate DIDs, handles, and NSIDs with battle-tested logic
- **AT-URI parsing** - Parse and create `at://` URIs as immutable value objects
- **Shared configuration** - Common AT Protocol settings (PLC directory, PDS endpoint, public API) in one place
- **Extensible resolvers** - Pluggable DID method resolvers with support for `did:plc` and `did:web`
- **DNS lexicon resolution** - Discover lexicon schemas via DNS TXT records
- **Microcosm integration** - Backlink discovery via Constellation and fast record caching via Slingshot

Quick Example
-------------

[](#quick-example)

```
use SocialDept\AtpSupport\Facades\Resolver;
use SocialDept\AtpSupport\Identity;
use SocialDept\AtpSupport\AtUri;
use SocialDept\AtpSupport\Nsid;

// Resolve a handle to a DID
$did = Resolver::handleToDid('alice.bsky.social');

// Resolve a DID to its PDS endpoint
$pds = Resolver::resolvePds('did:plc:ewvi7nxzyoun6zhxrhs64oiz');

// Validate identities
Identity::isDid('did:plc:abc123');          // true
Identity::isHandle('alice.bsky.social');     // true

// Parse AT-URIs
$uri = AtUri::parse('at://did:plc:xyz/app.bsky.feed.post/3k4abc');
$uri->did;        // did:plc:xyz
$uri->collection; // app.bsky.feed.post
$uri->rkey;       // 3k4abc

// Work with NSIDs
$nsid = Nsid::parse('app.bsky.feed.post');
$nsid->getAuthority(); // app.bsky.feed
$nsid->getName();      // post
```

Installation
------------

[](#installation)

```
composer require socialdept/atp-support
```

Publish the configuration:

```
php artisan vendor:publish --tag=atp-support-config
```

Configuration
-------------

[](#configuration)

All shared AT Protocol settings live in `config/atp-support.php`:

```
return [
    'plc_directory' => env('ATP_PLC_DIRECTORY', 'https://plc.directory'),
    'pds_endpoint' => env('ATP_PDS_ENDPOINT', 'https://bsky.social'),
    'public_api' => env('ATP_PUBLIC_API', 'https://public.api.bsky.app'),
    'timeout' => env('ATP_RESOLVER_TIMEOUT', 10),
    'cache' => [
        'enabled' => env('ATP_RESOLVER_CACHE_ENABLED', true),
        'did_ttl' => env('ATP_RESOLVER_CACHE_DID_TTL', 3600),
        'handle_ttl' => env('ATP_RESOLVER_CACHE_HANDLE_TTL', 3600),
        'pds_ttl' => env('ATP_RESOLVER_CACHE_PDS_TTL', 3600),
    ],
];
```

Other `atp-*` packages read shared values like `public_api` directly from this config.

Usage
-----

[](#usage)

### Resolving Identities

[](#resolving-identities)

The `Resolver` facade is the main entry point for all resolution operations:

```
use SocialDept\AtpSupport\Facades\Resolver;

// Resolve a DID to its DID Document
$doc = Resolver::resolveDid('did:plc:ewvi7nxzyoun6zhxrhs64oiz');
$doc->getPdsEndpoint(); // https://morel.us-east.host.bsky.network
$doc->getHandle();      // alice.bsky.social

// Convert a handle to a DID
$did = Resolver::handleToDid('alice.bsky.social');

// Auto-detect and resolve (accepts both DIDs and handles)
$doc = Resolver::resolveIdentity('alice.bsky.social');

// Resolve directly to PDS endpoint
$pds = Resolver::resolvePds('alice.bsky.social');
```

### Caching

[](#caching)

All resolutions are cached by default with configurable TTLs. You can bypass or clear the cache:

```
// Bypass cache for a single call
$doc = Resolver::resolveDid('did:plc:abc123', useCache: false);

// Clear specific caches
Resolver::clearDidCache('did:plc:abc123');
Resolver::clearHandleCache('alice.bsky.social');
Resolver::clearPdsCache('did:plc:abc123');

// Clear everything
Resolver::clearCache();
```

### Validating Identities

[](#validating-identities)

The `Identity` class provides static validation methods:

```
use SocialDept\AtpSupport\Identity;

Identity::isDid('did:plc:abc123');     // true
Identity::isDid('not-a-did');          // false

Identity::isHandle('alice.bsky.social'); // true
Identity::isHandle('invalid');           // false

Identity::isPlcDid('did:plc:abc123');  // true
Identity::isWebDid('did:web:example.com'); // true

Identity::extractDidMethod('did:plc:abc123'); // "plc"
```

### Parsing AT-URIs

[](#parsing-at-uris)

The `AtUri` value object parses the `at://` URI format used throughout AT Protocol:

```
use SocialDept\AtpSupport\AtUri;

$uri = AtUri::parse('at://did:plc:xyz/app.bsky.feed.post/3k4abc');

$uri->did;        // did:plc:xyz
$uri->collection; // app.bsky.feed.post
$uri->rkey;       // 3k4abc

// Create programmatically
$uri = AtUri::make('did:plc:xyz', 'app.bsky.feed.post', '3k4abc');
echo $uri; // at://did:plc:xyz/app.bsky.feed.post/3k4abc

// Returns null for invalid URIs
AtUri::parse('not-a-uri'); // null
```

### Working with NSIDs

[](#working-with-nsids)

Namespace Identifiers are the reversed-domain notation used for AT Protocol collections and methods:

```
use SocialDept\AtpSupport\Nsid;

$nsid = Nsid::parse('app.bsky.feed.post');

$nsid->getAuthority();       // app.bsky.feed
$nsid->getName();            // post
$nsid->getSegments();        // ['app', 'bsky', 'feed', 'post']
$nsid->toDomain();           // post.feed.bsky.app
$nsid->getAuthorityDomain(); // feed.bsky.app

// Validation
Nsid::isValid('app.bsky.feed.post');  // true
Nsid::isValid('invalid');             // false

// Equality
$nsid->equals(Nsid::parse('app.bsky.feed.post')); // true
```

### DNS Lexicon Resolution

[](#dns-lexicon-resolution)

Discover lexicon schemas published via DNS TXT records:

```
use SocialDept\AtpSupport\Resolvers\LexiconDnsResolver;

$resolver = app(LexiconDnsResolver::class);

// Full pipeline: DNS lookup -> DID resolution -> XRPC fetch
$schema = $resolver->resolve('com.example.myrecord');

// Individual steps
$did = $resolver->lookupDns('example.com');
$schema = $resolver->retrieveSchema($pdsEndpoint, $did, 'com.example.myrecord');
```

### Microcosm

[](#microcosm)

[Microcosm.blue](https://microcosm.blue) provides protocol-level content discovery APIs for AT Protocol. ATP Support includes HTTP clients for two Microcosm services:

- **Constellation** - Backlink indexing: find all records that link to a given subject
- **Slingshot** - Fast record and identity caching

#### Constellation (Backlinks)

[](#constellation-backlinks)

```
use SocialDept\AtpSupport\Microcosm\ConstellationClient;

$constellation = app(ConstellationClient::class);

// Find all likes on a post
$backlinks = $constellation->getBacklinks(
    subject: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mcibiyf7fs2r',
    source: 'app.bsky.feed.like:subject.uri',
    limit: 50,
);

$backlinks->total;   // 2852
$backlinks->records; // BacklinkReference[]
$backlinks->cursor;  // Pagination cursor

// Get just the count
$count = $constellation->getBacklinksCount(
    subject: 'at://did:plc:abc/app.bsky.feed.post/rk1',
    source: 'app.bsky.feed.like:subject.uri',
);

// Get a summary of all link types pointing at a target
$summary = $constellation->getAllLinks('at://did:plc:abc/app.bsky.feed.post/rk1');
$summary->total();                              // Total records across all types
$summary->forCollection('app.bsky.feed.like');  // Filter to likes
```

The `source` parameter uses `collection:path` format, where the path is the dot-notation location of the linking field within the record.

#### Slingshot (Record Cache)

[](#slingshot-record-cache)

```
use SocialDept\AtpSupport\Microcosm\SlingshotClient;

$slingshot = app(SlingshotClient::class);

// Fetch a cached record
$record = $slingshot->getRecord('did:plc:abc', 'app.bsky.feed.post', 'rk1');
$record->uri;   // AT-URI
$record->cid;   // Content ID
$record->value; // Record data

// Fetch by AT-URI
$record = $slingshot->getRecordByUri('at://did:plc:abc/app.bsky.feed.post/rk1');

// Resolve a minimal identity document
$doc = $slingshot->resolveMiniDoc('did:plc:z72i7hdynmk6r22z27h6tvur');
$doc->did;        // did:plc:z72i7hdynmk6r22z27h6tvur
$doc->handle;     // bsky.app
$doc->pds;        // https://puffball.us-east.host.bsky.network
$doc->signingKey; // Public signing key
```

#### Microcosm Facade

[](#microcosm-facade)

Access both clients through a single facade:

```
use SocialDept\AtpSupport\Facades\Microcosm;

Microcosm::constellation()->getBacklinks(...);
Microcosm::slingshot()->getRecord(...);
```

#### Microcosm Configuration

[](#microcosm-configuration)

Add these environment variables to customize endpoints:

```
ATP_CONSTELLATION_URL=https://constellation.microcosm.blue
ATP_CONSTELLATION_TIMEOUT=10
ATP_SLINGSHOT_URL=https://slingshot.microcosm.blue
ATP_SLINGSHOT_TIMEOUT=5
```

### Custom DID Resolvers

[](#custom-did-resolvers)

Register custom resolvers for additional DID methods:

```
use SocialDept\AtpSupport\Contracts\DidResolver;
use SocialDept\AtpSupport\Data\DidDocument;

class CustomDidResolver implements DidResolver
{
    public function resolve(string $did): DidDocument
    {
        // Your resolution logic
    }

    public function supports(string $method): bool
    {
        return $method === 'custom';
    }
}

// Register in a service provider
$manager = app(DidResolverManager::class);
$manager->register('custom', new CustomDidResolver());
```

API Reference
-------------

[](#api-reference)

### Facade Methods

[](#facade-methods)

MethodDescription`Resolver::resolveDid($did)`Resolve DID to DidDocument`Resolver::handleToDid($handle)`Convert handle to DID string`Resolver::resolveHandle($handle)`Resolve handle to DidDocument`Resolver::resolveIdentity($actor)`Auto-detect and resolve DID or handle`Resolver::resolvePds($actor)`Get PDS endpoint for DID or handle`Resolver::clearDidCache($did)`Clear cached DID data`Resolver::clearHandleCache($handle)`Clear cached handle data`Resolver::clearPdsCache($actor)`Clear cached PDS data`Resolver::clearCache()`Clear all cached data### Value Objects

[](#value-objects)

ClassDescription`AtUri`Immutable AT-URI parser (`at://did/collection/rkey`)`Nsid`Immutable Namespace Identifier`DidDocument`Resolved DID Document with PDS and handle access### Microcosm

[](#microcosm-1)

ClassDescription`ConstellationClient`Backlink discovery and link counting via Constellation`SlingshotClient`Fast record and identity resolution via Slingshot`Microcosm`Service class wrapping both clients`BacklinkReference`Data object: `did`, `collection`, `rkey`, `uri()``GetBacklinksResponse`Data object: `total`, `records`, `cursor``GetRecordResponse`Data object: `uri`, `cid`, `value``MiniDoc`Data object: `did`, `handle`, `pds`, `signingKey``LinkSummary`Data object: `links`, `forCollection()`, `total()``MicrocosmException`Exception for Microcosm request failures### Validation

[](#validation)

MethodDescription`Identity::isDid($value)`Validate DID format`Identity::isHandle($value)`Validate handle format`Identity::isPlcDid($did)`Check for `did:plc` method`Identity::isWebDid($did)`Check for `did:web` method`Identity::extractDidMethod($did)`Get method from DID string`Nsid::isValid($nsid)`Validate NSID format### Exceptions

[](#exceptions)

ExceptionDescription`ResolverException`Base exception for all resolution errors`DidResolutionException`DID resolution failures`HandleResolutionException`Handle resolution failuresRequirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11+

Resources
---------

[](#resources)

- [AT Protocol Documentation](https://atproto.com/)
- [DID Specification](https://www.w3.org/TR/did-1.0/)
- [AT-URI Specification](https://atproto.com/specs/at-uri-scheme)
- [NSID Specification](https://atproto.com/specs/nsid)

Support &amp; Contributing
--------------------------

[](#support--contributing)

Found a bug or have a feature request? [Open an issue](https://github.com/socialdept/atp-support/issues).

Want to contribute? We'd love your help! Check out the [contribution guidelines](CONTRIBUTING.md).

Credits
-------

[](#credits)

- [Miguel Batres](https://batres.co) - founder &amp; lead maintainer
- [All contributors](https://github.com/socialdept/atp-support/graphs/contributors)

License
-------

[](#license)

ATP Support is open-source software licensed under the [MIT license](LICENSE).

---

**Built for the Atmosphere** • By Social Dept.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance84

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

4

Last Release

99d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ae252717302843968ef8adec35c3edb4a8fe70656083863691b6566b54ffeea9?d=identicon)[socialdept](/maintainers/socialdept)

---

Top Contributors

[![btrsco](https://avatars.githubusercontent.com/u/1373528?v=4)](https://github.com/btrsco "btrsco (12 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/socialdept-atp-support/health.svg)

```
[![Health](https://phpackages.com/badges/socialdept-atp-support/health.svg)](https://phpackages.com/packages/socialdept-atp-support)
```

###  Alternatives

[laravolt/avatar

Turn name, email, and any other string into initial-based avatar or gravatar.

2.0k5.4M31](/packages/laravolt-avatar)[anlutro/l4-settings

Persistent settings in Laravel.

9312.4M19](/packages/anlutro-l4-settings)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[flarum/core

Delightfully simple forum software.

211.3M1.9k](/packages/flarum-core)[nativephp/mobile

NativePHP for Mobile

82724.0k43](/packages/nativephp-mobile)[ashallendesign/favicon-fetcher

A Laravel package for fetching website's favicons.

190272.4k3](/packages/ashallendesign-favicon-fetcher)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
