Skip to content

Commit b83daf4

Browse files
committed
fix ethereum starship test errors
1 parent af9a509 commit b83daf4

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/** @type {import('ts-jest').JestConfigWithTsJest} */
2+
module.exports = {
3+
testTimeout: 15000,
4+
preset: 'ts-jest',
5+
testEnvironment: 'node',
6+
transform: {
7+
'^.+\\.tsx?$': [
8+
'ts-jest',
9+
{
10+
babelConfig: false,
11+
tsconfig: 'tsconfig.json',
12+
},
13+
],
14+
},
15+
transformIgnorePatterns: [`/node_modules/*`],
16+
modulePathIgnorePatterns: ['<rootDir>/dist/'],
17+
testRegex: '/starship/__tests__/.*\\.(test|spec)\\.(jsx?|tsx?)$',
18+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
19+
};
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { toHex, fromHex } from '@interchainjs/utils';
2+
import { keccak_256 } from '@noble/hashes/sha3';
3+
4+
/**
5+
* EIP-55 checksum implementation
6+
*/
7+
function toEIP55Checksum(address: string): string {
8+
const addr = address.toLowerCase().replace('0x', '');
9+
const hash = toHex(keccak_256(Buffer.from(addr, 'utf8')));
10+
11+
let checksumAddress = '0x';
12+
for (let i = 0; i < addr.length; i++) {
13+
if (parseInt(hash[i], 16) >= 8) {
14+
checksumAddress += addr[i].toUpperCase();
15+
} else {
16+
checksumAddress += addr[i];
17+
}
18+
}
19+
return checksumAddress;
20+
}
21+
22+
/**
23+
* Validate Ethereum address format and checksum
24+
*/
25+
export function isValidEthereumAddress(address: string): boolean {
26+
// Check basic format - accept both 0x and 0X prefixes
27+
if ((!address.startsWith('0x') && !address.startsWith('0X')) || address.length !== 42) {
28+
return false;
29+
}
30+
31+
// Check if it's a valid hex string
32+
const hex = address.slice(2);
33+
if (!/^[a-fA-F0-9]{40}$/.test(hex)) {
34+
return false;
35+
}
36+
37+
// If it's all lowercase or all uppercase, it's valid (no checksum)
38+
if (hex === hex.toLowerCase() || hex === hex.toUpperCase()) {
39+
return true;
40+
}
41+
42+
// If it has mixed case, validate the checksum
43+
try {
44+
// Normalize to lowercase 0x prefix for checksum validation
45+
const normalizedAddress = '0x' + hex.toLowerCase();
46+
const expectedChecksum = toEIP55Checksum(normalizedAddress);
47+
return '0x' + hex === expectedChecksum;
48+
} catch {
49+
return false;
50+
}
51+
}
52+
53+
/**
54+
* Convert an Ethereum address to its checksummed version
55+
*/
56+
export function toChecksumAddress(address: string): string {
57+
if (!address.startsWith('0x') || address.length !== 42) {
58+
throw new Error('Invalid Ethereum address format');
59+
}
60+
61+
const hex = address.slice(2);
62+
if (!/^[a-fA-F0-9]{40}$/.test(hex)) {
63+
throw new Error('Invalid Ethereum address format');
64+
}
65+
66+
return toEIP55Checksum(address.toLowerCase());
67+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { fromUtf8, toUtf8, fromHex, toHex } from '@interchainjs/utils';
2+
3+
/**
4+
* Convert a UTF-8 string to hex (without 0x prefix)
5+
*/
6+
export function utf8ToHex(str: string): string {
7+
const bytes = fromUtf8(str);
8+
return toHex(bytes);
9+
}
10+
11+
/**
12+
* Convert a hex string to UTF-8 string
13+
*/
14+
export function hexToUtf8(hex: string): string {
15+
// Remove 0x prefix if present
16+
const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;
17+
18+
// Validate hex string
19+
if (!/^[a-fA-F0-9]*$/.test(cleanHex)) {
20+
throw new Error(`Invalid hex string: ${hex}`);
21+
}
22+
23+
// Ensure even length
24+
if (cleanHex.length % 2 !== 0) {
25+
throw new Error(`Invalid hex string: ${hex}`);
26+
}
27+
28+
const bytes = fromHex(cleanHex);
29+
return toUtf8(bytes);
30+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export * from './ContractEncoder';
2+
export * from './address';
3+
export * from './encoding';

0 commit comments

Comments
 (0)