From 1115aae1a092d6edbdb50099b7bcc011ade2c927 Mon Sep 17 00:00:00 2001 From: Krasimir Raykov Date: Wed, 25 May 2022 11:04:18 +0300 Subject: [PATCH] fix: hex values with 0x prefix are valid (#87) * fix: hex values with 0x prefix are valid * feat: two types of hex validation * fix: unit tests * fix: 0x is required for evm chains --- src/chains.ts | 23 ++++++++++++----------- src/common.ts | 3 ++- tests/chains/avalanche.test.ts | 5 ++++- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/chains.ts b/src/chains.ts index e0fcf7c9d..1b006e38a 100644 --- a/src/chains.ts +++ b/src/chains.ts @@ -8,13 +8,14 @@ import { isValidSolanaAddress, isValidBitcoinCashAddress, formatBitcoinCashAddress, - isValidHex, + isValidHexWithout0xPrefix, isValidSolanaTx, toLowerCaseWithout0x, with0x, isValidTerraAddress, isValidTerraTx, - getRSKChainID + getRSKChainID, + isValidHexWith0xPrefix } from './common' const chains: { [key in ChainId]: Chain } = { @@ -33,7 +34,7 @@ const chains: { [key in ChainId]: Chain } = { // TODO: include network types in validation isValidAddress: (address) => !!validateBitcoinAddress(address), formatAddress: (address) => address, - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWithout0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.BitcoinCash]: { @@ -51,7 +52,7 @@ const chains: { [key in ChainId]: Chain } = { // TODO: include network types in validation isValidAddress: (address) => isValidBitcoinCashAddress(address), formatAddress: (address) => formatBitcoinCashAddress(address), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWithout0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.Ethereum]: { @@ -68,7 +69,7 @@ const chains: { [key in ChainId]: Chain } = { hasTokens: true, isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string) => toChecksumAddress(with0x(hexAddress)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.Rootstock]: { @@ -86,7 +87,7 @@ const chains: { [key in ChainId]: Chain } = { isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string, network?: string) => toChecksumAddress(with0x(hexAddress), getRSKChainID(network)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.BinanceSmartChain]: { @@ -103,7 +104,7 @@ const chains: { [key in ChainId]: Chain } = { hasTokens: true, isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string) => toChecksumAddress(with0x(hexAddress)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.Near]: { @@ -171,7 +172,7 @@ const chains: { [key in ChainId]: Chain } = { hasTokens: true, isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string) => toChecksumAddress(with0x(hexAddress)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.Arbitrum]: { @@ -188,7 +189,7 @@ const chains: { [key in ChainId]: Chain } = { hasTokens: true, isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string) => toChecksumAddress(with0x(hexAddress)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.Fuse]: { @@ -205,7 +206,7 @@ const chains: { [key in ChainId]: Chain } = { hasTokens: true, isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string) => toChecksumAddress(with0x(hexAddress)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => toLowerCaseWithout0x(hash) }, [ChainId.Avalanche]: { @@ -222,7 +223,7 @@ const chains: { [key in ChainId]: Chain } = { hasTokens: true, isValidAddress: (hexAddress: string) => isValidAddress(with0x(hexAddress)), formatAddress: (hexAddress: string) => toChecksumAddress(with0x(hexAddress)), - isValidTransactionHash: (hash: string) => isValidHex(hash), + isValidTransactionHash: (hash: string) => isValidHexWith0xPrefix(hash), formatTransactionHash: (hash: string) => hash } } diff --git a/src/common.ts b/src/common.ts index f9a419c42..62e511e54 100644 --- a/src/common.ts +++ b/src/common.ts @@ -3,7 +3,8 @@ import * as cashaddr from 'cashaddrjs' const BASE58_LENGTH = 32 -export const isValidHex = (hash: string) => /^([A-Fa-f0-9]{64})$/.test(hash) +export const isValidHexWith0xPrefix = (hash: string) => /(0x)([A-Fa-f0-9]{64})$/.test(hash) +export const isValidHexWithout0xPrefix = (hash: string) => /^([A-Fa-f0-9]{64})$/.test(hash) export const toLowerCaseWithout0x = (hash: string) => hash.toLowerCase().replace(/0x/g, '') export const with0x = (hash: string) => (hash.startsWith('0x') ? hash : '0x' + hash) diff --git a/tests/chains/avalanche.test.ts b/tests/chains/avalanche.test.ts index d4bf85aa2..c9b81ef6e 100644 --- a/tests/chains/avalanche.test.ts +++ b/tests/chains/avalanche.test.ts @@ -59,9 +59,12 @@ describe('Avalanche chain tests', function () { }) it('Provides correct tx validation', () => { - const validTxHash = 'b4ec649426ba04cd0407d5929288ff3d59d8baca9b810cf4147620bab6dadba3' + const validTxHash = '0xb4ec649426ba04cd0407d5929288ff3d59d8baca9b810cf4147620bab6dadba3' expect(avalanche.isValidTransactionHash(validTxHash)).to.be.true + const invalidTxHashWithout0x = 'b4ec649426ba04cd0407d5929288ff3d59d8baca9b810cf4147620bab6dadba3' + expect(avalanche.isValidTransactionHash(invalidTxHashWithout0x)).to.be.false + const validTxHashInvalidSigner = '8pRdygzR8Zk9oMYmqiyzUpqJQnFmaAnMLniexycNLavr_9eed84cfc2ac0068dd8fc10b8b3b71c8d0f74cfd09211e036bdb8561c264747' expect(avalanche.isValidTransactionHash(validTxHashInvalidSigner)).to.be.false