@unique-nft/utils
Version:
A tiny library to work with Substrate and Ethereum addresses and do some more
616 lines (608 loc) • 23.5 kB
JavaScript
import {
__export
} from "./chunk-SMH5LAMQ.mjs";
// src/Address/index.ts
var Address_exports = {};
__export(Address_exports, {
Address: () => Address,
algorithms: () => imports_exports,
collection: () => collection,
compare: () => compare,
constants: () => constants_exports,
extract: () => extract,
is: () => is,
mirror: () => mirror,
nesting: () => nesting,
normalize: () => normalize,
substrate: () => substrate,
validate: () => validate
});
// src/Address/constants.ts
var constants_exports = {};
__export(constants_exports, {
COLLECTION_ADDRESS_PREFIX: () => COLLECTION_ADDRESS_PREFIX,
NESTING_PREFIX: () => NESTING_PREFIX,
STATIC_ADDRESSES: () => STATIC_ADDRESSES
});
var STATIC_ADDRESSES = {
contractHelpers: "0x842899ECF380553E8a4de75bF534cdf6fBF64049",
collectionHelpers: "0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F"
};
var NESTING_PREFIX = "0xf8238ccfff8ed887463fd5e0";
var COLLECTION_ADDRESS_PREFIX = "0x17c4e6453cc49aaaaeaca894e6d9683e";
// src/Address/imports.ts
var imports_exports = {};
__export(imports_exports, {
base58: () => base58,
base64: () => base64,
basex: () => basex,
blake2b: () => blake2b,
keccak_256: () => keccak_256
});
import basex from "base-x";
import { keccak_256 } from "@noble/hashes/sha3";
import { blake2b } from "@noble/hashes/blake2b";
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
var BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base58 = basex(BASE58_ALPHABET);
var base64 = basex(BASE64_ALPHABET);
// src/Address/ethereum.ts
import { HexString } from "utf-helpers";
var DWORDHexString = {
_checkU32: (num) => {
if (typeof num !== "number")
throw new Error(`Passed number is not a number: ${typeof num}, ${num}`);
if (isNaN(num))
throw new Error(`Passed number is NaN: ${num}`);
if (num < 0)
throw new Error(`Passed number is less than 0: ${num}`);
if (num > 4294967295)
throw new Error(`Passed number is more than 2**32: ${num}`);
if (num !== Math.floor(num))
throw new Error(`Passed number is not an integer number: ${num}`);
return num;
},
fromNumber: (n) => {
return DWORDHexString._checkU32(n).toString(16).padStart(8, "0");
},
toNumber: (s) => {
const num = parseInt(s, 16);
if (isNaN(num))
throw new Error(`Passed string is not hexadecimal: ${s}`);
return DWORDHexString._checkU32(num);
}
};
var unsafeNormalizeEthereumAddress = (address) => {
const addr = address.toLowerCase().replace(/^0x/i, "");
const addressHash = HexString.fromU8a(keccak_256(addr)).replace(/^0x/i, "");
let checksumAddress = "0x";
for (let i = 0; i < addr.length; i++) {
checksumAddress += parseInt(addressHash[i], 16) > 7 ? addr[i].toUpperCase() : addr[i];
}
return checksumAddress;
};
var normalizeEthereumAddress = (address) => {
validate.ethereumAddress(address);
return unsafeNormalizeEthereumAddress(address);
};
var compareEthereumAddresses = (address1, address2) => {
const addr1 = typeof address1 === "string" ? address1 : address1.Ethereum || address1.ethereum;
const addr2 = typeof address2 === "string" ? address2 : address2.Ethereum || address2.ethereum;
if (!addr1 || !addr2 || !is.ethereumAddress(addr1) || !is.ethereumAddress(addr2)) {
return false;
}
return addr1.toLowerCase() === addr2.toLowerCase();
};
var collectionIdToEthAddress = (collectionId) => {
validate.collectionId(collectionId);
return unsafeNormalizeEthereumAddress(
COLLECTION_ADDRESS_PREFIX + DWORDHexString.fromNumber(collectionId)
);
};
var ethAddressToCollectionId = (address) => {
validate.collectionAddress(address);
return DWORDHexString.toNumber(address.slice(-8));
};
var collectionIdAndTokenIdToNestingAddress = (collectionId, tokenId) => {
validate.collectionId(collectionId);
validate.tokenId(tokenId);
return unsafeNormalizeEthereumAddress(
NESTING_PREFIX + DWORDHexString.fromNumber(collectionId) + DWORDHexString.fromNumber(tokenId)
);
};
var nestingAddressToCollectionIdAndTokenId = (address) => {
validate.nestingAddress(address);
return {
collectionId: DWORDHexString.toNumber(address.slice(-16, -8)),
tokenId: DWORDHexString.toNumber(address.slice(-8))
};
};
// src/Address/substrate.ts
import { HexString as HexString2 } from "utf-helpers";
var blake2AsU8a = (u8a, dkLen = 32) => {
return blake2b(u8a, { dkLen });
};
var u8aConcat = (u8as) => {
let offset = 0;
let length = 0;
for (let i = 0; i < u8as.length; i++) {
length += u8as[i].length;
}
const result = new Uint8Array(length);
for (let i = 0; i < u8as.length; i++) {
result.set(u8as[i], offset);
offset += u8as[i].length;
}
return result;
};
var SS58_PREFIX = new Uint8Array([83, 83, 53, 56, 80, 82, 69]);
var sshash = (data) => {
return blake2AsU8a(u8aConcat([SS58_PREFIX, data]), 64);
};
var checkAddressChecksum = (decoded, ignoreChecksum = false) => {
const ss58Length = decoded[0] & 64 ? 2 : 1;
const ss58Decoded = ss58Length === 1 ? decoded[0] : (decoded[0] & 63) << 2 | decoded[1] >> 6 | (decoded[1] & 63) << 8;
const isPublicKey = [34 + ss58Length, 35 + ss58Length].includes(decoded.length);
const length = decoded.length - (isPublicKey ? 2 : 1);
let isValid = false;
if (!ignoreChecksum) {
const hash = sshash(decoded.subarray(0, length));
isValid = (decoded[0] & 128) === 0 && ![46, 47].includes(decoded[0]) && (isPublicKey ? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1] : decoded[decoded.length - 1] === hash[0]);
}
return [isValid, length, ss58Length, ss58Decoded];
};
var normalizeSubstrateAddress = (address, prefix = 42) => {
return encodeSubstrateAddress(decodeSubstrateAddress(address).u8a, prefix);
};
function encodeSubstrateAddress(key, ss58Format = 42) {
const u8a = typeof key === "string" ? HexString2.toU8a(key) : typeof key === "bigint" ? HexString2.toU8a(key.toString(16)) : key;
if (ss58Format < 0 || ss58Format > 16383 || [46, 47].includes(ss58Format)) {
throw new Error(`ss58Format is not valid, received ${typeof ss58Format} "${ss58Format}"`);
}
const allowedDecodedLengths = [1, 2, 4, 8, 32, 33];
if (!allowedDecodedLengths.includes(u8a.length)) {
throw new Error(`key length is not valid, received ${u8a.length}, valid values are ${allowedDecodedLengths.join(", ")}`);
}
const u8aPrefix = ss58Format < 64 ? new Uint8Array([ss58Format]) : new Uint8Array([
(ss58Format & 252) >> 2 | 64,
ss58Format >> 8 | (ss58Format & 3) << 6
]);
const input = u8aConcat([u8aPrefix, u8a]);
return base58.encode(
u8aConcat([
input,
sshash(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1)
])
);
}
function decodeSubstrateAddress(address, ignoreChecksum, ss58Format = -1) {
let realError = null;
try {
if (is.substratePublicKey(address)) {
return {
u8a: HexString2.toU8a(address),
bigint: BigInt(address),
hex: address,
ss58Prefix: 42
};
} else if (address.startsWith("0x")) {
throw new Error(`Invalid substrate address, received ${address}. Wrong or mangled public key?`);
}
const decoded = base58.decode(address);
const allowedEncodedLengths = [3, 4, 6, 10, 35, 36, 37, 38];
if (!allowedEncodedLengths.includes(decoded.length)) {
realError = new Error(`key length is not valid, decoded key length is ${decoded.length}, valid values are ${allowedEncodedLengths.join(", ")}`);
throw realError;
}
const [isValid, endPos, ss58Length, ss58Decoded] = checkAddressChecksum(decoded, ignoreChecksum);
if (!ignoreChecksum && !isValid) {
realError = new Error(`Invalid decoded address checksum`);
throw realError;
}
if (![-1, ss58Decoded].includes(ss58Format)) {
realError = new Error(`Expected ss58Format ${ss58Format}, received ${ss58Decoded}`);
throw realError;
}
const publicKey = decoded.slice(ss58Length, endPos);
const hex = HexString2.fromU8a(publicKey);
return {
u8a: publicKey,
hex,
bigint: BigInt(hex),
ss58Prefix: ss58Decoded
};
} catch (error) {
throw realError ? realError : new Error(`Decoding ${address}: ${error.message}`);
}
}
var compareSubstrateAddresses = (address1, address2) => {
const addr1 = typeof address1 === "string" ? address1 : address1.Substrate || address1.substrate;
const addr2 = typeof address2 === "string" ? address2 : address2.Substrate || address2.substrate;
if (!addr1 || !addr2) {
return false;
}
try {
const decoded1 = decodeSubstrateAddress(addr1);
const decoded2 = decodeSubstrateAddress(addr2);
return decoded1.bigint === decoded2.bigint;
} catch (e) {
return false;
}
};
var addressToEvm = (address, ignoreChecksum) => {
const truncated = decodeSubstrateAddress(address, ignoreChecksum).u8a.subarray(0, 20);
return normalizeEthereumAddress(HexString2.fromU8a(truncated));
};
var EVM_PREFIX_U8A = new Uint8Array([101, 118, 109, 58]);
var evmToAddress = (evmAddress, ss58Format = 42) => {
validate.ethereumAddress(evmAddress);
const message = u8aConcat([EVM_PREFIX_U8A, HexString2.toU8a(evmAddress)]);
return encodeSubstrateAddress(blake2AsU8a(message), ss58Format);
};
// src/Address/crossAccountId.ts
var guessAddressAndExtractCrossAccountIdUnsafe = (rawAddress, normalize2 = false) => {
const address = rawAddress;
if (typeof address === "object") {
if (address.hasOwnProperty("eth") && address.hasOwnProperty("sub")) {
const subPublicKey = address.sub.hasOwnProperty("_hex") && typeof address.sub._hex === "string" ? address.sub._hex : address.sub;
if (typeof subPublicKey !== "string" || !subPublicKey.startsWith("0x")) {
throw new Error(`Substrate public key must be a hex string, got ${subPublicKey}`);
}
const subBigInt = BigInt(subPublicKey);
const ethBigInt = BigInt(address.eth);
if (!(Number(subBigInt === 0n) ^ Number(ethBigInt === 0n))) {
throw new Error(`One of the addresses must be 0, got eth ${address.eth} and substrate public key ${address.sub}.`);
}
if (subBigInt === 0n) {
return { Ethereum: normalizeEthereumAddress(address.eth) };
} else {
return { Substrate: normalizeSubstrateAddress(subPublicKey) };
}
} else if (address.hasOwnProperty("Substrate") || address.hasOwnProperty("substrate")) {
const substrateAddress = address.hasOwnProperty("Substrate") ? address.Substrate : address.substrate;
if (is.substratePublicKey(substrateAddress)) {
return { Substrate: normalizeSubstrateAddress(substrateAddress) };
} else if (is.substrateAddress(substrateAddress)) {
return { Substrate: normalize2 ? normalizeSubstrateAddress(substrateAddress) : substrateAddress };
} else {
throw new Error(`Address ${substrateAddress} is not a valid Substrate address`);
}
} else if (address.hasOwnProperty("Ethereum") || address.hasOwnProperty("ethereum")) {
const ethereumAddress = address.hasOwnProperty("Ethereum") ? address.Ethereum : address.ethereum;
validate.ethereumAddress(ethereumAddress);
return { Ethereum: normalize2 ? normalizeEthereumAddress(ethereumAddress) : ethereumAddress };
} else {
throw new Error(`Address ${address} is not a valid crossAccountId object (should contain "Substrate"/"substrate" or "Ethereum"/"ethereum" field) or EthCrossAccountId (should contain "eth" and "sub" fields)`);
}
}
if (typeof address === "string") {
if (is.substrateAddress(address))
return { Substrate: normalize2 ? normalizeSubstrateAddress(address) : address };
else if (is.ethereumAddress(address))
return { Ethereum: normalize2 ? normalizeEthereumAddress(address) : address };
else if (is.substratePublicKey(address))
return { Substrate: normalizeSubstrateAddress(address) };
else {
throw new Error(`Address ${address} is not a valid Substrate or Ethereum address`);
}
}
throw new Error(`Address ${address} is not a string or object: ${typeof address}`);
};
var guessAddressAndExtractCrossAccountIdSafe = (address, normalize2 = false) => {
try {
return guessAddressAndExtractCrossAccountIdUnsafe(address, normalize2);
} catch {
return null;
}
};
var substrateOrMirrorIfEthereum = (address, normalize2 = false) => {
const addressObject = guessAddressAndExtractCrossAccountIdUnsafe(address, normalize2);
return addressObject.Substrate ? addressObject.Substrate : mirror.ethereumToSubstrate(addressObject.Ethereum);
};
var addressInAnyFormToEnhancedCrossAccountId = (address, ss58Prefix = 42) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(address);
if (crossAccountId.Ethereum) {
const normalized = normalizeEthereumAddress(crossAccountId.Ethereum);
return {
...crossAccountId,
address: normalized,
addressSS58: normalized,
substratePublicKey: normalized,
isEthereum: true,
isSubstrate: false,
type: "Ethereum"
};
} else {
return {
...crossAccountId,
address: normalizeSubstrateAddress(crossAccountId.Substrate),
addressSS58: normalizeSubstrateAddress(crossAccountId.Substrate, ss58Prefix),
substratePublicKey: decodeSubstrateAddress(crossAccountId.Substrate).hex,
isEthereum: false,
isSubstrate: true,
type: "Substrate"
};
}
};
// src/Address/index.ts
var ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
var SUB_PUBLIC_KEY_REGEX = /^0x[a-fA-F0-9]{64}$/;
var validate = {
substrateAddress: (address) => {
decodeSubstrateAddress(address);
return true;
},
ethereumAddress: (address) => {
if (!is.ethereumAddress(address)) {
throw new Error(`address "${address}" is not valid ethereum address`);
}
return true;
},
substratePublicKey: (address) => {
if (!is.substratePublicKey(address)) {
throw new Error(`address "${address}" is not valid substrate public key`);
}
return true;
},
collectionAddress: (address) => {
if (!is.collectionAddress(address)) {
throw new Error(`address ${address} is not a collection address`);
}
return true;
},
nestingAddress: (address) => {
if (!is.nestingAddress(address)) {
throw new Error(`address ${address} is not a nesting address`);
}
return true;
},
collectionId: (collectionId) => {
if (!is.collectionId(collectionId)) {
throw new Error(`collectionId should be a number between 0 and 0xffffffff`);
}
return true;
},
tokenId: (tokenId) => {
if (!is.tokenId(tokenId)) {
throw new Error(`collectionId should be a number between 0 and 0xffffffff`);
}
return true;
}
};
var is = {
substrateAddress: (address) => {
try {
decodeSubstrateAddress(address);
return !is.substratePublicKey(address);
} catch {
return false;
}
},
ethereumAddress: (address) => {
return typeof address === "string" && address.length === 42 && !!address.match(ETH_ADDRESS_REGEX);
},
substratePublicKey: (address) => {
return typeof address === "string" && address.length === 66 && !!address.match(SUB_PUBLIC_KEY_REGEX);
},
collectionAddress: (address) => {
return is.ethereumAddress(address) && address.toLowerCase().startsWith(COLLECTION_ADDRESS_PREFIX);
},
nestingAddress: (address) => {
return is.ethereumAddress(address) && address.toLowerCase().startsWith(NESTING_PREFIX);
},
collectionId: (collectionId) => {
return !(typeof collectionId !== "number" || isNaN(collectionId) || collectionId < 0 || collectionId > 4294967295);
},
tokenId: (tokenId) => {
return !(typeof tokenId !== "number" || isNaN(tokenId) || tokenId < 0 || tokenId > 4294967295);
},
crossAccountId(obj) {
return is.substrateAddressObject(obj) || is.ethereumAddressObject(obj);
},
crossAccountIdUncapitalized(obj) {
return is.substrateAddressObjectUncapitalized(obj) || is.ethereumAddressObjectUncapitalized(obj);
},
substrateAddressObject(obj) {
return typeof obj === "object" && typeof obj?.Substrate === "string" && is.substrateAddress(obj.Substrate);
},
ethereumAddressObject(obj) {
return typeof obj === "object" && typeof obj?.Ethereum === "string" && is.ethereumAddress(obj.Ethereum);
},
substrateAddressObjectUncapitalized(obj) {
return typeof obj === "object" && typeof obj?.substrate === "string" && is.substrateAddress(obj.substrate);
},
ethereumAddressObjectUncapitalized(obj) {
return typeof obj === "object" && typeof obj?.ethereum === "string" && is.ethereumAddress(obj.ethereum);
},
substrateAddressInAnyForm(address) {
return typeof address === "string" ? is.substrateAddress(address) : typeof address === "object" && !!address && (is.substrateAddressObject(address) || is.substrateAddressObjectUncapitalized(address));
},
ethereumAddressInAnyForm(address) {
return typeof address === "string" ? is.ethereumAddress(address) : typeof address === "object" && !!address && (is.ethereumAddressObject(address) || is.ethereumAddressObjectUncapitalized(address));
},
validAddressInAnyForm(address) {
return is.ethereumAddressInAnyForm(address) || is.substrateAddressInAnyForm(address);
}
};
var collection = {
idToAddress: collectionIdToEthAddress,
addressToId: ethAddressToCollectionId
};
var nesting = {
idsToAddress: collectionIdAndTokenIdToNestingAddress,
addressToIds: nestingAddressToCollectionIdAndTokenId
};
var extract = {
address: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId);
return crossAccountId.Substrate || crossAccountId.Ethereum;
},
addressSafe: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdSafe(addressOrCrossAccountId);
return crossAccountId ? crossAccountId.Substrate || crossAccountId.Ethereum : null;
},
addressNormalized: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId, true);
return crossAccountId.Substrate || crossAccountId.Ethereum;
},
addressNormalizedSafe: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdSafe(addressOrCrossAccountId, true);
return crossAccountId ? crossAccountId.Substrate || crossAccountId.Ethereum : null;
},
addressForScanNormalized: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId, true);
return crossAccountId.Substrate || crossAccountId.Ethereum.toLowerCase();
},
addressForScanNormalizedSafe: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdSafe(addressOrCrossAccountId, true);
return crossAccountId ? crossAccountId.Substrate || crossAccountId.Ethereum.toLowerCase() : null;
},
crossAccountId: (addressOrCrossAccountId) => {
return guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId);
},
crossAccountIdSafe: (addressOrCrossAccountId) => {
return guessAddressAndExtractCrossAccountIdSafe(addressOrCrossAccountId);
},
crossAccountIdNormalized: (addressOrCrossAccountId) => {
return guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId, true);
},
crossAccountIdNormalizedSafe: (addressOrCrossAccountId) => {
return guessAddressAndExtractCrossAccountIdSafe(addressOrCrossAccountId, true);
},
crossAccountIdUncapitalized: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId);
return crossAccountId.Substrate ? { substrate: crossAccountId.Substrate } : { ethereum: crossAccountId.Ethereum };
},
crossAccountIdUncapitalizedSafe: (addressOrCrossAccountId) => {
try {
return extract.crossAccountIdUncapitalized(addressOrCrossAccountId);
} catch {
return null;
}
},
crossAccountIdUncapitalizedNormalized: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId, true);
return crossAccountId.Substrate ? { substrate: crossAccountId.Substrate } : { ethereum: crossAccountId.Ethereum };
},
crossAccountIdUncapitalizedNormalizedSafe: (addressOrCrossAccountId) => {
try {
return extract.crossAccountIdUncapitalizedNormalized(addressOrCrossAccountId);
} catch {
return null;
}
},
substrateOrMirrorIfEthereum: (addressOrCrossAccountId) => {
return substrateOrMirrorIfEthereum(addressOrCrossAccountId);
},
substrateOrMirrorIfEthereumSafe: (addressOrCrossAccountId) => {
try {
return substrateOrMirrorIfEthereum(addressOrCrossAccountId);
} catch {
return null;
}
},
substrateOrMirrorIfEthereumNormalized: (addressOrCrossAccountId) => {
return substrateOrMirrorIfEthereum(addressOrCrossAccountId, true);
},
substrateOrMirrorIfEthereumNormalizedSafe: (addressOrCrossAccountId) => {
try {
return substrateOrMirrorIfEthereum(addressOrCrossAccountId, true);
} catch {
return null;
}
},
substratePublicKey: (addressOrCrossAccountId) => {
const crossAccountId = guessAddressAndExtractCrossAccountIdUnsafe(addressOrCrossAccountId);
if (!crossAccountId.Substrate) {
throw new Error("Address is not a substrate address");
}
return substrate.decode(crossAccountId.Substrate).hex;
},
substratePublicKeySafe: (addressOrCrossAccountId) => {
try {
return extract.substratePublicKey(addressOrCrossAccountId);
} catch {
return null;
}
},
enhancedCrossAccountId: (addressInAnyForm, ss58Prefix = 42) => {
return addressInAnyFormToEnhancedCrossAccountId(addressInAnyForm, ss58Prefix);
},
enhancedCrossAccountIdSafe: (addressInAnyForm, ss58Prefix = 42) => {
try {
return addressInAnyFormToEnhancedCrossAccountId(addressInAnyForm, ss58Prefix);
} catch {
return null;
}
},
ethCrossAccountId: (addressInAnyForm) => {
const addressEnhanced = addressInAnyFormToEnhancedCrossAccountId(addressInAnyForm);
if (addressEnhanced.Substrate) {
return {
eth: "0x0000000000000000000000000000000000000000",
sub: addressEnhanced.substratePublicKey
};
} else {
return {
eth: addressEnhanced.address,
sub: "0x00"
};
}
},
ethCrossAccountIdSafe: (addressInAnyForm) => {
try {
return extract.ethCrossAccountId(addressInAnyForm);
} catch {
return null;
}
}
};
var mirror = {
substrateToEthereum: addressToEvm,
ethereumToSubstrate: evmToAddress
};
var normalize = {
substrateAddress: normalizeSubstrateAddress,
ethereumAddress: normalizeEthereumAddress
};
var compare = {
substrateAddresses: compareSubstrateAddresses,
ethereumAddresses: compareEthereumAddresses
};
var substrate = {
encode: encodeSubstrateAddress,
decode: decodeSubstrateAddress,
compare: compareSubstrateAddresses
};
var Address = {
constants: constants_exports,
algorithms: imports_exports,
is,
validate,
collection,
nesting,
extract,
mirror,
normalize,
compare,
substrate,
utils: {
DWORDHexString
}
};
export {
constants_exports,
imports_exports,
validate,
is,
collection,
nesting,
extract,
mirror,
normalize,
compare,
substrate,
Address,
Address_exports
};
//# sourceMappingURL=chunk-6B63RM6C.mjs.map