neo-blockchain-client
Version:
NEO Blockchain client.
1,658 lines (1,430 loc) • 47 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var neoBlockchainCore = require('neo-blockchain-core');
var _ = _interopDefault(require('lodash'));
var asynciterable = require('ix/asynciterable');
var BN = _interopDefault(require('bn.js'));
var BigNumber = _interopDefault(require('bignumber.js'));
var flatmap = require('ix/asynciterable/flatmap');
var DataLoader = _interopDefault(require('dataloader'));
var fetch = _interopDefault(require('isomorphic-fetch'));
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _next(value) {
step("next", value);
}
function _throw(err) {
step("throw", err);
}
_next();
});
};
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _slicedToArray(arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return _sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
}
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
}
var _fixBabelExtend = function (O) {
var gOPD = O.getOwnPropertyDescriptor,
gPO = O.getPrototypeOf || function (o) {
return o.__proto__;
},
sPO = O.setPrototypeOf || function (o, p) {
o.__proto__ = p;
return o;
},
construct = _typeof(Reflect) === 'object' ? Reflect.construct : function (Parent, args, Class) {
var Constructor,
a = [null];
a.push.apply(a, args);
Constructor = Parent.bind.apply(Parent, a);
return sPO(new Constructor(), Class.prototype);
};
return function fixBabelExtend(Class) {
var Parent = gPO(Class);
return sPO(Class, sPO(function Super() {
return construct(Parent, arguments, gPO(this).constructor);
}, Parent));
};
}(Object);
var UnknownBlockError = _fixBabelExtend(
/*#__PURE__*/
function (_Error) {
_inherits(UnknownBlockError, _Error);
function UnknownBlockError() {
var _this;
_classCallCheck(this, UnknownBlockError);
_this = _possibleConstructorReturn(this, (UnknownBlockError.__proto__ || Object.getPrototypeOf(UnknownBlockError)).call(this, 'Unknown block'));
Object.defineProperty(_this, "unknownBlock", {
configurable: true,
enumerable: true,
writable: true,
value: true
});
return _this;
}
return UnknownBlockError;
}(Error));
var InvalidContractParameterError = _fixBabelExtend(
/*#__PURE__*/
function (_Error2) {
_inherits(InvalidContractParameterError, _Error2);
function InvalidContractParameterError(parameter, expected) {
var _this2;
_classCallCheck(this, InvalidContractParameterError);
_this2 = _possibleConstructorReturn(this, (InvalidContractParameterError.__proto__ || Object.getPrototypeOf(InvalidContractParameterError)).call(this, "Expected one of ".concat(JSON.stringify(expected), " ") + "ContractParameterTypes, found ".concat(parameter.type)));
_this2.parameter = parameter;
_this2.expected = expected;
return _this2;
}
return InvalidContractParameterError;
}(Error));
var SendTransactionError = _fixBabelExtend(
/*#__PURE__*/
function (_Error3) {
_inherits(SendTransactionError, _Error3);
function SendTransactionError() {
_classCallCheck(this, SendTransactionError);
return _possibleConstructorReturn(this, (SendTransactionError.__proto__ || Object.getPrototypeOf(SendTransactionError)).call(this, 'Something went wrong!'));
}
return SendTransactionError;
}(Error));
var FETCH_ONE_POLL_MS = 5000;
var QUEUE_SIZE = 1000;
var BATCH_SIZE = 50; // $FlowFixMe
var AsyncBlockIterator =
/*#__PURE__*/
function () {
function AsyncBlockIterator(_ref) {
var client = _ref.client,
filter = _ref.filter;
_classCallCheck(this, AsyncBlockIterator);
this._client = client;
this._items = [];
this._resolvers = [];
this.__done = false;
this._currentIndex = filter.indexStart || 0;
this._fetching = false;
this._startHeight = null;
this._indexStop = filter.indexStop;
} // $FlowFixMe
_createClass(AsyncBlockIterator, [{
key: Symbol.asyncIterator,
value: function value() {
return this;
}
}, {
key: "next",
value: function next() {
var _this = this;
if (!this.__done) {
this._fetch();
}
if (this._items.length > 0) {
var item = this._items.shift();
if (item.type === 'error') {
return Promise.reject(item.error);
}
return Promise.resolve({
done: false,
value: item.value
});
}
if (this.__done) {
return Promise.resolve({
done: true
});
}
return new Promise(function (resolve, reject) {
_this._resolvers.push({
resolve: resolve,
reject: reject
});
});
}
}, {
key: "_write",
value: function _write(value) {
this._push({
type: 'value',
value: value
});
}
}, {
key: "_error",
value: function _error(error) {
this._push({
type: 'error',
error: error
});
}
}, {
key: "_push",
value: function _push(item) {
if (this.__done) {
throw new Error('AsyncBlockIterator already ended');
}
if (this._resolvers.length > 0) {
var _resolvers$shift = this._resolvers.shift(),
_resolve = _resolvers$shift.resolve,
_reject = _resolvers$shift.reject;
if (item.type === 'error') {
_reject(item.error);
} else {
_resolve({
done: false,
value: item.value
});
}
} else {
this._items.push(item);
}
}
}, {
key: "_done",
value: function _done() {
this._resolvers.forEach(function (_ref2) {
var resolve = _ref2.resolve;
return resolve({
done: true
});
});
this._resolvers = [];
this.__done = true;
}
}, {
key: "_fetch",
value: function _fetch() {
var _this2 = this;
if (this._fetching) {
return;
}
this._fetching = true;
this._asyncFetch().then(function () {
_this2._fetching = false;
}).catch(function (error) {
_this2._fetching = false;
_this2._error(error);
});
}
}, {
key: "_asyncFetch",
value: function () {
var _ref3 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee() {
var _this3 = this;
var startHeight, blockCount, index, _ref4, _ref5, block, newStartHeight, toFetch, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _chunk, blocks;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
startHeight = this._startHeight;
if (!(startHeight == null)) {
_context.next = 7;
break;
}
_context.next = 4;
return this._client.getBlockCount();
case 4:
blockCount = _context.sent;
startHeight = blockCount - 1;
this._startHeight = startHeight;
case 7:
index = this._currentIndex;
if (!(this._indexStop != null && index > this._indexStop)) {
_context.next = 12;
break;
}
this._done();
_context.next = 55;
break;
case 12:
if (!(index >= startHeight)) {
_context.next = 24;
break;
}
_context.next = 15;
return Promise.all([this._fetchOne(index), // Refresh the block count in case we got behind somehow
this._client.getBlockCount()]);
case 15:
_ref4 = _context.sent;
_ref5 = _slicedToArray(_ref4, 2);
block = _ref5[0];
newStartHeight = _ref5[1];
this._currentIndex += 1;
this._write(block);
this._startHeight = newStartHeight;
_context.next = 55;
break;
case 24:
toFetch = Math.min(QUEUE_SIZE - this._items.length, startHeight - index);
if (this._indexStop != null) {
toFetch = Math.min(toFetch, this._indexStop - index + 1);
}
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context.prev = 29;
_iterator = _.chunk(_.range(0, toFetch), BATCH_SIZE)[Symbol.iterator]();
case 31:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context.next = 41;
break;
}
_chunk = _step.value;
_context.next = 35;
return Promise.all(_chunk.map(function (offset) {
return _this3._fetchOne(index + offset);
}));
case 35:
blocks = _context.sent;
this._currentIndex += _chunk.length;
blocks.forEach(function (block) {
return _this3._write(block);
});
case 38:
_iteratorNormalCompletion = true;
_context.next = 31;
break;
case 41:
_context.next = 47;
break;
case 43:
_context.prev = 43;
_context.t0 = _context["catch"](29);
_didIteratorError = true;
_iteratorError = _context.t0;
case 47:
_context.prev = 47;
_context.prev = 48;
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
case 50:
_context.prev = 50;
if (!_didIteratorError) {
_context.next = 53;
break;
}
throw _iteratorError;
case 53:
return _context.finish(50);
case 54:
return _context.finish(47);
case 55:
case "end":
return _context.stop();
}
}
}, _callee, this, [[29, 43, 47, 55], [48,, 50, 54]]);
}));
function _asyncFetch() {
return _ref3.apply(this, arguments);
}
return _asyncFetch;
}()
}, {
key: "_fetchOne",
value: function () {
var _ref6 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(index) {
var _this4 = this;
var block;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.prev = 0;
_context2.next = 3;
return this._client.getBlock(index);
case 3:
block = _context2.sent;
return _context2.abrupt("return", block);
case 7:
_context2.prev = 7;
_context2.t0 = _context2["catch"](0);
if (!(_context2.t0 instanceof UnknownBlockError || _context2.t0.unknownBlock)) {
_context2.next = 11;
break;
}
return _context2.abrupt("return", new Promise(function (resolve, reject) {
setTimeout(function () {
return _this4._fetchOne(index).then(resolve, reject);
}, FETCH_ONE_POLL_MS);
}));
case 11:
throw _context2.t0;
case 12:
case "end":
return _context2.stop();
}
}
}, _callee2, this, [[0, 7]]);
}));
function _fetchOne(_x) {
return _ref6.apply(this, arguments);
}
return _fetchOne;
}()
}]);
return AsyncBlockIterator;
}();
var hash160 = (function (client, hash) {
if (typeof hash === 'string') {
try {
return client.addressToScriptHash(hash);
} catch (error) {
return neoBlockchainCore.common.stringToUInt160(hash);
}
} else if (hash instanceof Buffer) {
return neoBlockchainCore.common.bufferToUInt160(hash);
}
return neoBlockchainCore.common.hexToUInt160(hash);
});
var hash256 = (function (client, hash) {
if (typeof hash === 'string') {
return neoBlockchainCore.common.stringToUInt256(hash);
} else if (hash instanceof Buffer) {
return neoBlockchainCore.common.bufferToUInt256(hash);
}
return neoBlockchainCore.common.hexToUInt256(hash);
});
var number = (function (client, value) {
return new BigNumber(value);
});
var privateKey = (function (client, privateKeyLike) {
if (typeof privateKeyLike === 'string') {
try {
return client.wifToPrivateKey(privateKeyLike);
} catch (error) {
return neoBlockchainCore.common.stringToPrivateKey(privateKeyLike);
}
} else if (privateKeyLike instanceof Buffer) {
return neoBlockchainCore.common.bufferToPrivateKey(privateKeyLike);
}
return neoBlockchainCore.common.hexToPrivateKey(privateKeyLike);
});
var converters = {
hash160: hash160,
hash256: hash256,
number: number,
privateKey: privateKey
};
var TEN = new BigNumber('10');
// TODO: Generate methods based on ABI, currently hard coded for NEP5
var SmartContractInstance =
/*#__PURE__*/
function () {
function SmartContractInstance(_ref) {
var abi = _ref.abi,
contractScriptHash = _ref.contractScriptHash,
client = _ref.client;
_classCallCheck(this, SmartContractInstance);
this._abi = abi;
this._contractScriptHash = contractScriptHash;
this._client = client;
this._data = null;
}
_createClass(SmartContractInstance, [{
key: "iterActions",
value: function iterActions(filterIn) {
var _this = this;
var filter = filterIn || {};
return flatmap.flatMap(this._client.iterBlocks({
indexStart: filter.blockIndexStart,
indexStop: filter.blockIndexStop
}), function () {
var _ref2 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(block) {
var actions;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _this._client.getActions({
blockIndexStart: block.index,
transactionIndexStart: block.index === filter.blockIndexStart ? filter.transactionIndexStart : undefined,
indexStart: block.index === filter.blockIndexStart ? filter.indexStart : undefined,
blockIndexStop: block.index,
transactionIndexStop: block.index === filter.blockIndexStop ? filter.transactionIndexStop : undefined,
indexStop: block.index === filter.blockIndexStop ? filter.indexStop : undefined,
scriptHash: neoBlockchainCore.JSONHelper.writeUInt160(_this._contractScriptHash)
});
case 2:
actions = _context.sent;
return _context.abrupt("return", asynciterable.AsyncIterableX.of.apply(asynciterable.AsyncIterableX, _toConsumableArray(actions)));
case 4:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function (_x) {
return _ref2.apply(this, arguments);
};
}());
}
}, {
key: "getAllStorage",
value: function getAllStorage() {
return this._client.getAllStorage(this._contractScriptHash);
}
}, {
key: "transfer",
value: function () {
var _ref4 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(fromAddressIn, toAddressIn, valueIn, _ref3) {
var privateKey, fromAddress, toAddress, value, decimals, sb;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
privateKey = _ref3.privateKey;
fromAddress = converters.hash160(this._client, fromAddressIn);
toAddress = converters.hash160(this._client, toAddressIn);
value = converters.number(this._client, valueIn);
_context2.next = 6;
return this.decimals();
case 6:
decimals = _context2.sent;
sb = new neoBlockchainCore.ScriptBuilder();
sb.emitAppCall(this._contractScriptHash, 'transfer', fromAddress, toAddress, this._numberToInteger(value, decimals));
sb.emitOp('THROWIFNOT'); // TODO: Why is this not covered by Flow?
return _context2.abrupt("return", this._client._sendTransaction(new neoBlockchainCore.InvocationTransaction({
version: 1,
attributes: [new neoBlockchainCore.UInt160Attribute({
usage: neoBlockchainCore.ATTRIBUTE_USAGE.SCRIPT,
value: fromAddress
}), new neoBlockchainCore.BufferAttribute({
usage: neoBlockchainCore.ATTRIBUTE_USAGE.REMARK1,
value: neoBlockchainCore.utils.toSignedBuffer(new BN(neoBlockchainCore.utils.randomUInt()))
})],
script: sb.build(),
gas: neoBlockchainCore.utils.ZERO
}), privateKey));
case 11:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
function transfer(_x2, _x3, _x4, _x5) {
return _ref4.apply(this, arguments);
}
return transfer;
}()
}, {
key: "name",
value: function name() {
return this._getData().then(function (result) {
return result.name;
});
}
}, {
key: "symbol",
value: function symbol() {
return this._getData().then(function (result) {
return result.symbol;
});
}
}, {
key: "decimals",
value: function () {
var _ref5 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee3() {
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
return _context3.abrupt("return", this._getData().then(function (result) {
return result.decimals;
}));
case 1:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
function decimals() {
return _ref5.apply(this, arguments);
}
return decimals;
}()
}, {
key: "totalSupply",
value: function () {
var _ref6 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee4() {
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
return _context4.abrupt("return", this._getData().then(function (result) {
return result.totalSupply;
}));
case 1:
case "end":
return _context4.stop();
}
}
}, _callee4, this);
}));
function totalSupply() {
return _ref6.apply(this, arguments);
}
return totalSupply;
}()
}, {
key: "_integerToNumber",
value: function _integerToNumber(value, decimals) {
if (decimals > 0) {
return value.div(TEN.pow(decimals));
}
return value;
}
}, {
key: "_numberToInteger",
value: function _numberToInteger(valueIn, decimals) {
var value = valueIn;
if (decimals > 0) {
value = valueIn.times(TEN.pow(decimals));
}
return new BN(value.toString(10), 10);
}
}, {
key: "_invokeScript",
value: function () {
var _ref7 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee5(script) {
var result;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_context5.next = 2;
return this._client.invokeScript(script);
case 2:
result = _context5.sent;
if (!(result.type === 'Error')) {
_context5.next = 5;
break;
}
throw new Error(result.message);
case 5:
return _context5.abrupt("return", result.stack);
case 6:
case "end":
return _context5.stop();
}
}
}, _callee5, this);
}));
function _invokeScript(_x6) {
return _ref7.apply(this, arguments);
}
return _invokeScript;
}()
}, {
key: "_getData",
value: function _getData() {
var _this2 = this;
if (this._data == null) {
var sb = new neoBlockchainCore.ScriptBuilder();
sb.emitAppCall(this._contractScriptHash, 'name');
sb.emitAppCall(this._contractScriptHash, 'symbol');
sb.emitAppCall(this._contractScriptHash, 'decimals');
sb.emitAppCall(this._contractScriptHash, 'totalSupply');
this._data = this._invokeScript(sb.build()).then(function (result) {
var name = _this2._client.parameters.toString(result[3]);
var symbol = _this2._client.parameters.toString(result[2]);
var decimals = _this2._client.parameters.toInteger(result[1]).toNumber();
var totalSupply = _this2._integerToNumber(_this2._client.parameters.toInteger(result[0]), decimals);
return {
name: name,
symbol: symbol,
decimals: decimals,
totalSupply: totalSupply
};
}).catch(function (error) {
_this2._data = null;
throw error;
});
}
return this._data;
}
}]);
return SmartContractInstance;
}();
var SmartContract =
/*#__PURE__*/
function () {
function SmartContract(_ref) {
var abi = _ref.abi,
client = _ref.client;
_classCallCheck(this, SmartContract);
this._abi = abi;
this._client = client;
}
_createClass(SmartContract, [{
key: "at",
value: function at(contractScriptHash) {
return new SmartContractInstance({
abi: this._abi,
contractScriptHash: converters.hash160(this._client, contractScriptHash),
client: this._client
});
}
}]);
return SmartContract;
}();
// TODO: Actually implement this.
var NEP5 = {};
var abi = {
NEP5: NEP5
};
function createNullable(to) {
return function (parameter) {
try {
return to(parameter);
} catch (error) {
return null;
}
};
}
var toString = function toString(parameter) {
if (parameter.type === 'String') {
return parameter.value;
} else if (parameter.type === 'ByteArray') {
return neoBlockchainCore.JSONHelper.readBuffer(parameter.value).toString('utf8');
}
throw new InvalidContractParameterError(parameter, ['String', 'ByteArray']);
};
var toStringNullable = createNullable(toString);
var toHash160 = function toHash160(parameter) {
if (parameter.type === 'Hash160') {
return parameter.value;
} else if (parameter.type === 'ByteArray') {
return neoBlockchainCore.common.uInt160ToString(neoBlockchainCore.common.bufferToUInt160(neoBlockchainCore.JSONHelper.readBuffer(parameter.value)));
}
throw new InvalidContractParameterError(parameter, ['Hash160', 'ByteArray']);
};
var toHash160Nullable = createNullable(toHash160);
var toInteger = function toInteger(parameter) {
if (parameter.type === 'Integer') {
return new BigNumber(parameter.value);
} else if (parameter.type === 'ByteArray') {
return new BigNumber(neoBlockchainCore.utils.fromSignedBuffer(neoBlockchainCore.JSONHelper.readBuffer(parameter.value)).toString(10));
}
throw new InvalidContractParameterError(parameter, ['Integer', 'ByteArray']);
};
var toIntegerNullable = createNullable(toInteger);
var parameters = {
toString: toString,
toStringNullable: toStringNullable,
toHash160: toHash160,
toHash160Nullable: toHash160Nullable,
toInteger: toInteger,
toIntegerNullable: toIntegerNullable
};
// eslint-disable-next-line
var Client =
/*#__PURE__*/
function () {
function Client(optionsIn) {
_classCallCheck(this, Client);
Object.defineProperty(this, "parameters", {
configurable: true,
enumerable: true,
writable: true,
value: parameters
});
Object.defineProperty(this, "abi", {
configurable: true,
enumerable: true,
writable: true,
value: abi
});
var options = optionsIn || {};
this._addressVersion = options.addressVersion == null ? neoBlockchainCore.common.NEO_ADDRESS_VERSION : options.addressVersion;
this._privateKeyVersion = options.privateKeyVersion == null ? neoBlockchainCore.common.NEO_PRIVATE_KEY_VERSION : options.privateKeyVersion;
}
_createClass(Client, [{
key: "getAccount",
// eslint-disable-next-line
value: function getAccount(addressOrScriptHash) {
throw new Error('Not Implemented');
} // eslint-disable-next-line
}, {
key: "getAsset",
value: function getAsset(hash) {
throw new Error('Not Implemented');
} // eslint-disable-next-line
}, {
key: "getBlock",
value: function getBlock(hashOrIndex) {
throw new Error('Not Implemented');
}
}, {
key: "smartContract",
value: function smartContract(abiIn) {
return new SmartContract({
abi: abiIn,
client: this
});
} // eslint-disable-next-line
}, {
key: "getActions",
value: function getActions(filters) {
throw new Error('Not Implemented');
}
}, {
key: "getBestBlockHash",
value: function getBestBlockHash() {
throw new Error('Not Implemented');
}
}, {
key: "getBlockCount",
value: function getBlockCount() {
throw new Error('Not Implemented');
}
}, {
key: "iterBlocks",
value: function iterBlocks(filter) {
return new AsyncBlockIterator({
filter: filter,
client: this
});
} // eslint-disable-next-line
}, {
key: "sendRawTransaction",
value: function sendRawTransaction(value) {
throw new Error('Not Implemented');
}
}, {
key: "transferRaw",
value: function transferRaw(inputs, outputs, _ref) {
var privateKey = _ref.privateKey;
return this._sendTransaction( // TODO: Not covered by Flow...
new neoBlockchainCore.ContractTransaction({
inputs: this._convertInputs(inputs),
outputs: this._convertOutputs(outputs)
}), privateKey);
}
}, {
key: "claimRaw",
value: function claimRaw(claims, outputs, _ref2) {
var privateKey = _ref2.privateKey;
return this._sendTransaction( // TODO: Not covered by Flow...
new neoBlockchainCore.ClaimTransaction({
claims: this._convertInputs(claims),
outputs: this._convertOutputs(outputs)
}), privateKey);
} // eslint-disable-next-line
}, {
key: "invokeScript",
value: function invokeScript(script) {
throw new Error('Not Implemented');
} // eslint-disable-next-line
}, {
key: "getAllStorage",
value: function getAllStorage(hash) {
throw new Error('Not Implemented');
}
}, {
key: "scriptHashToAddress",
value: function scriptHashToAddress(scriptHash) {
return neoBlockchainCore.crypto.scriptHashToAddress({
addressVersion: this._addressVersion,
scriptHash: converters.hash160(this, scriptHash)
});
}
}, {
key: "addressToScriptHash",
value: function addressToScriptHash(address) {
return neoBlockchainCore.crypto.addressToScriptHash({
addressVersion: this._addressVersion,
address: address
});
}
}, {
key: "wifToPrivateKey",
value: function wifToPrivateKey(wif) {
return neoBlockchainCore.crypto.wifToPrivateKey(wif, this._privateKeyVersion);
}
}, {
key: "privateKeyToWIF",
value: function privateKeyToWIF(privateKey) {
return neoBlockchainCore.crypto.privateKeyToWif(converters.privateKey(this, privateKey), this._privateKeyVersion);
}
}, {
key: "privateKeyToAddress",
value: function privateKeyToAddress(privateKey) {
return neoBlockchainCore.crypto.privateKeyToAddress({
addressVersion: this._addressVersion,
privateKey: converters.privateKey(this, privateKey)
});
}
}, {
key: "createPrivateKey",
value: function createPrivateKey() {
return neoBlockchainCore.crypto.createPrivateKey();
}
}, {
key: "encryptNEP2",
value: function encryptNEP2(_ref3) {
var password = _ref3.password,
privateKey = _ref3.privateKey;
return neoBlockchainCore.crypto.encryptNEP2({
addressVersion: this._addressVersion,
privateKey: converters.privateKey(this, privateKey),
password: password
});
}
}, {
key: "decryptNEP2",
value: function decryptNEP2(_ref4) {
var password = _ref4.password,
encryptedKey = _ref4.encryptedKey;
return neoBlockchainCore.crypto.decryptNEP2({
addressVersion: this._addressVersion,
encryptedKey: encryptedKey,
password: password
});
}
}, {
key: "_convertInputs",
value: function _convertInputs(inputs) {
var _this = this;
// TODO: Not covered by Flow...
return inputs.map(function (input) {
return new neoBlockchainCore.Input({
hash: converters.hash256(_this, input.txid),
index: input.index
});
});
}
}, {
key: "_convertOutputs",
value: function _convertOutputs(outputs) {
var _this2 = this;
// TODO: Not covered by Flow...
return outputs.map(function (output) {
return new neoBlockchainCore.Output({
address: converters.hash160(_this2, output.address),
asset: converters.hash256(_this2, output.asset),
value: neoBlockchainCore.common.fixed8FromDecimal(output.value)
});
});
}
}, {
key: "_sendTransaction",
value: function () {
var _ref5 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(transactionUnsigned, privateKeyLike) {
var transaction;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
transaction = transactionUnsigned.sign(converters.privateKey(this, privateKeyLike));
_context.next = 3;
return this.sendRawTransaction(transaction.serializeWire());
case 3:
return _context.abrupt("return", neoBlockchainCore.JSONHelper.writeUInt256(transaction.hash));
case 4:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function _sendTransaction(_x, _x2) {
return _ref5.apply(this, arguments);
}
return _sendTransaction;
}()
}]);
return Client;
}();
var JSONRPCClient =
/*#__PURE__*/
function (_Client) {
_inherits(JSONRPCClient, _Client);
function JSONRPCClient(provider, optionsIn) {
var _this;
_classCallCheck(this, JSONRPCClient);
var options = optionsIn || {};
_this = _possibleConstructorReturn(this, (JSONRPCClient.__proto__ || Object.getPrototypeOf(JSONRPCClient)).call(this, {
addressVersion: options.addressVersion,
privateKeyVersion: options.privateKeyVersion
}));
_this._provider = provider;
return _this;
}
_createClass(JSONRPCClient, [{
key: "getAccount",
value: function getAccount(addressOrScriptHash) {
return this._provider.request({
method: 'getaccountstate',
params: [this.scriptHashToAddress(converters.hash160(this, addressOrScriptHash))]
});
}
}, {
key: "getAsset",
value: function getAsset(hash) {
return this._provider.request({
method: 'getassetstate',
params: [neoBlockchainCore.JSONHelper.writeUInt256(converters.hash256(this, hash))]
});
}
}, {
key: "getBlock",
value: function getBlock(hashOrIndex) {
return this._provider.request({
method: 'getblock',
params: [typeof hashOrIndex === 'number' ? hashOrIndex : neoBlockchainCore.JSONHelper.writeUInt256(converters.hash256(this, hashOrIndex)), 1]
});
} // eslint-disable-next-line
}, {
key: "getActions",
value: function getActions(filter) {
return this._provider.request({
method: 'getactions',
params: [_extends({}, filter, {
scriptHash: filter.scriptHash == null ? undefined : neoBlockchainCore.JSONHelper.writeUInt160(converters.hash160(this, filter.scriptHash))
})]
});
}
}, {
key: "getBestBlockHash",
value: function getBestBlockHash() {
return this._provider.request({
method: 'getbestblockhash'
});
}
}, {
key: "getBlockCount",
value: function getBlockCount() {
return this._provider.request({
method: 'getblockcount'
});
}
}, {
key: "sendRawTransaction",
value: function sendRawTransaction(value) {
return this._provider.request({
method: 'sendrawtransaction',
params: [neoBlockchainCore.JSONHelper.writeBuffer(value)]
}).then(function (result) {
if (!result) {
throw new SendTransactionError();
}
});
}
}, {
key: "invokeScript",
value: function invokeScript(script) {
return this._provider.request({
method: 'invokescriptv2',
params: [neoBlockchainCore.JSONHelper.writeBuffer(script)]
});
} // eslint-disable-next-line
}, {
key: "getAllStorage",
value: function getAllStorage(hash) {
return this._provider.request({
method: 'getallstorage',
params: [neoBlockchainCore.JSONHelper.writeUInt160(converters.hash160(this, hash))]
});
}
}]);
return JSONRPCClient;
}(Client);
var _fixBabelExtend$1 = function (O) {
var gOPD = O.getOwnPropertyDescriptor,
gPO = O.getPrototypeOf || function (o) {
return o.__proto__;
},
sPO = O.setPrototypeOf || function (o, p) {
o.__proto__ = p;
return o;
},
construct = _typeof(Reflect) === 'object' ? Reflect.construct : function (Parent, args, Class) {
var Constructor,
a = [null];
a.push.apply(a, args);
Constructor = Parent.bind.apply(Parent, a);
return sPO(new Constructor(), Class.prototype);
};
return function fixBabelExtend(Class) {
var Parent = gPO(Class);
return sPO(Class, sPO(function Super() {
return construct(Parent, arguments, gPO(this).constructor);
}, Parent));
};
}(Object);
// eslint-disable-next-line
var JSONRPCError = _fixBabelExtend$1(
/*#__PURE__*/
function (_Error) {
_inherits(JSONRPCError, _Error);
function JSONRPCError(responseError) {
var _this;
_classCallCheck(this, JSONRPCError);
_this = _possibleConstructorReturn(this, (JSONRPCError.__proto__ || Object.getPrototypeOf(JSONRPCError)).call(this, responseError.message));
_this.responseError = responseError;
return _this;
}
return JSONRPCError;
}(Error));
var InvalidRPCResponseError = _fixBabelExtend$1(
/*#__PURE__*/
function (_Error2) {
_inherits(InvalidRPCResponseError, _Error2);
function InvalidRPCResponseError() {
_classCallCheck(this, InvalidRPCResponseError);
return _possibleConstructorReturn(this, (InvalidRPCResponseError.__proto__ || Object.getPrototypeOf(InvalidRPCResponseError)).call(this, 'Did not receive valid rpc response'));
}
return InvalidRPCResponseError;
}(Error));
var HTTPError = _fixBabelExtend$1(
/*#__PURE__*/
function (_Error3) {
_inherits(HTTPError, _Error3);
function HTTPError(status, text) {
var _this2;
_classCallCheck(this, HTTPError);
var message = "HTTP Error ".concat(status);
if (text != null) {
message = "".concat(message, ": ").concat(text);
}
_this2 = _possibleConstructorReturn(this, (HTTPError.__proto__ || Object.getPrototypeOf(HTTPError)).call(this, message));
_this2.status = status;
_this2.text = text;
return _this2;
}
return HTTPError;
}(Error));
// take a long time to respond
var TIMEOUT_MS = 20000;
var PARSE_ERROR_CODE = -32700;
var PARSE_ERROR_MESSAGE = 'Parse error';
var request = function () {
var _ref2 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(_ref) {
var endpoint, requests, timeoutMS, triesIn, timeout, tries, parseErrorTries, result, finalError, response, text;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
endpoint = _ref.endpoint, requests = _ref.requests, timeoutMS = _ref.timeoutMS, triesIn = _ref.tries;
timeout = timeoutMS == null ? 5000 : timeoutMS;
tries = triesIn == null ? 0 : triesIn;
parseErrorTries = 3;
case 4:
if (!(tries >= 0)) {
_context.next = 36;
break;
}
_context.prev = 5;
_context.next = 8;
return fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requests),
timeout: timeout
});
case 8:
response = _context.sent;
if (response.ok) {
_context.next = 20;
break;
}
text = null;
_context.prev = 11;
_context.next = 14;
return response.text();
case 14:
text = _context.sent;
_context.next = 19;
break;
case 17:
_context.prev = 17;
_context.t0 = _context["catch"](11);
case 19:
throw new HTTPError(response.status, text);
case 20:
_context.next = 22;
return response.json();
case 22:
result = _context.sent;
if (Array.isArray(result)) {
_context.next = 27;
break;
}
if (result.error && result.error.code === PARSE_ERROR_CODE && result.error.message === PARSE_ERROR_MESSAGE && parseErrorTries > 0) {
tries += 1;
parseErrorTries -= 1;
}
_context.next = 28;
break;
case 27:
return _context.abrupt("return", result);
case 28:
_context.next = 33;
break;
case 30:
_context.prev = 30;
_context.t1 = _context["catch"](5);
finalError = _context.t1;
case 33:
tries -= 1;
_context.next = 4;
break;
case 36:
if (!(finalError != null)) {
_context.next = 38;
break;
}
throw finalError;
case 38:
throw new InvalidRPCResponseError();
case 39:
case "end":
return _context.stop();
}
}
}, _callee, this, [[5, 30], [11, 17]]);
}));
return function request(_x) {
return _ref2.apply(this, arguments);
};
}();
var handleResponse = function handleResponse(responseJSON) {
if (responseJSON.error != null) {
if (responseJSON.error.code === -100 && responseJSON.error.message === 'Unknown block') {
throw new UnknownBlockError();
}
throw new JSONRPCError(responseJSON.error);
}
return responseJSON.result;
};
var JSONRPCHttpProvider =
/*#__PURE__*/
function () {
function JSONRPCHttpProvider(endpoint) {
_classCallCheck(this, JSONRPCHttpProvider);
this.batcher = new DataLoader(function () {
var _ref3 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(requests) {
var result;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return request({
endpoint: endpoint,
requests: requests,
tries: 1,
timeoutMS: TIMEOUT_MS
});
case 2:
result = _context2.sent;
return _context2.abrupt("return", result);
case 4:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function (_x2) {
return _ref3.apply(this, arguments);
};
}(), {
maxBatchSize: 25,
cache: false
});
}
_createClass(JSONRPCHttpProvider, [{
key: "request",
value: function () {
var _ref4 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee3(req) {
var responseJSON;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return this.batcher.load(_extends({
jsonrpc: '2.0',
id: 1,
params: []
}, req));
case 2:
responseJSON = _context3.sent;
return _context3.abrupt("return", handleResponse(responseJSON));
case 4:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
function request(_x3) {
return _ref4.apply(this, arguments);
}
return request;
}()
}]);
return JSONRPCHttpProvider;
}();
var client = new JSONRPCClient(new JSONRPCHttpProvider('https://neotracker.io/rpc'));
var testClient = new JSONRPCClient(new JSONRPCHttpProvider('https://testnet.neotracker.io/rpc'));
exports.client = client;
exports.testClient = testClient;
exports.JSONRPCClient = JSONRPCClient;
exports.JSONRPCHttpProvider = JSONRPCHttpProvider;
exports.Client = Client;
//# sourceMappingURL=index.js.map