import type { Address } from 'abitype' import { type StringToBytesErrorType, stringToBytes, } from '../encoding/toBytes.js' import { InvalidAddressError } from '../errors/address.js' import type { ErrorType } from '../errors/utils.js' import { type Keccak256ErrorType, keccak256 } from '../hash/keccak256.js' import { LruMap } from '../utils/lru.js' import { type IsAddressErrorType, isAddress } from './isAddress.js' const checksumAddressCache = /*#__PURE__*/ new LruMap
(8192) export type ChecksumAddressErrorType = | Keccak256ErrorType | StringToBytesErrorType | ErrorType export function checksumAddress(address_: Address): Address { if (checksumAddressCache.has(address_)) return checksumAddressCache.get(address_)! const hexAddress = address_.substring(2).toLowerCase() const hash = keccak256(stringToBytes(hexAddress), 'bytes') const address = hexAddress.split('') for (let i = 0; i < 40; i += 2) { if (hash[i >> 1] >> 4 >= 8 && address[i]) { address[i] = address[i].toUpperCase() } if ((hash[i >> 1] & 0x0f) >= 8 && address[i + 1]) { address[i + 1] = address[i + 1].toUpperCase() } } const result = `0x${address.join('')}` as const checksumAddressCache.set(address_, result) return result } export type GetAddressErrorType = | ChecksumAddressErrorType | IsAddressErrorType | ErrorType export function getAddress(address: string): Address { if (!isAddress(address, { strict: false })) throw new InvalidAddressError({ address }) return checksumAddress(address) }