@lodestar/types
Version:
Typescript types required for lodestar
40 lines • 1.47 kB
JavaScript
import { ByteVectorType } from "@chainsafe/ssz";
import { keccak256 } from "ethereum-cryptography/keccak.js";
export class ExecutionAddressType extends ByteVectorType {
constructor() {
super(20, { typeName: "ExecutionAddress" });
}
toJson(value) {
const str = super.toJson(value);
return toChecksumAddress(str);
}
}
function isAddressValid(address) {
return /^(0x)?[0-9a-f]{40}$/i.test(address);
}
/**
* Formats an address according to [ERC55](https://eips.ethereum.org/EIPS/eip-55)
*/
export function toChecksumAddress(address) {
if (!isAddressValid(address)) {
throw Error(`Invalid address: ${address}`);
}
const rawAddress = (address.startsWith("0x") ? address.slice(2) : address).toLowerCase();
const chars = rawAddress.split("");
// Inspired by https://github.com/ethers-io/ethers.js/blob/cac1da1f912c2ae9ba20f25aa51a91766673cd76/src.ts/address/address.ts#L8
const expanded = new Uint8Array(chars.length);
for (let i = 0; i < expanded.length; i++) {
expanded[i] = rawAddress[i].charCodeAt(0);
}
const hashed = keccak256(expanded);
for (let i = 0; i < chars.length; i += 2) {
if (hashed[i >> 1] >> 4 >= 8) {
chars[i] = chars[i].toUpperCase();
}
if ((hashed[i >> 1] & 0x0f) >= 8) {
chars[i + 1] = chars[i + 1].toUpperCase();
}
}
return "0x" + chars.join("");
}
//# sourceMappingURL=executionAddress.js.map