Vai al contenuto principale
Core è un’implementazione interna avanzata. Non è necessario per le operazioni comuni come post, recupero feed o notifiche. Consultalo quando devi manipolare direttamente le strutture dati di AT Protocol.

Panoramica del modello dati di AT Protocol

Il repository di AT Protocol adotta una struttura dati content-addressable. Per l’archiviazione, il trasferimento e la verifica dei dati vengono usati i seguenti elementi.
ClasseRuolo
CBORSerializzazione binaria
CIDContent address (identificatore hash)
CARLettura/scrittura di archivi di repository
TIDChiave di record cronologica
VarintCodifica di interi a lunghezza variabile (interno)

CBOR

La classe CBOR fornisce codifica e decodifica nel formato DAG-CBOR adottato da AT Protocol. Come estensione di CBOR standard supporta i link CID (tag 42).

Codifica

use Revolution\Bluesky\Core\CBOR;

$record = [
    '$type'     => 'app.bsky.feed.post',
    'text'      => 'Hello, Bluesky!',
    'createdAt' => '2025-01-01T00:00:00.000Z',
];

$bytes = CBOR::encode($record); // stringa binaria

Decodifica

use Revolution\Bluesky\Core\CBOR;

// Decodifica un singolo elemento
$data = CBOR::decode($bytes);

// Decodifica il primo elemento dello stream e restituisce il resto
[$item, $remainder] = CBOR::decodeFirst($bytes);

// Decodifica tutti gli elementi dello stream
$items = CBOR::decodeAll($bytes);

Casi d’uso

Se vuoi calcolare o verificare manualmente il CID di un post, ti serve la codifica CBOR (vedi anche la pagina verify).
use Revolution\Bluesky\Core\CBOR;
use Revolution\Bluesky\Core\CID;

$record = data_get($block, 'value');
$cbor   = CBOR::encode($record);
$bool   = CID::verify($cbor, data_get($block, 'cid'));

CID (Content Identifier)

Il CID è un identificatore autodescrittivo basato sull’hash dei dati. In AT Protocol l’hash SHA-256 viene incapsulato in un multihash, e poi codificato con multicodec e multibase.

CIDv0 e CIDv1

VersioneCodificaCarattere inizialeUso
v0base58btcQm...Specifica vecchia (blob)
v1base32bafy...Specifica nuova (record)

API principali

use Revolution\Bluesky\Core\CID;

// Genera un CID dai dati
$cid = CID::encode($data, CID::DAG_CBOR); // per i record
$cid = CID::encode($data, CID::RAW);      // binario (immagini, ecc.)

// Verifica un CID
$bool = CID::verify($data, $cid, CID::DAG_CBOR);
$bool = CID::verify($file, $cid, CID::RAW);

// Analizza un CID
$decoded = CID::decode($cid); // ['version', 'codec', 'hash']

// Verifica la versione del CID
$version = CID::version($cid); // 0 o 1

// Conversione in rappresentazione a byte
$bytes = CID::decodeBytes($cid);
$cid   = CID::encodeBytes($bytes);

CAR (Content Addressable aRchive)

Un file CAR è un formato binario che archivia il repository di AT Protocol come sequenza di blocchi. I dati ottenuti da com.atproto.sync.getRepo sono in questo formato.

Decodifica

use Revolution\Bluesky\Core\CAR;

// Decodifica l'intero file CAR (root e tutti i blocchi)
['roots' => $roots, 'blocks' => $blocks] = CAR::decode($carData);

// Ottieni solo i root CID
$roots = CAR::decodeRoots($carData);

// Itera i blocchi
foreach (CAR::blockIterator($carData) as [$cid, $block]) {
    // $cid: stringa CID, $block: dati binari
}

// Ottieni una mappa di record
foreach (CAR::blockMap($carData) as $key => $record) {
    // $key: chiave del record, $record: array decodificato
}

Verifica di un Signed Commit

Per confermare che il file CAR appartenga effettivamente a un dato utente, verifica la firma del Signed Commit con la chiave pubblica del DID Document.
use Revolution\Bluesky\Core\CAR;
use Revolution\Bluesky\Crypto\DidKey;
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Support\DidDocument;

$did = 'did:plc:***';

$didDoc    = DidDocument::make(Bluesky::identity()->resolveDID($did)->json());
$publicKey = DidKey::parse($didDoc->publicKey());

$signed    = CAR::signedCommit($carData);
$bool      = CAR::verifySignedCommit($signed, $publicKey);
Implementazione di esempio: DownloadRepoCommand

TID (Timestamp Identifier)

TID è l’ID cronologico usato come chiave dei record in AT Protocol. È una stringa di 13 caratteri codificata in base32, composta da un timestamp in microsecondi e da un clock ID.
Esempio: 3jujm55ngfc24

Generazione e conversione

use Revolution\Bluesky\Core\TID;

// Genera il prossimo TID
$tid = TID::next();
echo $tid->toString(); // stringa tipo "3jujm55ngfc24"

// Crea un TID da una stringa
$tid = TID::fromStr('3jujm55ngfc24');

// Crea a partire da timestamp (microsecondi) e clock ID
$tid = TID::fromTime(microtime(true) * 1000000, 0);

Struttura del TID

Con TID::s32encode() e TID::s32decode() puoi convertire tra intero e stringa.

Varint (interi a lunghezza variabile)

Varint è un’utility interna usata nel parsing binario di CAR / CBOR. Normalmente non la usi direttamente.
use Revolution\Bluesky\Core\Varint;

// Codifica un intero
$bytes = Varint::encode(1234);

// Decodifica da uno stream (restituisce valore e numero di byte consumati)
[$value, $bytesRead] = Varint::decodeStream($stream);

Sul mocking delle funzionalità Core

Le funzionalità Core (CBOR/CID/CAR/TID) non effettuano accessi esterni, quindi non è necessario mockarle nei test.
// Utilizzabili direttamente anche nei test
$bytes = CBOR::encode(['text' => 'Hello']);
$cid   = CID::encode($bytes, CID::DAG_CBOR);
$bool  = CID::verify($bytes, $cid);

Source: src/Core/
Ultima modifica il 13 luglio 2026