ipld#
is a mostly DASL-compliant implementation of CIDs, CAR, and DAG-CBOR for OCaml.
This library implements the core IPLD primitives needed for atproto.
components#
- CID - Content Identifiers (CIDv1) with SHA-256 digests
- CAR - Content Addressable aRchives for storing and transferring IPLD data
- DAG-CBOR - Deterministic CBOR encoding for content-addressed data
installation#
Add to your dune-project:
(depends
ipld)
usage#
working with CIDs#
open Ipld
(* Create a CID from data *)
let cid = Cid.create Cid.Dcbor data_bytes
(* Encode CID to base32 string *)
let cid_string = Cid.to_string cid
(* => "bafyreihffx5a2e7k5uwrmmgofbvzujc5cmw5h4espouwuxt3liqoflx3ee" *)
(* Decode CID from string *)
match Cid.of_string cid_string with
| Ok cid -> (* use cid *)
| Error msg -> failwith msg
(* Convert to/from bytes *)
let bytes = Cid.to_bytes cid
match Cid.of_bytes bytes with
| Ok cid -> (* use cid *)
| Error msg -> failwith msg
DAG-CBOR encoding#
open Dag_cbor
(* Create CBOR values *)
let value = `Map (String_map.of_list [
("name", `String "Alice");
("age", `Integer 30L);
("verified", `Boolean true);
("profile_cid", `Link some_cid);
])
(* Encode to bytes *)
let encoded = Dag_cbor.encode value
(* Decode from bytes *)
let decoded = Dag_cbor.decode encoded
CAR files#
CAR (Content Addressable aRchive) files store multiple IPLD blocks with their CIDs.
open Car
(* Write blocks to a CAR file *)
let blocks = [
(cid1, data1);
(cid2, data2);
(cid3, data3);
] in
Car.write ~roots:[root_cid] blocks output_channel
(* Read blocks from a CAR file *)
let (roots, blocks) = Car.read input_channel
types#
CID#
type Cid.t = {
version: int; (* Always 1 for CIDv1 *)
codec: codec; (* Raw or Dcbor *)
digest: digest; (* SHA-256 hash *)
bytes: bytes; (* Serialized CID *)
}
type codec = Raw | Dcbor
DAG-CBOR#
type Dag_cbor.value =
| `Null
| `Boolean of bool
| `Integer of int64
| `Float of float
| `String of string
| `Bytes of bytes
| `Array of value array
| `Map of value String_map.t
| `Link of Cid.t
| `Tag of int * value