UNPKG

neo-blockchain-client

Version:
1,658 lines (1,430 loc) 47 kB
'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