UNPKG

@open-rights-exchange/orejs

Version:

Orejs is a Javascript helper library to provide simple high-level access to the ore-protocol. Orejs uses eosJS as a wrapper to the EOS blockchain.

353 lines 18 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; /* Private */ var _a = require('eosjs'), Serialize = _a.Serialize, RpcError = _a.RpcError; var ecc = require('eosjs-ecc'); var _b = require('./constants'), BLOCKS_BEHIND_REF_BLOCK = _b.BLOCKS_BEHIND_REF_BLOCK, BLOCKS_TO_CHECK = _b.BLOCKS_TO_CHECK, CHECK_INTERVAL = _b.CHECK_INTERVAL, GET_BLOCK_ATTEMPTS = _b.GET_BLOCK_ATTEMPTS, TRANSACTION_ENCODING = _b.TRANSACTION_ENCODING, TRANSACTION_EXPIRY_IN_SECONDS = _b.TRANSACTION_EXPIRY_IN_SECONDS; var mapError = require('./errors').mapError; // NOTE: More than a simple wrapper for eos.rpc.get_info // NOTE: Saves state from get_info, which can be used by other methods // NOTE: For example, newaccount will have different field names, depending on the server_version_string function getInfo() { return __awaiter(this, void 0, void 0, function () { var info; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.eos.rpc.get_info({})]; case 1: info = _a.sent(); this.chainInfo = info; return [2 /*return*/, info]; } }); }); } /* Public */ function hasTransaction(block, transactionId) { return __awaiter(this, void 0, void 0, function () { var result; return __generator(this, function (_a) { if (block.transactions) { result = block.transactions.find(function (transaction) { return transaction.trx.id === transactionId; }); if (result !== undefined) { return [2 /*return*/, true]; } } return [2 /*return*/, false]; }); }); } function getChainId() { return __awaiter(this, void 0, void 0, function () { var _a, chainId; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, getInfo.bind(this)()]; case 1: _a = (_b.sent()).chain_id, chainId = _a === void 0 ? null : _a; return [2 /*return*/, chainId]; } }); }); } function sendTransaction(func, confirm, awaitTransactionOptions) { return __awaiter(this, void 0, void 0, function () { var transaction, error_1, errString; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(confirm === true)) return [3 /*break*/, 2]; return [4 /*yield*/, awaitTransaction.bind(this)(func, awaitTransactionOptions)]; case 1: transaction = _a.sent(); return [3 /*break*/, 5]; case 2: _a.trys.push([2, 4, , 5]); return [4 /*yield*/, func()]; case 3: transaction = _a.sent(); return [3 /*break*/, 5]; case 4: error_1 = _a.sent(); errString = mapError(error_1); throw new Error("Send Transaction Failure: " + errString); case 5: return [2 /*return*/, transaction]; } }); }); } // NOTE: Use this to await for transactions to be added to a block // NOTE: Useful, when committing sequential transactions with inter-dependencies // NOTE: This does NOT confirm that the transaction is irreversible, aka finalized // NOTE: blocksToCheck = the number of blocks to check, after committing the transaction, before giving up // NOTE: checkInterval = the time between block checks in MS // NOTE: getBlockAttempts = the number of failed attempts at retrieving a particular block, before giving up function awaitTransaction(func, options) { var _this = this; if (options === void 0) { options = {}; } var _a = options.blocksToCheck, blocksToCheck = _a === void 0 ? BLOCKS_TO_CHECK : _a, _b = options.checkInterval, checkInterval = _b === void 0 ? CHECK_INTERVAL : _b, _c = options.getBlockAttempts, getBlockAttempts = _c === void 0 ? GET_BLOCK_ATTEMPTS : _c; var startingBlockNumToCheck; var blockNumToCheck; return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { var preCommitInfo, preCommitHeadBlockNum, transaction, processed, _a, block_num, error_2, errString, blockToCheck, getBlockAttempt, blockHasTransaction, inProgress, intConfirm; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, getInfo.bind(this)()]; case 1: preCommitInfo = _b.sent(); preCommitHeadBlockNum = preCommitInfo.head_block_num; _b.label = 2; case 2: _b.trys.push([2, 4, , 5]); return [4 /*yield*/, func()]; case 3: transaction = _b.sent(); processed = (transaction || {}).processed; _a = (processed || {}).block_num, block_num = _a === void 0 ? preCommitHeadBlockNum : _a; startingBlockNumToCheck = block_num - 1; return [3 /*break*/, 5]; case 4: error_2 = _b.sent(); errString = mapError(error_2); return [2 /*return*/, reject(new Error("Await Transaction Failure: " + errString))]; case 5: getBlockAttempt = 1; blockHasTransaction = false; inProgress = false; blockNumToCheck = startingBlockNumToCheck; intConfirm = setInterval(function () { return __awaiter(_this, void 0, void 0, function () { var error_3; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 3, , 4]); if (inProgress) return [2 /*return*/]; inProgress = true; return [4 /*yield*/, this.eos.rpc.get_block(blockNumToCheck)]; case 1: blockToCheck = _a.sent(); return [4 /*yield*/, hasTransaction(blockToCheck, transaction.transaction_id)]; case 2: blockHasTransaction = _a.sent(); if (blockHasTransaction) { clearInterval(intConfirm); resolve(transaction); } getBlockAttempt = 1; blockNumToCheck += 1; inProgress = false; return [3 /*break*/, 4]; case 3: error_3 = _a.sent(); if (getBlockAttempt >= getBlockAttempts) { clearInterval(intConfirm); return [2 /*return*/, reject(new Error("Await Transaction Failure: Failure to find a block, after " + getBlockAttempt + " attempts to check block " + blockNumToCheck + "."))]; } getBlockAttempt += 1; return [3 /*break*/, 4]; case 4: if (blockNumToCheck > startingBlockNumToCheck + blocksToCheck) { clearInterval(intConfirm); return [2 /*return*/, reject(new Error("Await Transaction Timeout: Waited for " + blocksToCheck + " blocks ~(" + (checkInterval / 1000) * blocksToCheck + " seconds) starting with block num: " + startingBlockNumToCheck + ". This does not mean the transaction failed just that the transaction wasn't found in a block before timeout"))]; } return [2 /*return*/]; } }); }); }, checkInterval); return [2 /*return*/]; } }); }); }); } function getAllTableRows(params, key_field, json) { if (key_field === void 0) { key_field = 'id'; } if (json === void 0) { json = true; } return __awaiter(this, void 0, void 0, function () { var results, lowerBound, limit, parameters; return __generator(this, function (_a) { switch (_a.label) { case 0: results = []; lowerBound = 0; limit = -1; parameters = __assign(__assign({}, params), { json: json, lower_bound: params.lower_bound || lowerBound, scope: params.scope || params.code, limit: params.limit || limit }); return [4 /*yield*/, this.eos.rpc.get_table_rows(parameters)]; case 1: results = _a.sent(); return [2 /*return*/, results.rows]; } }); }); } // check if the publickey belongs to the account provided function checkPubKeytoAccount(account, publicKey) { return __awaiter(this, void 0, void 0, function () { var keyaccounts, accounts; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.eos.rpc.history_get_key_accounts(publicKey)]; case 1: keyaccounts = _a.sent(); return [4 /*yield*/, keyaccounts.account_names]; case 2: accounts = _a.sent(); if (accounts.includes(account)) { return [2 /*return*/, true]; } return [2 /*return*/, false]; } }); }); } // NOTE: setting the broadcast parameter to false allows us to receive signed transactions, without submitting them function transact(actions, broadcast, blocksBehind, expireSeconds) { if (broadcast === void 0) { broadcast = true; } if (blocksBehind === void 0) { blocksBehind = BLOCKS_BEHIND_REF_BLOCK; } if (expireSeconds === void 0) { expireSeconds = TRANSACTION_EXPIRY_IN_SECONDS; } return this.eos.transact({ actions: actions }, { blocksBehind: blocksBehind, broadcast: broadcast, expireSeconds: expireSeconds }); } function serializeTransaction(transaction, transactionOptions) { if (transactionOptions === void 0) { transactionOptions = {}; } var _a = transactionOptions.blocksBehind, blocksBehind = _a === void 0 ? BLOCKS_BEHIND_REF_BLOCK : _a, _b = transactionOptions.expireSeconds, expireSeconds = _b === void 0 ? TRANSACTION_EXPIRY_IN_SECONDS : _b, _c = transactionOptions.broadcast, broadcast = _c === void 0 ? false : _c, _d = transactionOptions.sign, sign = _d === void 0 ? false : _d; var options = { blocksBehind: blocksBehind, expireSeconds: expireSeconds, broadcast: broadcast, sign: sign }; return this.eos.transact(transaction, options); } function deserializeTransaction(serializedTransaction) { return this.eos.deserializeTransaction(serializedTransaction); } function createSignBuffer(serializedTransaction) { return __awaiter(this, void 0, void 0, function () { var chainId; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, getChainId.bind(this)()]; case 1: chainId = _a.sent(); return [2 /*return*/, Buffer.concat([ Buffer.from(chainId, 'hex'), Buffer.from(serializedTransaction), Buffer.from(new Uint8Array(32)) ])]; } }); }); } function signSerializedTransactionBuffer(signBuffer, privateKey, encoding) { if (encoding === void 0) { encoding = TRANSACTION_ENCODING; } return ecc.sign(signBuffer, privateKey).toString(); } function isValidPublicKey(publicKey) { return ecc.isValidPublic(publicKey); } function recoverPublicKeyFromSignature(signBuffer, transaction, encoding) { if (encoding === void 0) { encoding = TRANSACTION_ENCODING; } return ecc.recover(signBuffer, transaction); } function signRawTransaction(transaction, transactionOptions, privateKey, additionalSignatures) { if (transactionOptions === void 0) { transactionOptions = {}; } if (additionalSignatures === void 0) { additionalSignatures = []; } return __awaiter(this, void 0, void 0, function () { var serializedTrx, serializeTransaction, signBuf, signature, signedTrx; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, serializeTransaction.bind(this)(transaction, transactionOptions)]; case 1: serializedTrx = _a.sent(); serializeTransaction = serializedTrx.serializeTransaction; return [4 /*yield*/, createSignBuffer.bind(this)(serializeTransaction)]; case 2: signBuf = _a.sent(); return [4 /*yield*/, signSerializedTransactionBuffer(signBuf, privateKey)]; case 3: signature = _a.sent(); signedTrx = {}; signedTrx.signatures = []; signedTrx.signatures.push(signature); signedTrx.serializedTransaction = serializedTrx.serializedTransaction; if (additionalSignatures.length > 0) { signedTrx.signatures.concat(additionalSignatures); } return [2 /*return*/, signedTrx]; } }); }); } function pushSignedTransaction(signedTransaction) { return this.eos.pushSignedTransaction(signedTransaction); } module.exports = { checkPubKeytoAccount: checkPubKeytoAccount, createSignBuffer: createSignBuffer, getAllTableRows: getAllTableRows, hasTransaction: hasTransaction, hexToUint8Array: Serialize.hexToUint8Array, isValidPublicKey: isValidPublicKey, pushSignedTransaction: pushSignedTransaction, recoverPublicKeyFromSignature: recoverPublicKeyFromSignature, sendTransaction: sendTransaction, serializeTransaction: serializeTransaction, deserializeTransaction: deserializeTransaction, signRawTransaction: signRawTransaction, signSerializedTransactionBuffer: signSerializedTransactionBuffer, transact: transact }; //# sourceMappingURL=eos.js.map