@xylabs/hex
Version:
Base functionality used throughout XY Labs TypeScript/JavaScript libraries
361 lines (329 loc) • 10.8 kB
JavaScript
// 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