This repository contains all of the code for the NPM package @namehash/ens-utils that exports functions for parsing names, handling currency, numbers, prices, and time.
| Module | Description |
|---|---|
nameparser |
Offers a way to process and normalize string inputs conform to the expected ENS name format configured. |
currency |
Especially useful in applications dealing with financial transactions, crypto assets, or any domain where currency representation and conversion are crucial. |
number |
Utility functions for converting between different numeric formats (string, Decimal, number, and bigint) and for performing approximate scaling of bigint values. |
price |
This module provides a robust foundation for handling monetary values within a financial application, offering flexibility for currency operations, conversions, and formatting. |
time |
Includes functions for time manipulation, formatting, and calculation. |
npm install @namehash/ens-utilsENS names are crucial in the Ethereum ecosystem, serving as human-readable addresses that map to Ethereum addresses. However, user input can be unpredictable and may not always conform to the expected ENS name format.
The Name Parser module offers a way to process and normalize these inputs into a consistent format, applying transformations such as trimming whitespace, normalizing names, and appending assumed TLDs when necessary, helping user handle labels and name hashes.
It utilizes the @adraffy/ens-normalize library for normalization purposes.
The module defines several constants for use within the ENS ecosystem, such as:
The character used to separate labels in an ENS name.
export const LABEL_SEPARATOR = ".";The top-level domain for Ethereum names (eth).
export const ETH_TLD = "eth";The minimum length of a label that can be registered under .eth.
export const MIN_ETH_REGISTRABLE_LABEL_LENGTH = 3;This interface defines the configuration options for the name parser.
| Property | Type | Description |
|---|---|---|
trimWhitespace |
boolean |
Whether to remove leading and trailing whitespace characters. |
attemptEnsNormalization |
boolean |
Whether to attempt ENS normalization on the input. Uses ens_normalize for this purpose. |
assumedTld |
string | null |
An optional label to be added as an assumed top-level domain. If null, disables any assumed TLD. |
A union type representing the types of transformations that can be performed on the input name.
type NameParserTransformation =
| "trim_whitespace"
| "assume_tld"
| "ens_normalize";This interface represents the result of parsing a name from user input.
| Property | Type | Description |
|---|---|---|
inputName |
string |
The original user input. |
outputName |
ENSName |
The parsed and transformed ENS name. |
transformations |
NameParserTransformation[] |
A list of transformations that were applied to the input name to construct the output name. |
The Normalization type represents the normalization status of an ENS name or label. It can be one of the following:
normalized: The name or label is normalized.unnormalized: The name or label is not normalized.unknown: The normalization status of the name or label is unknown.
export type Normalization =
| "normalized" /** `normalized`: The name or label is normalized. */
| "unnormalized" /** `unnormalized`: The name or label is not normalized. */
| "unknown" /** `unknown`: The name or label is unknown because it cannot be looked up from its hash. */;The NamespaceRoot type identifies the root namespace of an ENS name, which can be:
ens: For names ending in.ethand the ENS root.dns: For names belonging to the DNS namespace.unknown: For names with an undetermined namespace root.
export type NamespaceRoot =
| "ens" /** For now: Only given to names ending in "eth" and the ENS root */
| "dns"
| "unknown"; /** For now: Used for all other cases. Future enhancements will make this more specific. */The RegistrationPotential type indicates whether an ENS name is registrable, and it can be one of:
unregisterable: Direct subnames of.ethnot long enough for current contracts.invalid: Names are technically registerable but unnormalized.registerable: Names that are eligible for registration.unknown: Names with an undetermined registration potential.
export type RegistrationPotential =
| "unregisterable" /** For now: Only given to direct subnames of .eth that are not long enough for current ETHRegistrarController contracts */
| "invalid" /** Invalid names are technically registerable, but are unnormalized and should not be registered. */
| "registerable"
| "unknown"; /** For now: Used for all other cases. Future enhancements will make this more specific. */The DecentralizationStatus type describes the decentralization status of an ENS name:
unruggable: Names guaranteed to be decentralized.icann: Names under the jurisdiction of ICANN.unknown: Names with an unknown decentralization status.
export type DecentralizationStatus =
| "unruggable" /** For now: Only given to direct subnames of .eth, the name "eth", and the ENS root. */
| "icann"
| "unknown"; /** For now: Used for all other cases. Future enhancements will make this more specific. */The ENSName interface represents an ENS name, including its labels, display name, and normalization status.
interface ENSName {
name: string;
labels: string[];
displayName: string;
displayLabels: string[];
normalization: Normalization;
}Trims leading and trailing whitespace from each label in an array of labels.
Parameters
labels: The array of labels to trim the whitespaces from (string[]).
Returns
string[]- The array of labels without leading and trailing whitespaces.
Appends an assumed TLD to the last label if necessary, based on the configuration.
Parameters
labels: The array of labels to trim the whitespaces from (string[]).assumedTld: An optional label to be added as an assumed top-level domain. (string).
Returns
string[]- The array of labels with TLD appended.
The main function that takes an input name and options, applying configured transformations to parse the name into a standardized ENS name format.
Parameters
inputName: The input name to be parsed (string).options: The configured transformations to parse the name into a standardized ENS name format. (NameParserOptions | undefined).
Returns
ParsedName- This interface represents the result of parsing a name from user input.
import { parseName } from "./nameparser";
const options = {
trimWhitespace: true,
attemptEnsNormalization: true,
assumedTld: "eth",
};
const { inputName, outputName, transformations } = parseName(
" example.eth ",
options,
);This example demonstrates how to use the parseName function with the NameParserOptions to parse and normalize an ENS name input. The output would be a ParsedName object with the original input, the processed ENS name, and the transformations applied.
Computes the Keccak-256 hash of a provided label.
Parameters
label: The text label to hash.
Returns
- Keccak-256 hash of the label as a hexadecimal string.
const hashedLabel = labelhash("example");
console.log(hashedLabel); // Outputs the Keccak-256 hash of "example"Validates if a given string is a properly formatted Keccak-256 hash.
Parameters
hash: The hash string to validate.
Returns
trueif the hash is a valid Keccak-256 hash, otherwisefalse.
Encodes a given labelhash into a specific format, denoted by square brackets.
Parameters
labelhash: The labelhash value to encode.
Returns
- The encoded labelhash.
Decodes an encoded labelhash, extracting the original labelhash value.
Parameters
encodedLabelhash: The encoded labelhash to decode.
Returns
- The labelhash value of the encoded labelhash.
Checks if a label contains an encoded labelhash.
Parameters
label: The label to evaluate.
Returns
trueif the label contains an encoded labelhash, otherwisefalse.
Normalizes a Keccak-256 hash to a consistent format, addressing prefix presence and letter casing.
Parameters
hash: The hash to normalize.withPrefix: Whether to include the "0x" prefix in the normalized hash.
Returns
- A normalized Keccak-256 hash.
Throws: Error if the hash is not a valid Keccak-256 hash.
Normalizes an encoded labelhash to a standard format, ensuring the labelhash component is properly normalized.
Parameters
label: The label containing an encoded labelhash to normalize.
Returns A normalized encoded labelhash.
labelsEqual(labels1: string[], labels2: string[]): Checks if two sets of labels are equal.getDisplayLabels(labels: string[]): Converts labels into a display-optimized form.tryNormalize(labels: string[]): Attempts to normalize a set of labels.
buildENSName(name: string): Builds anENSNameobject from a string name.getNamespaceRoot(name: ENSName): Identifies the namespace root of a name.getDecentralizationStatus(name: ENSName): Identifies the decentralization status of a name.getRegistrationPotential(name: ENSName): Identifies the registration potential of a name.
isValidDNSTld(label: string): Identifies if a label represents a valid TLD in the DNS namespace.ethRegistrarControllerLength(label: string): Calculates the length of a label as determined by the EthRegistrarController smart contracts.
The Currency module provides solutions for managing different currencies, their display rules and configurations within a software application. It is especially useful in applications dealing with financial transactions, crypto assets, or any domain where currency representation and conversion are crucial.
Defines the supported currencies with their string representations.
export enum Currency {
Dai = "DAI",
Eth = "ETH",
Usd = "USD",
Usdc = "USDC",
Weth = "WETH",
Gas = "GAS",
}Specifies the rules for displaying currencies.
export enum CurrencyDisplayRule {
NativeCurrency = "NativeCurrency",
PreferredCurrency = "PreferredCurrency",
}A type that narrows down the Currency enum to only include Usd and Eth as the supported preferred currencies.
export type SupportedPreferredCurrencies = Currency.Usd | Currency.Eth;Defines the configuration for each currency including symbols, acronyms, decimals, and other display-related settings.
export interface CurrencyConfig {
Symbol: string;
Acronym: string;
Decimals: bigint;
DisplayDecimals: bigint;
UnitOfMeasure: string;
MaxDisplayValue: number;
MinDisplayValue: number;
OverflowDisplayPrice: string;
ExtendedCurrencyNameSingular: string;
ExtendedCurrencyNamePlural: string;
OneUnitOfCurrency: string;
}Defines the default preferred currency as Currency.Usd.
export const DEFAULT_PREFERRED_CURRENCY = Currency.Usd;A record mapping each Currency to its CurrencyConfig.
Example
import type { Currency, CurrencyConfig } from "@namehash/ens-utils";
export const PriceCurrencyFormat: Record<Currency, CurrencyConfig> = {
/* Configuration for each currency */
};Determines the primary display currency based on the provided display rule, preferred currency, and native currency.
Parameters
rule: The display rule to apply (CurrencyDisplayRule).preferredCurrency: The preferred currency (Currency).nativeCurrency: The native currency (Currency).
Returns
Currency- The determined primary display currency.
Determines the alternate display currency based on the provided display rule, preferred currency, and native currency.
Parameters
- Similar to
getPrimaryDisplayCurrency.
Returns
Currency- The determined alternate display currency.
Converts a string to a Currency enum value, throwing an error if the input is not a valid currency.
Parameters
string: The string to parse.
Returns
Currency- The parsed currency.
Example
import { parseStringToCurrency } from "@namehash/ens-utils";
const ethStringToCurrency = parseStringToCurrency("eth");
// ethStringToCurrency equals Currency.Eth
console.log(ethStringToCurrency); // "Eth"The Number module was designed to facilitate working with different numerical types and precision scaling in TypeScript applications, this module is essential for applications that require precision arithmetic or need to handle large numbers (beyond the safe range of JavaScript's number type) by providing tools to convert and scale these values safely and effectively.
Converts a string to a bigint. Throws an error if the conversion is not possible.
Parameters
stringValue:String- The string value to convert to a bigint.
Returns
bigint- The string value converted to a bigint.
Example
import { stringToBigInt } from "@namehash/ens-utils";
const bigIntValue = stringToBigInt("12345");Converts a Decimal value to a bigint by first converting the Decimal to a number with fixed decimal places and rounding, then converting that number to a bigint. Uses Decimal from Decimal.js.
Parameters
decimalValue:Decimal- The Decimal value to convert to a bigint.
Returns
bigint- The Decimal value converted to a bigint.
Example
import { decimalToBigInt } from "@namehash/ens-utils";
const bigIntValue = decimalToBigInt(new Decimal(123.45));Converts a number to a bigint after fixing it to zero decimal places. Throws an error if the conversion is not possible.
Parameters
numberValue:number- The bigint value to convert to a number.
Returns
bigint- The bigint value converted to a number.
Example
import { numberToBigInt } from "@namehash/ens-utils";
const bigIntValue = numberToBigInt(123.45);Converts a bigint to a number.
Parameters
bigIntValue:bigint- The bigint value to convert to a number.
Returns
number- The bigint value converted to a number.
Example
import { bigIntToNumber } from "@namehash/ens-utils";
const numberValue = bigIntToNumber(12345n);Approximately scales a bigint value by a scale factor, using a specified number of digits of precision.
Parameters
bigIntValue: bigint - The value to scale.scaleFactor: number - The factor to scale by.digitsOfPrecision: bigint - The number of digits of precision to use. Must be non-negative.
Returns
bigint- The scaled value.
Example
import { approxScaleBigInt } from "@namehash/ens-utils";
const scaledValue = approxScaleBigInt(100n, 0.1, 1n); // === 10nstringToBigIntandnumberToBigIntwill throw an error if the input cannot be converted to abigint.approxScaleBigIntthrows an error ifdigitsOfPrecisionis negative or if calculations overflow, underflow, or result in non-finite numbers.
This module consists of a collection of utility functions designed to handle and format time-related data in TypeScript.
- Conversion between time units (e.g., milliseconds to seconds)
- Current time retrieval
- Time formatting (e.g., to human-readable forms, short date formats)
- Calculation of time differences and descriptions relative to "now"
| Constant | Type | Description |
|---|---|---|
SECONDS_PER_YEAR |
number |
Defines the number of seconds in a year. |
ONE_MINUTE_IN_SECONDS |
bigint |
Represents one minute in seconds as a BigInt. |
ONE_HOUR_IN_SECONDS |
bigint |
Represents one hour in seconds as a BigInt. |
ONE_DAY_IN_SECONDS |
bigint |
Represents one day in seconds as a BigInt. |
ONE_WEEK_IN_SECONDS |
bigint |
Represents one week in seconds as a BigInt. |
Converts milliseconds to seconds.
Parameters
ms:bigint- The milliseconds to convert.
Returns
bigint- The converted time in seconds.
Retrieves the current time in seconds.
Returns
bigint- The current timestamp in seconds.
Formats a timestamp to a Date object.
Parameters
timestamp:bigint- The UNIX timestamp to format.asSeconds:boolean(optional) - If the timestamp is in seconds (defaults tofalse).
Returns
Date- A Date object for the formatted timestamp.
Formats a timestamp to a string representing the distance to now, optionally with a suffix.
Parameters
timestamp:bigint- The timestamp to format.addSuffix:boolean(optional) - Whether to add a suffix.
Returns
string- The formatted distance string.
Formats a timestamp into a short date format.
Parameters
timestamp: bigint - The timestamp to format.
Returns
string- The date formatted as a short string.
Provides a description of a timestamp, formatted either as a relative distance to now or as a short date.
Parameters
timestamp:bigint- The timestamp to describe.showAsDistance:boolean- Whether to show the timestamp as a distance from now.withSufix:boolean(optional) - Whether to include a suffix in the description.
Returns string - A description of the timestamp.
Converts a timestamp into a formatted string representing local date and time.
Parameters
timestamp:bigint- The timestamp to format.
Returns
string- The localized and formatted date and time string.
Returns a pretty string representing the difference between a timestamp and the current time.
Parameters
timestamp:bigint- The timestamp to compare with the current time.
Returns
string- A human-readable description of the time difference.
The Price module can be part of a financial application´ dealing with currency conversion, arithmetic operations on prices, formatting for display, and approximations. It primarily operates with a custom Price type, handling various currencies with support for arithmetic operations such as addition, subtraction, multiplication, and conversion between currencies using exchange rates.
Represents a monetary value in a specific currency.
import type { Currency } from "@namehash/ens-utils";
type Price = {
value: bigint;
currency: Currency;
};- value: The monetary value as a
bigint. - currency: The currency of the value, defined by the
Currencytype.
Maps different currencies to their exchange rate in USD.
import type { Currency } from "@namehash/ens-utils";
interface ExchangeRates extends Partial<Record<Currency, number>> {}An example ExchangeRates object:
{
"ETH": 1737.16,
"DAI": 0.99999703,
"USDC": 1,
"WETH": 1737.16,
"USD": 1
}Converts a Price object to its numeric representation considering its currency's decimals.
Parameters
price:Price- The Price to have its value returned as a number.
Returns number - A number representing the Price considering its Currency decimals.
Example
import { priceAsNumber } from "@namehash/ens-utils";
const tenUSDC = {
value: 100000n,
currency: Currency.Usdc,
};
const tenUsdcAsNumber = priceAsNumber(tenUSDC);
// tenUsdcDollarsAsNumber equals Number(1)Converts a numeric value to a Price object in the specified currency.
Parameters
number:number- The number to be set as the Price value.currency:Currency- The currency to be set as the Price currency.
Returns:
Price- A Price object containing a value and a currency.
Example
import { numberAsPrice } from "@namehash/ens-utils";
const fromNumberTenToEthValue = numberAsPrice(10, Currency.Eth);
// fromNumberTenToEthValue equals {
// value: 10000000000000000000n,
// currency: Currency.Eth
// }Adds multiple Price objects, ensuring they are in the same currency.
Parameters
prices:Array<Price>- An array of Price values.
Returns
Price- The summing of eachpricesPrice.
Example
import { addPrices } from "@namehash/ens-utils";
const networkFee: Price = {
value: X,
currency: Currency.Eth,
};
const ethDomainPrice: Price = {
value: Y,
currency: Currency.Eth,
};
const totalCost = addPrices([networkFee, ethDomainPrice]);
// totalCost equals {
// value: X + Y,
// currency: Currency.Eth
// }Throws: Error if trying to add prices of different currencies.
Subtracts one Price object from another, given they are in the same currency.
Parameters
price1:Price- The Price to be subtracted from.price2:Price- The Price to be subtracted.
Returns
Price- Theprice1subtracted byprice2.
Example
import { subtractPrices } from "@namehash/ens-utils";
const ethDomainPrice: Price = {
value: X,
currency: Currency.Eth,
};
const ethDomainPricePremium: Price = {
value: Y,
currency: Currency.Eth,
};
const totalCost = subtractPrices(ethDomainPrice, ethDomainPricePremium);
// totalCost equals {
// value: X - Y,
// currency: Currency.Eth
// }Throws: Error if currencies do not match.
Multiplies a Price by a numeric value.
Parameters
price1:Price- The Price to be multiplied.price2:number- A number to multiplyprice1for.
Returns
Price- Theprice1, as a Price, having itsvaluemultiplied byprice2.
Example
import { multiplyPriceByNumber } from "@namehash/ens-utils";
const ethDomainPrice: Price = {
value: X,
currency: Currency.Eth,
};
const multiplier = 2;
const totalCost = multiplyPriceByNumber(ethDomainPrice, multiplier);
// totalCost equals {
// value: X * 2,
// currency: Currency.Eth
// }Returns a string representing a Price formatted for display, with optional prefix or suffix.
Parameters
price:Price- The Price to format.withPrefix= false:boolean- Wether to add a Currency prefix.withSufix= false:boolean- Wether to add a Currency sufix.
Returns
string- A human-readable formatted Price string.
Example
import { formattedPrice } from "@namehash/ens-utils";
const fiveDollarsInEth = 5000000000000000000n;
const a = formattedPrice({
price: { currency: Currency.Eth, value: fiveDollarsInEth },
});
const b = formattedPrice({
price: { currency: Currency.Eth, value: fiveDollarsInEth },
withSufix: true,
});
const c = formattedPrice({
price: { currency: Currency.Eth, value: fiveDollarsInEth },
withPrefix: true,
});
const d = formattedPrice({
price: { currency: Currency.Eth, value: fiveDollarsInEth },
withPrefix: true,
withSufix: true,
});
// a equals 5.000
// b equals 5.000 ETH
// c equals Ξ5.000
// d equals Ξ5.000 ETHScales a Price object by a factor with a specified number of digits of precision.
Parameters
price: Price - The Price to scale.scaleFactor: number - The factor to scale by.digitsOfPrecision= 20n: bigint - The number of digits of precision to use. Must be non-negative.
Returns
Price- Thepricescaled by thescaleFactorconsidering the number ofdigitsOfPrecision.
Example
import { approxScalePrice } from "@namehash/ens-utils";
const decayedPrice = approxScalePrice(PREMIUM_START_PRICE, decayFactor);
// decayedPrice equals PREMIUM_START_PRICE scaled (up or down, depending on decayFactor value) by decayedPriceConverts a Price from one currency to another using provided exchange rates.
Parameters
fromPrice:Price- The price to be converted to a new Currency.toCurrency:Currency- The new Currency to convertfromPriceto.exchangeRates:ExchangeRates- The exchange rates object. Refer to ExchangeRates
Returns
Price- The convertedfromPriceinto itstoCurrencyvalue, calculated based on the providedexchangeRates.
Example
import { convertCurrencyWithRates } from "@namehash/ens-utils";
const fromUsd = {
value: 500n,
currency: Currency.Usd,
};
const exchangeRatesRecord = {
[Currency.Eth]: 2277.56570676,
[Currency.Usd]: 1,
};
const fromUsdToEth = convertCurrencyWithRates(
fromUsd,
Currency.Eth,
exchangeRatesRecord,
);
// fromUsdToEth equals the Eth amount of $5 based on the provided currencies exchange rates- Arithmetic Operations (add, subtract): Throws an error if currencies do not match.
- Conversion Operations: Throws an error if exchange rates do not include the necessary currencies.
Visit our website and get in contact.
Licensed under the MIT License, Copyright © 2023-present NameHash Labs.
See LICENSE for more information.