@parity/api
Version:
The Parity Promise-based API library for interfacing with Ethereum over RPC
222 lines (221 loc) • 7.26 kB
JavaScript
;
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
// SPDX-License-Identifier: MIT
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-use-before-define */
var bignumber_js_1 = require("bignumber.js");
var types_1 = require("../util/types");
var format_1 = require("../util/format");
/**
* Validate input address.
*
* @param address - Input address to validate.
*/
exports.inAddress = function (address) {
// TODO: address validation if we have upper-lower addresses
return exports.inHex(address);
};
/**
* Validate input addresses.
*
* @param addresses - Input addresses to validate.
*/
exports.inAddresses = function (addresses) {
return (addresses || []).map(exports.inAddress);
};
exports.inBlockNumber = function (blockNumber) {
if (types_1.isString(blockNumber)) {
switch (blockNumber) {
case 'earliest':
case 'latest':
case 'pending':
return blockNumber;
}
}
return exports.inNumber16(blockNumber);
};
exports.inData = function (data) {
if (data && data.length && !types_1.isHex(data)) {
data = data
.split('')
.map(function (chr) { return ("0" + chr.charCodeAt(0).toString(16)).slice(-2); })
.join('');
}
return exports.inHex(data);
};
exports.inHash = function (hash) {
return exports.inHex(hash);
};
exports.inTopics = function (topics) {
if (!topics) {
return [];
}
// @ts-ignore I don't want to deal with resursive nested arrays
// TODO https://stackoverflow.com/questions/52638149/recursive-nested-array-type-can-it-be-done
return topics
.filter(function (topic) { return topic === null || topic; })
.map(function (topic) {
if (topic === null) {
return null;
}
if (Array.isArray(topic)) {
return exports.inTopics(topic);
}
return format_1.padLeft(topic, 32);
});
};
exports.inFilter = function (options) {
var result = {};
if (options) {
Object.keys(options).forEach(function (key) {
switch (key) {
case 'address':
if (types_1.isArray(options[key])) {
result[key] = options[key].map(exports.inAddress);
}
else {
result[key] = exports.inAddress(options[key]);
}
break;
case 'fromBlock':
case 'toBlock':
result[key] = exports.inBlockNumber(options[key]);
break;
case 'limit':
result[key] = exports.inNumber10(options[key]);
break;
case 'topics':
result[key] = exports.inTopics(options[key]);
break;
default:
// @ts-ignore Here, we explicitly pass down extra keys, if they exist
result[key] = options[key];
}
});
}
return result;
};
exports.inHex = function (str) { return format_1.toHex(str); };
exports.inNumber10 = function (n) {
if (types_1.isInstanceOf(n, bignumber_js_1.default)) {
return n.toNumber();
}
return new bignumber_js_1.default(n || 0).toNumber();
};
exports.inNumber16 = function (n) {
var bn = types_1.isInstanceOf(n, bignumber_js_1.default)
? n
: new bignumber_js_1.default(n || 0);
if (!bn.isInteger()) {
throw new Error("[format/input::inNumber16] the given number is not an integer: " + bn.toFormat());
}
return exports.inHex(bn.toString(16));
};
exports.inOptionsCondition = function (condition) {
if (condition) {
return {
block: condition.block ? exports.inNumber10(condition.block) : null,
time: condition.time
? exports.inNumber10(Math.floor(condition.time.getTime() / 1000))
: null
};
}
return null;
};
exports.inOptions = function (_options) {
if (_options === void 0) { _options = {}; }
var options = Object.assign({}, _options);
var result = {};
Object.keys(options).forEach(function (key) {
switch (key) {
case 'to':
// Don't encode the `to` option if it's empty
// (eg. contract deployments)
if (options[key]) {
result.to = exports.inAddress(options[key]);
}
break;
case 'from':
result[key] = exports.inAddress(options[key]);
break;
case 'condition':
result[key] = exports.inOptionsCondition(options[key]);
break;
case 'gas':
case 'gasPrice':
result[key] = exports.inNumber16(new bignumber_js_1.default(options[key]) // TODO Round number
);
break;
case 'value':
case 'nonce':
result[key] = exports.inNumber16(options[key]);
break;
case 'data':
result[key] = exports.inData(options[key]);
break;
default:
// @ts-ignore Here, we explicitly pass down extra keys, if they exist
result[key] = options[key];
}
});
return result;
};
exports.inTraceFilter = function (filterObject) {
var result = {};
if (filterObject) {
Object.keys(filterObject).forEach(function (key) {
switch (key) {
case 'fromAddress':
case 'toAddress':
result[key] = []
.concat(filterObject[key])
.map(function (address) { return exports.inAddress(address); });
break;
case 'toBlock':
case 'fromBlock':
result[key] = exports.inBlockNumber(filterObject[key]);
break;
default:
// @ts-ignore Here, we explicitly pass down extra keys, if they exist
result[key] = filterObject[key];
}
});
}
return result;
};
exports.inTraceType = function (whatTrace) {
if (types_1.isString(whatTrace)) {
return [whatTrace];
}
return whatTrace;
};
exports.inDeriveType = function (derive) {
return derive && derive.type === 'hard' ? 'hard' : 'soft';
};
exports.inDeriveHash = function (derive) {
var hash = derive && derive.hash
? derive.hash
: derive;
var type = exports.inDeriveType(derive);
return {
hash: exports.inHex(hash),
type: type
};
};
exports.inDeriveIndex = function (derive) {
if (!derive) {
return [];
}
var deriveAsArray = types_1.isArray(derive) ? derive : [derive];
return deriveAsArray.map(function (item) {
var index = exports.inNumber10(item && item.index
? item.index
: item);
return {
index: index,
type: exports.inDeriveType(item)
};
});
};