@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
JavaScript
"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