import { Tuple, Hex, Bytes, Variant, _void, Struct, compactNumber, Vector, u64 } from '@polkadot-api/substrate-bindings';
import { getConstant, getStorageCodecs } from '../codecs.js';
import { blockStorage } from '../executor/chainToStorage.js';
import { logger } from '../logger.js';

const log = logger.child({ module: "slot-utils" });
const getSlotDuration = async (chain, block) => {
  const babe = await getConstant(block, "Babe", "ExpectedBlockTime");
  if (babe) return BigInt(babe);
  const async = await getConstant(block, "AsyncBacking", "ExpectedBlockTime");
  if (async) return BigInt(async);
  return getAuraSlotDuration(chain, block);
};
const getCurrentTimestamp = async (chain, block) => {
  const codecs = await getStorageCodecs(block, "Timestamp", "Now");
  if (!codecs) {
    throw new Error("No Timestamp.Now");
  }
  const node = await chain.getStorage(block.hash, codecs.keys.enc());
  if (node.value != null) {
    const decoded = codecs.value.dec(node.value);
    return typeof decoded === "bigint" ? decoded : BigInt(decoded);
  }
  const fallback = codecs.fallback ?? BigInt(Date.now());
  return typeof fallback === "bigint" ? fallback : BigInt(fallback);
};
const getCurrentSlot = async (chain, block) => {
  const [timestamp, slotDuration] = await Promise.all([
    getCurrentTimestamp(chain, block),
    getSlotDuration(chain, block)
  ]);
  return timestamp / slotDuration;
};
const getAuraSlotDuration = async (chain, block) => {
  try {
    const { result } = await chain.executor.runRuntimeCall({
      storage: blockStorage(chain, block.hash),
      call: "AuraApi_slot_duration",
      params: "0x"
    });
    return u64.dec(result);
  } catch {
  }
  log.error("couldn't get aura slot duration, defaulting to 12s");
  return 12000n;
};
const digestVal = Tuple(Hex(4), Bytes());
const digest = Variant(
  {
    Other: Bytes(),
    Consensus: digestVal,
    Seal: digestVal,
    PreRuntime: digestVal,
    RuntimeEnvironmentUpdated: _void
  },
  [0, 4, 5, 6, 8]
);
const runtimeBlockHeader = Struct({
  parent_hash: Hex(32),
  number: compactNumber,
  state_root: Hex(32),
  extrinsics_root: Hex(32),
  digest: Vector(digest)
});

export { getCurrentSlot, getCurrentTimestamp, getSlotDuration, runtimeBlockHeader };
//# sourceMappingURL=slot-utils.js.map
