jcc-moac-abi
Version:
Decoder and encoder for the MOAC ABI and decode events from MOAC transactions
194 lines • 7.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var abiDecoder = require("abi-decoder");
var contract_1 = require("chain3/lib/chain3/contract");
var isFunction = require("lodash/isFunction");
var abiCoder = require("web3-eth-abi");
var web3_utils_1 = require("web3-utils");
/**
* decoder and encoder for moac
*
* @export
* @class MoacABI
*/
var MoacABI = /** @class */ (function () {
/**
* Creates an instance of MoacABI.
* @param {Contract} contract moac contract instance
* @memberof MoacABI
*/
function MoacABI(contract) {
var _this = this;
/**
* get item of function meta data
*
* @param {string} name defined function name in the abi
* @param {*} args parameters according to the defined inputs
* @returns {IABIItem}
* @memberof MoacABI
*/
this.getAbiItem = function (name) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var method = _this._contract[name];
if (!isFunction(method)) {
throw new Error("The contract doesn't contain \"" + name + "\" function");
}
var filterABIs = _this._abi.filter(function (item) { return item.name === name; });
var abi;
if (filterABIs.length === 1) {
abi = filterABIs[0];
}
else {
abi = filterABIs.find(function (item) { return item.inputs.length === args.length; });
if (!abi) {
throw new Error("Invalid number of arguments to Solidity function");
}
}
return abi;
};
/**
* encode the input value by function name
*
* @param {string} name defined function name in the abi
* @param {*} args parameters according to the defined inputs
* @returns {string}
* @memberof MoacABI
*/
this.encode = function (name) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
var method = _this._contract[name];
if (!isFunction(method)) {
throw new Error("The contract doesn't contain \"" + name + "\" function");
}
var filterABIs = _this._abi.filter(function (item) { return item.name === name; });
var encodedData;
if (filterABIs.length === 1) {
encodedData = method["getData"].apply(null, args);
}
else {
var abi = filterABIs.find(function (item) { return item.inputs.length === args.length; });
if (!abi) {
throw new Error("Invalid number of arguments to Solidity function");
}
// detail: https://github.com/MOACChain/chain3/blob/master/lib/chain3/function.js#L282
var typename = abi.inputs.map(function (input) { return input.type; }).join(",");
encodedData = method[typename].getData.apply(null, args);
}
if (encodedData.includes("NaN")) {
throw new Error('The encoded data contains "NaN", please check the input arguments');
}
return encodedData;
};
if (contract instanceof contract_1.Contract) {
this._contract = contract;
this._abi = contract.abi;
}
else {
throw new Error("The input value isn't a contract instance");
}
}
/**
* decode the input value
*
* @static
* @param {string} data
* @returns {IDecoded[]}
* @memberof MoacABI
*/
MoacABI.decode = function (data) {
var decodedData = abiDecoder.decodeMethod(data);
return decodedData;
};
/**
* decode moac transaction logs
*
* [Reference](https://github.com/ConsenSys/abi-decoder/blob/master/index.js#L130)
*
* @static
* @param {ILog[]} logs
* @returns {IDecodedLog[]} if event is defined and decode succeed, return log that contains
* events as input arguments and name as event's name, otherwise return itself.
* @memberof MoacABI
*/
MoacABI.decodeLogs = function (logs) {
return logs.filter(function (log) { return log.topics.length > 0; }).map(function (logItem) {
var methodID = logItem.topics[0].slice(2);
var method = abiDecoder.getMethodIDs()[methodID];
if (method) {
var logData = logItem.TxData;
var decodedParams_1 = [];
var dataIndex_1 = 0;
var topicsIndex_1 = 1;
var dataTypes_1 = [];
method.inputs.map(function (input) {
if (!input.indexed) {
dataTypes_1.push(input.type);
}
});
var decodedData_1 = abiCoder.decodeParameters(dataTypes_1, logData.slice(2));
// Loop topic and data to get the params
method.inputs.map(function (param) {
var decodedP = {
name: param.name,
type: param.type,
};
if (param.indexed) {
decodedP.value = logItem.topics[topicsIndex_1];
topicsIndex_1++;
}
else {
decodedP.value = decodedData_1[dataIndex_1];
dataIndex_1++;
}
if (param.type === "address") {
decodedP.value = decodedP.value.toLowerCase();
// 42 because len(0x) + 40
if (decodedP.value.length > 42) {
var toRemove = decodedP.value.length - 42;
var temp = decodedP.value.split("");
temp.splice(2, toRemove);
decodedP.value = temp.join("");
}
}
if (param.type === "uint256" || param.type === "uint8" || param.type === "int") {
decodedP.value = new web3_utils_1.BN(decodedP.value).toString(10);
}
decodedParams_1.push(decodedP);
});
return Object.assign(logItem, { events: decodedParams_1, name: method.name });
}
return logItem;
});
};
/**
* add abi to abiDecoder
*
* @static
* @param {IABIItem[]} abi
* @memberof MoacABI
*/
MoacABI.addABI = function (abi) {
abiDecoder.addABI(abi);
};
/**
* remove ABIs and methodIDs from abiDecoder
*
* @static
* @param {IABIItem[]} abi
* @memberof MoacABI
*/
MoacABI.removeABI = function (abi) {
abiDecoder.getABIs().length = 0;
abiDecoder.removeABI(abi);
};
return MoacABI;
}());
exports.MoacABI = MoacABI;
exports.default = MoacABI;
//# sourceMappingURL=abi.js.map