UNPKG

postchain-client

Version:

Client library for accessing a Postchain node through REST.

277 lines 11.4 kB
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 { Buffer } from "buffer"; import { logger } from "../.."; import { SerializedTransactionFormatException, InvalidTxRidException, } from "../restclient/errors"; import { handlePostResponse } from "../restclient/restclient"; import * as gtxTool from "../gtx/gtx"; import { BlockchainUrlUndefinedException, DirectoryNodeUrlPoolException, InvalidTransactionFormatException, MissingBlockchainIdentifierError, } from "./errors"; import { getBlockchainRidFromIid } from "../restclient/restclientutil"; import { toBuffer } from "../formatter"; import { createClient } from "./blockchainClient"; import { FailoverStrategy } from "./enums"; import { createNodeManager } from "../restclient/nodeManager"; export function getClientConfigFromSettings(settings) { var _a, _b, _c, _d, _e, _f, _g, _h; return __awaiter(this, void 0, void 0, function* () { const nodeUrlPoolToUse = yield getNodeUrlsFromSettings(settings); if (nodeUrlPoolToUse.length === 0) { const id = (_b = (_a = settings.blockchainRid) !== null && _a !== void 0 ? _a : settings.blockchainIid) !== null && _b !== void 0 ? _b : "Unknown"; throw new BlockchainUrlUndefinedException(id); } const endpointPool = createEndpointObjects(nodeUrlPoolToUse); const nodeManager = createNodeManager({ nodeUrls: nodeUrlPoolToUse, useStickyNode: (_c = settings.useStickyNode) !== null && _c !== void 0 ? _c : false, unavailableDuration: (_d = settings.failOverConfig) === null || _d === void 0 ? void 0 : _d.unreachableDuration, }); const blockchainRidToUse = yield (() => __awaiter(this, void 0, void 0, function* () { if (settings.blockchainRid) { return settings.blockchainRid; } if (settings.blockchainIid !== undefined) { return yield getBlockchainRidFromIid({ nodeManager, endpointPool, chainId: settings.blockchainIid, }); } throw new MissingBlockchainIdentifierError(); }))(); return { endpointPool, nodeManager: nodeManager, blockchainRid: blockchainRidToUse, statusPollInterval: settings.statusPollInterval || 500, statusPollCount: settings.statusPollCount || 20, failoverStrategy: ((_e = settings.failOverConfig) === null || _e === void 0 ? void 0 : _e.strategy) || defaultFailoverConfig.strategy, attemptsPerEndpoint: ((_f = settings.failOverConfig) === null || _f === void 0 ? void 0 : _f.attemptsPerEndpoint) || defaultFailoverConfig.attemptsPerEndpoint, attemptInterval: ((_g = settings.failOverConfig) === null || _g === void 0 ? void 0 : _g.attemptInterval) || defaultFailoverConfig.attemptInterval, unreachableDuration: ((_h = settings.failOverConfig) === null || _h === void 0 ? void 0 : _h.unreachableDuration) || defaultFailoverConfig.unreachableDuration, }; }); } export function validTxRid(txRID) { if (txRID.length != 32) { const error = new InvalidTxRidException(txRID); logger.error(error.toString()); return false; } return true; } export function nodeDiscovery({ nodeManager, directoryEndpointPool, failOverConfig, blockchainRid, blockchainIid, }) { return __awaiter(this, void 0, void 0, function* () { if (directoryEndpointPool.length === 0) { throw new DirectoryNodeUrlPoolException(); } if (!blockchainRid && blockchainIid === undefined) { throw new MissingBlockchainIdentifierError(); } const directoryIid = 0; const directoryBRID = yield getBlockchainRidFromIid({ nodeManager, endpointPool: directoryEndpointPool, chainId: directoryIid, failOverConfig, }); const blockchainRidToUse = yield (() => __awaiter(this, void 0, void 0, function* () { if (blockchainRid) { return blockchainRid; } if (blockchainIid !== undefined) { return yield getBlockchainRidFromIid({ nodeManager, endpointPool: directoryEndpointPool, chainId: blockchainIid, failOverConfig, }); } throw new MissingBlockchainIdentifierError(); }))(); const queryObject = { name: "cm_get_blockchain_api_urls", args: { blockchain_rid: toBuffer(blockchainRidToUse) }, }; const D1Client = yield createClient({ nodeUrlPool: getUrlsFromEndpoints(directoryEndpointPool), blockchainRid: directoryBRID, }); const baseUrls = yield D1Client.query(queryObject); return baseUrls; }); } export function convertToRellOperation(operations) { return operations.map((operation) => { var _a; return { opName: operation.name, args: (_a = operation.args) !== null && _a !== void 0 ? _a : [], }; }); } export function getSerializedGTX(gtx) { const gtxBytes = gtxTool.serialize(gtx); if (!Buffer.isBuffer(gtxBytes)) { throw new SerializedTransactionFormatException(); } return gtxBytes; } export function getGTXFromBufferOrTransactionOrOperation(transaction, blockchainRid) { if (Buffer.isBuffer(transaction)) { return gtxTool.deserialize(transaction); } else if ("operations" in transaction) { return { blockchainRid: toBuffer(blockchainRid), operations: convertToRellOperation(transaction.operations), signers: transaction.signers, signatures: [], }; } else if ("name" in transaction) { return { blockchainRid: toBuffer(blockchainRid), operations: convertToRellOperation([transaction]), signers: [], signatures: [], }; } else { throw new InvalidTransactionFormatException(); } } export const callbackPromiseBuilder = (reject, resolve, callback) => { return (error, result) => { if (error) { if (typeof callback === "function") { callback(error, null); } reject(error); } else { if (typeof callback === "function") { callback(null, result); } resolve(result); } }; }; export const handlePostResponsePromisified = (error, statusCode, rspBody) => { return new Promise((resolve, reject) => { handlePostResponse(error, statusCode, rspBody, (_error) => { if (_error) { reject(_error); } else { resolve(); } }); }); }; function ensureArray(input) { if (typeof input === "string") { return [input]; } return input; } export const formatTransactionInfoResponse = (transactionInfoResponse) => { return { blockRid: toBuffer(transactionInfoResponse.blockRID), blockHeight: transactionInfoResponse.blockHeight, blockHeader: toBuffer(transactionInfoResponse.blockHeader), witness: toBuffer(transactionInfoResponse.witness), timestamp: transactionInfoResponse.timestamp, txRid: toBuffer(transactionInfoResponse.txRID), txHash: toBuffer(transactionInfoResponse.txHash), txData: toBuffer(transactionInfoResponse.txData), }; }; export const formatBlockInfoResponse = (blockInfoResponse) => { return { rid: toBuffer(blockInfoResponse.rid), prevBlockRid: toBuffer(blockInfoResponse.prevBlockRID), header: toBuffer(blockInfoResponse.header), transactions: blockInfoResponse.transactions.map(formatTransaction), height: blockInfoResponse.height, witness: toBuffer(blockInfoResponse.witness), witnesses: blockInfoResponse.witnesses.map((witness) => { return toBuffer(witness); }), timestamp: blockInfoResponse.timestamp, }; }; const formatTransaction = (transaction) => { const formattedTransaction = { rid: toBuffer(transaction.rid), hash: toBuffer(transaction.hash), }; if (transaction.data !== undefined) { formattedTransaction.data = toBuffer(transaction.data); } return formattedTransaction; }; export const isKeyPair = (keypair) => { return (typeof keypair === "object" && keypair !== null && "privKey" in keypair && "pubKey" in keypair && keypair.privKey instanceof Buffer && keypair.pubKey instanceof Buffer); }; function getNodeUrlsFromSettings(settings) { var _a; return __awaiter(this, void 0, void 0, function* () { if (settings.directoryNodeUrlPool) { // If directoryNodeUrlPool is provided, use nodeDiscovery const nodeManager = createNodeManager({ nodeUrls: ensureArray(settings.directoryNodeUrlPool), unavailableDuration: (_a = settings.failOverConfig) === null || _a === void 0 ? void 0 : _a.unreachableDuration, }); return yield nodeDiscovery({ nodeManager, directoryEndpointPool: createEndpointObjects(ensureArray(settings.directoryNodeUrlPool)), failOverConfig: settings.failOverConfig, blockchainRid: settings.blockchainRid, blockchainIid: settings.blockchainIid, }); } else if (typeof settings.nodeUrlPool === "string") { // If nodeUrlPool is a string, convert it to an array return [settings.nodeUrlPool]; } else if (Array.isArray(settings.nodeUrlPool)) { // If nodeUrlPool is already an array, use it as-is return settings.nodeUrlPool; } else { // Default to an empty array if no valid configuration is provided return []; } }); } export const defaultFailoverConfig = { strategy: FailoverStrategy.AbortOnError, attemptsPerEndpoint: 3, attemptInterval: 500, unreachableDuration: 30000, }; export const createEndpointObjects = (endpointPoolUrls) => { const endpoints = endpointPoolUrls.map((endpointUrl) => { return { url: endpointUrl, whenAvailable: 0 }; }); return endpoints; }; export const getUrlsFromEndpoints = (endpointPool) => { return endpointPool.map((endpoint) => endpoint.url); }; //# sourceMappingURL=utils.js.map