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.
| Classe | Ruolo |
|---|
CBOR | Serializzazione binaria |
CID | Content address (identificatore hash) |
CAR | Lettura/scrittura di archivi di repository |
TID | Chiave di record cronologica |
Varint | Codifica 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
| Versione | Codifica | Carattere iniziale | Uso |
|---|
| v0 | base58btc | Qm... | Specifica vecchia (blob) |
| v1 | base32 | bafy... | 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.
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);
Link di riferimento