@colony/colony-js-adapter-ethers
Version:
ColonyContract adapter for ethers.js
387 lines (306 loc) • 12 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _ethers = require('ethers');
var _ethers2 = _interopRequireDefault(_ethers);
var _colonyJsUtils = require('@colony/colony-js-utils');
var _colonyJsContractLoader = require('@colony/colony-js-contract-loader');
var _colonyJsContractLoader2 = _interopRequireDefault(_colonyJsContractLoader);
var _EthersContract = require('./EthersContract');
var _EthersContract2 = _interopRequireDefault(_EthersContract);
var _defaults = require('./defaults');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// See https://solidity.readthedocs.io/en/v0.4.24/control-structures.html#error-handling-assert-require-revert-and-exceptions
var SOLIDITY_ERROR = '0x08c379a0';
var EthersAdapter = function () {
function EthersAdapter(_ref) {
var loader = _ref.loader,
provider = _ref.provider,
wallet = _ref.wallet;
(0, _classCallCheck3.default)(this, EthersAdapter);
this.loader = loader;
this.provider = provider;
this.wallet = wallet;
}
(0, _createClass3.default)(EthersAdapter, [{
key: 'callTransaction',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(transaction) {
var result, reason, error;
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return this.provider.call(transaction);
case 2:
result = _context.sent;
if (!((result.length - 2) / 2 % 32 === 4 && result.slice(0, 10) === SOLIDITY_ERROR)) {
_context.next = 8;
break;
}
reason = _ethers2.default.utils.AbiCoder.defaultCoder.decode(['string'], '0x' + result.slice(10));
error = new Error('Reverted: ' + reason);
// $FlowFixMe
Object.assign(error, { reason: reason });
throw error;
case 8:
return _context.abrupt('return', result);
case 9:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
function callTransaction(_x) {
return _ref2.apply(this, arguments);
}
return callTransaction;
}()
}, {
key: 'getContract',
value: function () {
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(query) {
var _ref4, address, abi;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return this.loader.load(query, {
abi: true,
address: true,
bytecode: false
});
case 2:
_context2.t0 = _context2.sent;
if (_context2.t0) {
_context2.next = 5;
break;
}
_context2.t0 = {};
case 5:
_ref4 = _context2.t0;
address = _ref4.address;
abi = _ref4.abi;
if (!(typeof address !== 'string')) {
_context2.next = 10;
break;
}
throw new Error('Unable to parse contract address');
case 10:
return _context2.abrupt('return', new _EthersContract2.default(address, abi, this.wallet));
case 11:
case 'end':
return _context2.stop();
}
}
}, _callee2, this);
}));
function getContract(_x2) {
return _ref3.apply(this, arguments);
}
return getContract;
}()
}, {
key: 'getContractDeployTransaction',
value: function () {
var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(query, contractParams) {
var _ethers$Contract;
var _ref6, abi, bytecode;
return _regenerator2.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return this.loader.load(query, {
abi: true,
address: false,
bytecode: true
});
case 2:
_ref6 = _context3.sent;
abi = _ref6.abi;
bytecode = _ref6.bytecode;
return _context3.abrupt('return', (_ethers$Contract = _ethers2.default.Contract).getDeployTransaction.apply(_ethers$Contract, [bytecode, abi].concat((0, _toConsumableArray3.default)(contractParams))));
case 6:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
function getContractDeployTransaction(_x3, _x4) {
return _ref5.apply(this, arguments);
}
return getContractDeployTransaction;
}()
}, {
key: '_getTransactionReceipt',
value: function () {
var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(transactionHash) {
var receipt;
return _regenerator2.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.next = 2;
return this.provider.getTransactionReceipt(transactionHash);
case 2:
receipt = _context4.sent;
if (!(receipt == null)) {
_context4.next = 5;
break;
}
throw new Error('Transaction receipt not found (transaction: ' + transactionHash + ')');
case 5:
return _context4.abrupt('return', receipt);
case 6:
case 'end':
return _context4.stop();
}
}
}, _callee4, this);
}));
function _getTransactionReceipt(_x5) {
return _ref7.apply(this, arguments);
}
return _getTransactionReceipt;
}()
}, {
key: 'waitForTransaction',
value: function () {
var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(transactionHash) {
var timeoutMs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _defaults.DEFAULT_TRANSACTION_WAIT_TIMEOUT;
return _regenerator2.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
return _context5.abrupt('return', (0, _colonyJsUtils.raceAgainstTimeout)(this.provider.waitForTransaction(transactionHash), timeoutMs));
case 1:
case 'end':
return _context5.stop();
}
}
}, _callee5, this);
}));
function waitForTransaction(_x7) {
return _ref8.apply(this, arguments);
}
return waitForTransaction;
}()
}, {
key: 'getTransactionReceipt',
value: function () {
var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(transactionHash, timeoutMs) {
var receipt;
return _regenerator2.default.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
receipt = void 0;
_context6.prev = 1;
_context6.next = 4;
return this._getTransactionReceipt(transactionHash);
case 4:
receipt = _context6.sent;
_context6.next = 11;
break;
case 7:
_context6.prev = 7;
_context6.t0 = _context6['catch'](1);
if (_context6.t0.toString().includes('Transaction receipt not found')) {
_context6.next = 11;
break;
}
throw _context6.t0;
case 11:
if (receipt) {
_context6.next = 14;
break;
}
_context6.next = 14;
return this.waitForTransaction(transactionHash, timeoutMs);
case 14:
receipt = this._getTransactionReceipt(transactionHash);
return _context6.abrupt('return', receipt);
case 16:
case 'end':
return _context6.stop();
}
}
}, _callee6, this, [[1, 7]]);
}));
function getTransactionReceipt(_x8, _x9) {
return _ref9.apply(this, arguments);
}
return getTransactionReceipt;
}()
/**
* Sign a message hash (as binary) and return a split signature.
*/
}, {
key: 'signMessage',
value: function () {
var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(messageHash) {
var messageBytes, signature, _ethers$utils$splitSi, sigR, sigS, sigV;
return _regenerator2.default.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
messageBytes = _ethers2.default.utils.arrayify(messageHash);
_context7.next = 3;
return this.wallet.signMessage(messageBytes);
case 3:
signature = _context7.sent;
_ethers$utils$splitSi = _ethers2.default.utils.splitSignature(signature), sigR = _ethers$utils$splitSi.r, sigS = _ethers$utils$splitSi.s, sigV = _ethers$utils$splitSi.v;
return _context7.abrupt('return', {
sigR: sigR,
sigS: sigS,
sigV: sigV
});
case 6:
case 'end':
return _context7.stop();
}
}
}, _callee7, this);
}));
function signMessage(_x10) {
return _ref10.apply(this, arguments);
}
return signMessage;
}()
/**
* Given a message digest and a signature, recover the address used to
* sign the message.
*/
// eslint-disable-next-line class-methods-use-this
}, {
key: 'ecRecover',
value: function ecRecover(digest, _ref11) {
var sigR = _ref11.sigR,
sigS = _ref11.sigS,
sigV = _ref11.sigV;
// This method doesn't need to be static, but flow Interfaces don't
// support static methods.
var recoveryParam = sigV - 27;
return _ethers2.default.SigningKey.recover(digest, sigR, sigS, recoveryParam);
}
}]);
return EthersAdapter;
}();
exports.default = EthersAdapter;
//# sourceMappingURL=EthersAdapter.js.map