"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decodeCid = exports.decodeManifestCid = exports.decodeFeedCid = exports.encodeManifestReference = exports.encodeFeedReference = exports.encodeReference = exports.ReferenceType = exports.REFERENCE_HEX_LENGTH = exports.SWARM_FEED_CODEC = exports.SWARM_MANIFEST_CODEC = exports.SWARM_NS_CODEC = exports.KECCAK_256_CODEC = void 0; const multiformats_1 = require("multiformats"); const digest_1 = require("multiformats/hashes/digest"); // https://github.com/multiformats/multicodec/blob/master/table.csv exports.KECCAK_256_CODEC = 0x1b; exports.SWARM_NS_CODEC = 0xe4; exports.SWARM_MANIFEST_CODEC = 0xfa; exports.SWARM_FEED_CODEC = 0xfb; exports.REFERENCE_HEX_LENGTH = 64; var ReferenceType; (function (ReferenceType) { ReferenceType["FEED"] = "feed"; ReferenceType["MANIFEST"] = "manifest"; })(ReferenceType = exports.ReferenceType || (exports.ReferenceType = {})); /** * Mapping for getting ReferenceType from given codec. */ const CODEC_TYPE_MAPPING = { [exports.SWARM_FEED_CODEC]: ReferenceType.FEED, [exports.SWARM_MANIFEST_CODEC]: ReferenceType.MANIFEST, }; /** * Encode Swarm hex-encoded Reference into CID that has appropriate codec set based on `type` parameter. * * @param ref * @param type */ function encodeReference(ref, type) { switch (type) { case ReferenceType.FEED: return _encodeReference(ref, exports.SWARM_FEED_CODEC); case ReferenceType.MANIFEST: return _encodeReference(ref, exports.SWARM_MANIFEST_CODEC); default: throw new Error('Unknown reference type.'); } } exports.encodeReference = encodeReference; /** * Encode Swarm hex-encoded Reference into CID and sets Feed codec. * @param ref */ function encodeFeedReference(ref) { return _encodeReference(ref, exports.SWARM_FEED_CODEC); } exports.encodeFeedReference = encodeFeedReference; /** * Encode Swarm hex-encoded Reference into CID and sets Manifest codec. * @param ref */ function encodeManifestReference(ref) { return _encodeReference(ref, exports.SWARM_MANIFEST_CODEC); } exports.encodeManifestReference = encodeManifestReference; /** * Function to decode Feed CID (both from string or CID instance) into hex encoded Swarm reference. * * @param cid * @throws Error if the decoded codec did not matched Swarm Feed codec */ function decodeFeedCid(cid) { const result = _decodeReference(cid); if (result.type !== ReferenceType.FEED) { throw new Error('CID did not have Swarm Feed codec!'); } return result.reference; } exports.decodeFeedCid = decodeFeedCid; /** * Function to decode Manifest CID (both from string or CID instance) into hex encoded Swarm reference. * * @param cid * @throws Error if the decoded codec did not matched Swarm Manifest codec */ function decodeManifestCid(cid) { const result = _decodeReference(cid); if (result.type !== ReferenceType.MANIFEST) { throw new Error('CID did not have Swarm Manifest codec!'); } return result.reference; } exports.decodeManifestCid = decodeManifestCid; /** * Decode CID or base encoded CID string into DecodeResult interface. * Does not throw exception if the codec was not Swarm related. In that case `type` is undefined. * * @see DecodeResult * @param cid */ function decodeCid(cid) { return _decodeReference(cid); } exports.decodeCid = decodeCid; function _decodeReference(cid) { if (typeof cid === 'string') { cid = multiformats_1.CID.parse(cid); } return { reference: bytesToHex(cid.multihash.digest), type: CODEC_TYPE_MAPPING[cid.code], }; } function _encodeReference(ref, codec) { assertReference(ref); const hashBytes = hexToBytes(ref); return multiformats_1.CID.createV1(codec, (0, digest_1.create)(exports.KECCAK_256_CODEC, hashBytes)); } /** * Converts a hex string to Uint8Array * * @param hex string input without 0x prefix! */ function hexToBytes(hex) { assertHexString(hex); const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < bytes.length; i++) { const hexByte = hex.substr(i * 2, 2); bytes[i] = parseInt(hexByte, 16); } return bytes; } /** * Converts array of number or Uint8Array to HexString without prefix. * * @param bytes The input array * @param len The length of the non prefixed HexString */ function bytesToHex(bytes, len) { const hexByte = (n) => n.toString(16).padStart(2, '0'); const hex = Array.from(bytes, hexByte).join(''); if (len && hex.length !== len) { throw new TypeError(`Resulting HexString does not have expected length ${len}: ${hex}`); } return hex; } /** * Type guard for HexStrings. * Requires no 0x prefix! * * @param s string input * @param len expected length of the HexString */ function isHexString(s, len) { return typeof s === 'string' && /^[0-9a-f]+$/i.test(s) && (!len || s.length === len); } /** * Verifies if the provided input is a HexString. * * @param s string input * @param len expected length of the HexString * @param name optional name for the asserted value * @returns HexString or throws error */ function assertHexString(s, len, name = 'value') { if (!isHexString(s, len)) { // Don't display length error if no length specified in order not to confuse user const lengthMsg = len ? ` of length ${len}` : ''; throw new TypeError(`${name} not valid hex string${lengthMsg}: ${s}`); } } function assertReference(ref) { assertHexString(ref); if (ref.length !== exports.REFERENCE_HEX_LENGTH) { throw new TypeError(`Reference does not have expected length 64 characters. Encrypted references are not supported.`); } }