Suite of AT Protocol TypeScript libraries built on web standards
1import { CID } from "multiformats/cid";
2
3export const DAG_CBOR_MULTICODEC = 0x71;
4export const RAW_BIN_MULTICODEC = 0x55;
5export const SHA2_256_MULTIHASH_CODE = 0x12;
6
7export type MultihashDigest<Code extends number = number> = {
8 code: Code;
9 digest: Uint8Array;
10 size: number;
11 bytes: Uint8Array;
12};
13
14export interface Cid {
15 version: 0 | 1;
16 code: number;
17 multihash: MultihashDigest;
18 bytes: Uint8Array;
19 equals(other: unknown): boolean;
20 toString(): string;
21}
22
23export interface CidParseOptions {
24 strict?: boolean;
25}
26
27export function asCid(value: unknown): Cid | null {
28 return CID.asCID(value) as Cid | null;
29}
30
31export function parseCid(input: string, options?: CidParseOptions): Cid {
32 const cid = CID.parse(input) as Cid;
33 if (!isCid(cid, options)) {
34 throw new Error(`Invalid CID string`);
35 }
36 return cid;
37}
38
39export function parseCidSafe(
40 input: string,
41 options?: CidParseOptions,
42): Cid | null {
43 try {
44 return parseCid(input, options);
45 } catch {
46 return null;
47 }
48}
49
50export function decodeCid(bytes: Uint8Array): Cid {
51 return CID.decode(bytes) as Cid;
52}
53
54export function createCid(code: number, digest: MultihashDigest): Cid {
55 return CID.createV1(code, digest) as Cid;
56}
57
58export function isCid(
59 value: unknown,
60 options?: CidParseOptions,
61): value is Cid {
62 const cid = asCid(value);
63 if (!cid) return false;
64
65 if (options?.strict) {
66 if (cid.version !== 1) return false;
67 if (cid.code !== RAW_BIN_MULTICODEC && cid.code !== DAG_CBOR_MULTICODEC) {
68 return false;
69 }
70 if (cid.multihash.code !== SHA2_256_MULTIHASH_CODE) return false;
71 }
72
73 return true;
74}
75
76export function validateCidString(
77 input: string,
78 options?: CidParseOptions,
79): boolean {
80 return parseCidSafe(input, options)?.toString() === input;
81}
82
83export function ensureValidCidString(
84 input: string,
85 options?: CidParseOptions,
86): void {
87 if (!validateCidString(input, options)) {
88 throw new Error(`Invalid CID string`);
89 }
90}