Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 17
Add address related utils#112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
4d8a8024902357763a25bd421bb7324508958ae2d238444a94a49c16b907e53File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| import { keccak_256 as keccak256 } from '@noble/hashes/sha3'; | ||
| import { is, pattern, string, Struct } from 'superstruct'; | ||
| import { assert } from './assert'; | ||
| import { bytesToHex } from './bytes'; | ||
| export type Hex = `0x${string}`; | ||
| @@ -9,6 +11,14 @@ export const StrictHexStruct = pattern(string(), /^0x[0-9a-f]+$/iu) as Struct< | ||
| Hex, | ||
| null | ||
| >; | ||
| export const HexAddressStruct = pattern( | ||
| string(), | ||
| /^0x[0-9a-f]{40}$/u, | ||
| ) as Struct<Hex, null>; | ||
| export const HexChecksumAddressStruct = pattern( | ||
| string(), | ||
| /^0x[0-9a-fA-F]{40}$/u, | ||
| ) as Struct<Hex, null>; | ||
| /** | ||
| * Check if a string is a valid hex string. | ||
| @@ -55,6 +65,58 @@ export function assertIsStrictHexString(value: unknown): asserts value is Hex { | ||
| ); | ||
| } | ||
| /** | ||
| * Validate that the passed prefixed hex string is an all-lowercase | ||
| * hex address, or a valid mixed-case checksum address. | ||
| * | ||
| * @param possibleAddress - Input parameter to check against. | ||
| * @returns Whether or not the input is a valid hex address. | ||
| */ | ||
| export function isValidHexAddress(possibleAddress: Hex) { | ||
| return ( | ||
| is(possibleAddress, HexAddressStruct) || | ||
| isValidChecksumAddress(possibleAddress) | ||
| ); | ||
| } | ||
| /** | ||
| * Encode a passed hex string as an ERC-55 mixed-case checksum address. | ||
| * | ||
| * @param address - The hex address to encode. | ||
| * @returns The address encoded according to ERC-55. | ||
| * @see https://eips.ethereum.org/EIPS/eip-55 | ||
| */ | ||
| export function getChecksumAddress(address: Hex) { | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should do more validation here, such as checking if the provided address is 20 bytes long. MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just added an assertion to check the string we receive here | ||
| assert(is(address, HexChecksumAddressStruct), 'Invalid hex address.'); | ||
| const unPrefixed = remove0x(address.toLowerCase()); | ||
| const unPrefixedHash = remove0x(bytesToHex(keccak256(unPrefixed))); | ||
| return `0x${unPrefixed | ||
| .split('') | ||
| .map((character, nibbleIndex) => { | ||
| const hashCharacter = unPrefixedHash[nibbleIndex]; | ||
| assert(is(hashCharacter, string()), 'Hash shorter than address.'); | ||
| return parseInt(hashCharacter, 16) > 7 | ||
| ? character.toUpperCase() | ||
| : character; | ||
| }) | ||
| .join('')}`; | ||
| } | ||
| /** | ||
| * Validate that the passed hex string is a valid ERC-55 mixed-case | ||
| * checksum address. | ||
| * | ||
| * @param possibleChecksum - The hex address to check. | ||
| * @returns True if the address is a checksum address. | ||
| */ | ||
| export function isValidChecksumAddress(possibleChecksum: Hex) { | ||
| if (!is(possibleChecksum, HexChecksumAddressStruct)) { | ||
| return false; | ||
| } | ||
| return getChecksumAddress(possibleChecksum) === possibleChecksum; | ||
| } | ||
| /** | ||
| * Add the `0x`-prefix to a hexadecimal string. If the string already has the | ||
| * prefix, it is returned as-is. | ||
Uh oh!
There was an error while loading. Please reload this page.