UNPKG

minterjs-tx

Version:

A simple module for creating, manipulating and signing Minter transactions

176 lines (168 loc) 7.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = definePropertiesNonBinary; var rlp = _interopRequireWildcard(require("rlp")); var _bytes = require("ethereumjs-util/dist/bytes.js"); var _ethjsUtil = require("ethjs-util"); var _assert = _interopRequireDefault(require("assert")); var _minterjsUtil = require("minterjs-util"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } /** * @typedef {Object} FieldSettings * @property {string} name - the name of the properties * @property {string} [alias] - alias to the name * @property {*} [default] - default value * @property {number} [length] - the number of bytes the field can have * @property {boolean} [allowLess] - if the field can be less than the length * @property {boolean} [allowZero] * @property {boolean} [isNonBinaryArray] - if the field can be non binary array * @property {function} [nonBinaryArrayTransform] - function to transform each item of the non binary array * @property {boolean} [storeNullAsArray] - store falsy values as rlp array `0xc0` (to distinguish from `0x80` integer zero @see https://eth.wiki/en/fundamentals/rlp#examples) */ /** * Defines properties on a `Object`. It make the assumption that underlying data is binary. * @param {Object} self the `Object` to define properties on * @param {Array<FieldSettings>} fields an array fields to define. Fields can contain: * * `name` - the name of the properties * * `length` - the number of bytes the field can have * * `allowLess` - if the field can be less than the length * * `allowZero` * * `isNonBinaryArray` - if the field can be non binary array * * `nonBinaryArrayTransform` - function to transform each item of the non binary array * @param {*} [data] data to be validated against the definitions * @param {TxDataExtraOptions} [options] */ function definePropertiesNonBinary(self, fields, data) { var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; self.raw = []; self._fields = []; // attach the `toJSON` self.toJSON = function toJSON(label) { /* eslint-disable unicorn/prevent-abbreviations */ if (label) { var obj = {}; self._fields.forEach(function (field) { obj[field] = "0x".concat(self[field].toString('hex')); }); return obj; } return (0, _bytes.baToJSON)(this.raw); }; self.serialize = function serialize() { return rlp.encode(self.raw); }; self.serializeToString = function serialize() { return "0x".concat(self.serialize().toString('hex')); }; fields.forEach(function (field, i) { self._fields.push(field.name); function getter() { return self.raw[i]; } function setter(v) { if (typeof field.isNonBinaryArray === 'undefined' && field.allowNonBinaryArray) { field.isNonBinaryArray = field.allowNonBinaryArray; console.warn('allowNonBinaryArray is deprecated, use isNonBinaryArray instead'); } if (field.isNonBinaryArray) { if (typeof v === 'undefined') { v = []; } if (!Array.isArray(v)) { throw new TypeError('Invalid value for isNonBinaryArray field'); } if (field.nonBinaryArrayTransform && typeof field.nonBinaryArrayTransform === 'function') { v = v.map(function (item) { return field.nonBinaryArrayTransform(item); }); } else { v = v.map(function (item) { return (0, _minterjsUtil.toBuffer)(item); }); } // cast 0x00 to 0x, to represent in RLP as 0x80 instead of 0x00 v = v.map(function (item) { if (item.toString('hex') === '00' /* && !field.allowZero */) { return Buffer.from([]); } return item; }); } else if (typeof v === 'undefined' && options.forceDefaultValues && !field.allowLess && field.length > 0) { // fill with zeros v = Buffer.alloc(field.length, 0); } else if (field.storeNullAsArray && (!v && v !== 0 || Array.isArray(v) && v.length === 0)) { v = []; } else { v = (0, _minterjsUtil.toBuffer)(v); if (v.toString('hex') === '00' && !field.allowZero) { v = Buffer.from([]); } if (field.allowLess && field.length > 0) { v = (0, _bytes.unpadBuffer)(v); (0, _assert["default"])(field.length >= v.length, "The field ".concat(field.name, " must not have more ").concat(field.length, " bytes")); } else if (!(field.allowZero && v.length === 0) && field.length > 0) { // not allowedZero and not allowLess (0, _assert["default"])(field.length === v.length, "The field ".concat(field.name, " must have byte length of ").concat(field.length)); } } self.raw[i] = v; } Object.defineProperty(self, field.name, { enumerable: true, configurable: true, get: getter, set: setter }); if (field["default"]) { self[field.name] = field["default"]; } else if (options.forceDefaultValues) { // trigger setter, even if no data passed self[field.name] = undefined; } // attach alias if (field.alias) { Object.defineProperty(self, field.alias, { enumerable: false, configurable: true, set: setter, get: getter }); } }); // if the constructor is passed data if (data) { if (typeof data === 'string') { data = Buffer.from((0, _ethjsUtil.stripHexPrefix)(data), 'hex'); } if (Buffer.isBuffer(data)) { data = rlp.decode(data); } if (Array.isArray(data)) { if (data.length > self._fields.length) { throw new Error('wrong number of fields in data'); } // set fields from array data.forEach(function (d, i) { self[self._fields[i]] = d; }); } else if (_typeof(data) === 'object') { var keys = Object.keys(data); fields.forEach(function (field) { if (keys.indexOf(field.name) !== -1) self[field.name] = data[field.name]; if (keys.indexOf(field.alias) !== -1) self[field.alias] = data[field.alias]; }); } else { throw new TypeError('invalid data'); } } return self; } /** * @typedef {Object} TxDataExtraOptions * @property {boolean} [forceDefaultValues] */