diff --git a/package-lock.json b/package-lock.json index 0dc4c2d8..b5a96b1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1331,14 +1331,6 @@ "safer-buffer": "^2.1.0" } }, - "eip55": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/eip55/-/eip55-1.0.3.tgz", - "integrity": "sha512-x1p4OJNlt0G3mPPZx9GgwOaLFvz8Wd4VFpkx3iNzW4SrakFnjjO4mDdmAJpETxJZp9SlNB4UFqDuFhElnX9K/Q==", - "requires": { - "keccak": "^1.3.0" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -4216,6 +4208,14 @@ } } }, + "rskjs-util": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rskjs-util/-/rskjs-util-1.0.3.tgz", + "integrity": "sha512-Q6zfYFQndaBln1iY2gnBfYgDLymbZHAxKXOcZVLAKJkHilcieoUN3ZXVxLA3K30KlgAfmRVG72iTzi+yPNZB1w==", + "requires": { + "keccak": "^1.0.2" + } + }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", diff --git a/package.json b/package.json index b02ae2b4..bb6463c7 100644 --- a/package.json +++ b/package.json @@ -36,12 +36,11 @@ }, "dependencies": { "@types/cashaddrjs": "^0.3.0", - "base-x": "^3.0.7", "bech32": "^1.1.3", "bs58check": "^2.1.2", "cashaddrjs": "^0.3.8", - "eip55": "^1.0.3", "ripple-address-codec": "^4.0.0", + "rskjs-util": "^1.0.3", "safe-buffer": "^5.2.0" } } diff --git a/src/@types/eip55/index.d.ts b/src/@types/eip55/index.d.ts deleted file mode 100644 index 8c1ebca4..00000000 --- a/src/@types/eip55/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'eip55' { - export function encode(data: string): string; - export function verify(data: string): boolean; -} diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 0bf4f2ce..f90eddcc 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -69,7 +69,17 @@ const vectors: Array = [ name: 'RSK', coinType: 137, passingVectors: [ - { text: '0x314159265dD8dbb310642f98f50C066173C1259b', hex: '314159265dd8dbb310642f98f50c066173c1259b' }, + { text: '0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD', hex: '5aaeb6053f3e94c9b9a09f33669435e7ef1beaed' }, + { + text: '0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed', + hex: '5aaeb6053f3e94c9b9a09f33669435e7ef1beaed', + canonical: '0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD', + }, + { + text: '0x5AAEB6053F3E94C9B9A09F33669435E7EF1BEAED', + hex: '5aaeb6053f3e94c9b9a09f33669435e7ef1beaed', + canonical: '0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD', + }, ], }, { diff --git a/src/index.ts b/src/index.ts index 543bf3ec..825d37e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,8 @@ import * as bech32 from 'bech32'; import * as bs58check from 'bs58check'; import * as cashaddr from 'cashaddrjs'; -import * as eip55 from 'eip55'; import * as ripple from 'ripple-address-codec'; +import * as rsk from 'rskjs-util'; interface IFormat { coinType: number; @@ -163,18 +163,28 @@ function decodeBitcoinCash(data: string): Buffer { } } -function encodeChecksummedHex(data: Buffer): string { - return eip55.encode('0x' + data.toString('hex')); +function makeChecksummedHexEncoder(chainId?: number) { + return (data: Buffer) => rsk.toChecksumAddress(data.toString('hex'), chainId || null); } -function decodeChecksummedHex(data: string): Buffer { - return Buffer.from(data.slice(2), 'hex'); +function makeChecksummedHexDecoder(chainId?: number) { + return (data: string) => { + const stripped = rsk.stripHexPrefix(data); + if ( + !rsk.isValidChecksumAddress(data, chainId || null) && + stripped !== stripped.toLowerCase() && + stripped !== stripped.toUpperCase() + ) { + throw Error('Invalid address checksum'); + } + return Buffer.from(rsk.stripHexPrefix(data), 'hex'); + }; } -const hexChecksumChain = (name: string, coinType: number) => ({ +const hexChecksumChain = (name: string, coinType: number, chainId?: number) => ({ coinType, - decoder: decodeChecksummedHex, - encoder: encodeChecksummedHex, + decoder: makeChecksummedHexDecoder(chainId), + encoder: makeChecksummedHexEncoder(chainId), name, }); @@ -185,7 +195,7 @@ const formats: IFormat[] = [ base58Chain('MONA', 22, [0x32], [0x05]), hexChecksumChain('ETH', 60), hexChecksumChain('ETC', 61), - hexChecksumChain('RSK', 137), + hexChecksumChain('RSK', 137, 30), { coinType: 144, decoder: (data: string) => ripple.codec.decodeChecked(data),