- Consolidated duplicate UndoManagers to single instance - Fixed connection promise to only resolve on 'connected' status - Fixed WebSocketProvider import (WebsocketProvider) - Added proper doc.destroy() cleanup - Renamed isPresenceInitialized property to avoid conflict Co-Authored-By: Paperclip <noreply@paperclip.ing>
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
import type { Address } from 'abitype'
|
|
|
|
import { InvalidAddressError } from '../../errors/address.js'
|
|
import type { ErrorType } from '../../errors/utils.js'
|
|
import {
|
|
type StringToBytesErrorType,
|
|
stringToBytes,
|
|
} from '../encoding/toBytes.js'
|
|
import { type Keccak256ErrorType, keccak256 } from '../hash/keccak256.js'
|
|
import { LruMap } from '../lru.js'
|
|
import { type IsAddressErrorType, isAddress } from './isAddress.js'
|
|
|
|
const checksumAddressCache = /*#__PURE__*/ new LruMap<Address>(8192)
|
|
|
|
export type ChecksumAddressErrorType =
|
|
| Keccak256ErrorType
|
|
| StringToBytesErrorType
|
|
| ErrorType
|
|
|
|
export function checksumAddress(
|
|
address_: Address,
|
|
/**
|
|
* Warning: EIP-1191 checksum addresses are generally not backwards compatible with the
|
|
* wider Ethereum ecosystem, meaning it will break when validated against an application/tool
|
|
* that relies on EIP-55 checksum encoding (checksum without chainId).
|
|
*
|
|
* It is highly recommended to not use this feature unless you
|
|
* know what you are doing.
|
|
*
|
|
* See more: https://github.com/ethereum/EIPs/issues/1121
|
|
*/
|
|
chainId?: number | undefined,
|
|
): Address {
|
|
if (checksumAddressCache.has(`${address_}.${chainId}`))
|
|
return checksumAddressCache.get(`${address_}.${chainId}`)!
|
|
|
|
const hexAddress = chainId
|
|
? `${chainId}${address_.toLowerCase()}`
|
|
: address_.substring(2).toLowerCase()
|
|
const hash = keccak256(stringToBytes(hexAddress), 'bytes')
|
|
|
|
const address = (
|
|
chainId ? hexAddress.substring(`${chainId}0x`.length) : 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_}.${chainId}`, result)
|
|
return result
|
|
}
|
|
|
|
export type GetAddressErrorType =
|
|
| ChecksumAddressErrorType
|
|
| IsAddressErrorType
|
|
| ErrorType
|
|
|
|
export function getAddress(
|
|
address: string,
|
|
/**
|
|
* Warning: EIP-1191 checksum addresses are generally not backwards compatible with the
|
|
* wider Ethereum ecosystem, meaning it will break when validated against an application/tool
|
|
* that relies on EIP-55 checksum encoding (checksum without chainId).
|
|
*
|
|
* It is highly recommended to not use this feature unless you
|
|
* know what you are doing.
|
|
*
|
|
* See more: https://github.com/ethereum/EIPs/issues/1121
|
|
*/
|
|
chainId?: number,
|
|
): Address {
|
|
if (!isAddress(address, { strict: false }))
|
|
throw new InvalidAddressError({ address })
|
|
return checksumAddress(address, chainId)
|
|
}
|