"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateNetworkFee = void 0;
const neon_core_1 = require("@cityofzion/neon-core");
/**
 * Calculates the network fee required to process the transaction.
 * The fields signers, attributes and script needs to be fully populated for this to work.
 *
 * @param txn - A partially filled out transaction.
 * @param feePerByte - The current feePerByte in Policy contract.
 * @param signingAccts - The accounts that will be signing this.
 */
function calculateNetworkFee(txn, feePerByte, executionFeeFactor) {
    const feePerByteBigInteger = feePerByte instanceof neon_core_1.u.BigInteger
        ? feePerByte
        : neon_core_1.u.BigInteger.fromNumber(feePerByte);
    const txClone = new neon_core_1.tx.Transaction(txn);
    txClone.witnesses = txn.witnesses.map((w) => {
        const verificationScript = w.verificationScript;
        if (neon_core_1.sc.isMultisigContract(verificationScript)) {
            const threshold = neon_core_1.wallet.getSigningThresholdFromVerificationScript(verificationScript.toBigEndian());
            return new neon_core_1.tx.Witness({
                invocationScript: generateFakeInvocationScript()
                    .toScript()
                    .repeat(threshold),
                verificationScript,
            });
        }
        else {
            return new neon_core_1.tx.Witness({
                invocationScript: generateFakeInvocationScript().toScript(),
                verificationScript,
            });
        }
    });
    const verificationExecutionFee = txClone.witnesses.reduce((totalFee, witness) => {
        return totalFee
            .add(neon_core_1.sc.calculateExecutionFee(witness.invocationScript.toBigEndian(), executionFeeFactor))
            .add(neon_core_1.sc.calculateExecutionFee(witness.verificationScript.toBigEndian(), executionFeeFactor));
    }, neon_core_1.u.BigInteger.fromNumber(0));
    const sizeFee = feePerByteBigInteger.mul(txClone.serialize(true).length / 2);
    return sizeFee.add(verificationExecutionFee);
}
exports.calculateNetworkFee = calculateNetworkFee;
function generateFakeInvocationScript() {
    return new neon_core_1.sc.OpToken(neon_core_1.sc.OpCode.PUSHDATA1, "0".repeat(128));
}
//# sourceMappingURL=calculateNetworkFee.js.map