postchain-client
Version:
Client library for accessing a Postchain node through REST.
129 lines • 5.94 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 { checkDigestSignature } from "../encryption/encryption";
import { toBuffer } from "../formatter";
import { gtvHash } from "../gtv";
import { getDigestToSign, rawGtvToGtx } from "../gtx/gtx";
import { decodeValue, encodeValue } from "../gtx/serialization";
import { DifferentNumberOfSignersException, MissingTransactionProof, ProofRidException, SignatureException, SystemChainException, } from "./error";
export function getClusterOfBlockchain(client, blockchainRid) {
return __awaiter(this, void 0, void 0, function* () {
try {
const clusterName = yield client.query({
name: "cm_get_blockchain_cluster",
args: { brid: blockchainRid },
});
return clusterName;
}
catch (error) {
throw new SystemChainException(error.message);
}
});
}
export function getClusterInfo(client, name) {
return __awaiter(this, void 0, void 0, function* () {
try {
const clusterInfo = yield client.query({
name: "cm_get_cluster_info",
args: { name },
});
return clusterInfo;
}
catch (error) {
throw new SystemChainException(error.message);
}
});
}
export function getAnchoringTransactionForBlockRid(client, blockchainRid, blockRid) {
return __awaiter(this, void 0, void 0, function* () {
try {
const anchoringTxForBlockRid = yield client.query({
name: "get_anchoring_transaction_for_block_rid",
args: { blockchain_rid: blockchainRid, block_rid: blockRid },
});
return convertToAnchoringTransaction(anchoringTxForBlockRid);
}
catch (error) {
throw new SystemChainException(error.message);
}
});
}
export function convertToAnchoringTransaction(responseTx) {
const { tx_rid, tx_data, tx_op_index } = responseTx;
return {
txRid: tx_rid,
txData: tx_data,
txOpIndex: tx_op_index,
};
}
export function calculateBlockRID(decodedTxProof) {
const sourceBlockHeader = decodedTxProof.blockHeader;
if (!sourceBlockHeader) {
throw new Error("Failed to get blockHeader from confirmation proof");
}
const decodeSourceBlockRid = decodeValue(sourceBlockHeader);
return gtvHash(decodeSourceBlockRid);
}
// fetch tx from txRID and verifies with secp256k1.ecdsaVerify that txRID and signer creates signatures that are on the blockchain transaction
export function fetchAndVerifyTransaction(sourceClient, txToProveRID, proofHash, txToProveSigners) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
const rawTx = yield sourceClient.getTransaction(txToProveRID);
const txGtv = decodeValue(rawTx);
const fetchedTxHash = gtvHash(txGtv);
if (Buffer.compare(fetchedTxHash, proofHash)) {
// We received another hash for tx RID than what was included in proof
// Possibly rouge or faulty node(s). Anyway, we need to give up.
throw new MissingTransactionProof(proofHash, fetchedTxHash);
}
const fetchedTx = rawGtvToGtx(txGtv);
if (txToProveSigners.length != ((_a = fetchedTx.signatures) === null || _a === void 0 ? void 0 : _a.length)) {
throw new DifferentNumberOfSignersException((_c = (_b = fetchedTx.signatures) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0, txToProveSigners.length);
}
const txRID = getDigestToSign(fetchedTx);
if (Buffer.compare(txRID, txToProveRID)) {
throw new ProofRidException();
}
for (const signer of txToProveSigners) {
let hasSignature = false;
for (const signature of fetchedTx.signatures) {
// verify that txRID (hash of gtxBody) signed by signers equals the signatures from network
if (checkDigestSignature(txRID, signer, signature)) {
hasSignature = true;
break;
}
}
if (!hasSignature)
throw new SignatureException(signer);
}
return { verifiedTx: fetchedTx, verifiedTxHash: fetchedTxHash };
});
}
export function composeProofTransactionObject(sourceBlockchainRid, verifiedTxHash, txProof, iccfTxSigners, anchoringTx, anchoringProof, isNetwork = true) {
let operationArgs;
operationArgs = {
sourceBlockchainRid: toBuffer(sourceBlockchainRid),
transactionHash: verifiedTxHash,
transactionProof: encodeValue(txProof),
};
if (isNetwork) {
operationArgs = Object.assign(Object.assign({}, operationArgs), { transactionData: anchoringTx === null || anchoringTx === void 0 ? void 0 : anchoringTx.txData, transactionIndex: anchoringTx === null || anchoringTx === void 0 ? void 0 : anchoringTx.txOpIndex, anchoringProof: anchoringProof && encodeValue(anchoringProof) });
}
return {
operations: [
{
name: "iccf_proof",
args: Object.values(operationArgs),
},
],
signers: iccfTxSigners,
};
}
//# sourceMappingURL=utils.js.map