UNPKG

@xylabs/hex

Version:

Base functionality used throughout XY Labs TypeScript/JavaScript libraries

361 lines (329 loc) 10.8 kB
// src/address/address.ts import * as z from "zod"; // src/HexRegEx.ts var HexRegExMinMax = (minBytes = 0, maxBytes = Number.MAX_SAFE_INTEGER / 2) => { return new RegExp(`^[a-f0-9]{${minBytes * 2},${maxBytes * 2}}$`); }; var HexRegExMinMaxMixedCaseWithPrefix = (minBytes = 0, maxBytes = Number.MAX_SAFE_INTEGER / 2) => { return new RegExp(`^0x[a-fA-F0-9]{${minBytes * 2},${maxBytes * 2}}$`); }; var HexRegEx = /^[0-9a-f]+$/; var HexRegExWithPrefix = /^0x[0-9a-f]+$/; // src/address/address.ts var ZERO_ADDRESS = "0000000000000000000000000000000000000000"; var ADDRESS_LENGTH = 40; var AddressRegEx = HexRegExMinMax(ADDRESS_LENGTH / 2, ADDRESS_LENGTH / 2); var AddressZod = z.string().regex(AddressRegEx).transform((v) => v); // src/address/AddressTransformZod.ts import * as z4 from "zod"; // src/address/AddressValidationZod.ts import * as z3 from "zod"; // src/hex/as.ts import { assertError } from "@xylabs/error"; // src/hex/from/fromHexString.ts import { isNumber } from "@xylabs/typeof"; // src/hex/nibble.ts var bitsToNibbles = (value) => { const nibbles = value >> 2; if (value !== nibbles << 2) throw new Error("Bits for nibbles must multiple of 4"); return nibbles; }; var nibblesToBits = (value) => { return value << 2; }; // src/hex/is.ts var isHex = (value, config) => { if (typeof value !== "string") return false; const valueCharLength = config?.prefix ? value.length - 2 : value.length; if (config?.bitLength !== void 0 && valueCharLength !== bitsToNibbles(config?.bitLength)) return false; return config?.prefix ? HexRegExWithPrefix.test(value) : HexRegEx.test(value); }; // src/hex/from/fromHexString.ts var hexFromHexString = (value, config = {}) => { const { prefix = false, byteSize = 8, bitLength } = config; const nibbleBoundary = bitsToNibbles(byteSize); const unEvened = (value.startsWith("0x") ? value.slice(2) : value).toLowerCase(); if (isHex(unEvened)) { const evenCharacters = unEvened.padStart(Math.ceil(unEvened.length / nibbleBoundary) * nibbleBoundary, "0"); const padded = isNumber(bitLength) ? evenCharacters.padStart(bitLength / 4, "0") : evenCharacters; return (prefix ? `0x${padded}` : padded).toLowerCase(); } else { throw new Error("Received string is not a value hex"); } }; // src/hex/from/fromArrayBuffer.ts var hexFromArrayBuffer = (buffer, config) => { const unPadded = [...new Uint8Array(buffer)].map((x) => x.toString(16).padStart(2, "0")).join(""); return hexFromHexString(unPadded, config); }; // src/hex/from/fromBigInt.ts var hexFromBigInt = (value, config = {}) => { const unPadded = value.toString(16); return hexFromHexString(unPadded, config); }; // src/hex/from/fromNumber.ts var hexFromNumber = (value, config) => { return hexFromBigInt(BigInt(value), config); }; // src/hex/from/from.ts var hexFrom = (value, config) => { switch (typeof value) { case "string": { return hexFromHexString(value, config); } case "bigint": { return hexFromBigInt(value, config); } case "number": { return hexFromNumber(value, config); } case "object": { return hexFromArrayBuffer(value, config); } default: { throw new Error(`Invalid type: ${typeof value}`); } } }; // src/hex/as.ts function asHex(value, assert) { let stringValue = void 0; switch (typeof value) { case "string": { stringValue = hexFromHexString(value); break; } default: { return assertError(value, assert, `Unsupported type [${typeof value}]`); } } return isHex(stringValue) ? stringValue : assertError(value, assert, `Value is not Hex [${value}]`); } // src/hex/hex.ts import * as z2 from "zod"; var HexZod = z2.string().regex(HexRegEx, { message: "Invalid hex format" }).transform((val) => val); // src/hex/isHexZero.ts import { isString } from "@xylabs/typeof"; var isHexZero = (value) => { return isString(value) ? BigInt(hexFromHexString(value, { prefix: true })) === 0n : void 0; }; // src/hex/legacy.ts var toHexLegacy = (buffer) => { return [...new Uint8Array(buffer)].map((x) => x.toString(16).padStart(2, "0")).join(""); }; // src/hex/to.ts var toHex = (value, config = {}) => { const { prefix = false } = config; return hexFrom(value, { prefix, ...config }); }; // src/address/AddressValidationZod.ts var AddressValidationZod = z3.string().refine((x) => HexZod.safeParse(x).success).refine((x) => x.length === ADDRESS_LENGTH, { error: (e) => new Error(`Address must have 40 characters [${e.input}]`) }).transform((v) => v); // src/address/AddressTransformZod.ts var AddressTransformZod = z4.union([z4.string(), z4.bigint(), z4.number()]).transform((value) => { switch (typeof value) { case "bigint": { return value.toString(16).padStart(ADDRESS_LENGTH, "0"); } case "string": { if (value.startsWith("0x")) { return value.slice(2); } return value; } case "number": { return BigInt(value).toString(16).padStart(ADDRESS_LENGTH, "0"); } } }).refine((x) => AddressValidationZod.safeParse(x).data).transform((x) => x); // src/address/as.ts import { assertError as assertError2 } from "@xylabs/error"; import { isObject } from "@xylabs/typeof"; // src/address/is.ts var isAddress = (value, config = {}) => { const { bitLength = 160, prefix = false } = config; return isHex(value, { bitLength, prefix }); }; function isAddressV2(value) { return AddressValidationZod.safeParse(value).success; } // src/address/as.ts function asAddress(value, assert) { try { let stringValue = void 0; switch (typeof value) { case "string": { stringValue = hexFromHexString(value, { prefix: false, byteSize: 4 }); break; } default: { return isObject(assert) ? assertError2(value, assert, `Unsupported type [${typeof value}]`) : void 0; } } return isAddress(stringValue) ? stringValue : assertError2(value, assert, `Value is not an Address [${value}]`); } catch (ex) { const error = ex; return assertError2(void 0, assert, error.message); } } function asAddressV2(value, assert = false) { return assert ? AddressValidationZod.parse(value) : AddressValidationZod.safeParse(value).data; } // src/address/to.ts var toAddress = (value, config = {}) => { const { bitLength = 160, prefix = false } = config; return hexFrom(value, { bitLength, prefix, ...config }); }; function toAddressV2(value, assert = false) { return assert ? AddressTransformZod.parse(value) : AddressTransformZod.safeParse(value).data; } // src/ethAddress.ts import { assertError as assertError3 } from "@xylabs/error"; import * as z5 from "zod"; var EthAddressRegEx = HexRegExMinMaxMixedCaseWithPrefix(20, 20); var EthAddressToStringZod = z5.string().regex(EthAddressRegEx); var EthAddressToStringSchema = EthAddressToStringZod; var EthAddressFromStringZod = z5.string().regex(EthAddressRegEx).transform((v) => toEthAddress(v)); var EthAddressFromStringSchema = EthAddressFromStringZod; var ETH_ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; var toEthAddress = (value, config = {}) => { const { bitLength = 160, prefix = false } = config; return `0x${hexFrom(value, { bitLength, prefix, ...config })}`; }; var isEthAddress = (value, config = {}) => { const { bitLength = 160, prefix = true } = config; const loweredValue = typeof value === "string" ? value.toLowerCase() : value; return isHex(loweredValue, { bitLength, prefix }); }; var EthAddressZod = z5.string().regex(EthAddressRegEx, { message: "Invalid address format" }).refine( isEthAddress ); function asEthAddress(value, assert) { try { let stringValue = void 0; switch (typeof value) { case "string": { stringValue = hexFromHexString(value, { prefix: true, byteSize: 4 }); break; } default: { if (value !== void 0) { return assertError3(value, assert, `Unsupported type [${typeof value}]`); } } } return isEthAddress(stringValue) ? stringValue : assertError3(value, assert, `Value is not an EthAddress [${value}]`); } catch (ex) { const error = ex; return assertError3(void 0, assert, error.message); } } // src/hash/as.ts import { assertError as assertError4 } from "@xylabs/error"; import { isUndefined } from "@xylabs/typeof"; // src/hash/is.ts var isHash = (value, bitLength = 256) => { return isHex(value, { bitLength }); }; // src/hash/as.ts function asHash(value, assert) { let stringValue = void 0; switch (typeof value) { case "string": { stringValue = hexFromHexString(value); break; } default: { return isUndefined(assert) ? void 0 : assertError4(value, assert, `Unsupported type [${typeof value}]`); } } return isHash(stringValue) ? stringValue : assertError4(value, assert, `Value is not a Hash [${value}]`); } // src/hash/hash.ts import * as z6 from "zod"; var HASH_LENGTH = 32; var HashRegEx = HexRegExMinMax(HASH_LENGTH, HASH_LENGTH); var ZERO_HASH = "0000000000000000000000000000000000000000000000000000000000000000"; var HashBitLength = [32, 64, 128, 256, 512, 1024, 2048, 4096]; var isHashBitLength = (value) => { return typeof value === "number" && HashBitLength.includes(value); }; var HashZod = z6.string().regex(HashRegEx, { message: "Invalid hex format" }).transform((val) => val); // src/hash/zod.ts import * as z7 from "zod"; var HashToJsonZod = HashZod.transform((v) => v); var JsonToHashZod = z7.string().transform((v) => asHash(v, true)); // src/hexToBigInt.ts function hexToBigInt(hex) { return BigInt(hexFromHexString(hex, { prefix: true })); } // src/zod.ts import * as z8 from "zod"; var BigIntToJsonZod = z8.bigint().nonnegative().transform((x) => toHex(x)); var JsonToBigIntZod = z8.string().transform((x) => toHex(x)).transform((x) => hexToBigInt(x)); export { ADDRESS_LENGTH, AddressRegEx, AddressTransformZod, AddressValidationZod, AddressZod, BigIntToJsonZod, ETH_ZERO_ADDRESS, EthAddressFromStringSchema, EthAddressFromStringZod, EthAddressRegEx, EthAddressToStringSchema, EthAddressToStringZod, EthAddressZod, HASH_LENGTH, HashBitLength, HashRegEx, HashToJsonZod, HashZod, HexRegEx, HexRegExMinMax, HexRegExMinMaxMixedCaseWithPrefix, HexRegExWithPrefix, HexZod, JsonToBigIntZod, JsonToHashZod, ZERO_ADDRESS, ZERO_HASH, asAddress, asAddressV2, asEthAddress, asHash, asHex, bitsToNibbles, hexFrom, hexFromArrayBuffer, hexFromBigInt, hexFromHexString, hexFromNumber, hexToBigInt, isAddress, isAddressV2, isEthAddress, isHash, isHashBitLength, isHex, isHexZero, nibblesToBits, toAddress, toAddressV2, toEthAddress, toHex, toHexLegacy }; //# sourceMappingURL=index.mjs.map