@xyo-network/xl1-protocol-sdk 1.26.23 → 1.26.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts +2 -0
  2. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts.map +1 -1
  3. package/dist/neutral/config/Actor.d.ts +12 -0
  4. package/dist/neutral/config/Actor.d.ts.map +1 -1
  5. package/dist/neutral/config/Actors.d.ts +2 -0
  6. package/dist/neutral/config/Actors.d.ts.map +1 -1
  7. package/dist/neutral/config/Base.d.ts +2 -0
  8. package/dist/neutral/config/Base.d.ts.map +1 -1
  9. package/dist/neutral/config/Config.d.ts +8 -0
  10. package/dist/neutral/config/Config.d.ts.map +1 -1
  11. package/dist/neutral/config/HostActor.d.ts +12 -0
  12. package/dist/neutral/config/HostActor.d.ts.map +1 -1
  13. package/dist/neutral/config/Validation.d.ts +2 -0
  14. package/dist/neutral/config/Validation.d.ts.map +1 -1
  15. package/dist/neutral/context/Actor.d.ts +12 -0
  16. package/dist/neutral/context/Actor.d.ts.map +1 -1
  17. package/dist/neutral/context/HostActor.d.ts +12 -0
  18. package/dist/neutral/context/HostActor.d.ts.map +1 -1
  19. package/dist/neutral/getFileConfig.d.ts +4 -0
  20. package/dist/neutral/getFileConfig.d.ts.map +1 -1
  21. package/dist/neutral/getFileConfig.mjs +19 -1
  22. package/dist/neutral/getFileConfig.mjs.map +1 -1
  23. package/dist/neutral/index.mjs +1980 -1929
  24. package/dist/neutral/index.mjs.map +1 -1
  25. package/dist/neutral/isInternetAvailable.d.ts.map +1 -1
  26. package/dist/neutral/model/CreatableProviderContext.zod.d.ts +12 -0
  27. package/dist/neutral/model/CreatableProviderContext.zod.d.ts.map +1 -1
  28. package/dist/neutral/primitives/uncle/findBestUncle.d.ts +15 -34
  29. package/dist/neutral/primitives/uncle/findBestUncle.d.ts.map +1 -1
  30. package/dist/neutral/primitives/uncle/getProducerKey.d.ts +4 -0
  31. package/dist/neutral/primitives/uncle/getProducerKey.d.ts.map +1 -0
  32. package/dist/neutral/primitives/uncle/index.d.ts +1 -0
  33. package/dist/neutral/primitives/uncle/index.d.ts.map +1 -1
  34. package/dist/neutral/primitives/uncle/scoreUncle.d.ts +3 -1
  35. package/dist/neutral/primitives/uncle/scoreUncle.d.ts.map +1 -1
  36. package/dist/neutral/test/index.mjs +427 -411
  37. package/dist/neutral/test/index.mjs.map +1 -1
  38. package/package.json +8 -12
@@ -634,130 +634,210 @@ var TelemetryConfigZod = z14.object({
634
634
  // src/config/Validation.ts
635
635
  import { AddressZod as AddressZod2, asAddress } from "@xylabs/sdk-js";
636
636
  import { globalRegistry as globalRegistry11, z as z15 } from "zod";
637
- var ValidationConfigZod = z15.object({
638
- allowedRewardRedeemers: z15.preprocess((val) => {
639
- if (typeof val === "string") {
640
- return val.split(",").map((s) => asAddress(s.trim()));
641
- }
642
- return val;
643
- }, z15.array(AddressZod2).optional().register(globalRegistry11, {
644
- description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
645
- title: "allowedRewardRedeemers",
646
- type: "array"
647
- })),
648
- allowedRewardEscrowAccountSigners: z15.preprocess((val) => {
649
- if (typeof val === "string") {
650
- return val.split(",").map((s) => asAddress(s.trim()));
651
- }
652
- return val;
653
- }, z15.array(AddressZod2).optional().register(globalRegistry11, {
654
- description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
655
- title: "allowedRewardEscrowAccountSigners",
656
- type: "array"
657
- }))
658
- });
659
637
 
660
- // src/config/Base.ts
661
- var BaseConfigZod = z16.object({
662
- chain: ChainConfigZod.default(ChainConfigZod.parse({})).describe("Configuration for the chain"),
663
- dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
664
- evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
665
- log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
666
- providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
667
- remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
668
- storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
669
- telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
670
- validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
671
- });
638
+ // src/primitives/block/rate/blockRate.ts
639
+ import { isDefined as isDefined3, isFalsy } from "@xylabs/sdk-js";
640
+ import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
672
641
 
673
- // src/config/Actor.ts
674
- var ActorConfigZod = BaseConfigZod.extend({
675
- name: z17.string(),
676
- mnemonic: MnemonicStringZod.optional().register(globalRegistry12, {
677
- description: "Mnemonic for the Actor wallet",
678
- title: "mnemonic",
679
- type: "string"
680
- }),
681
- healthCheckPort: z17.coerce.number().optional().register(globalRegistry12, {
682
- description: "Port for the Producer health checks",
683
- title: "producer.healthCheckPort",
684
- type: "number"
685
- })
642
+ // src/primitives/block/rate/timeHelpers.ts
643
+ import { assertEx as assertEx4, isDefined as isDefined2 } from "@xylabs/sdk-js";
644
+ var rateMultipliers = {
645
+ millis: 1,
646
+ seconds: 1e3,
647
+ minutes: 1e3 * 60,
648
+ hours: 1e3 * 60 * 60,
649
+ days: 1e3 * 60 * 60 * 24,
650
+ weeks: 1e3 * 60 * 60 * 24 * 7
651
+ };
652
+ var timeDurations = (timeInMs) => ({
653
+ millis: timeInMs,
654
+ seconds: timeInMs / 1e3,
655
+ minutes: timeInMs / (1e3 * 60),
656
+ hours: timeInMs / (1e3 * 60 * 60),
657
+ days: timeInMs / (1e3 * 60 * 60 * 24),
658
+ weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
686
659
  });
687
- var isActorConfig = zodIsFactory2(ActorConfigZod);
688
- var asActorConfig = zodAsFactory2(ActorConfigZod, "asActorConfig");
689
- var toActorConfig = zodToFactory2(ActorConfigZod, "toActorConfig");
690
-
691
- // src/config/Actors.ts
692
- import z18 from "zod";
693
- var ActorsConfigZod = z18.array(ActorConfigZod.loose()).describe("Actor-specific configurations that override the base configuration when the actor is running").default([]);
694
-
695
- // src/config/Config.ts
696
- var ConfigZod = BaseConfigZod.extend({ actors: ActorsConfigZod }).describe("The complete configuration for the protocol, including global settings and actor-specific overrides");
697
-
698
- // src/block/hydrate/allHashesPresent.ts
699
- function allHashesPresent(hashes, payloads) {
700
- const payloadHashes = new Set(payloads.map((p) => p._hash));
701
- return hashes.every((hash) => payloadHashes.has(hash));
702
- }
703
-
704
- // src/block/hydrate/flattenHydratedBlock.ts
705
- import { toHydratedBlock } from "@xyo-network/xl1-protocol-lib";
706
- var flattenHydratedBlock = (hydratedBlock) => {
707
- const [blk, blkPayloads] = hydratedBlock;
708
- return [...blkPayloads, blk];
660
+ var getTimeConfigInMilliseconds = (timeConfig) => {
661
+ const assertedTimeConfig = assertEx4(isDefined2(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
662
+ let totalMilliseconds = 0;
663
+ if ("years" in assertedTimeConfig) {
664
+ totalMilliseconds += assertedTimeConfig.years * 31536e6;
665
+ return totalMilliseconds;
666
+ }
667
+ if ("months" in assertedTimeConfig) {
668
+ totalMilliseconds += assertedTimeConfig.months * 2592e6;
669
+ return totalMilliseconds;
670
+ }
671
+ if ("weeks" in assertedTimeConfig) {
672
+ totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
673
+ return totalMilliseconds;
674
+ }
675
+ if ("days" in assertedTimeConfig) {
676
+ totalMilliseconds += assertedTimeConfig.days * 864e5;
677
+ return totalMilliseconds;
678
+ }
679
+ if ("hours" in assertedTimeConfig) {
680
+ totalMilliseconds += assertedTimeConfig.hours * 36e5;
681
+ return totalMilliseconds;
682
+ }
683
+ if ("minutes" in assertedTimeConfig) {
684
+ totalMilliseconds += assertedTimeConfig.minutes * 6e4;
685
+ return totalMilliseconds;
686
+ }
687
+ return totalMilliseconds;
709
688
  };
710
689
 
711
- // src/block/hydrate/flattenHydratedBlocks.ts
712
- var flattenHydratedBlocks = (hydratedBlocks) => hydratedBlocks.flatMap((blk) => flattenHydratedBlock(blk));
690
+ // src/primitives/block/rate/blockRate.ts
691
+ var blockRate = (startBlock, endBlock, timeUnit) => {
692
+ const startingBlock = startBlock[0];
693
+ const endingBlock = endBlock[0];
694
+ const heightDifference = endingBlock.block - startingBlock.block;
695
+ const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
696
+ if (timeDifference === 0) {
697
+ throw new Error("Time difference must be greater than 0");
698
+ }
699
+ const rate = heightDifference / timeDifference;
700
+ const timeUnitValue = isDefined3(timeUnit) ? timeUnit : "millis";
701
+ const returnedTimeDifference = isDefined3(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
702
+ const timePerBlock = returnedTimeDifference / heightDifference;
703
+ return {
704
+ range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
705
+ span: heightDifference,
706
+ rate: isDefined3(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
707
+ timeUnit: timeUnitValue,
708
+ timeDifference: returnedTimeDifference,
709
+ timePerBlock
710
+ };
711
+ };
712
+ var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
713
+ if (endBlockHeight <= startBlockHeight) {
714
+ console.error("startBlockHeight", startBlockHeight);
715
+ console.error("endBlockHeight", endBlockHeight);
716
+ throw new Error("End block height must be greater than start block height");
717
+ }
718
+ const startingBlock = await viewer.blockByNumber(startBlockHeight);
719
+ const endingBlock = await viewer.blockByNumber(endBlockHeight);
720
+ if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
721
+ throw new Error("Could not retrieve blocks for speed calculation");
722
+ }
723
+ return { startingBlock, endingBlock };
724
+ };
725
+ var calculateBlockRate = async (viewer, range, timeUnit) => {
726
+ const [startBlockHeight, endBlockHeight] = range;
727
+ const { startingBlock, endingBlock } = await getBlockRateBlocks(
728
+ viewer,
729
+ startBlockHeight,
730
+ endBlockHeight
731
+ );
732
+ return blockRate(startingBlock, endingBlock, timeUnit);
733
+ };
713
734
 
714
- // src/block/hydrate/hydrateBlock.ts
715
- import { assertEx as assertEx4 } from "@xylabs/sdk-js";
716
- import { asAnyPayload } from "@xyo-network/sdk-js";
717
- import { asBlockBoundWitnessWithStorageMeta, isTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
718
- var hydrateBlock = async (context, hash, maxDepth = 1, minDepth = maxDepth) => {
719
- assertEx4(maxDepth >= 0, () => "maxDepth must be greater than or equal to 0");
720
- assertEx4(minDepth >= 0, () => "minDepth must be greater than or equal to 0");
721
- assertEx4(maxDepth >= minDepth, () => "maxDepth must be greater than or equal to minDepth");
722
- const { chainMap } = context;
723
- const [block] = await chainMap.get([hash]);
724
- const bw = assertEx4(asBlockBoundWitnessWithStorageMeta(
725
- assertEx4(block, () => `block ${hash} not found`)
726
- ), () => `hash ${hash} is not a BlockBoundWitness`);
727
- if (maxDepth === 0) return [bw, []];
728
- const blkPayloads = (await chainMap.get(bw.payload_hashes)).map((p) => asAnyPayload(p, true));
729
- if (minDepth === 1) assertEx4(allHashesPresent(bw.payload_hashes, blkPayloads), () => `Unable to find all payloads for block ${hash}`);
730
- if (maxDepth === 1) return [bw, blkPayloads];
731
- const transactions = blkPayloads.filter(isTransactionBoundWitnessWithStorageMeta);
732
- const transactionsPayloadHashes = transactions.flatMap((tx) => tx.payload_hashes);
733
- const transactionsPayloads = (await chainMap.get(transactionsPayloadHashes)).map((p) => asAnyPayload(p, true));
734
- assertEx4(allHashesPresent(transactionsPayloadHashes, transactionsPayloads), () => `Unable to find all payloads for transactions in block ${hash}`);
735
- const allPayloadsHashes = new Set([...blkPayloads, ...transactionsPayloads].flatMap((p) => p._hash));
736
- const allPayloads = (await chainMap.get([...allPayloadsHashes])).map((p) => asAnyPayload(p, true));
737
- const allPayloadsFiltered = allPayloads.filter((p) => allPayloadsHashes.has(p._hash));
738
- if (maxDepth === 2) assertEx4(allHashesPresent(
739
- [...allPayloadsHashes],
740
- allPayloadsFiltered
741
- ), () => `Unable to find all payloads for transactions in block ${hash}`);
742
- return [bw, allPayloadsFiltered];
735
+ // src/primitives/block/rate/stepRate.ts
736
+ import { assertEx as assertEx5 } from "@xylabs/sdk-js";
737
+ import {
738
+ asXL1BlockRange as asXL1BlockRange2,
739
+ isValidStep,
740
+ StepSizes
741
+ } from "@xyo-network/xl1-protocol-lib";
742
+ var stepRate = async (viewer, start, step, count = 1, timeUnit) => {
743
+ const end = start + step * count;
744
+ const range = asXL1BlockRange2([start, end], true);
745
+ return await calculateBlockRate(viewer, range, timeUnit);
746
+ };
747
+ var calculateStepSizeRate = async (viewer, start, stepIndex, count = 1, timeUnit) => {
748
+ assertEx5(isValidStep(stepIndex), () => `Invalid step index: ${stepIndex}`);
749
+ const step = StepSizes[stepIndex];
750
+ return await stepRate(viewer, start, step, count, timeUnit);
743
751
  };
744
752
 
745
- // src/block/primitives/blockFromBlockNumber.ts
753
+ // src/primitives/block/rate/timeRate.ts
746
754
  import {
747
- asHash,
755
+ assertEx as assertEx6,
748
756
  isDefined as isDefined4,
749
- spanAsync
757
+ isDefinedNotNull
750
758
  } from "@xylabs/sdk-js";
751
- import { toSafeJsonString } from "@xylabs/sdk-js";
752
- import {
753
- asSignedBlockBoundWitnessWithStorageMeta,
754
- SignedBlockBoundWitnessWithHashMetaZod,
755
- StepSizes
756
- } from "@xyo-network/xl1-protocol-lib";
759
+ import { asXL1BlockNumber, asXL1BlockRange as asXL1BlockRange3 } from "@xyo-network/xl1-protocol-lib";
760
+ var DEFAULT_TOLERANCE_MS = 3e4;
761
+ var DEFAULT_MAX_ATTEMPTS = 10;
762
+ var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
763
+ assertEx6(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
764
+ const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
765
+ const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
766
+ const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
767
+ assertEx6(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
768
+ const blocksPerMillisecondRate = 1 / (12 * 1e3);
769
+ const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds);
770
+ const endBlockNumber = await findEndBlockRecursive(
771
+ viewer,
772
+ resolvedStartBlock,
773
+ timeInMilliseconds,
774
+ initialBlocksInDuration,
775
+ toleranceMs,
776
+ maxAttempts
777
+ );
778
+ return await calculateBlockRate(
779
+ viewer,
780
+ asXL1BlockRange3([endBlockNumber, resolvedStartBlock.block], true),
781
+ timeUnit
782
+ );
783
+ };
784
+ var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBlocksBack, toleranceMs, attemptsRemaining) => {
785
+ console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`);
786
+ assertEx6(attemptsRemaining >= 0, () => "Maximum attempts reached while searching for end block");
787
+ const startBlockEpoch = startBlock.$epoch;
788
+ const estimatedEndBlockNumber = asXL1BlockNumber(startBlock.block - estimatedBlocksBack, true);
789
+ if (estimatedEndBlockNumber < 0) {
790
+ throw new Error("Estimated end block number is less than zero");
791
+ }
792
+ const endBlock = await viewer.blockByNumber(estimatedEndBlockNumber);
793
+ const resolvedEndBlock = assertEx6(
794
+ isDefined4(endBlock?.[0]) ? endBlock[0] : void 0,
795
+ () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
796
+ );
797
+ const endBlockEpoch = resolvedEndBlock.$epoch;
798
+ if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
799
+ throw new TypeError("Block has missing or invalid $epoch");
800
+ }
801
+ const actualTimeDifference = startBlockEpoch - endBlockEpoch;
802
+ if (actualTimeDifference === 0) {
803
+ throw new Error("Start and end blocks have identical timestamps");
804
+ }
805
+ const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
806
+ if (timeDelta <= toleranceMs) {
807
+ return resolvedEndBlock.block;
808
+ }
809
+ let adjustedBlocksBack;
810
+ if (actualTimeDifference < targetTimeMs) {
811
+ const adjustmentFactor = targetTimeMs / actualTimeDifference;
812
+ adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
813
+ } else {
814
+ const adjustmentFactor = actualTimeDifference / targetTimeMs;
815
+ adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
816
+ }
817
+ adjustedBlocksBack = Number.isFinite(adjustedBlocksBack) && adjustedBlocksBack >= 1 ? adjustedBlocksBack : 1;
818
+ return await findEndBlockRecursive(
819
+ viewer,
820
+ startBlock,
821
+ targetTimeMs,
822
+ adjustedBlocksBack,
823
+ toleranceMs,
824
+ attemptsRemaining - 1
825
+ );
826
+ };
827
+
828
+ // src/primitives/step/completedStepRewardAddress.ts
829
+ import { toAddress } from "@xylabs/sdk-js";
830
+ import { StepSizes as StepSizes2 } from "@xyo-network/xl1-protocol-lib";
831
+ import { keccak256 } from "ethers";
832
+ function completedStepRewardAddress({ block, step }) {
833
+ const resolvedStepSize = step < StepSizes2.length ? StepSizes2[step] : step;
834
+ const addressKey = new TextEncoder().encode(`${block}|${resolvedStepSize}`);
835
+ return toAddress(keccak256(addressKey).slice(-40), { prefix: false });
836
+ }
757
837
 
758
838
  // src/ChainContextHelpers.ts
759
839
  import {
760
- isDefined as isDefined3,
840
+ isDefined as isDefined6,
761
841
  isObject,
762
842
  isUndefined as isUndefined2,
763
843
  timeBudget
@@ -803,7 +883,7 @@ var LruCacheMap = class {
803
883
  };
804
884
 
805
885
  // src/driver/memory/MemoryMap.ts
806
- import { isDefined as isDefined2 } from "@xylabs/sdk-js";
886
+ import { isDefined as isDefined5 } from "@xylabs/sdk-js";
807
887
  var MemoryMap = class {
808
888
  map;
809
889
  constructor() {
@@ -822,7 +902,7 @@ var MemoryMap = class {
822
902
  const results = [];
823
903
  for (const id of ids) {
824
904
  const data = this.map.get(id);
825
- if (isDefined2(data)) {
905
+ if (isDefined5(data)) {
826
906
  results.push(data);
827
907
  }
828
908
  }
@@ -859,7 +939,7 @@ async function withContextCacheResponse(context, name, key, func, { max = 1e4 }
859
939
  );
860
940
  const { timeBudgetLimit = 0 } = context;
861
941
  const cacheResult = await cache.get(key);
862
- if (isDefined3(cacheResult)) {
942
+ if (isDefined6(cacheResult)) {
863
943
  return cacheResult;
864
944
  }
865
945
  const result = timeBudgetLimit > 0 ? timeBudget(name, context.logger, func, timeBudgetLimit) : func();
@@ -867,317 +947,160 @@ async function withContextCacheResponse(context, name, key, func, { max = 1e4 }
867
947
  return result;
868
948
  }
869
949
 
870
- // src/block/primitives/blockFromBlockNumber.ts
871
- async function blockFromBlockNumber(context, blockNumber) {
872
- return await spanAsync("blockFromBlockNumber", async () => {
873
- const cacheKey = `${blockNumber}`;
874
- const { chainMap, head } = context;
875
- return await withContextCacheResponse(context, "blockFromBlockNumber", cacheKey, async () => {
876
- const [result] = await chainMap.get([head._hash]);
877
- if (!isDefined4(result)) {
878
- throw new Error(`Head block not found for hash: ${head._hash}`);
879
- }
880
- let currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
881
- result,
882
- () => `Found Payload is not a Signed<BlockBoundWitness>: ${JSON.stringify(result, null, 2)}`
883
- );
884
- if (currentBlock.block < blockNumber) {
885
- throw new Error(`Block number ${blockNumber} is greater than head ${currentBlock.block}.`);
886
- }
887
- while (currentBlock.block > blockNumber) {
888
- let jumpHash = currentBlock.previous;
889
- let jumpBlockNumber = currentBlock.block - 1;
890
- for (const [step, stepSize] of StepSizes.entries()) {
891
- const possibleJumpBlockNumber = currentBlock.block - currentBlock.block % stepSize - 1;
892
- if (possibleJumpBlockNumber >= blockNumber && possibleJumpBlockNumber <= jumpBlockNumber) {
893
- jumpBlockNumber = possibleJumpBlockNumber;
894
- jumpHash = asHash(currentBlock.step_hashes?.at(step), () => `Step hash not found for step ${step} in block ${currentBlock.block}`);
895
- }
896
- }
897
- const [newBlock] = await chainMap.get([
898
- asHash(jumpHash, () => `Jump hash not found for block number [${blockNumber}]: ${jumpBlockNumber} ${toSafeJsonString(currentBlock, 10)}`)
899
- ]);
900
- if (!isDefined4(newBlock)) {
901
- throw new Error(`Block not found for jump hash: ${jumpHash}`);
902
- }
903
- currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
904
- newBlock,
905
- () => {
906
- const result2 = SignedBlockBoundWitnessWithHashMetaZod.safeParse(newBlock);
907
- return `Found Payload [jump hash] is not a Signed<BlockBoundWitness>: ${result2.error}`;
908
- }
909
- );
910
- if (currentBlock.block === blockNumber) {
911
- break;
912
- }
913
- if (currentBlock.block < blockNumber) {
914
- throw new Error(`Block number ${blockNumber} is not a valid step block number for block ${head._hash}.`);
915
- }
916
- }
917
- return currentBlock;
918
- });
919
- }, { ...context, timeBudgetLimit: 500 });
920
- }
921
-
922
- // src/block/primitives/validateTransactionOpcodes.ts
923
- import {
924
- assertEx as assertEx5,
925
- isHash,
926
- toSafeJsonString as toSafeJsonString2
927
- } from "@xylabs/sdk-js";
928
- import {
929
- PayloadBuilder
930
- } from "@xyo-network/sdk-js";
931
- import { isExecutable } from "@xyo-network/xl1-protocol-lib";
932
- async function validateTransactionsOpcodes(txs) {
933
- const txElevatedPayloads = [];
934
- for (const [txBw, txPayloads] of txs) {
935
- if (isExecutable(txBw)) {
936
- const operations = txBw.script.map((op) => op.split("|"));
937
- for (const [opCode, ...args] of operations) {
938
- switch (opCode) {
939
- case "elevate": {
940
- const [hash, ...rest] = args;
941
- const txPayloadsWithStorageMeta = await PayloadBuilder.addStorageMeta(txPayloads);
942
- assertEx5(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
943
- if (isHash(hash)) {
944
- assertEx5(
945
- txBw.payload_hashes.includes(hash),
946
- () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
947
- );
948
- const txPayload = assertEx5(
949
- txPayloadsWithStorageMeta.find((p) => p._hash === hash),
950
- () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
951
- );
952
- txElevatedPayloads.push(txPayload);
953
- } else {
954
- throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
955
- }
956
- break;
957
- }
958
- default: {
959
- throw new Error(`Invalid opCode ${opCode}`);
960
- }
961
- }
962
- }
963
- }
964
- }
965
- return txElevatedPayloads;
950
+ // src/block/hydrate/allHashesPresent.ts
951
+ function allHashesPresent(hashes, payloads) {
952
+ const payloadHashes = new Set(payloads.map((p) => p._hash));
953
+ return hashes.every((hash) => payloadHashes.has(hash));
966
954
  }
967
955
 
968
- // src/simple/block/SimpleBlockViewer.ts
969
- import {
970
- assertEx as assertEx10,
971
- exists,
972
- isUndefined as isUndefined4
973
- } from "@xylabs/sdk-js";
974
- import {
975
- asSignedHydratedBlockWithHashMeta,
976
- asSignedHydratedBlockWithStorageMeta,
977
- asXL1BlockNumber as asXL1BlockNumber2,
978
- BlockViewerMoniker,
979
- DataLakeViewerMoniker,
980
- FinalizationViewerMoniker
981
- } from "@xyo-network/xl1-protocol-lib";
982
-
983
- // src/primitives/block/rate/blockRate.ts
984
- import { isDefined as isDefined6, isFalsy } from "@xylabs/sdk-js";
985
- import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
986
-
987
- // src/primitives/block/rate/timeHelpers.ts
988
- import { assertEx as assertEx6, isDefined as isDefined5 } from "@xylabs/sdk-js";
989
- var rateMultipliers = {
990
- millis: 1,
991
- seconds: 1e3,
992
- minutes: 1e3 * 60,
993
- hours: 1e3 * 60 * 60,
994
- days: 1e3 * 60 * 60 * 24,
995
- weeks: 1e3 * 60 * 60 * 24 * 7
996
- };
997
- var timeDurations = (timeInMs) => ({
998
- millis: timeInMs,
999
- seconds: timeInMs / 1e3,
1000
- minutes: timeInMs / (1e3 * 60),
1001
- hours: timeInMs / (1e3 * 60 * 60),
1002
- days: timeInMs / (1e3 * 60 * 60 * 24),
1003
- weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
1004
- });
1005
- var getTimeConfigInMilliseconds = (timeConfig) => {
1006
- const assertedTimeConfig = assertEx6(isDefined5(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
1007
- let totalMilliseconds = 0;
1008
- if ("years" in assertedTimeConfig) {
1009
- totalMilliseconds += assertedTimeConfig.years * 31536e6;
1010
- return totalMilliseconds;
1011
- }
1012
- if ("months" in assertedTimeConfig) {
1013
- totalMilliseconds += assertedTimeConfig.months * 2592e6;
1014
- return totalMilliseconds;
1015
- }
1016
- if ("weeks" in assertedTimeConfig) {
1017
- totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
1018
- return totalMilliseconds;
1019
- }
1020
- if ("days" in assertedTimeConfig) {
1021
- totalMilliseconds += assertedTimeConfig.days * 864e5;
1022
- return totalMilliseconds;
1023
- }
1024
- if ("hours" in assertedTimeConfig) {
1025
- totalMilliseconds += assertedTimeConfig.hours * 36e5;
1026
- return totalMilliseconds;
1027
- }
1028
- if ("minutes" in assertedTimeConfig) {
1029
- totalMilliseconds += assertedTimeConfig.minutes * 6e4;
1030
- return totalMilliseconds;
1031
- }
1032
- return totalMilliseconds;
956
+ // src/block/hydrate/flattenHydratedBlock.ts
957
+ import { toHydratedBlock } from "@xyo-network/xl1-protocol-lib";
958
+ var flattenHydratedBlock = (hydratedBlock) => {
959
+ const [blk, blkPayloads] = hydratedBlock;
960
+ return [...blkPayloads, blk];
1033
961
  };
1034
962
 
1035
- // src/primitives/block/rate/blockRate.ts
1036
- var blockRate = (startBlock, endBlock, timeUnit) => {
1037
- const startingBlock = startBlock[0];
1038
- const endingBlock = endBlock[0];
1039
- const heightDifference = endingBlock.block - startingBlock.block;
1040
- const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
1041
- if (timeDifference === 0) {
1042
- throw new Error("Time difference must be greater than 0");
1043
- }
1044
- const rate = heightDifference / timeDifference;
1045
- const timeUnitValue = isDefined6(timeUnit) ? timeUnit : "millis";
1046
- const returnedTimeDifference = isDefined6(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
1047
- const timePerBlock = returnedTimeDifference / heightDifference;
1048
- return {
1049
- range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
1050
- span: heightDifference,
1051
- rate: isDefined6(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
1052
- timeUnit: timeUnitValue,
1053
- timeDifference: returnedTimeDifference,
1054
- timePerBlock
1055
- };
1056
- };
1057
- var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
1058
- if (endBlockHeight <= startBlockHeight) {
1059
- console.error("startBlockHeight", startBlockHeight);
1060
- console.error("endBlockHeight", endBlockHeight);
1061
- throw new Error("End block height must be greater than start block height");
1062
- }
1063
- const startingBlock = await viewer.blockByNumber(startBlockHeight);
1064
- const endingBlock = await viewer.blockByNumber(endBlockHeight);
1065
- if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
1066
- throw new Error("Could not retrieve blocks for speed calculation");
1067
- }
1068
- return { startingBlock, endingBlock };
1069
- };
1070
- var calculateBlockRate = async (viewer, range, timeUnit) => {
1071
- const [startBlockHeight, endBlockHeight] = range;
1072
- const { startingBlock, endingBlock } = await getBlockRateBlocks(
1073
- viewer,
1074
- startBlockHeight,
1075
- endBlockHeight
1076
- );
1077
- return blockRate(startingBlock, endingBlock, timeUnit);
1078
- };
963
+ // src/block/hydrate/flattenHydratedBlocks.ts
964
+ var flattenHydratedBlocks = (hydratedBlocks) => hydratedBlocks.flatMap((blk) => flattenHydratedBlock(blk));
1079
965
 
1080
- // src/primitives/block/rate/stepRate.ts
966
+ // src/block/hydrate/hydrateBlock.ts
1081
967
  import { assertEx as assertEx7 } from "@xylabs/sdk-js";
968
+ import { asAnyPayload } from "@xyo-network/sdk-js";
969
+ import { asBlockBoundWitnessWithStorageMeta, isTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
970
+ var hydrateBlock = async (context, hash, maxDepth = 1, minDepth = maxDepth) => {
971
+ assertEx7(maxDepth >= 0, () => "maxDepth must be greater than or equal to 0");
972
+ assertEx7(minDepth >= 0, () => "minDepth must be greater than or equal to 0");
973
+ assertEx7(maxDepth >= minDepth, () => "maxDepth must be greater than or equal to minDepth");
974
+ const { chainMap } = context;
975
+ const [block] = await chainMap.get([hash]);
976
+ const bw = assertEx7(asBlockBoundWitnessWithStorageMeta(
977
+ assertEx7(block, () => `block ${hash} not found`)
978
+ ), () => `hash ${hash} is not a BlockBoundWitness`);
979
+ if (maxDepth === 0) return [bw, []];
980
+ const blkPayloads = (await chainMap.get(bw.payload_hashes)).map((p) => asAnyPayload(p, true));
981
+ if (minDepth === 1) assertEx7(allHashesPresent(bw.payload_hashes, blkPayloads), () => `Unable to find all payloads for block ${hash}`);
982
+ if (maxDepth === 1) return [bw, blkPayloads];
983
+ const transactions = blkPayloads.filter(isTransactionBoundWitnessWithStorageMeta);
984
+ const transactionsPayloadHashes = transactions.flatMap((tx) => tx.payload_hashes);
985
+ const transactionsPayloads = (await chainMap.get(transactionsPayloadHashes)).map((p) => asAnyPayload(p, true));
986
+ assertEx7(allHashesPresent(transactionsPayloadHashes, transactionsPayloads), () => `Unable to find all payloads for transactions in block ${hash}`);
987
+ const allPayloadsHashes = new Set([...blkPayloads, ...transactionsPayloads].flatMap((p) => p._hash));
988
+ const allPayloads = (await chainMap.get([...allPayloadsHashes])).map((p) => asAnyPayload(p, true));
989
+ const allPayloadsFiltered = allPayloads.filter((p) => allPayloadsHashes.has(p._hash));
990
+ if (maxDepth === 2) assertEx7(allHashesPresent(
991
+ [...allPayloadsHashes],
992
+ allPayloadsFiltered
993
+ ), () => `Unable to find all payloads for transactions in block ${hash}`);
994
+ return [bw, allPayloadsFiltered];
995
+ };
996
+
997
+ // src/block/primitives/blockFromBlockNumber.ts
1082
998
  import {
1083
- asXL1BlockRange as asXL1BlockRange2,
1084
- isValidStep,
1085
- StepSizes as StepSizes2
999
+ asHash,
1000
+ isDefined as isDefined7,
1001
+ spanAsync
1002
+ } from "@xylabs/sdk-js";
1003
+ import { toSafeJsonString } from "@xylabs/sdk-js";
1004
+ import {
1005
+ asSignedBlockBoundWitnessWithStorageMeta,
1006
+ SignedBlockBoundWitnessWithHashMetaZod,
1007
+ StepSizes as StepSizes3
1086
1008
  } from "@xyo-network/xl1-protocol-lib";
1087
- var stepRate = async (viewer, start, step, count = 1, timeUnit) => {
1088
- const end = start + step * count;
1089
- const range = asXL1BlockRange2([start, end], true);
1090
- return await calculateBlockRate(viewer, range, timeUnit);
1091
- };
1092
- var calculateStepSizeRate = async (viewer, start, stepIndex, count = 1, timeUnit) => {
1093
- assertEx7(isValidStep(stepIndex), () => `Invalid step index: ${stepIndex}`);
1094
- const step = StepSizes2[stepIndex];
1095
- return await stepRate(viewer, start, step, count, timeUnit);
1096
- };
1009
+ async function blockFromBlockNumber(context, blockNumber) {
1010
+ return await spanAsync("blockFromBlockNumber", async () => {
1011
+ const cacheKey = `${blockNumber}`;
1012
+ const { chainMap, head } = context;
1013
+ return await withContextCacheResponse(context, "blockFromBlockNumber", cacheKey, async () => {
1014
+ const [result] = await chainMap.get([head._hash]);
1015
+ if (!isDefined7(result)) {
1016
+ throw new Error(`Head block not found for hash: ${head._hash}`);
1017
+ }
1018
+ let currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
1019
+ result,
1020
+ () => `Found Payload is not a Signed<BlockBoundWitness>: ${JSON.stringify(result, null, 2)}`
1021
+ );
1022
+ if (currentBlock.block < blockNumber) {
1023
+ throw new Error(`Block number ${blockNumber} is greater than head ${currentBlock.block}.`);
1024
+ }
1025
+ while (currentBlock.block > blockNumber) {
1026
+ let jumpHash = currentBlock.previous;
1027
+ let jumpBlockNumber = currentBlock.block - 1;
1028
+ for (const [step, stepSize] of StepSizes3.entries()) {
1029
+ const possibleJumpBlockNumber = currentBlock.block - currentBlock.block % stepSize - 1;
1030
+ if (possibleJumpBlockNumber >= blockNumber && possibleJumpBlockNumber <= jumpBlockNumber) {
1031
+ jumpBlockNumber = possibleJumpBlockNumber;
1032
+ jumpHash = asHash(currentBlock.step_hashes?.at(step), () => `Step hash not found for step ${step} in block ${currentBlock.block}`);
1033
+ }
1034
+ }
1035
+ const [newBlock] = await chainMap.get([
1036
+ asHash(jumpHash, () => `Jump hash not found for block number [${blockNumber}]: ${jumpBlockNumber} ${toSafeJsonString(currentBlock, 10)}`)
1037
+ ]);
1038
+ if (!isDefined7(newBlock)) {
1039
+ throw new Error(`Block not found for jump hash: ${jumpHash}`);
1040
+ }
1041
+ currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
1042
+ newBlock,
1043
+ () => {
1044
+ const result2 = SignedBlockBoundWitnessWithHashMetaZod.safeParse(newBlock);
1045
+ return `Found Payload [jump hash] is not a Signed<BlockBoundWitness>: ${result2.error}`;
1046
+ }
1047
+ );
1048
+ if (currentBlock.block === blockNumber) {
1049
+ break;
1050
+ }
1051
+ if (currentBlock.block < blockNumber) {
1052
+ throw new Error(`Block number ${blockNumber} is not a valid step block number for block ${head._hash}.`);
1053
+ }
1054
+ }
1055
+ return currentBlock;
1056
+ });
1057
+ }, { ...context, timeBudgetLimit: 500 });
1058
+ }
1097
1059
 
1098
- // src/primitives/block/rate/timeRate.ts
1060
+ // src/block/primitives/validateTransactionOpcodes.ts
1099
1061
  import {
1100
1062
  assertEx as assertEx8,
1101
- isDefined as isDefined7,
1102
- isDefinedNotNull
1063
+ isHash,
1064
+ toSafeJsonString as toSafeJsonString2
1103
1065
  } from "@xylabs/sdk-js";
1104
- import { asXL1BlockNumber, asXL1BlockRange as asXL1BlockRange3 } from "@xyo-network/xl1-protocol-lib";
1105
- var DEFAULT_TOLERANCE_MS = 3e4;
1106
- var DEFAULT_MAX_ATTEMPTS = 10;
1107
- var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
1108
- assertEx8(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
1109
- const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
1110
- const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
1111
- const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
1112
- assertEx8(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
1113
- const blocksPerMillisecondRate = 1 / (12 * 1e3);
1114
- const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds);
1115
- const endBlockNumber = await findEndBlockRecursive(
1116
- viewer,
1117
- resolvedStartBlock,
1118
- timeInMilliseconds,
1119
- initialBlocksInDuration,
1120
- toleranceMs,
1121
- maxAttempts
1122
- );
1123
- return await calculateBlockRate(
1124
- viewer,
1125
- asXL1BlockRange3([endBlockNumber, resolvedStartBlock.block], true),
1126
- timeUnit
1127
- );
1128
- };
1129
- var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBlocksBack, toleranceMs, attemptsRemaining) => {
1130
- console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`);
1131
- assertEx8(attemptsRemaining >= 0, () => "Maximum attempts reached while searching for end block");
1132
- const startBlockEpoch = startBlock.$epoch;
1133
- const estimatedEndBlockNumber = asXL1BlockNumber(startBlock.block - estimatedBlocksBack, true);
1134
- if (estimatedEndBlockNumber < 0) {
1135
- throw new Error("Estimated end block number is less than zero");
1136
- }
1137
- const endBlock = await viewer.blockByNumber(estimatedEndBlockNumber);
1138
- const resolvedEndBlock = assertEx8(
1139
- isDefined7(endBlock?.[0]) ? endBlock[0] : void 0,
1140
- () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
1141
- );
1142
- const endBlockEpoch = resolvedEndBlock.$epoch;
1143
- if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
1144
- throw new TypeError("Block has missing or invalid $epoch");
1145
- }
1146
- const actualTimeDifference = startBlockEpoch - endBlockEpoch;
1147
- if (actualTimeDifference === 0) {
1148
- throw new Error("Start and end blocks have identical timestamps");
1149
- }
1150
- const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
1151
- if (timeDelta <= toleranceMs) {
1152
- return resolvedEndBlock.block;
1153
- }
1154
- let adjustedBlocksBack;
1155
- if (actualTimeDifference < targetTimeMs) {
1156
- const adjustmentFactor = targetTimeMs / actualTimeDifference;
1157
- adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
1158
- } else {
1159
- const adjustmentFactor = actualTimeDifference / targetTimeMs;
1160
- adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
1066
+ import {
1067
+ PayloadBuilder
1068
+ } from "@xyo-network/sdk-js";
1069
+ import { isExecutable } from "@xyo-network/xl1-protocol-lib";
1070
+ async function validateTransactionsOpcodes(txs) {
1071
+ const txElevatedPayloads = [];
1072
+ for (const [txBw, txPayloads] of txs) {
1073
+ if (isExecutable(txBw)) {
1074
+ const operations = txBw.script.map((op) => op.split("|"));
1075
+ for (const [opCode, ...args] of operations) {
1076
+ switch (opCode) {
1077
+ case "elevate": {
1078
+ const [hash, ...rest] = args;
1079
+ const txPayloadsWithStorageMeta = await PayloadBuilder.addStorageMeta(txPayloads);
1080
+ assertEx8(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
1081
+ if (isHash(hash)) {
1082
+ assertEx8(
1083
+ txBw.payload_hashes.includes(hash),
1084
+ () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
1085
+ );
1086
+ const txPayload = assertEx8(
1087
+ txPayloadsWithStorageMeta.find((p) => p._hash === hash),
1088
+ () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
1089
+ );
1090
+ txElevatedPayloads.push(txPayload);
1091
+ } else {
1092
+ throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
1093
+ }
1094
+ break;
1095
+ }
1096
+ default: {
1097
+ throw new Error(`Invalid opCode ${opCode}`);
1098
+ }
1099
+ }
1100
+ }
1101
+ }
1161
1102
  }
1162
- adjustedBlocksBack = Number.isFinite(adjustedBlocksBack) && adjustedBlocksBack >= 1 ? adjustedBlocksBack : 1;
1163
- return await findEndBlockRecursive(
1164
- viewer,
1165
- startBlock,
1166
- targetTimeMs,
1167
- adjustedBlocksBack,
1168
- toleranceMs,
1169
- attemptsRemaining - 1
1170
- );
1171
- };
1172
-
1173
- // src/primitives/step/completedStepRewardAddress.ts
1174
- import { toAddress } from "@xylabs/sdk-js";
1175
- import { StepSizes as StepSizes3 } from "@xyo-network/xl1-protocol-lib";
1176
- import { keccak256 } from "ethers";
1177
- function completedStepRewardAddress({ block, step }) {
1178
- const resolvedStepSize = step < StepSizes3.length ? StepSizes3[step] : step;
1179
- const addressKey = new TextEncoder().encode(`${block}|${resolvedStepSize}`);
1180
- return toAddress(keccak256(addressKey).slice(-40), { prefix: false });
1103
+ return txElevatedPayloads;
1181
1104
  }
1182
1105
 
1183
1106
  // src/primitives/datalake/addDataLakePayloadsToPayloads.ts
@@ -1249,6 +1172,99 @@ async function hydratedBlockByNumber(context, blockNumber) {
1249
1172
  }, { ...context, timeBudgetLimit: 500 });
1250
1173
  }
1251
1174
 
1175
+ // src/primitives/uncle/findBestUncle.ts
1176
+ var DEFAULT_MIN_CANDIDATES = 2;
1177
+ var DEFAULT_BACKOFF_MS = 12e4;
1178
+
1179
+ // src/config/Validation.ts
1180
+ var ValidationConfigZod = z15.object({
1181
+ allowedRewardRedeemers: z15.preprocess((val) => {
1182
+ if (typeof val === "string") {
1183
+ return val.split(",").map((s) => asAddress(s.trim()));
1184
+ }
1185
+ return val;
1186
+ }, z15.array(AddressZod2).optional().register(globalRegistry11, {
1187
+ description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
1188
+ title: "allowedRewardRedeemers",
1189
+ type: "array"
1190
+ })),
1191
+ allowedRewardEscrowAccountSigners: z15.preprocess((val) => {
1192
+ if (typeof val === "string") {
1193
+ return val.split(",").map((s) => asAddress(s.trim()));
1194
+ }
1195
+ return val;
1196
+ }, z15.array(AddressZod2).optional().register(globalRegistry11, {
1197
+ description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
1198
+ title: "allowedRewardEscrowAccountSigners",
1199
+ type: "array"
1200
+ })),
1201
+ minCandidates: z15.coerce.number().default(DEFAULT_MIN_CANDIDATES).register(globalRegistry11, {
1202
+ default: DEFAULT_MIN_CANDIDATES,
1203
+ description: "Minimum number of uncle candidates before selecting the best uncle",
1204
+ title: "validation.minCandidates",
1205
+ type: "number"
1206
+ }),
1207
+ backoffMs: z15.coerce.number().default(DEFAULT_BACKOFF_MS).register(globalRegistry11, {
1208
+ default: DEFAULT_BACKOFF_MS,
1209
+ description: "Back-off timeout in ms. If head age exceeds this, minCandidates is ignored",
1210
+ title: "validation.backoffMs",
1211
+ type: "number"
1212
+ })
1213
+ });
1214
+
1215
+ // src/config/Base.ts
1216
+ var BaseConfigZod = z16.object({
1217
+ chain: ChainConfigZod.default(ChainConfigZod.parse({})).describe("Configuration for the chain"),
1218
+ dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
1219
+ evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
1220
+ log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
1221
+ providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
1222
+ remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
1223
+ storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
1224
+ telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
1225
+ validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
1226
+ });
1227
+
1228
+ // src/config/Actor.ts
1229
+ var ActorConfigZod = BaseConfigZod.extend({
1230
+ name: z17.string(),
1231
+ mnemonic: MnemonicStringZod.optional().register(globalRegistry12, {
1232
+ description: "Mnemonic for the Actor wallet",
1233
+ title: "mnemonic",
1234
+ type: "string"
1235
+ }),
1236
+ healthCheckPort: z17.coerce.number().optional().register(globalRegistry12, {
1237
+ description: "Port for the Producer health checks",
1238
+ title: "producer.healthCheckPort",
1239
+ type: "number"
1240
+ })
1241
+ });
1242
+ var isActorConfig = zodIsFactory2(ActorConfigZod);
1243
+ var asActorConfig = zodAsFactory2(ActorConfigZod, "asActorConfig");
1244
+ var toActorConfig = zodToFactory2(ActorConfigZod, "toActorConfig");
1245
+
1246
+ // src/config/Actors.ts
1247
+ import z18 from "zod";
1248
+ var ActorsConfigZod = z18.array(ActorConfigZod.loose()).describe("Actor-specific configurations that override the base configuration when the actor is running").default([]);
1249
+
1250
+ // src/config/Config.ts
1251
+ var ConfigZod = BaseConfigZod.extend({ actors: ActorsConfigZod }).describe("The complete configuration for the protocol, including global settings and actor-specific overrides");
1252
+
1253
+ // src/simple/block/SimpleBlockViewer.ts
1254
+ import {
1255
+ assertEx as assertEx10,
1256
+ exists,
1257
+ isUndefined as isUndefined4
1258
+ } from "@xylabs/sdk-js";
1259
+ import {
1260
+ asSignedHydratedBlockWithHashMeta,
1261
+ asSignedHydratedBlockWithStorageMeta,
1262
+ asXL1BlockNumber as asXL1BlockNumber2,
1263
+ BlockViewerMoniker,
1264
+ DataLakeViewerMoniker,
1265
+ FinalizationViewerMoniker
1266
+ } from "@xyo-network/xl1-protocol-lib";
1267
+
1252
1268
  // src/utils/HydratedCache.ts
1253
1269
  import { LRUCache as LRUCache2 } from "lru-cache";
1254
1270
  var HydratedCache = class {