locklift
Version:
Node JS framework for working with Ever contracts. Inspired by Truffle and Hardhat. Helps you to build, test, run and maintain your smart contracts.
116 lines (115 loc) • 5.17 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ViewTracingTree = void 0;
const types_1 = require("../types");
const lodash_1 = __importDefault(require("lodash"));
const everscale_inpage_provider_1 = require("everscale-inpage-provider");
const utils_1 = require("../utils");
const utils_2 = require("./utils");
const tokens_1 = require("./tokens");
const rxjs_1 = require("rxjs");
class ViewTracingTree {
contractGetter;
accounts;
viewTraceTree;
tokens;
balanceChangeInfo;
msgErrorsStore;
constructor(viewTraceTree, contractGetter, accounts) {
this.contractGetter = contractGetter;
this.accounts = accounts;
this.viewTraceTree = (0, utils_2.applyTotalFees)(lodash_1.default.cloneDeep(viewTraceTree));
this.balanceChangeInfo = (0, rxjs_1.pipe)(utils_2.getBalanceChangingInfo, utils_2.getBalanceDiff)(this.viewTraceTree);
this.msgErrorsStore = (0, utils_2.getErrorsInfo)(this.viewTraceTree);
this.tokens = new tokens_1.Tokens(this.viewTraceTree);
}
getErrorsByContract = (contract) => {
return this.msgErrorsStore[(0, utils_1.extractStringAddress)(contract)];
};
getAllErrors = () => Object.entries(this.msgErrorsStore).flatMap(([key, errors]) => errors.map(error => ({ contract: key, ...error })));
getBalanceDiff = (contracts) => {
if (Array.isArray(contracts)) {
return contracts.reduce((acc, contract) => {
const address = (0, utils_1.extractStringAddress)(contract);
return { ...acc, [address]: this.balanceChangeInfo[address.toString()]?.balanceDiff.toString() };
}, {});
}
const address = (0, utils_1.extractStringAddress)(contracts);
return this.balanceChangeInfo[address].balanceDiff.toString();
};
findCallsForContract = ({ contract, name, }) => {
return this.findForContract({ contract, name })
.map(el => el?.params)
.filter(utils_1.isT);
};
findEventsForContract = ({ contract, name, }) => this.findForContract({ name, contract })
.map(el => el?.params)
.filter(utils_1.isT);
findForContract = ({ contract, name, }) => {
if (name in contract.methodsAbi) {
return this.findByType({ name, type: types_1.TraceType.FUNCTION_CALL, contract });
}
return this.findByType({ name, type: types_1.TraceType.EVENT, contract });
};
findByType = (params) => this._findByType(params, this.viewTraceTree).map(el => el.decodedMsg);
findByTypeWithFullData = (params) => {
return this._findByType(params, this.viewTraceTree);
};
_findByType = ({ type, name, contract }, tree, isRoot = true) => {
const matchedMethods = [];
if (isRoot && (0, utils_2.isDesiredMethod)({ type, name, contract }, tree)) {
matchedMethods.push(tree);
}
for (const trace of tree.outTraces) {
if ((0, utils_2.isDesiredMethod)({ type, name, contract }, trace)) {
matchedMethods.push(trace);
}
if (trace.outTraces.length > 0) {
matchedMethods.push(...this._findByType({ name, type, contract }, trace, false));
}
}
return matchedMethods;
};
totalGasUsed = () => (0, utils_2.calculateTotalFees)(this.viewTraceTree).toNumber();
beautyPrint = async (printerConfig) => {
const contracts = this.accounts.map(({ codeHash, id }) => this.contractGetter(codeHash, new everscale_inpage_provider_1.Address(id)));
console.log((0, utils_2.printer)(this.viewTraceTree, {
contracts,
}, printerConfig) +
"\n" +
this._beautyPrint(this.viewTraceTree, 0, contracts, printerConfig));
};
_beautyPrint = (viewTrace, offset, contracts, printerConfig) => {
let traces = "";
for (const viewTraceInt of viewTrace.outTraces) {
traces =
traces +
`${Array(offset).fill(" ").join("")} ${(0, utils_2.printer)(viewTraceInt, {
contracts,
}, printerConfig)}\n${this._beautyPrint(viewTraceInt, offset + 1, contracts, printerConfig)}`;
}
return traces;
};
}
exports.ViewTracingTree = ViewTracingTree;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const extractAllAddresses = (viewTrace) => {
const addresses = extractAddressFromObject(viewTrace.decodedMsg || {});
return viewTrace.outTraces.reduce((acc, next) => {
return [...acc, ...extractAllAddresses(next)];
}, addresses);
};
const extractAddressFromObject = (obj) => {
return Object.values(obj).reduce((acc, value) => {
if (value instanceof everscale_inpage_provider_1.Address) {
return [...acc, value.toString()];
}
if (value instanceof Object) {
return [...acc, ...extractAddressFromObject(value)];
}
return acc;
}, []);
};