An encrypted personal cloud built on the AT Protocol.
at main 37 lines 1.2 kB view raw
1// Base64, fingerprint, and AT-URI encoding utilities. 2 3/** Standard base64 from bytes. */ 4export function uint8ArrayToBase64(bytes: Uint8Array): string { 5 let binary = ""; 6 for (const byte of bytes) { 7 binary += String.fromCharCode(byte); 8 } 9 return btoa(binary); 10} 11 12/** Base64 to bytes — handles unpadded strings (PDS returns unpadded). */ 13export function base64ToUint8Array(b64: string): Uint8Array { 14 // Pad to multiple of 4 15 const padded = b64 + "=".repeat((4 - (b64.length % 4)) % 4); 16 const binary = atob(padded); 17 const bytes = new Uint8Array(binary.length); 18 for (let i = 0; i < binary.length; i++) { 19 bytes[i] = binary.charCodeAt(i); 20 } 21 return bytes; 22} 23 24/** First 8 bytes of a public key as a colon-separated hex fingerprint. */ 25export function formatFingerprint(pubkey: Uint8Array): string { 26 return Array.from(pubkey.slice(0, 8)) 27 .map((b) => b.toString(16).padStart(2, "0")) 28 .join(":"); 29} 30 31/** Extract the rkey from an AT-URI: `at://did/collection/rkey` → `rkey`. */ 32export function rkeyFromUri(atUri: string): string { 33 const parts = atUri.split("/"); 34 const rkey = parts.at(-1); 35 if (!rkey) throw new Error(`Invalid AT-URI: ${atUri}`); 36 return rkey; 37}