postchain-client
Version:
Client library for accessing a Postchain node through REST.
536 lines • 34.5 kB
JavaScript
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());
});
};
import { randomBytes } from "crypto";
import cloneDeep from "lodash/cloneDeep";
import { getBlockAnchoringTransaction } from "../ICCF/IccfProofTxMaterialBuilder";
import * as logger from "../logger";
import { toBuffer, toString, toQueryObjectGTV, ensureString, ensureBuffer } from "../formatter";
import { decodeValue, encodeValue } from "../gtx/serialization";
import * as gtxTool from "../gtx/gtx";
import { callbackPromiseBuilder, formatBlockInfoResponse, formatTransactionInfoResponse, getClientConfigFromSettings, getGTXFromBufferOrTransactionOrOperation, getSerializedGTX, handlePostResponsePromisified, handleSystemConfirmations, isKeyPair, getAnchoringClientAndSystemChainRid, getSystemAnchoringTransaction, linkPromiEvents, handleGetResponse, handlePostResponse, handleDappConfirmations, getMerkleHashVersionFromDapp, formatRejectedTransactionFromResponse, } from "./utils";
import { Web3PromiEvent } from "../promiEvent/promiEvents";
import { NumberOfSignersAndSignaturesException } from "../gtx/errors";
import { ResponseStatus, ChainConfirmationLevel, AnchoringStatus, TransactionEvent, Method, } from "./enums";
import { isBlockIdentifierValid } from "./validation/blockIdentifier";
import { isNetworkSettingValid } from "./validation/networkSettings";
import { isSignMethodValid } from "./validation/signMethod";
import { isTxRidValid } from "./validation/txRid";
import { AnchoringTransactionSchema } from "./validation/anchoringTransaction";
import { isBlockInfoResponse, isBlockInfoResponseArray, isRawGtv, isRejectedTransactionResponseArray, isTransaction, isTransactionConfirmationProof, isTransactionInfoResponse, isTransactionInfoResponseArray, isTransactionsCount, } from "./validation/requests";
import { awaitGetAnchoringTransactionForBlockRid } from "../ICCF/utils";
import { requestWithFailoverStrategy } from "./requestWithFailoverStrategy";
import { validateTransactionStatusReponse } from "./validation/transactionStatusReponse";
export function createClient(settings) {
return __awaiter(this, void 0, void 0, function* () {
isNetworkSettingValid(settings, { throwOnError: true });
const config = yield getClientConfigFromSettings(settings);
config.merkleHashVersion = yield getMerkleHashVersion(settings);
return {
config,
query(nameOrQueryObject, args, callback) {
return __awaiter(this, void 0, void 0, function* () {
let _name, _args;
if (typeof nameOrQueryObject === "string") {
_name = nameOrQueryObject;
_args = args;
}
else {
_name = nameOrQueryObject === null || nameOrQueryObject === void 0 ? void 0 : nameOrQueryObject.name;
_args = nameOrQueryObject === null || nameOrQueryObject === void 0 ? void 0 : nameOrQueryObject.args;
}
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.POST, `query_gtv/${config.blockchainRid}`, config, encodeValue(toQueryObjectGTV(_name, _args)));
return new Promise((resolve, reject) => {
handlePostResponse(error, statusCode, isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
signTransaction(transaction, signMethod, callback) {
return __awaiter(this, void 0, void 0, function* () {
logger.debug(`Signing transaction with ${!isKeyPair(signMethod) ? "signature provider containing " : ""}pubKey: ${toString(signMethod.pubKey)}`);
const gtx = getGTXFromBufferOrTransactionOrOperation(transaction, config.blockchainRid);
try {
const signedTx = yield (isKeyPair(signMethod)
? gtxTool.sign(gtx, signMethod.privKey, config.merkleHashVersion, signMethod.pubKey)
: gtxTool.sign(gtx, signMethod, config.merkleHashVersion));
const gtxBytes = getSerializedGTX(signedTx);
if (typeof callback === "function") {
callback(null, gtxBytes);
}
return gtxBytes;
}
catch (error) {
if (typeof callback === "function") {
callback(error, null);
}
// Todo the error should be replaced with the custom error MissingSignerException
throw new Error(error);
}
});
},
sendTransaction(transaction, doStatusPolling = true, callback, confirmationLevel = ChainConfirmationLevel.Dapp) {
const promiEvent = new Web3PromiEvent((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
var _a;
try {
const gtx = getGTXFromBufferOrTransactionOrOperation(transaction, config.blockchainRid);
if (gtx.signers.length !== ((_a = gtx.signatures) === null || _a === void 0 ? void 0 : _a.length)) {
reject(new NumberOfSignersAndSignaturesException());
}
const gtxBytes = getSerializedGTX(gtx);
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.POST, `tx/${config.blockchainRid}`, config, gtxBytes);
const transactionRid = gtxTool.getDigestToSign(gtx, config.merkleHashVersion);
try {
yield handlePostResponsePromisified(error, statusCode, isRawGtv(rspBody));
if (typeof callback === "function") {
callback(null, {
status: ResponseStatus.Waiting,
statusCode,
transactionRid: transactionRid,
});
}
}
catch (_error) {
if (typeof callback === "function") {
callback(_error, null);
}
return reject(_error);
}
const client = this;
const statusPollingConfig = {
dappStatusPolling: client.config.dappStatusPolling,
clusterAnchoringStatusPolling: client.config.clusterAnchoringStatusPolling,
systemAnchoringStatusPolling: client.config.systemAnchoringStatusPolling,
};
let transactionReceipt = yield handleDappConfirmations(transactionRid, doStatusPolling, confirmationLevel, promiEvent, statusPollingConfig.dappStatusPolling, () => client.getTransactionStatus(transactionRid, callback));
if (confirmationLevel === ChainConfirmationLevel.None ||
confirmationLevel === ChainConfirmationLevel.Dapp) {
resolve(transactionReceipt);
return;
}
const { anchoringClient, systemAnchoringChainBridString } = yield getAnchoringClientAndSystemChainRid(client);
transactionReceipt = yield handleSystemConfirmations(transactionReceipt, confirmationLevel, promiEvent, statusPollingConfig, anchoringClient, systemAnchoringChainBridString, () => client.getClusterAnchoringTransactionConfirmation(transactionRid, anchoringClient, callback), anchoredTxRid => client.getSystemAnchoringTransactionConfirmation(anchoredTxRid, anchoringClient, systemAnchoringChainBridString, callback));
resolve(transactionReceipt);
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
reject(error);
}
}));
return promiEvent;
},
signAndSendUniqueTransaction(transactionOrOperation, signMethod, doStatusPolling = true, callback, confirmationLevel = ChainConfirmationLevel.Dapp) {
isSignMethodValid(signMethod, { throwOnError: true });
const promiEvent = new Web3PromiEvent((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
const client = this;
const transaction = "name" in transactionOrOperation
? {
operations: [transactionOrOperation],
signers: [signMethod.pubKey],
}
: transactionOrOperation;
const hasNop = transaction.operations.some(operation => {
return operation.name === "nop";
});
const transactionWithNop = hasNop ? transaction : client.addNop(transaction);
try {
const signedTx = yield client.signTransaction(transactionWithNop, signMethod);
promiEvent.emit(TransactionEvent.Signed, signedTx);
const sendTransactionPromiEvent = client.sendTransaction(signedTx, doStatusPolling, callback, confirmationLevel);
linkPromiEvents(sendTransactionPromiEvent, promiEvent);
resolve(yield sendTransactionPromiEvent);
}
catch (error) {
reject(error);
}
}));
return promiEvent;
},
getTransaction(transactionRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
isTxRidValid(transactionRid, { throwOnError: true });
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `tx/${config.blockchainRid}/${ensureString(transactionRid)}`, config);
const transaction = isTransaction(rspBody);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, statusCode === 200 && transaction ? toBuffer(transaction.tx) : isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getTransactionStatus(transactionRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
isTxRidValid(transactionRid, { throwOnError: true });
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `tx/${config.blockchainRid}/${transactionRid.toString("hex")}/status`, config);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, isRawGtv(rspBody), callbackPromiseBuilder(reject, result => resolve(validateTransactionStatusReponse({
statusCode,
result,
})), callback));
});
});
},
addNop(transaction) {
const _transaction = cloneDeep(transaction);
const noOperation = {
name: "nop",
args: [randomBytes(32)],
};
_transaction.operations = [..._transaction.operations, noOperation];
return _transaction;
},
getTransactionsInfo(limit = 25, beforeTime, callback, afterTime, signerPubKey) {
return __awaiter(this, void 0, void 0, function* () {
const beforeTimeQueryParam = beforeTime ? `&before-time=${beforeTime.getTime()}` : "";
const afterTimeQueryParam = afterTime ? `&after-time=${afterTime.getTime()}` : "";
const signerQueryParam = signerPubKey ? `&signer=${signerPubKey}` : "";
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `transactions/${config.blockchainRid}?limit=${limit}${beforeTimeQueryParam}${afterTimeQueryParam}${signerQueryParam}`, config);
const transactionsInfoResponseArray = isTransactionInfoResponseArray(rspBody);
const body = statusCode === 200 && transactionsInfoResponseArray
? transactionsInfoResponseArray.map(formatTransactionInfoResponse)
: rspBody;
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, isRawGtv(body), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getTransactionInfo(transactionRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
isTxRidValid(transactionRid, { throwOnError: true });
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `transactions/${config.blockchainRid}/${ensureString(transactionRid)}`, config);
const transactionInfoResponse = isTransactionInfoResponse(rspBody);
const body = statusCode === 200 && transactionInfoResponse
? formatTransactionInfoResponse(transactionInfoResponse)
: rspBody;
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, isRawGtv(body), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getAnchoringStatusForBlockRid(blockRid, anchoringClient, systemAnchoringChainRid) {
return __awaiter(this, void 0, void 0, function* () {
const client = this;
const result = { status: AnchoringStatus.NotAnchored };
const clusterAnchoredTx = yield awaitGetAnchoringTransactionForBlockRid(anchoringClient, ensureBuffer(client.config.blockchainRid), ensureBuffer(blockRid), config.clusterAnchoringStatusPolling);
if (!clusterAnchoredTx) {
return result;
}
const anchoringTransactionValidation = AnchoringTransactionSchema.safeParse(clusterAnchoredTx);
if (!anchoringTransactionValidation.success) {
return result;
}
result.status = AnchoringStatus.ClusterAnchored;
result.clusterAnchoredTx = anchoringTransactionValidation.data;
const systemAnchoredTransaction = yield getSystemAnchoringTransaction(config.endpointPool, anchoringTransactionValidation.data.txRid, anchoringClient, systemAnchoringChainRid, config.systemAnchoringStatusPolling, config.merkleHashVersion);
if (!systemAnchoredTransaction) {
return result;
}
result.status = AnchoringStatus.SystemAnchored;
result.systemAnchoredTx = systemAnchoredTransaction;
return result;
});
},
getTransactionConfirmationLevel(transactionRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
const client = this;
const dappConfirmation = yield client.getTransactionStatus(transactionRid);
const response = {
status: dappConfirmation.status,
statusCode: dappConfirmation.statusCode,
transactionRid: ensureBuffer(transactionRid),
};
if (dappConfirmation.status === ResponseStatus.Waiting) {
return response;
}
let clusterAnchoringResult = null;
if (dappConfirmation.status === ResponseStatus.Confirmed) {
const { anchoringClient, systemAnchoringChainBridString } = yield getAnchoringClientAndSystemChainRid(client);
clusterAnchoringResult = yield client.getClusterAnchoringTransactionConfirmation(transactionRid, anchoringClient);
if (clusterAnchoringResult === AnchoringStatus.NotAnchored || !clusterAnchoringResult) {
return response;
}
if (clusterAnchoringResult === AnchoringStatus.FailedAnchoring) {
response.status = AnchoringStatus.FailedAnchoring;
response.statusCode = 400;
return response;
}
const anchoringTransactionValidation = AnchoringTransactionSchema.safeParse(clusterAnchoringResult);
if (!anchoringTransactionValidation.success) {
return response;
}
if (anchoringTransactionValidation.success) {
response.status = AnchoringStatus.ClusterAnchored;
response.statusCode = 200;
response.clusterAnchoredTx = anchoringTransactionValidation.data;
response.clusterAnchoringClientBrid = anchoringClient.config.blockchainRid;
const systemAnchoringResult = yield client.getSystemAnchoringTransactionConfirmation(anchoringTransactionValidation.data.txRid, anchoringClient, systemAnchoringChainBridString);
if (!systemAnchoringResult) {
return response;
}
response.status = AnchoringStatus.SystemAnchored;
response.systemAnchoredTx = systemAnchoringResult;
response.systemAnchoringClientBrid = systemAnchoringChainBridString;
return response;
}
}
return response;
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
});
},
getTransactionCount(callback) {
return __awaiter(this, void 0, void 0, function* () {
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `transactions/${config.blockchainRid}/count`, config, undefined, true);
const transactionsCount = isTransactionsCount(rspBody);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, statusCode === 200 ? transactionsCount === null || transactionsCount === void 0 ? void 0 : transactionsCount.transactionsCount : isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getBlockInfo(blockIdentifier, txs = false, callback) {
return __awaiter(this, void 0, void 0, function* () {
isBlockIdentifierValid(blockIdentifier, { throwOnError: true });
const queryString = typeof blockIdentifier === "string" ? blockIdentifier : `height/${blockIdentifier}`;
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `blocks/${config.blockchainRid}/${queryString}?txs=${txs}`, config);
const blockInfoResponse = isBlockInfoResponse(rspBody);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, statusCode === 200 && blockInfoResponse !== null && blockInfoResponse
? formatBlockInfoResponse(blockInfoResponse)
: isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getLatestBlock(txs = false, callback) {
return __awaiter(this, void 0, void 0, function* () {
const shouldIncludeFullTransaction = txs ? `&txs=${txs}` : "";
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `blocks/${config.blockchainRid}?limit=1${shouldIncludeFullTransaction}`, config, undefined, true);
const indexOfLatestBlock = 0;
const blockInfoResponseArray = isBlockInfoResponseArray(rspBody);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, statusCode === 200 && blockInfoResponseArray !== null && blockInfoResponseArray
? formatBlockInfoResponse(blockInfoResponseArray[indexOfLatestBlock])
: isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getBlocks({ limit, beforeTime, afterTime, beforeHeight, afterHeight, txs, callback, } = {}) {
return __awaiter(this, void 0, void 0, function* () {
const searchValues = {
limit,
txs,
"before-time": beforeTime,
"after-time": afterTime,
"before-height": beforeHeight,
"after-height": afterHeight,
};
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(searchValues)) {
if (value !== undefined) {
searchParams.append(key, value.toString());
}
}
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `blocks/${config.blockchainRid}?${searchParams}`, config);
const blockInfoResponseArray = isBlockInfoResponseArray(rspBody);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, statusCode === 200 && blockInfoResponseArray
? blockInfoResponseArray.map(formatBlockInfoResponse)
: isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getClientNodeUrlPool() {
return config.endpointPool.map((endpoint) => endpoint.url);
},
/**
* Retrieves a confirmation proof for a transaction with the specified sha256
* hash.
* @param txRid A buffer of 32 bytes
* @param callback parameters (error, responseObjectProof) if first
* parameter is not null, an error occurred.
* If first parameter is null, then the second parameter is an object
* like the following:
*
* {hash: messageHashBuffer,
* blockHeader: blockHeaderBuffer,
* signatures: [{pubKey: pubKeyBuffer, signature: sigBuffer}, ...],
* merklePath: [{side: <0|1>, hash: <hash buffer level n-1>},
* ...
* {side: <0|1>, hash: <hash buffer level 1>}]}
*
* If no such transaction RID exists, the callback will be called with (null, null).
*
* The proof object can be validated using
* postchain-common.util.validateMerklePath(proof.merklePath, proof.hash,
* proof.blockHeader.slice(32, 64))
*
* The signatures must be validated agains some know trusted source for valid signers
* at this specific block height.
*/
getConfirmationProof(txRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
isTxRidValid(txRid, { throwOnError: true });
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `tx/${config.blockchainRid}/${ensureString(txRid)}/confirmationProof`, config);
const confirmationProof = {
merkleProofTree: "",
txIndex: 0,
};
if (statusCode === 200) {
try {
const transactionConfirmationProof = isTransactionConfirmationProof(rspBody);
if (!transactionConfirmationProof) {
throw error;
}
const decodedProof = decodeValue(toBuffer(transactionConfirmationProof.proof));
confirmationProof.txIndex = decodedProof.txIndex;
confirmationProof.hash = decodedProof.hash;
confirmationProof.blockHeader = decodedProof.blockHeader;
confirmationProof.witness = decodedProof.witness;
confirmationProof.merkleProofTree = decodedProof.merkleProofTree;
}
catch (decodeError) {
if (callback) {
callback(decodeError, null);
}
throw decodeError;
}
}
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, statusCode === 200 ? confirmationProof : isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getClusterAnchoringTransactionConfirmation(transactionRid, anchoringClient, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
isTxRidValid(transactionRid, { throwOnError: true });
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
const client = this;
try {
let confirmationProof;
try {
confirmationProof = yield client.getConfirmationProof(transactionRid);
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
return AnchoringStatus.NotAnchored;
}
const anchoringTransaction = yield getBlockAnchoringTransaction(client, anchoringClient, transactionRid, confirmationProof);
if (!anchoringTransaction)
return AnchoringStatus.NotAnchored;
return anchoringTransaction;
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
return AnchoringStatus.FailedAnchoring;
}
});
},
getSystemAnchoringTransactionConfirmation(anchoredTxRid, anchoringClient, systemAnchoringChainRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
try {
isTxRidValid(anchoredTxRid, { throwOnError: true });
}
catch (error) {
callback === null || callback === void 0 ? void 0 : callback(error, null);
throw error;
}
const systemAnchoringTransactionTransaction = yield getSystemAnchoringTransaction(config.endpointPool, anchoredTxRid, anchoringClient, systemAnchoringChainRid, config.systemAnchoringStatusPolling, config.merkleHashVersion);
return systemAnchoringTransactionTransaction;
});
},
getWaitingTransactions(blockchainRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `/tx/${ensureString(blockchainRid)}/waiting`, config);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
getWaitingTransaction(blockchainRid, txRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
const { error, statusCode, rspBody, transactionTimestamp } = yield requestWithFailoverStrategy(Method.GET, `/tx/${ensureString(blockchainRid)}/waiting/${ensureString(txRid)}`, config);
const transaction = isTransaction(rspBody);
const result = transaction ? toBuffer(transaction.tx) : isRawGtv(rspBody);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, result, callbackPromiseBuilder(reject, txData => resolve({
txData: isRawGtv(txData),
transactionTimestamp: Number(transactionTimestamp),
}), callback));
});
});
},
getRejectedTransactions(blockchainRid, callback) {
return __awaiter(this, void 0, void 0, function* () {
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `/tx/${ensureString(blockchainRid)}/rejected`, config);
const rejectedTransactionsArray = isRejectedTransactionResponseArray(rspBody);
const validResponseBody = statusCode === 200 && rejectedTransactionsArray
? rejectedTransactionsArray.map(rejectedTransaction => formatRejectedTransactionFromResponse(rejectedTransaction))
: rspBody;
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, isRawGtv(validResponseBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
/**
* Get app structure. Returns list of app modules in JSON format
* @param callback - leverages error-first pattern and called when promise resolves
*/
getAppStructure(callback) {
return __awaiter(this, void 0, void 0, function* () {
const { error, statusCode, rspBody } = yield requestWithFailoverStrategy(Method.GET, `/query/${config.blockchainRid}?type=rell.get_app_structure`, config);
return new Promise((resolve, reject) => {
handleGetResponse(error, statusCode, isRawGtv(rspBody), callbackPromiseBuilder(reject, resolve, callback));
});
});
},
};
function getMerkleHashVersion(settings) {
return __awaiter(this, void 0, void 0, function* () {
let merkleHashVersion;
if (settings.merkleHashVersion !== undefined) {
merkleHashVersion = settings.merkleHashVersion;
}
else {
merkleHashVersion = yield getMerkleHashVersionFromDapp(config);
}
return merkleHashVersion;
});
}
});
}
//# sourceMappingURL=blockchainClient.js.map