import { toHex } from '@pezkuwi/papi-utils';
import { createDecoder } from 'scale-ts';
import '../utils/ss58-util.mjs';
import '../codecs/scale/Binary.mjs';
import '../codecs/scale/bitSequence.mjs';
import '../codecs/scale/char.mjs';
import '../codecs/scale/compact.mjs';
import '../codecs/scale/Hex.mjs';
import '../codecs/scale/fixed-str.mjs';
import '../codecs/scale/Variant.mjs';
import '../codecs/scale/ethAccount.mjs';
import '../codecs/scale/shaped.mjs';
import '../codecs/scale/BitSeq.mjs';
import '../codecs/blockHeader.mjs';
import '../codecs/metadata/metadata.mjs';
import '../codecs/metadata/v14.mjs';
import '../codecs/metadata/v15.mjs';
import '../codecs/metadata/v16.mjs';
import '../codecs/metadata/lookup.mjs';
import { trieNodeDec } from './node-decoder.mjs';
import { Blake2256 } from '../hashes/blake2.mjs';
import '@noble/hashes/blake3.js';
import '@noble/hashes/sha3.js';

const TrieNodeWithHash = (hasher) => createDecoder((input) => {
  const hash = toHex(hasher(new Uint8Array(input.buffer)));
  try {
    return {
      hash,
      ...trieNodeDec(input)
    };
  } catch {
    return { type: "Raw", hash, value: "" };
  }
});
const validateProofs = (proofs, hasher = Blake2256) => {
  const proofsList = proofs.map(TrieNodeWithHash(hasher));
  const proofsRecord = Object.fromEntries(proofsList.map((p) => [p.hash, p]));
  const hashes = proofsList.map((p) => p.hash);
  const roots = new Set(hashes);
  const setRawValue = (input) => {
    if (input.value) return;
    const val = proofs[hashes.indexOf(input.hash)];
    input.value = typeof val === "string" ? val : toHex(val);
  };
  proofsList.forEach((p) => {
    if ("children" in p) {
      Object.values(p.children).forEach((hash) => {
        const child = proofsRecord[hash];
        if (child) {
          child.parent = p.hash;
          roots.delete(hash);
        }
      });
    }
    if (p.type === "BranchWithHash" || p.type === "LeafWithHash") {
      const childHash = p.value;
      const child = proofsRecord[childHash];
      if (!child) return;
      roots.delete(childHash);
      if (child.type !== "Raw") {
        Object.keys(child).forEach((k) => delete child[k]);
        child.type = "Raw";
        child.hash = childHash;
      }
      child.parent = p.hash;
      setRawValue(child);
    }
    if (p.type === "Raw") setRawValue(p);
  });
  return roots.size === 1 ? { rootHash: roots.values().next().value, proofs: proofsRecord } : null;
};

export { TrieNodeWithHash, validateProofs };
//# sourceMappingURL=proofs.mjs.map
