@giveth/eth-contract-class
Version:
generate js wrapper class around an ethereum contract
184 lines (146 loc) • 6.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _web3CorePromievent = _interopRequireDefault(require("web3-core-promievent"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function checkWeb3(web3) {
if (typeof web3.version !== 'string' || !web3.version.startsWith('1.')) {
throw new Error('web3 version 1.x is required');
}
}
var validOptKeys = ['from', 'to', 'gasPrice', 'gas', 'value', 'data', 'nonce', 'maxFeePerGas', 'maxPriorityFeePerGas'];
var filterOpts = function filterOpts(opts) {
var validOpts = {};
validOptKeys.forEach(function (key) {
validOpts[key] = opts[key];
});
return validOpts;
};
var estimateGas = function estimateGas(web3, method, opts) {
if (opts.$noEstimateGas) return Promise.resolve(4700000);
if (opts.$gas || opts.gas) return Promise.resolve(opts.$gas || opts.gas);
var o = filterOpts(opts); // remove nonce from estimateGas. It isn't necessary and causes
// ganache-cli to error when submitting multiple txs asynchronously
// before the 1st has been mined
delete o.nonce;
return method.estimateGas(o) // eslint-disable-next-line no-confusing-arrow
.then(function (gas) {
return opts.$extraGas ? gas + opts.$extraGas : Math.floor(gas * 1.1);
});
}; // if constant method, executes a call, otherwise, estimates gas and executes send
var execute = function execute(web3, txObject, opts, cb) {
var _method = txObject._method;
if (_method.constant) return txObject.call(filterOpts(opts)); // we need to create a new PromiEvent here b/c estimateGas returns a regular promise
// however on a 'send' we want to return a PromiEvent
var defer = new _web3CorePromievent["default"]();
var relayEvent = function relayEvent(event) {
return function () {
var _defer$eventEmitter;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return (_defer$eventEmitter = defer.eventEmitter).emit.apply(_defer$eventEmitter, [event].concat(args));
};
};
estimateGas(web3, txObject, opts).then(function (gas) {
// 21272 is min gas to work in older versions of ganache-cli
var filteredOpts = Object.assign({}, filterOpts(opts), {
gas: gas < 21272 ? 21272 : gas
});
return cb ? txObject.send(filteredOpts, cb) : txObject.send(filteredOpts) // relay all events to our promiEvent
.on('transactionHash', relayEvent('transactionHash')).on('confirmation', relayEvent('confirmation')).on('receipt', function (r) {
if (opts.verbose) {
console.log(r.gasUsed);
}
return relayEvent('receipt')(r);
}).on('error', relayEvent('error'));
}).then(defer.resolve)["catch"](defer.reject);
return defer.eventEmitter;
};
var methodWrapper = function methodWrapper(web3, method) {
var cb;
var opts = {};
for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
args[_key2 - 2] = arguments[_key2];
}
if (typeof args[args.length - 1] === 'function') cb = args.pop();
if (_typeof(args[args.length - 1]) === 'object' && !Array.isArray(args[args.length - 1])) opts = args.pop();
var txObject = method.apply(void 0, args);
return execute(web3, txObject, opts, cb);
};
var _default = function _default(abi) {
var bytecode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
if (!abi) throw new Error('missing abi');
if (bytecode && !bytecode.startsWith('0x')) bytecode = '0x' + bytecode;
var C = function C(web3, address) {
var _this = this;
checkWeb3(web3);
this.$web3 = web3;
this.$address = address;
this.$contract = new web3.eth.Contract(abi, address);
this.$abi = abi;
this.$byteCode = bytecode;
Object.keys(this.$contract.methods).filter(function (key) {
return !key.startsWith('0x');
}).forEach(function (key) {
_this[key] = function () {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return methodWrapper.apply(void 0, [web3, _this.$contract.methods[key]].concat(args));
};
}); // set default from address
web3.eth.getAccounts().then(function (accounts) {
_this.$contract.options.from = accounts.length > 0 ? accounts[0] : undefined;
})["catch"]();
};
C["new"] = function (web3) {
if (!bytecode || bytecode === '0x') throw new Error('missing bytecode');
var opts = {};
for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
args[_key4 - 1] = arguments[_key4];
}
if (args && args.length > 0 && _typeof(args[args.length - 1]) === 'object') {
opts = args.pop();
}
var deploy = new web3.eth.Contract(abi).deploy({
data: bytecode,
arguments: args
});
var getAccount = function getAccount() {
if (opts.from) return Promise.resolve(opts.from);
return web3.eth.getAccounts() // eslint-disable-next-line no-confusing-arrow
.then(function (accounts) {
return accounts.length > 0 ? accounts[0] : undefined;
});
}; // we need to create a new PromiEvent here b/c getAccount returns a regular promise
// however on a 'deploy' we want to return a PromiEvent
var defer = new _web3CorePromievent["default"]();
var relayEvent = function relayEvent(event) {
return function () {
var _defer$eventEmitter2;
for (var _len5 = arguments.length, params = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
params[_key5] = arguments[_key5];
}
return (_defer$eventEmitter2 = defer.eventEmitter).emit.apply(_defer$eventEmitter2, [event].concat(params));
};
};
getAccount().then(function (account) {
return Object.assign(opts, {
from: account
});
}).then(function () {
return execute(web3, deploy, opts) // relay all events to our promiEvent
.on('transactionHash', relayEvent('transactionHash')).on('confirmation', relayEvent('confirmation')).on('receipt', relayEvent('receipt')).on('error', relayEvent('error'));
}).then(function (contract) {
return new C(web3, contract.options.address);
}).then(defer.resolve)["catch"](defer.reject);
return defer.eventEmitter;
};
return C;
};
exports["default"] = _default;
//# sourceMappingURL=generateClass.js.map