create safer isValidAddress method (#11089)
parent
761288b18f
commit
8254213b9c
@ -0,0 +1,53 @@ |
||||
import { |
||||
isHexString, |
||||
isValidAddress, |
||||
isValidChecksumAddress, |
||||
addHexPrefix, |
||||
} from 'ethereumjs-util'; |
||||
|
||||
export const BURN_ADDRESS = '0x0000000000000000000000000000000000000000'; |
||||
|
||||
export function isBurnAddress(address) { |
||||
return address === BURN_ADDRESS; |
||||
} |
||||
|
||||
/** |
||||
* Validates that the input is a hex address. This utility method is a thin |
||||
* wrapper around ethereumjs-util.isValidAddress, with the exception that it |
||||
* does not throw an error when provided values that are not hex strings. In |
||||
* addition, and by default, this method will return true for hex strings that |
||||
* meet the length requirement of a hex address, but are not prefixed with `0x` |
||||
* Finally, if the mixedCaseUseChecksum flag is true and a mixed case string is |
||||
* provided this method will validate it has the proper checksum formatting. |
||||
* @param {string} possibleAddress - Input parameter to check against |
||||
* @param {Object} [options] - options bag |
||||
* @param {boolean} [options.allowNonPrefixed] - If true will first ensure '0x' |
||||
* is prepended to the string |
||||
* @param {boolean} [options.mixedCaseUseChecksum] - If true will treat mixed |
||||
* case addresses as checksum addresses and validate that proper checksum |
||||
* format is used |
||||
* @returns {boolean} whether or not the input is a valid hex address |
||||
*/ |
||||
export function isValidHexAddress( |
||||
possibleAddress, |
||||
{ allowNonPrefixed = true, mixedCaseUseChecksum = false } = {}, |
||||
) { |
||||
const addressToCheck = allowNonPrefixed |
||||
? addHexPrefix(possibleAddress) |
||||
: possibleAddress; |
||||
if (!isHexString(addressToCheck)) { |
||||
return false; |
||||
} |
||||
|
||||
if (mixedCaseUseChecksum) { |
||||
const prefixRemoved = addressToCheck.slice(2); |
||||
const lower = prefixRemoved.toLowerCase(); |
||||
const upper = prefixRemoved.toUpperCase(); |
||||
const allOneCase = prefixRemoved === lower || prefixRemoved === upper; |
||||
if (!allOneCase) { |
||||
return isValidChecksumAddress(addressToCheck); |
||||
} |
||||
} |
||||
|
||||
return isValidAddress(addressToCheck); |
||||
} |
@ -0,0 +1,57 @@ |
||||
import { strict as assert } from 'assert'; |
||||
import { toChecksumAddress } from 'ethereumjs-util'; |
||||
import { isValidHexAddress } from './hexstring-utils'; |
||||
|
||||
describe('hexstring utils', function () { |
||||
describe('isValidHexAddress', function () { |
||||
it('should allow 40-char non-prefixed hex', function () { |
||||
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825'; |
||||
const result = isValidHexAddress(address); |
||||
assert.equal(result, true); |
||||
}); |
||||
|
||||
it('should allow 42-char prefixed hex', function () { |
||||
const address = '0xfdea65c8e26263f6d9a1b5de9555d2931a33b825'; |
||||
const result = isValidHexAddress(address); |
||||
assert.equal(result, true); |
||||
}); |
||||
|
||||
it('should NOT allow 40-char non-prefixed hex when allowNonPrefixed is false', function () { |
||||
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b825'; |
||||
const result = isValidHexAddress(address, { allowNonPrefixed: false }); |
||||
assert.equal(result, false); |
||||
}); |
||||
|
||||
it('should NOT allow any length of non hex-prefixed string', function () { |
||||
const address = 'fdea65c8e26263f6d9a1b5de9555d2931a33b85'; |
||||
const result = isValidHexAddress(address); |
||||
assert.equal(result, false); |
||||
}); |
||||
|
||||
it('should NOT allow less than 42 character hex-prefixed string', function () { |
||||
const address = '0xfdea65ce26263f6d9a1b5de9555d2931a33b85'; |
||||
const result = isValidHexAddress(address); |
||||
assert.equal(result, false); |
||||
}); |
||||
|
||||
it('should recognize correct capitalized checksum', function () { |
||||
const address = '0xFDEa65C8e26263F6d9A1B5de9555D2931A33b825'; |
||||
const result = isValidHexAddress(address, { mixedCaseUseChecksum: true }); |
||||
assert.equal(result, true); |
||||
}); |
||||
|
||||
it('should recognize incorrect capitalized checksum', function () { |
||||
const address = '0xFDea65C8e26263F6d9A1B5de9555D2931A33b825'; |
||||
const result = isValidHexAddress(address, { mixedCaseUseChecksum: true }); |
||||
assert.equal(result, false); |
||||
}); |
||||
|
||||
it('should recognize this sample hashed address', function () { |
||||
const address = '0x5Fda30Bb72B8Dfe20e48A00dFc108d0915BE9Bb0'; |
||||
const result = isValidHexAddress(address, { mixedCaseUseChecksum: true }); |
||||
const hashed = toChecksumAddress(address.toLowerCase()); |
||||
assert.equal(hashed, address); |
||||
assert.equal(result, true); |
||||
}); |
||||
}); |
||||
}); |
Loading…
Reference in new issue