Viewing File: /home/ubuntu/vedadeals-frontend-base/node_modules/web3-utils/lib/utils.js

/*
 This file is part of web3.js.

 web3.js is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 web3.js is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * @file utils.js
 * @author Fabian Vogelsteller <fabian@ethereum.org>
 * @date 2017
 */
var BN = require('bn.js');
var numberToBN = require('number-to-bn');
var utf8 = require('utf8');
var ethereumjsUtil = require('ethereumjs-util');
var ethereumBloomFilters = require('ethereum-bloom-filters');
/**
 * Returns true if object is BN, otherwise false
 *
 * @method isBN
 * @param {Object} object
 * @return {Boolean}
 */
var isBN = function (object) {
    return BN.isBN(object);
};
/**
 * Returns true if object is BigNumber, otherwise false
 *
 * @method isBigNumber
 * @param {Object} object
 * @return {Boolean}
 */
var isBigNumber = function (object) {
    return object && object.constructor && object.constructor.name === 'BigNumber';
};
/**
 * Takes an input and transforms it into an BN
 *
 * @method toBN
 * @param {Number|String|BN} number, string, HEX string or BN
 * @return {BN} BN
 */
var toBN = function (number) {
    try {
        return numberToBN.apply(null, arguments);
    }
    catch (e) {
        throw new Error(e + ' Given value: "' + number + '"');
    }
};
/**
 * Takes and input transforms it into BN and if it is negative value, into two's complement
 *
 * @method toTwosComplement
 * @param {Number|String|BN} number
 * @return {String}
 */
var toTwosComplement = function (number) {
    return '0x' + toBN(number).toTwos(256).toString(16, 64);
};
/**
 * Checks if the given string is an address
 *
 * @method isAddress
 * @param {String} address the given HEX address
 * @return {Boolean}
 */
var isAddress = function (address) {
    // check if it has the basic requirements of an address
    if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
        return false;
        // If it's ALL lowercase or ALL upppercase
    }
    else if (/^(0x|0X)?[0-9a-f]{40}$/.test(address) || /^(0x|0X)?[0-9A-F]{40}$/.test(address)) {
        return true;
        // Otherwise check each case
    }
    else {
        return checkAddressChecksum(address);
    }
};
/**
 * Checks if the given string is a checksummed address
 *
 * @method checkAddressChecksum
 * @param {String} address the given HEX address
 * @return {Boolean}
 */
var checkAddressChecksum = function (address) {
    // Check each case
    address = address.replace(/^0x/i, '');
    var addressHash = sha3(address.toLowerCase()).replace(/^0x/i, '');
    for (var i = 0; i < 40; i++) {
        // the nth letter should be uppercase if the nth digit of casemap is 1
        if ((parseInt(addressHash[i], 16) > 7 && address[i].toUpperCase() !== address[i]) || (parseInt(addressHash[i], 16) <= 7 && address[i].toLowerCase() !== address[i])) {
            return false;
        }
    }
    return true;
};
/**
 * Should be called to pad string to expected length
 *
 * @method leftPad
 * @param {String} string to be padded
 * @param {Number} chars that result string should have
 * @param {String} sign, by default 0
 * @returns {String} right aligned string
 */
var leftPad = function (string, chars, sign) {
    var hasPrefix = /^0x/i.test(string) || typeof string === 'number';
    string = string.toString(16).replace(/^0x/i, '');
    var padding = (chars - string.length + 1 >= 0) ? chars - string.length + 1 : 0;
    return (hasPrefix ? '0x' : '') + new Array(padding).join(sign ? sign : "0") + string;
};
/**
 * Should be called to pad string to expected length
 *
 * @method rightPad
 * @param {String} string to be padded
 * @param {Number} chars that result string should have
 * @param {String} sign, by default 0
 * @returns {String} right aligned string
 */
var rightPad = function (string, chars, sign) {
    var hasPrefix = /^0x/i.test(string) || typeof string === 'number';
    string = string.toString(16).replace(/^0x/i, '');
    var padding = (chars - string.length + 1 >= 0) ? chars - string.length + 1 : 0;
    return (hasPrefix ? '0x' : '') + string + (new Array(padding).join(sign ? sign : "0"));
};
/**
 * Should be called to get hex representation (prefixed by 0x) of utf8 string
 *
 * @method utf8ToHex
 * @param {String} str
 * @returns {String} hex representation of input string
 */
var utf8ToHex = function (str) {
    str = utf8.encode(str);
    var hex = "";
    // remove \u0000 padding from either side
    str = str.replace(/^(?:\u0000)*/, '');
    str = str.split("").reverse().join("");
    str = str.replace(/^(?:\u0000)*/, '');
    str = str.split("").reverse().join("");
    for (var i = 0; i < str.length; i++) {
        var code = str.charCodeAt(i);
        // if (code !== 0) {
        var n = code.toString(16);
        hex += n.length < 2 ? '0' + n : n;
        // }
    }
    return "0x" + hex;
};
/**
 * Should be called to get utf8 from it's hex representation
 *
 * @method hexToUtf8
 * @param {String} hex
 * @returns {String} ascii string representation of hex value
 */
var hexToUtf8 = function (hex) {
    if (!isHexStrict(hex))
        throw new Error('The parameter "' + hex + '" must be a valid HEX string.');
    var str = "";
    var code = 0;
    hex = hex.replace(/^0x/i, '');
    // remove 00 padding from either side
    hex = hex.replace(/^(?:00)*/, '');
    hex = hex.split("").reverse().join("");
    hex = hex.replace(/^(?:00)*/, '');
    hex = hex.split("").reverse().join("");
    var l = hex.length;
    for (var i = 0; i < l; i += 2) {
        code = parseInt(hex.slice(i, i + 2), 16);
        // if (code !== 0) {
        str += String.fromCharCode(code);
        // }
    }
    return utf8.decode(str);
};
/**
 * Converts value to it's number representation
 *
 * @method hexToNumber
 * @param {String|Number|BN} value
 * @return {String}
 */
var hexToNumber = function (value) {
    if (!value) {
        return value;
    }
    if (typeof value === 'string' && !isHexStrict(value)) {
        throw new Error('Given value "' + value + '" is not a valid hex string.');
    }
    return toBN(value).toNumber();
};
/**
 * Converts value to it's decimal representation in string
 *
 * @method hexToNumberString
 * @param {String|Number|BN} value
 * @return {String}
 */
var hexToNumberString = function (value) {
    if (!value)
        return value;
    if (typeof value === 'string' && !isHexStrict(value)) {
        throw new Error('Given value "' + value + '" is not a valid hex string.');
    }
    return toBN(value).toString(10);
};
/**
 * Converts value to it's hex representation
 *
 * @method numberToHex
 * @param {String|Number|BN} value
 * @return {String}
 */
var numberToHex = function (value) {
    if ((value === null || value === undefined)) {
        return value;
    }
    if (!isFinite(value) && !isHexStrict(value)) {
        throw new Error('Given input "' + value + '" is not a number.');
    }
    var number = toBN(value);
    var result = number.toString(16);
    return number.lt(new BN(0)) ? '-0x' + result.slice(1) : '0x' + result;
};
/**
 * Convert a byte array to a hex string
 *
 * Note: Implementation from crypto-js
 *
 * @method bytesToHex
 * @param {Array} bytes
 * @return {String} the hex string
 */
var bytesToHex = function (bytes) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        /* jshint ignore:start */
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
        /* jshint ignore:end */
    }
    return '0x' + hex.join("");
};
/**
 * Convert a hex string to a byte array
 *
 * Note: Implementation from crypto-js
 *
 * @method hexToBytes
 * @param {string} hex
 * @return {Array} the byte array
 */
var hexToBytes = function (hex) {
    hex = hex.toString(16);
    if (!isHexStrict(hex)) {
        throw new Error('Given value "' + hex + '" is not a valid hex string.');
    }
    hex = hex.replace(/^0x/i, '');
    for (var bytes = [], c = 0; c < hex.length; c += 2)
        bytes.push(parseInt(hex.slice(c, c + 2), 16));
    return bytes;
};
/**
 * Auto converts any given value into it's hex representation.
 *
 * And even stringifys objects before.
 *
 * @method toHex
 * @param {String|Number|BN|Object|Buffer} value
 * @param {Boolean} returnType
 * @return {String}
 */
var toHex = function (value, returnType) {
    /*jshint maxcomplexity: false */
    if (isAddress(value)) {
        return returnType ? 'address' : '0x' + value.toLowerCase().replace(/^0x/i, '');
    }
    if (typeof value === 'boolean') {
        return returnType ? 'bool' : value ? '0x01' : '0x00';
    }
    if (Buffer.isBuffer(value)) {
        return '0x' + value.toString('hex');
    }
    if (typeof value === 'object' && !!value && !isBigNumber(value) && !isBN(value)) {
        return returnType ? 'string' : utf8ToHex(JSON.stringify(value));
    }
    // if its a negative number, pass it through numberToHex
    if (typeof value === 'string') {
        if (value.indexOf('-0x') === 0 || value.indexOf('-0X') === 0) {
            return returnType ? 'int256' : numberToHex(value);
        }
        else if (value.indexOf('0x') === 0 || value.indexOf('0X') === 0) {
            return returnType ? 'bytes' : value;
        }
        else if (!isFinite(value)) {
            return returnType ? 'string' : utf8ToHex(value);
        }
    }
    return returnType ? (value < 0 ? 'int256' : 'uint256') : numberToHex(value);
};
/**
 * Check if string is HEX, requires a 0x in front
 *
 * @method isHexStrict
 * @param {String} hex to be checked
 * @returns {Boolean}
 */
var isHexStrict = function (hex) {
    return ((typeof hex === 'string' || typeof hex === 'number') && /^(-)?0x[0-9a-f]*$/i.test(hex));
};
/**
 * Check if string is HEX
 *
 * @method isHex
 * @param {String} hex to be checked
 * @returns {Boolean}
 */
var isHex = function (hex) {
    return ((typeof hex === 'string' || typeof hex === 'number') && /^(-0x|0x)?[0-9a-f]*$/i.test(hex));
};
/**
 * Remove 0x prefix from string
 *
 * @method stripHexPrefix
 * @param {String} str to be checked
 * @returns {String}
 */
var stripHexPrefix = function (str) {
    if (str !== 0 && isHex(str))
        return str.replace(/^(-)?0x/i, '$1');
    return str;
};
/**
 * Returns true if given string is a valid Ethereum block header bloom.
 *
 * @method isBloom
 * @param {String} bloom encoded bloom filter
 * @return {Boolean}
 */
var isBloom = function (bloom) {
    return ethereumBloomFilters.isBloom(bloom);
};
/**
 * Returns true if the ethereum users address is part of the given bloom
 * note: false positives are possible.
 *
 * @method isUserEthereumAddressInBloom
 * @param {String} ethereumAddress encoded bloom filter
 * @param {String} bloom ethereum addresss
 * @return {Boolean}
 */
var isUserEthereumAddressInBloom = function (bloom, ethereumAddress) {
    return ethereumBloomFilters.isUserEthereumAddressInBloom(bloom, ethereumAddress);
};
/**
 * Returns true if the contract address is part of the given bloom
 * note: false positives are possible.
 *
 * @method isUserEthereumAddressInBloom
 * @param {String} bloom encoded bloom filter
 * @param {String} contractAddress contract addresss
 * @return {Boolean}
 */
var isContractAddressInBloom = function (bloom, contractAddress) {
    return ethereumBloomFilters.isContractAddressInBloom(bloom, contractAddress);
};
/**
 * Returns true if given string is a valid log topic.
 *
 * @method isTopic
 * @param {String} topic encoded topic
 * @return {Boolean}
 */
var isTopic = function (topic) {
    return ethereumBloomFilters.isTopic(topic);
};
/**
 * Returns true if the topic is part of the given bloom
 * note: false positives are possible.
 *
 * @method isTopicInBloom
 * @param {String} bloom encoded bloom filter
 * @param {String} topic encoded topic
 * @return {Boolean}
 */
var isTopicInBloom = function (bloom, topic) {
    return ethereumBloomFilters.isTopicInBloom(bloom, topic);
};
/**
 * Returns true if the value is part of the given bloom
 * note: false positives are possible.
 *
 * @method isInBloom
 * @param {String} bloom encoded bloom filter
 * @param {String | Uint8Array} topic encoded value
 * @return {Boolean}
 */
var isInBloom = function (bloom, topic) {
    return ethereumBloomFilters.isInBloom(bloom, topic);
};
/**
 * Hashes values to a sha3 hash using keccak 256
 *
 * To hash a HEX string the hex must have 0x in front.
 *
 * @method sha3
 * @return {String} the sha3 string
 */
var SHA3_NULL_S = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470';
var sha3 = function (value) {
    if (isBN(value)) {
        value = value.toString();
    }
    if (isHexStrict(value) && /^0x/i.test((value).toString())) {
        value = ethereumjsUtil.toBuffer(value);
    }
    else if (typeof value === 'string') {
        // Assume value is an arbitrary string
        value = Buffer.from(value, 'utf-8');
    }
    var returnValue = ethereumjsUtil.bufferToHex(ethereumjsUtil.keccak256(value));
    if (returnValue === SHA3_NULL_S) {
        return null;
    }
    else {
        return returnValue;
    }
};
// expose the under the hood keccak256
sha3._Hash = ethereumjsUtil.keccak256;
/**
 * @method sha3Raw
 *
 * @param value
 *
 * @returns {string}
 */
var sha3Raw = function (value) {
    value = sha3(value);
    if (value === null) {
        return SHA3_NULL_S;
    }
    return value;
};
/**
 * Auto converts any given value into it's hex representation,
 * then converts hex to number.
 *
 * @method toNumber
 * @param {String|Number|BN} value
 * @return {Number}
 */
var toNumber = function (value) {
    return typeof value === 'number' ? value : hexToNumber(toHex(value));
};
// 1.x currently accepts 0x... strings, bn.js after update doesn't. it would be a breaking change
var BNwrapped = function (value) {
    // check negative
    if (typeof value == "string" && value.includes("0x")) {
        const [negative, hexValue] = value.toLocaleLowerCase().startsWith('-') ? ["-", value.slice(3)] : ["", value.slice(2)];
        return new BN(negative + hexValue, 16);
    }
    else {
        return new BN(value);
    }
};
Object.setPrototypeOf(BNwrapped, BN);
Object.setPrototypeOf(BNwrapped.prototype, BN.prototype);
module.exports = {
    BN: BNwrapped,
    isBN: isBN,
    isBigNumber: isBigNumber,
    toBN: toBN,
    isAddress: isAddress,
    isBloom: isBloom,
    isUserEthereumAddressInBloom: isUserEthereumAddressInBloom,
    isContractAddressInBloom: isContractAddressInBloom,
    isTopic: isTopic,
    isTopicInBloom: isTopicInBloom,
    isInBloom: isInBloom,
    checkAddressChecksum: checkAddressChecksum,
    utf8ToHex: utf8ToHex,
    hexToUtf8: hexToUtf8,
    hexToNumber: hexToNumber,
    hexToNumberString: hexToNumberString,
    numberToHex: numberToHex,
    toHex: toHex,
    hexToBytes: hexToBytes,
    bytesToHex: bytesToHex,
    isHex: isHex,
    isHexStrict: isHexStrict,
    stripHexPrefix: stripHexPrefix,
    leftPad: leftPad,
    rightPad: rightPad,
    toTwosComplement: toTwosComplement,
    sha3: sha3,
    sha3Raw: sha3Raw,
    toNumber: toNumber
};
Back to Directory File Manager