Skip to content

Commit

Permalink
feat: add ERC-55 support to ExecutionAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
jeluard committed Jan 25, 2024
1 parent 01d47b9 commit 304cd45
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 3 deletions.
3 changes: 2 additions & 1 deletion packages/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
"types": "lib/index.d.ts",
"dependencies": {
"@chainsafe/ssz": "^0.14.0",
"@lodestar/params": "^1.14.0"
"@lodestar/params": "^1.14.0",
"@lodestar/utils": "^1.14.0"
},
"keywords": [
"ethereum",
Expand Down
15 changes: 14 additions & 1 deletion packages/types/src/primitive/sszTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import {ByteVectorType, UintNumberType, UintBigintType, BooleanType} from "@chainsafe/ssz";
/* eslint-disable no-restricted-imports */
import {ByteArray} from "@chainsafe/ssz/lib/type/byteArray";
import {toChecksumAddress} from "@lodestar/utils";

export const Boolean = new BooleanType();
export const Byte = new UintNumberType(1);
Expand Down Expand Up @@ -54,11 +57,21 @@ export const Wei = UintBn256;
export const Root = new ByteVectorType(32);
export const BlobIndex = UintNum64;

export class ExecutionAddressType extends ByteVectorType {
constructor() {
super(20);
}
toJson(value: ByteArray): unknown {
const string = super.toJson(value) as string;
return toChecksumAddress(string);
}
}

export const Version = Bytes4;
export const DomainType = Bytes4;
export const ForkDigest = Bytes4;
export const BLSPubkey = Bytes48;
export const BLSSignature = Bytes96;
export const Domain = Bytes32;
export const ParticipationFlags = new UintNumberType(1, {setBitwiseOR: true});
export const ExecutionAddress = Bytes20;
export const ExecutionAddress = new ExecutionAddressType();
1 change: 1 addition & 0 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"bigint-buffer": "^1.1.5",
"case": "^1.6.3",
"chalk": "^5.2.0",
"ethereum-cryptography": "^1.2.0",
"js-yaml": "^4.1.0"
},
"devDependencies": {
Expand Down
24 changes: 23 additions & 1 deletion packages/utils/src/format.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {toHexString} from "./bytes.js";
import {keccak256} from "ethereum-cryptography/keccak.js";
import {fromHex, toHexString} from "./bytes.js";

/**
* Format bytes as `0x1234…1234`
Expand Down Expand Up @@ -27,3 +28,24 @@ export function truncBytes(root: Uint8Array | string): string {
const str = typeof root === "string" ? root : toHexString(root);
return str.slice(0, 14);
}

/**
* Formats an address according to [ERC55](https://eips.ethereum.org/EIPS/eip-55)
*
* @param address an hex address
* @returns an ERC55 formatted version of `address`
*/
export function toChecksumAddress(address: string): string {
const rawAddress = address.toLowerCase().startsWith("0x") ? address.slice(2) : address;
const bytes = fromHex(rawAddress);
const hash = toHexString(keccak256(bytes)).slice(2);
let checksumAddress = "0x";
for (let i = 0; i < rawAddress.length; i++) {
if (parseInt(hash[i], 16) >= 8) {
checksumAddress += rawAddress[i].toUpperCase();
} else {
checksumAddress += rawAddress[i];
}
}
return checksumAddress;
}
19 changes: 19 additions & 0 deletions packages/utils/test/unit/format.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {describe, it, expect} from "vitest";
import {toChecksumAddress} from "../../src/index.js";

describe("toChecksumAddress", () => {
it("should format address as ERC55", () => {
expect(toChecksumAddress("52908400098527886E0F7030069857D2E4169EE7")).toBe(
"0x52908400098527886E0F7030069857D2E4169EE7"
);
expect(toChecksumAddress("0x52908400098527886E0F7030069857D2E4169EE7")).toBe(
"0x52908400098527886E0F7030069857D2E4169EE7"
);
expect(toChecksumAddress("0xde709f2102306220921060314715629080e2fb77")).toBe(
"0xdE709F2102306220921060314715629080e2fB77"
);
expect(toChecksumAddress("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")).toBe(
"0x5AAEB6053F3E94C9b9A09F33669435E7Ef1BeAED"
);
});
});

0 comments on commit 304cd45

Please sign in to comment.