eth-eip712-util-browser
Version:
(Pure JS fork) Generate hashes of typed ethereum data for signing
131 lines (119 loc) • 3.28 kB
JavaScript
// Extracted from https://github.com/ethereumjs/ethereumjs-util and stripped out irrelevant code
// Original code licensed under the Mozilla Public License Version 2.0
const BN = require('bn.js')
const Buffer = require('buffer/').Buffer
const keccak256 = require('js-sha3').keccak256
/**
* Returns a buffer filled with 0s
* @method zeros
* @param {Number} bytes the number of bytes the buffer should be
* @return {Buffer}
*/
function zeros (bytes) {
return Buffer.allocUnsafe(bytes).fill(0)
}
/**
* Left Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
* Or it truncates the beginning if it exceeds.
* @method setLength
* @param {Buffer|Array} msg the value to pad
* @param {Number} length the number of bytes the output should be
* @param {Boolean} [right=false] whether to start padding form the left or right
* @return {Buffer|Array}
*/
function setLength (msg, length, right) {
const buf = zeros(length)
msg = toBuffer(msg)
if (right) {
if (msg.length < length) {
msg.copy(buf)
return buf
}
return msg.slice(0, length)
} else {
if (msg.length < length) {
msg.copy(buf, length - msg.length)
return buf
}
return msg.slice(-length)
}
}
/**
* Right Pads an `Array` or `Buffer` with leading zeros till it has `length` bytes.
* Or it truncates the beginning if it exceeds.
* @param {Buffer|Array} msg the value to pad
* @param {Number} length the number of bytes the output should be
* @return {Buffer|Array}
*/
function setLengthRight (msg, length) {
return setLength(msg, length, true)
}
/**
* Attempts to turn a value into a `Buffer`. As input it supports `Buffer`, `String`, `Number`, null/undefined, `BN` and other objects with a `toArray()` method.
* @param {*} v the value
*/
function toBuffer (v) {
if (!Buffer.isBuffer(v)) {
if (Array.isArray(v)) {
v = Buffer.from(v)
} else if (typeof v === 'string') {
if (isHexString(v)) {
v = Buffer.from(padToEven(stripHexPrefix(v)), 'hex')
} else {
v = Buffer.from(v)
}
} else if (typeof v === 'number') {
v = intToBuffer(v)
} else if (v === null || v === undefined) {
v = Buffer.allocUnsafe(0)
} else if (BN.isBN(v)) {
v = v.toArrayLike(Buffer)
} else if (v.toArray) {
// converts a BN to a Buffer
v = Buffer.from(v.toArray())
} else {
throw new Error('invalid type')
}
}
return v
}
/**
* Converts a `Buffer` into a hex `String`
* @param {Buffer} buf
* @return {String}
*/
function bufferToHex (buf) {
buf = toBuffer(buf)
return '0x' + buf.toString('hex')
}
/**
* Creates Keccak hash of the input
* @param {Buffer|Array|String|Number} a the input data
* @return {Buffer}
*/
function keccak (a) {
a = toBuffer(a)
return Buffer.from(keccak256(a), 'hex')
}
function padToEven (str) {
return str.length % 2 ? '0' + str : str
}
function isHexString (str) {
return typeof str === 'string' && str.match(/^0x[0-9A-Fa-f]*$/)
}
function stripHexPrefix (str) {
if (typeof str === 'string' && str.startsWith('0x')) {
return str.slice(2)
}
return str
}
module.exports = {
zeros,
setLength,
setLengthRight,
isHexString,
stripHexPrefix,
toBuffer,
bufferToHex,
keccak
}