import { privateKeyFromProtobuf, privateKeyToProtobuf, publicKeyFromProtobuf, publicKeyToProtobuf, } from "@libp2p/crypto/keys"; import type {PrivateKey} from "@libp2p/interface"; import {peerIdFromPrivateKey, peerIdFromString} from "@libp2p/peer-id"; import {fromString as uint8ArrayFromString} from "uint8arrays/from-string"; import {toString as uint8ArrayToString} from "uint8arrays/to-string"; import {readFile, writeFile600Perm} from "../util/index.js"; // Peer id to / from JSON taken from peer-id-factory // See https://github.com/libp2p/js-libp2p-peer-id/pull/9 for more details // after libp2p 2.0, PeerId no longer contains a private key // but we retain a semi-backwards-compatible on-disk format // Note: all properties are required export type PeerIdJSON = {id: string; pubKey: string; privKey: string}; export function exportToJSON(privateKey: PrivateKey): PeerIdJSON { const publicKey = privateKey.publicKey; const peerId = peerIdFromPrivateKey(privateKey); return { id: peerId.toString(), pubKey: uint8ArrayToString(publicKeyToProtobuf(publicKey), "base64pad"), privKey: uint8ArrayToString(privateKeyToProtobuf(privateKey), "base64pad"), }; } export function createFromJSON(obj: PeerIdJSON): PrivateKey { const privateKey = privateKeyFromProtobuf(uint8ArrayFromString(obj.privKey, "base64pad")); const publicKey = publicKeyFromProtobuf(uint8ArrayFromString(obj.pubKey, "base64pad")); const peerId = peerIdFromString(obj.id); if (!publicKey.equals(privateKey.publicKey)) { throw new Error("Public key does not match private key"); } if (!peerId.equals(peerIdFromPrivateKey(privateKey))) { throw new Error("Peer ID does not match private key"); } return privateKey; } export function writePrivateKey(filepath: string, privateKey: PrivateKey): void { writeFile600Perm(filepath, exportToJSON(privateKey)); } export function readPrivateKey(filepath: string): PrivateKey { return createFromJSON(readFile(filepath)); }