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 chai from "chai";
import chaiAsPromised from "chai-as-promised";
import * as secp256k1 from "secp256k1";
import { randomInt } from "crypto";
import { fetchAndVerifyTransaction } from "../../src/ICCF/utils";
import { signDigest } from "../../src/encryption/encryption";
import { getDigestToSign } from "../../src/gtx/gtx";
import { createClient } from "../../src/blockchainClient/blockchainClient";
import { toBuffer } from "../../src/formatter";
import * as gtxTool from "../../src/gtx/gtx";
const expect = chai.expect;
chai.use(chaiAsPromised);
const signerPrivKeyA = Buffer.alloc(32, "a");
const signerPubKeyA = Buffer.from(secp256k1.publicKeyCreate(signerPrivKeyA));
const sigProvA = {
    pubKey: signerPubKeyA,
    sign: (digest) => __awaiter(void 0, void 0, void 0, function* () { return signDigest(digest, signerPrivKeyA); }),
};
const getTxWithGTXAndTxRID = (client) => {
    const operation = {
        name: "setInteger",
        args: [1],
    };
    const gtxBody = {
        blockchainRID: toBuffer(client.config.blockchainRID),
        operations: [
            {
                opName: operation.name,
                args: operation.args,
            },
            {
                opName: "nop",
                args: [randomInt(10000)],
            },
        ],
        signers: [signerPubKeyA],
    };
    const gtx = Object.assign(Object.assign({}, gtxBody), { signatures: [] });
    const tx = {
        operations: [
            operation,
            {
                name: "nop",
                args: [randomInt(10000)],
            },
        ],
        signers: [signerPubKeyA],
    };
    const txRID = getDigestToSign(gtx);
    return { operation, gtx, txRID, tx };
};
const createSignSendTx = (client) => __awaiter(void 0, void 0, void 0, function* () {
    const { tx } = getTxWithGTXAndTxRID(client);
    const signedTx = yield client.signTransaction(tx, sigProvA);
    const { transactionRID } = yield client.sendTransaction(signedTx);
    const proof = yield client.getConfirmationProof(transactionRID);
    return { transactionRID, signedTx, proof };
});
describe("ICCF", () => {
    let client;
    before((done) => {
        client = createClient({
            nodeURLPool: process.env.ENDPOINT_POOL,
            blockchainRID: process.env.BLOCKCHAIN_RID,
        }).finally(() => {
            done();
        });
    });
    describe("fetchAndVerifyTransaction", () => __awaiter(void 0, void 0, void 0, function* () {
        it("ok", () => __awaiter(void 0, void 0, void 0, function* () {
            const _client = yield client;
            const { transactionRID, signedTx, proof } = yield createSignSendTx(_client);
            const { verifiedTx: updatedTx, verifiedTxHash: sourceTxHash } = yield fetchAndVerifyTransaction(_client, transactionRID, proof.hash, [
                signerPubKeyA,
            ]);
            expect(updatedTx).to.deep.equal(gtxTool.deserialize(signedTx));
            expect(sourceTxHash).to.deep.equal(proof.hash);
        }));
        it("throws error if fetched tx hash does not match hash from proof", () => __awaiter(void 0, void 0, void 0, function* () {
            const _client = yield client;
            const { transactionRID } = yield createSignSendTx(_client);
            const proofHash = Buffer.alloc(32, "a");
            try {
                yield fetchAndVerifyTransaction(_client, transactionRID, proofHash, [
                    signerPubKeyA,
                ]);
                expect.fail("Expected an error to be thrown");
            }
            catch (error) {
                expect(error.message).to.contain("Unable to verify source transaction proof,transaction hash in proof 6161616161616161616161616161616161616161616161616161616161616161 does not match hash from fetched transaction");
            }
        }));
        it("throws error if fetched tx number of signatures does not match expected list of signers", () => __awaiter(void 0, void 0, void 0, function* () {
            const _client = yield client;
            const { transactionRID, proof } = yield createSignSendTx(_client);
            try {
                yield fetchAndVerifyTransaction(_client, transactionRID, proof.hash, []);
                expect.fail("Expected an error to be thrown");
            }
            catch (error) {
                expect(error.message).to.contain("Transaction signatures amount 1 do not match expected amount of signers 0");
            }
        }));
        it("throws error if fetched tx has different RID than the tx asked for");
    }));
});
//# sourceMappingURL=iccfProofTxIntegration.js.map