/* 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 . */ import { ValidInputTypes } from '../types.js'; import { parseBaseType, hexToNumber } from '../utils.js'; import { isHexStrict } from './string.js'; /** * Checks if a given value is a valid big int */ export const isBigInt = (value: ValidInputTypes): boolean => typeof value === 'bigint'; // Note: this could be simplified using ** operator, but babel does not handle it well // you can find more at: https://github.com/babel/babel/issues/13109 and https://github.com/web3/web3.js/issues/6187 /** @internal */ export const bigintPower = (base: bigint, expo: bigint) => { let res = base; for (let index = 1; index < expo; index += 1) { res *= base; } return res; }; export const isUInt = ( value: ValidInputTypes, options: { abiType: string; bitSize?: never } | { bitSize: number; abiType?: never } = { abiType: 'uint', }, ) => { if ( !['number', 'string', 'bigint'].includes(typeof value) || (typeof value === 'string' && value.length === 0) ) { return false; } let size!: number; if (options?.abiType) { const { baseTypeSize } = parseBaseType(options.abiType); if (baseTypeSize) { size = baseTypeSize; } } else if (options.bitSize) { size = options.bitSize; } const maxSize = bigintPower(BigInt(2), BigInt(size ?? 256)) - BigInt(1); try { const valueToCheck = typeof value === 'string' && isHexStrict(value) ? BigInt(hexToNumber(value)) : BigInt(value as number); return valueToCheck >= 0 && valueToCheck <= maxSize; } catch (error) { // Some invalid number value given which can not be converted via BigInt return false; } }; export const isInt = ( value: ValidInputTypes, options: { abiType: string; bitSize?: never } | { bitSize: number; abiType?: never } = { abiType: 'int', }, ) => { if (!['number', 'string', 'bigint'].includes(typeof value)) { return false; } if (typeof value === 'number' && value > Number.MAX_SAFE_INTEGER) { return false; } let size!: number; if (options?.abiType) { const { baseTypeSize, baseType } = parseBaseType(options.abiType); if (baseType !== 'int') { return false; } if (baseTypeSize) { size = baseTypeSize; } } else if (options.bitSize) { size = options.bitSize; } const maxSize = bigintPower(BigInt(2), BigInt((size ?? 256) - 1)); const minSize = BigInt(-1) * bigintPower(BigInt(2), BigInt((size ?? 256) - 1)); try { const valueToCheck = typeof value === 'string' && isHexStrict(value) ? BigInt(hexToNumber(value)) : BigInt(value as number); return valueToCheck >= minSize && valueToCheck <= maxSize; } catch (error) { // Some invalid number value given which can not be converted via BigInt return false; } }; export const isNumber = (value: ValidInputTypes) => { if (isInt(value)) { return true; } // It would be a decimal number if ( typeof value === 'string' && /[0-9.]/.test(value) && value.indexOf('.') === value.lastIndexOf('.') ) { return true; } if (typeof value === 'number') { return true; } return false; };