import { ProofType, createProof } from "@chainsafe/persistent-merkle-tree";
import { loadState } from "@lodestar/state-transition";
import { getBlockResponse } from "../beacon/blocks/utils.js";
import { getStateResponseWithRegen } from "../beacon/state/utils.js";
export function getProofApi(opts, { chain, config }) {
    // It's currently possible to request gigantic proofs (eg: a proof of the entire beacon state)
    // We want some some sort of resistance against this DoS vector.
    const maxGindicesInProof = opts.maxGindicesInProof ?? 512;
    return {
        async getStateProof({ stateId, descriptor }) {
            // descriptor.length / 2 is a rough approximation of # of gindices
            if (descriptor.length / 2 > maxGindicesInProof) {
                throw new Error("Requested proof is too large.");
            }
            const res = await getStateResponseWithRegen(chain, stateId);
            const state = res.state instanceof Uint8Array ? loadState(config, chain.getHeadState(), res.state).state : res.state;
            // there should be no state changes in beacon-node so no need to commit() here
            const stateNode = state.node;
            const proof = createProof(stateNode, { type: ProofType.compactMulti, descriptor });
            return {
                data: proof,
                meta: { version: config.getForkName(state.slot) },
            };
        },
        async getBlockProof({ blockId, descriptor }) {
            // descriptor.length / 2 is a rough approximation of # of gindices
            if (descriptor.length / 2 > maxGindicesInProof) {
                throw new Error("Requested proof is too large.");
            }
            const { block } = await getBlockResponse(chain, blockId);
            // Commit any changes before computing the state root. In normal cases the state should have no changes here
            const blockNode = config.getForkTypes(block.message.slot).BeaconBlock.toView(block.message).node;
            const proof = createProof(blockNode, { type: ProofType.compactMulti, descriptor });
            return {
                data: proof,
                meta: { version: config.getForkName(block.message.slot) },
            };
        },
    };
}
//# sourceMappingURL=index.js.map