UNPKG

ether-unit-converter

Version:

The utility functions provide a conversation assortment of common utility functions, and can easily convert Wei to value and value to Wei without a round number.

193 lines (164 loc) 5.16 kB
/* Primary Attribution Richard Moore <ricmoo@me.com> https://github.com/ethers-io Note, Richard is a god of ether gods. Follow and respect him, and use Ethers.io! */ const BN = require('bn.js'); const numberToBN = require('number-to-bn'); const zero = new BN(0); const negative1 = new BN(-1); // complete ethereum unit map const unitMap = { 0: '0', // eslint-disable-line 1: '10', // eslint-disable-line 2: '100', // eslint-disable-line 3: '1000', // eslint-disable-line 4: '10000', // eslint-disable-line 5: '100000', // eslint-disable-line 6: '1000000', // eslint-disable-line 7: '10000000', // eslint-disable-line 8: '100000000', // eslint-disable-line 9: '1000000000', // eslint-disable-line 10: '10000000000', // eslint-disable-line 11: '100000000000', // eslint-disable-line 12: '1000000000000', // eslint-disable-line 13: '10000000000000', // eslint-disable-line 14: '100000000000000', // eslint-disable-line 15: '1000000000000000', // eslint-disable-line 16: '10000000000000000', // eslint-disable-line 17: '100000000000000000', // eslint-disable-line 18: '1000000000000000000', // eslint-disable-line 19: '10000000000000000000', // eslint-disable-line 20: '100000000000000000000', // eslint-disable-line 21: '1000000000000000000000', // eslint-disable-line 22: '10000000000000000000000', // eslint-disable-line 23: '100000000000000000000000', // eslint-disable-line 24: '1000000000000000000000000', // eslint-disable-line }; /** * Returns value of unit in Wei * * @method getValueOfUnit * @param {String} unit the unit to convert to, default ether * @returns {BigNumber} value of the unit (in Wei) * @throws error if the unit is not correct:w */ function getValueOfUnit(unitInput) { const unit = unitInput ? unitInput : 18; var unitValue = unitMap[unit]; // eslint-disable-line if (typeof unitValue !== 'string') { throw new Error( `[ethjs-unit] the unit provided ${unitInput} doesn't exists, please use the one of the following units ${JSON.stringify( unitMap, null, 2, )}`, ); } return new BN(unitValue, 10); } function numberToString(arg) { if (typeof arg === 'string') { if (!arg.match(/^-?[0-9.]+$/)) { throw new Error( `while converting number to string, invalid number value '${arg}', should be a number matching (^-?[0-9.]+).`, ); } return arg; } else if (typeof arg === 'number') { return String(arg); } else if ( typeof arg === 'object' && arg.toString && (arg.toTwos || arg.dividedToIntegerBy) ) { if (arg.toPrecision) { return String(arg.toPrecision()); } else { // eslint-disable-line return arg.toString(10); } } throw new Error( `while converting number to string, invalid number value '${arg}' type ${typeof arg}.`, ); } function fromWei(weiInput, unit, optionsInput) { var wei = numberToBN(weiInput); // eslint-disable-line var negative = wei.lt(zero); // eslint-disable-line const base = getValueOfUnit(unit); const baseLength = unitMap[unit].length - 1 || 1; const options = optionsInput || {}; if (negative) { wei = wei.mul(negative1); } var fraction = wei.mod(base).toString(10); // eslint-disable-line while (fraction.length < baseLength) { fraction = `0${fraction}`; } if (!options.pad) { fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1]; } var whole = wei.div(base).toString(10); // eslint-disable-line if (options.commify) { whole = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ','); } var value = `${whole}${fraction == '0' ? '' : `.${fraction}`}`; // eslint-disable-line if (negative) { value = `-${value}`; } return value; } function toWei(etherInput, unit) { var ether = numberToString(etherInput); // eslint-disable-line const base = getValueOfUnit(unit); const baseLength = unitMap[unit].length - 1 || 1; // Is it negative? var negative = ether.substring(0, 1) === '-'; // eslint-disable-line if (negative) { ether = ether.substring(1); } if (ether === '.') { throw new Error( `[ethjs-unit] while converting number ${etherInput} to wei, invalid value`, ); } // Split it into a whole and fractional part var comps = ether.split('.'); // eslint-disable-line if (comps.length > 2) { throw new Error( `[ethjs-unit] while converting number ${etherInput} to wei, too many decimal points`, ); } var whole = comps[0], fraction = comps[1]; // eslint-disable-line if (!whole) { whole = '0'; } if (!fraction) { fraction = '0'; } if (fraction.length > baseLength) { throw new Error( `[ethjs-unit] while converting number ${etherInput} to wei, too many decimal places`, ); } while (fraction.length < baseLength) { fraction += '0'; } whole = new BN(whole); fraction = new BN(fraction); var wei = whole.mul(base).add(fraction); // eslint-disable-line if (negative) { wei = wei.mul(negative1); } return new BN(wei.toString(10), 10); } module.exports = { unitMap, numberToString, getValueOfUnit, fromWei, toWei, };