"use strict"; /** * Conversion Utilities * */ Object.defineProperty(exports, "__esModule", { value: true }); var errors = require("./errors"); exports.AddressZero = '0x0000000000000000000000000000000000000000'; exports.HashZero = '0x0000000000000000000000000000000000000000000000000000000000000000'; function isBigNumber(value) { return !!value._bn; } function addSlice(array) { if (array.slice) { return array; } array.slice = function () { var args = Array.prototype.slice.call(arguments); return new Uint8Array(Array.prototype.slice.apply(array, args)); }; return array; } function isArrayish(value) { if (!value || parseInt(String(value.length)) != value.length || typeof (value) === 'string') { return false; } for (var i = 0; i < value.length; i++) { var v = value[i]; if (v < 0 || v >= 256 || parseInt(String(v)) != v) { return false; } } return true; } exports.isArrayish = isArrayish; function arrayify(value) { if (value == null) { errors.throwError('cannot convert null value to array', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } if (isBigNumber(value)) { value = value.toHexString(); } if (typeof (value) === 'string') { var match = value.match(/^(0x)?[0-9a-fA-F]*$/); if (!match) { errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } if (match[1] !== '0x') { errors.throwError('hex string must have 0x prefix', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } value = value.substring(2); if (value.length % 2) { value = '0' + value; } var result = []; for (var i = 0; i < value.length; i += 2) { result.push(parseInt(value.substr(i, 2), 16)); } return addSlice(new Uint8Array(result)); } else if (typeof (value) === 'string') { } if (isArrayish(value)) { return addSlice(new Uint8Array(value)); } errors.throwError('invalid arrayify value', null, { arg: 'value', value: value, type: typeof (value) }); return null; } exports.arrayify = arrayify; function concat(objects) { var arrays = []; var length = 0; for (var i = 0; i < objects.length; i++) { var object = arrayify(objects[i]); arrays.push(object); length += object.length; } var result = new Uint8Array(length); var offset = 0; for (var i = 0; i < arrays.length; i++) { result.set(arrays[i], offset); offset += arrays[i].length; } return addSlice(result); } exports.concat = concat; function stripZeros(value) { var result = arrayify(value); if (result.length === 0) { return result; } // Find the first non-zero entry var start = 0; while (result[start] === 0) { start++; } // If we started with zeros, strip them if (start) { result = result.slice(start); } return result; } exports.stripZeros = stripZeros; function padZeros(value, length) { value = arrayify(value); if (length < value.length) { throw new Error('cannot pad'); } var result = new Uint8Array(length); result.set(value, length - value.length); return addSlice(result); } exports.padZeros = padZeros; function isHexString(value, length) { if (typeof (value) !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) { return false; } if (length && value.length !== 2 + 2 * length) { return false; } return true; } exports.isHexString = isHexString; var HexCharacters = '0123456789abcdef'; function hexlify(value) { if (isBigNumber(value)) { return value.toHexString(); } if (typeof (value) === 'number') { if (value < 0) { errors.throwError('cannot hexlify negative value', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } var hex = ''; while (value) { hex = HexCharacters[value & 0x0f] + hex; value = Math.floor(value / 16); } if (hex.length) { if (hex.length % 2) { hex = '0' + hex; } return '0x' + hex; } return '0x00'; } if (typeof (value) === 'string') { var match = value.match(/^(0x)?[0-9a-fA-F]*$/); if (!match) { errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } if (match[1] !== '0x') { errors.throwError('hex string must have 0x prefix', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } if (value.length % 2) { value = '0x0' + value.substring(2); } return value; } if (isArrayish(value)) { var result = []; for (var i = 0; i < value.length; i++) { var v = value[i]; result.push(HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]); } return '0x' + result.join(''); } errors.throwError('invalid hexlify value', null, { arg: 'value', value: value }); return 'never'; } exports.hexlify = hexlify; function hexDataLength(data) { if (!isHexString(data) || (data.length % 2) !== 0) { return null; } return (data.length - 2) / 2; } exports.hexDataLength = hexDataLength; function hexDataSlice(data, offset, length) { if (!isHexString(data)) { errors.throwError('invalid hex data', errors.INVALID_ARGUMENT, { arg: 'value', value: data }); } if ((data.length % 2) !== 0) { errors.throwError('hex data length must be even', errors.INVALID_ARGUMENT, { arg: 'value', value: data }); } offset = 2 + 2 * offset; if (length != null) { return '0x' + data.substring(offset, offset + 2 * length); } return '0x' + data.substring(offset); } exports.hexDataSlice = hexDataSlice; function hexStripZeros(value) { if (!isHexString(value)) { errors.throwError('invalid hex string', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } while (value.length > 3 && value.substring(0, 3) === '0x0') { value = '0x' + value.substring(3); } return value; } exports.hexStripZeros = hexStripZeros; function hexZeroPad(value, length) { if (!isHexString(value)) { errors.throwError('invalid hex string', errors.INVALID_ARGUMENT, { arg: 'value', value: value }); } while (value.length < 2 * length + 2) { value = '0x0' + value.substring(2); } return value; } exports.hexZeroPad = hexZeroPad; function isSignature(value) { return (value && value.r != null && value.s != null); } function splitSignature(signature) { var v = 0; var r = '0x', s = '0x'; if (isSignature(signature)) { r = hexZeroPad(signature.r, 32); s = hexZeroPad(signature.s, 32); var recoveryParam = signature.recoveryParam; if (recoveryParam == null && signature.v != null) { recoveryParam = 1 - (signature.v % 2); } v = 27 + recoveryParam; } else { var bytes = arrayify(signature); if (bytes.length !== 65) { throw new Error('invalid signature'); } r = hexlify(bytes.slice(0, 32)); s = hexlify(bytes.slice(32, 64)); v = bytes[64]; if (v !== 27 && v !== 28) { v = 27 + (v % 2); } } return { r: r, s: s, recoveryParam: (v - 27), v: v }; } exports.splitSignature = splitSignature; function joinSignature(signature) { signature = splitSignature(signature); return hexlify(concat([ signature.r, signature.s, (signature.recoveryParam ? '0x1c' : '0x1b') ])); } exports.joinSignature = joinSignature;