Skip to content
markpaper

src/account/address.ts

v0.3.0 · 1 KB

Download file
import { HlAccountError } from './errors.js';

/** A full 20-byte EVM address in lowercase. */
export type Address = `0x${string}`;

const ADDRESS_ANY_CASE = /^0x[0-9a-fA-F]{40}$/;

/** True for a full `0x` + 40 hex address in any letter case. Shortened forms are never valid. */
export function isAddress(value: unknown): value is string {
  return typeof value === 'string' && ADDRESS_ANY_CASE.test(value);
}

/**
 * Validates and lowercases an address.
 *
 * Why lowercase on input: HL accepts any case, but may echo addresses back in checksum or lower
 * case, and viem returns checksum form. Mixed case silently breaks cache keys, dedup and the
 * comparison with `extraAgents` (one account ends up as two records).
 *
 * @throws {HlAccountError} `INVALID_ARGUMENT` when the value is not a full address.
 */
export function normalizeAddress(value: unknown, what = 'address'): Address {
  if (!isAddress(value)) {
    throw new HlAccountError('INVALID_ARGUMENT', `${what} must be a full 0x-prefixed 40-hex address`);
  }
  return value.toLowerCase() as Address;
}
All files