@xyo-network/xl1-protocol-sdk 2.2.0 → 2.2.2

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 (67) hide show
  1. package/dist/neutral/ChainContextHelpers.d.ts +1 -1
  2. package/dist/neutral/ChainContextHelpers.d.ts.map +1 -1
  3. package/dist/neutral/CreatableProvider/ProviderFactory.d.ts.map +1 -1
  4. package/dist/neutral/CreatableProvider/ProviderFactoryLocator.d.ts.map +1 -1
  5. package/dist/neutral/amount/index.d.ts +1 -1
  6. package/dist/neutral/amount/splitOnDecimalToString.d.ts.map +1 -1
  7. package/dist/neutral/amount/{XL1Amount.d.ts → xl1Amount.d.ts} +1 -1
  8. package/dist/neutral/amount/{XL1Amount.d.ts.map → xl1Amount.d.ts.map} +1 -1
  9. package/dist/neutral/block/hydrate/hydrateBlock.d.ts.map +1 -1
  10. package/dist/neutral/block/hydrate/tryHydrateBlock.d.ts.map +1 -1
  11. package/dist/neutral/block/primitives/hashFromBlockNumber.d.ts.map +1 -1
  12. package/dist/neutral/block/primitives/validateTransactionOpcodes.d.ts.map +1 -1
  13. package/dist/neutral/config/adaptLegacyConfig.d.ts.map +1 -1
  14. package/dist/neutral/createDeclarationPayload.d.ts.map +1 -1
  15. package/dist/neutral/createTransferPayload.d.ts.map +1 -1
  16. package/dist/neutral/getFileConfig.d.ts.map +1 -1
  17. package/dist/neutral/getFileConfig.mjs +2 -1
  18. package/dist/neutral/getFileConfig.mjs.map +2 -2
  19. package/dist/neutral/index.mjs +398 -278
  20. package/dist/neutral/index.mjs.map +4 -4
  21. package/dist/neutral/model/CreatableProviderContext.zod.d.ts.map +1 -1
  22. package/dist/neutral/primitives/chain/step/chainStepRewardAddress.d.ts.map +1 -1
  23. package/dist/neutral/primitives/chain/step/stepRewardTotal.d.ts.map +1 -1
  24. package/dist/neutral/primitives/chain/time/{externalBlockNumberFromXL1BlockNumber.d.ts → externalBlockNumberFromXl1BlockNumber.d.ts} +1 -1
  25. package/dist/neutral/primitives/chain/time/{externalBlockNumberFromXL1BlockNumber.d.ts.map → externalBlockNumberFromXl1BlockNumber.d.ts.map} +1 -1
  26. package/dist/neutral/primitives/chain/time/{externalBlockRangeFromXL1BlockRange.d.ts → externalBlockRangeFromXl1BlockRange.d.ts} +1 -1
  27. package/dist/neutral/primitives/chain/time/{externalBlockRangeFromXL1BlockRange.d.ts.map → externalBlockRangeFromXl1BlockRange.d.ts.map} +1 -1
  28. package/dist/neutral/primitives/chain/time/index.d.ts +2 -2
  29. package/dist/neutral/primitives/datalake/PayloadLocator.d.ts.map +1 -1
  30. package/dist/neutral/primitives/datalake/addDataLakePayloadsToPayloads.d.ts.map +1 -1
  31. package/dist/neutral/primitives/readPayloadMapFromStore.d.ts.map +1 -1
  32. package/dist/neutral/primitives/stake/activeStakeAtTimeByAddress.d.ts.map +1 -1
  33. package/dist/neutral/primitives/stake/activeStakeAtTimeByPosition.d.ts.map +1 -1
  34. package/dist/neutral/primitives/stake/weightedStakeForRangeByPosition.d.ts.map +1 -1
  35. package/dist/neutral/primitives/state/findMostRecentBlock.d.ts.map +1 -1
  36. package/dist/neutral/primitives/uncle/findUncles.d.ts.map +1 -1
  37. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts +3 -6
  38. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts.map +1 -1
  39. package/dist/neutral/simple/block/SimpleBlockViewer.d.ts.map +1 -1
  40. package/dist/neutral/simple/blockInvalidation/SimpleBlockInvalidationViewer.d.ts.map +1 -1
  41. package/dist/neutral/simple/blockValidation/SimpleBlockValidationViewer.d.ts.map +1 -1
  42. package/dist/neutral/simple/datalake/AbstractRestDataLake.d.ts.map +1 -1
  43. package/dist/neutral/simple/datalake/RestDataLakeRunner.d.ts.map +1 -1
  44. package/dist/neutral/simple/datalake/SimpleDataLakeRunner.d.ts.map +1 -1
  45. package/dist/neutral/simple/finalization/SimpleFinalizationRunner.d.ts.map +1 -1
  46. package/dist/neutral/simple/finalization/SimpleFinalizationViewer.d.ts.map +1 -1
  47. package/dist/neutral/simple/gateway/SimpleXyoGatewayRunner.d.ts.map +1 -1
  48. package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts.map +1 -1
  49. package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts +2 -0
  50. package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts.map +1 -1
  51. package/dist/neutral/simple/network/SimpleXyoNetwork.d.ts.map +1 -1
  52. package/dist/neutral/simple/timeSync2/SimpleTimeSyncViewer.d.ts.map +1 -1
  53. package/dist/neutral/simple/transactionInvalidation/SimpleTransactionInvalidationViewer.d.ts.map +1 -1
  54. package/dist/neutral/simple/transactionValidation/SimpleTransactionValidationViewer.d.ts.map +1 -1
  55. package/dist/neutral/summary/primitives/balances/balancesStepSummaryFromRange.d.ts.map +1 -1
  56. package/dist/neutral/test/buildBlock.d.ts.map +1 -1
  57. package/dist/neutral/test/buildRandomChain.d.ts.map +1 -1
  58. package/dist/neutral/test/buildRandomGenesisBlock.d.ts.map +1 -1
  59. package/dist/neutral/test/buildRandomTransaction.d.ts.map +1 -1
  60. package/dist/neutral/test/createProducerChainStakeIntentTransaction.d.ts.map +1 -1
  61. package/dist/neutral/test/index.mjs +140 -88
  62. package/dist/neutral/test/index.mjs.map +3 -3
  63. package/dist/neutral/transaction/buildTransaction.d.ts.map +1 -1
  64. package/dist/neutral/transaction/buildUnsignedTransaction.d.ts.map +1 -1
  65. package/dist/neutral/transaction/confirmSubmittedTransaction.d.ts.map +1 -1
  66. package/dist/neutral/transaction/hydrateTransaction.d.ts.map +1 -1
  67. package/package.json +8 -8
@@ -54,15 +54,18 @@ var hydrateBlock = async (context, hash, maxDepth = 1, minDepth = maxDepth) => {
54
54
  assertEx(block, () => `block ${hash} not found`)
55
55
  ), () => `hash ${hash} is not a BlockBoundWitness`);
56
56
  if (maxDepth === 0) return [bw, []];
57
- const blkPayloads = (await chainMap.get(bw.payload_hashes)).map((p) => asAnyPayload(p, true));
57
+ const blockPayloadResults = await chainMap.get(bw.payload_hashes);
58
+ const blkPayloads = blockPayloadResults.map((p) => asAnyPayload(p, true));
58
59
  if (minDepth === 1) assertEx(allHashesPresent(bw.payload_hashes, blkPayloads), () => `Unable to find all payloads for block ${hash}`);
59
60
  if (maxDepth === 1) return [bw, blkPayloads];
60
61
  const transactions = blkPayloads.filter(isTransactionBoundWitnessWithStorageMeta);
61
62
  const transactionsPayloadHashes = transactions.flatMap((tx) => tx.payload_hashes);
62
- const transactionsPayloads = (await chainMap.get(transactionsPayloadHashes)).map((p) => asAnyPayload(p, true));
63
+ const transactionPayloadResults = await chainMap.get(transactionsPayloadHashes);
64
+ const transactionsPayloads = transactionPayloadResults.map((p) => asAnyPayload(p, true));
63
65
  assertEx(allHashesPresent(transactionsPayloadHashes, transactionsPayloads), () => `Unable to find all payloads for transactions in block ${hash}`);
64
66
  const allPayloadsHashes = new Set([...blkPayloads, ...transactionsPayloads].flatMap((p) => p._hash));
65
- const allPayloads = (await chainMap.get([...allPayloadsHashes])).map((p) => asAnyPayload(p, true));
67
+ const allPayloadResults = await chainMap.get([...allPayloadsHashes]);
68
+ const allPayloads = allPayloadResults.map((p) => asAnyPayload(p, true));
66
69
  const allPayloadsFiltered = allPayloads.filter((p) => allPayloadsHashes.has(p._hash));
67
70
  if (maxDepth === 2) assertEx(allHashesPresent(
68
71
  [...allPayloadsHashes],
@@ -120,7 +123,7 @@ async function withContextCacheResponse(context, name, key, func, { max = 1e4 }
120
123
  // src/block/primitives/blockFromBlockNumber.ts
121
124
  async function blockFromBlockNumber(context, blockNumber) {
122
125
  return await spanAsync("blockFromBlockNumber", async () => {
123
- const cacheKey = `${blockNumber}`;
126
+ const cacheKey = String(blockNumber);
124
127
  const { chainMap, head } = context;
125
128
  return await withContextCacheResponse(context, "blockFromBlockNumber", cacheKey, async () => {
126
129
  const [result] = await chainMap.get([head._hash]);
@@ -226,35 +229,41 @@ import {
226
229
  PayloadBuilder
227
230
  } from "@xyo-network/sdk-js";
228
231
  import { isExecutable } from "@xyo-network/xl1-protocol-lib";
232
+ async function processElevateOperation(opCode, args, txBw, txPayloads) {
233
+ const [hash, ...rest] = args;
234
+ const txPayloadsWithStorageMeta = await PayloadBuilder.addStorageMeta(txPayloads);
235
+ assertEx2(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
236
+ if (isHash(hash)) {
237
+ assertEx2(
238
+ txBw.payload_hashes.includes(hash),
239
+ () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
240
+ );
241
+ return assertEx2(
242
+ txPayloadsWithStorageMeta.find((p) => p._hash === hash),
243
+ () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
244
+ );
245
+ }
246
+ throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
247
+ }
248
+ async function processOperation(opCode, args, txBw, txPayloads) {
249
+ switch (opCode) {
250
+ case "elevate": {
251
+ return await processElevateOperation(opCode, args, txBw, txPayloads);
252
+ }
253
+ default: {
254
+ throw new Error(`Invalid opCode ${opCode}`);
255
+ }
256
+ }
257
+ }
229
258
  async function validateTransactionsOpcodes(txs) {
230
259
  const txElevatedPayloads = [];
231
260
  for (const [txBw, txPayloads] of txs) {
232
261
  if (isExecutable(txBw)) {
233
262
  const operations = txBw.script.map((op) => op.split("|"));
234
263
  for (const [opCode, ...args] of operations) {
235
- switch (opCode) {
236
- case "elevate": {
237
- const [hash, ...rest] = args;
238
- const txPayloadsWithStorageMeta = await PayloadBuilder.addStorageMeta(txPayloads);
239
- assertEx2(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
240
- if (isHash(hash)) {
241
- assertEx2(
242
- txBw.payload_hashes.includes(hash),
243
- () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
244
- );
245
- const txPayload = assertEx2(
246
- txPayloadsWithStorageMeta.find((p) => p._hash === hash),
247
- () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
248
- );
249
- txElevatedPayloads.push(txPayload);
250
- } else {
251
- throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
252
- }
253
- break;
254
- }
255
- default: {
256
- throw new Error(`Invalid opCode ${opCode}`);
257
- }
264
+ const txPayload = await processOperation(opCode, args, txBw, txPayloads);
265
+ if (txPayload !== void 0) {
266
+ txElevatedPayloads.push(txPayload);
258
267
  }
259
268
  }
260
269
  }
@@ -292,12 +301,14 @@ import { toHex } from "@xylabs/sdk-js";
292
301
  import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk-js";
293
302
  import { TransferSchema } from "@xyo-network/xl1-protocol-lib";
294
303
  function createTransferPayload(from, transfers, context) {
295
- return new PayloadBuilder2({ schema: TransferSchema }).fields({
304
+ const payloadBuilder = new PayloadBuilder2({ schema: TransferSchema });
305
+ const builder = payloadBuilder.fields({
296
306
  epoch: Date.now(),
297
307
  from,
298
308
  transfers: Object.fromEntries(Object.entries(transfers).map(([k, v]) => [k, toHex(v)])),
299
309
  context
300
- }).build();
310
+ });
311
+ return builder.build();
301
312
  }
302
313
 
303
314
  // src/test/BuildBlockOptions.ts
@@ -352,6 +363,26 @@ var isBuildNextBlockOptions = (value) => {
352
363
  function calculateCompletedStepReward(step, balance) {
353
364
  return AttoXL1(StepRewardFractions[step][0] * balance / StepRewardFractions[step][1]);
354
365
  }
366
+ function buildStepHashes(blockNumber, inStepHashes, previousBlockHash, chainStepRewardAddress, stepRewardPoolBalance) {
367
+ const completedStepRewardTransfers = [];
368
+ const step_hashes = [];
369
+ for (const [i, step] of StepSizes3.entries()) {
370
+ if (blockNumber < step) {
371
+ break;
372
+ }
373
+ if (blockNumber % step === 0) {
374
+ if (StepRewardFractions[i][0] > 0 && chainStepRewardAddress !== XYO_ZERO_ADDRESS) {
375
+ const completedStepRewardHolderAddress = rewardAddressFromStepIdentity({ block: blockNumber, step });
376
+ const completedStepReward = calculateCompletedStepReward(i, stepRewardPoolBalance);
377
+ completedStepRewardTransfers.push(createTransferPayload(chainStepRewardAddress, { [completedStepRewardHolderAddress]: completedStepReward }));
378
+ }
379
+ step_hashes.push(assertEx3(previousBlockHash, () => `Previous block hash is required for step ${step} at block ${blockNumber}`));
380
+ } else if (isDefined3(inStepHashes.at(i))) {
381
+ step_hashes.push(inStepHashes[i]);
382
+ }
383
+ }
384
+ return { completedStepRewardTransfers, step_hashes };
385
+ }
355
386
  async function buildBlock(options) {
356
387
  const previousBlockNumber = isBuildGenesisBlockOptions(options) ? -1 : options.previousBlockNumber;
357
388
  const blockNumber = asXL1BlockNumber2(previousBlockNumber + 1, true);
@@ -366,7 +397,6 @@ async function buildBlock(options) {
366
397
  protocol = XL1_PROTOCOL_VERSION,
367
398
  signers
368
399
  } = options;
369
- const step_hashes = [];
370
400
  for (const [tx] of txs) {
371
401
  if (tx.nbf > blockNumber) {
372
402
  throw new Error(`Transaction ${await PayloadBuilder3.hash(tx)} not valid for block ${blockNumber} - NBF is ${tx.nbf}`);
@@ -375,24 +405,13 @@ async function buildBlock(options) {
375
405
  throw new Error(`Transaction ${await PayloadBuilder3.hash(tx)} not valid for block ${blockNumber} - EXP is ${tx.exp}`);
376
406
  }
377
407
  }
378
- const completedStepRewardTransfers = [];
379
- for (const [i, step] of StepSizes3.entries()) {
380
- if (blockNumber < step) {
381
- break;
382
- }
383
- if (blockNumber % step === 0) {
384
- if (StepRewardFractions[i][0] > 0 && chainStepRewardAddress !== XYO_ZERO_ADDRESS) {
385
- const completedStepRewardHolderAddress = rewardAddressFromStepIdentity({ block: blockNumber, step });
386
- const completedStepReward = calculateCompletedStepReward(i, stepRewardPoolBalance);
387
- completedStepRewardTransfers.push(createTransferPayload(chainStepRewardAddress, { [completedStepRewardHolderAddress]: completedStepReward }));
388
- }
389
- step_hashes.push(assertEx3(previousBlockHash, () => `Previous block hash is required for step ${step} at block ${blockNumber}`));
390
- } else {
391
- if (isDefined3(inStepHashes.at(i))) {
392
- step_hashes.push(inStepHashes[i]);
393
- }
394
- }
395
- }
408
+ const { step_hashes, completedStepRewardTransfers } = buildStepHashes(
409
+ blockNumber,
410
+ inStepHashes,
411
+ previousBlockHash,
412
+ chainStepRewardAddress,
413
+ stepRewardPoolBalance
414
+ );
396
415
  const previous = previousBlockHash ?? null;
397
416
  const block = blockNumber;
398
417
  const txElevatedPayloads = await validateTransactionsOpcodes(txs);
@@ -402,13 +421,15 @@ async function buildBlock(options) {
402
421
  ...txElevatedPayloads,
403
422
  ...completedStepRewardTransfers
404
423
  ];
405
- const [bw, txPayloads] = await new BoundWitnessBuilder().fields({
424
+ const boundWitnessBuilder = new BoundWitnessBuilder();
425
+ const builder = boundWitnessBuilder.fields({
406
426
  block,
407
427
  chain: chainId,
408
428
  previous,
409
429
  step_hashes,
410
430
  protocol
411
- }).meta({ $epoch: Date.now(), $signatures: [] }).signers(signers).payloads(await PayloadBuilder3.addStorageMeta(payloads)).build();
431
+ }).meta({ $epoch: Date.now(), $signatures: [] }).signers(signers).payloads(await PayloadBuilder3.addStorageMeta(payloads));
432
+ const [bw, txPayloads] = await builder.build();
412
433
  assertEx3(isBlockBoundWitness(bw), () => "Build of BlockBoundWitness failed");
413
434
  return [await PayloadBuilder3.addStorageMeta(bw), txPayloads.map((p) => asAnyPayload2(p, true))];
414
435
  }
@@ -484,10 +505,7 @@ async function buildTransaction(chain, onChainPayloads, offChainPayloads, signer
484
505
  exp
485
506
  };
486
507
  const elevatedHashes = await PayloadBuilder4.hashes(onChainPayloads);
487
- const script = [];
488
- for (const elevatedHash of elevatedHashes) {
489
- script.push(`elevate|${elevatedHash}`);
490
- }
508
+ const script = Array.from(elevatedHashes, (elevatedHash) => `elevate|${elevatedHash}`);
491
509
  const fields = {
492
510
  ...txBoundWitnessFields,
493
511
  from: from ?? (Array.isArray(signer) ? assertEx4(signer.at(0)?.address) : signer.address)
@@ -495,7 +513,9 @@ async function buildTransaction(chain, onChainPayloads, offChainPayloads, signer
495
513
  if (script.length > 0) {
496
514
  fields.script = script;
497
515
  }
498
- const [tx, txPayloads] = await new BoundWitnessBuilder2().fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).signers(Array.isArray(signer) ? signer : [signer]).build();
516
+ const boundWitnessBuilder = new BoundWitnessBuilder2();
517
+ const builder = boundWitnessBuilder.fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).signers(Array.isArray(signer) ? signer : [signer]);
518
+ const [tx, txPayloads] = await builder.build();
499
519
  return [await PayloadBuilder4.addHashMeta(tx), await PayloadBuilder4.addHashMeta(txPayloads.map((p) => asAnyPayload3(p, true)))];
500
520
  }
501
521
 
@@ -505,7 +525,8 @@ var buildRandomTransaction = async (chain, payloads, account, nbf = asXL1BlockNu
505
525
  const additionalPayloads = (payloads ?? []).filter((payload) => !isAllowedBlockPayload(payload));
506
526
  const sender = account ?? await Account.random();
507
527
  if (elevatedPayloads.length === 0) {
508
- const receiver = receiverAddress ?? (await Account.random()).address;
528
+ const defaultReceiver = await Account.random();
529
+ const receiver = receiverAddress ?? defaultReceiver.address;
509
530
  const transferPayload = createTransferPayload(sender.address, { [receiver]: 1n });
510
531
  elevatedPayloads.push(transferPayload);
511
532
  }
@@ -536,12 +557,14 @@ import {
536
557
  defaultTransactionFees as defaultTransactionFees2
537
558
  } from "@xyo-network/xl1-protocol-lib";
538
559
  async function createProducerChainStakeIntent(from, exp, nbf = 0) {
539
- return await PayloadBuilder6.addHashMeta(new PayloadBuilder6({ schema: ChainStakeIntentSchema }).fields({
560
+ const payloadBuilder = new PayloadBuilder6({ schema: ChainStakeIntentSchema });
561
+ const builder = payloadBuilder.fields({
540
562
  from,
541
563
  exp,
542
564
  nbf,
543
565
  intent: "producer"
544
- }).build());
566
+ });
567
+ return await PayloadBuilder6.addHashMeta(builder.build());
545
568
  }
546
569
 
547
570
  // src/test/createGenesisBlock.ts
@@ -585,13 +608,20 @@ var buildRandomChain = async (blockProducer, count = 10, previousBlock, chainId,
585
608
  remaining = remaining - 1;
586
609
  lastBlock = block;
587
610
  }
588
- const resolvedReceiverAddresses = receiverAddresses ?? [(await Account3.random()).address];
611
+ const defaultReceiver = await Account3.random();
612
+ const resolvedReceiverAddresses = receiverAddresses ?? [defaultReceiver.address];
589
613
  let saltCounter = 0;
590
614
  while (remaining > 0) {
591
615
  saltCounter += 1;
592
- const payloads = [new PayloadBuilder8({ schema: IdSchema2 }).fields({ salt: `${Date.now()}-${saltCounter}` }).build()];
616
+ const idPayloadBuilder = new PayloadBuilder8({ schema: IdSchema2 });
617
+ const idBuilder = idPayloadBuilder.fields({ salt: `${Date.now()}-${saltCounter}` });
618
+ const payloads = [idBuilder.build()];
593
619
  saltCounter += 1;
594
- const additionalPrivatePayloads = remaining % 2 === 0 ? [new PayloadBuilder8({ schema: asSchema2("network.xyo.private", true) }).fields({ salt: `${Date.now()}-${saltCounter}` }).build()] : [];
620
+ const additionalPrivatePayloads = remaining % 2 === 0 ? (() => {
621
+ const privatePayloadBuilder = new PayloadBuilder8({ schema: asSchema2("network.xyo.private", true) });
622
+ const privateBuilder = privatePayloadBuilder.fields({ salt: `${Date.now()}-${saltCounter}` });
623
+ return [privateBuilder.build()];
624
+ })() : [];
595
625
  const txs = [];
596
626
  for (const receiverAddress of resolvedReceiverAddresses) {
597
627
  txs.push(await buildRandomTransaction(
@@ -661,7 +691,7 @@ var ProviderFactory = class _ProviderFactory {
661
691
  get resolvedMoniker() {
662
692
  const labels = this.labels ?? {};
663
693
  const labelString = Object.entries(labels).map(([key, value]) => `${key}=${value}`).join(",");
664
- return labelString.length === 0 ? `${this.defaultMoniker}` : `${this.defaultMoniker}|${labelString}`;
694
+ return labelString.length === 0 ? this.defaultMoniker : `${this.defaultMoniker}|${labelString}`;
665
695
  }
666
696
  get uniqueId() {
667
697
  return this._uniqueId;
@@ -676,8 +706,7 @@ var ProviderFactory = class _ProviderFactory {
676
706
  let scopeObject;
677
707
  switch (this.scope) {
678
708
  case "global": {
679
- globalThis.xyoServiceSingletons ??= {};
680
- scopeObject = globalThis.xyoServiceSingletons;
709
+ scopeObject = getOrCreateGlobalSingletons();
681
710
  break;
682
711
  }
683
712
  case "context": {
@@ -714,6 +743,15 @@ var ProviderFactory = class _ProviderFactory {
714
743
  }
715
744
  }
716
745
  };
746
+ function getOrCreateGlobalSingletons() {
747
+ const existing = globalThis.xyoServiceSingletons;
748
+ if (existing !== void 0) {
749
+ return existing;
750
+ }
751
+ const singletons = {};
752
+ Reflect.set(globalThis, "xyoServiceSingletons", singletons);
753
+ return singletons;
754
+ }
717
755
 
718
756
  // src/CreatableProvider/AbstractCreatableProvider.ts
719
757
  var AbstractCreatableProvider = class extends AbstractCreatable {
@@ -883,7 +921,7 @@ var ProviderFactoryLocator = class _ProviderFactoryLocator {
883
921
  );
884
922
  }
885
923
  has(moniker) {
886
- return !!this._registry[moniker];
924
+ return Object.hasOwn(this._registry, moniker);
887
925
  }
888
926
  /**
889
927
  * Locates a provider factory that matches the supplied moniker and labels
@@ -900,10 +938,11 @@ var ProviderFactoryLocator = class _ProviderFactoryLocator {
900
938
  merge(locator) {
901
939
  const registry = { ...this.registry };
902
940
  for (const moniker in locator.registry) {
903
- if (registry[moniker]) {
904
- registry[moniker].push(...locator.registry[moniker] ?? []);
905
- } else {
941
+ const existing = registry[moniker];
942
+ if (existing === void 0) {
906
943
  registry[moniker] = locator.registry[moniker];
944
+ } else {
945
+ existing.push(...locator.registry[moniker] ?? []);
907
946
  }
908
947
  }
909
948
  return new _ProviderFactoryLocator(this.context, registry);
@@ -933,13 +972,13 @@ var ProviderFactoryLocator = class _ProviderFactoryLocator {
933
972
  return this;
934
973
  }
935
974
  registered(moniker) {
936
- return !!this.registry[moniker] || (this._parent?.registered(moniker) ?? false);
975
+ return Object.hasOwn(this.registry, moniker) || (this._parent?.registered(moniker) ?? false);
937
976
  }
938
977
  async tryGetInstance(moniker, { start = true, labels } = {}) {
939
978
  const resolvedParams = { context: this.context };
940
979
  const factory = this.tryLocate(moniker, labels);
941
- if (factory) {
942
- if (this.context.singletons[factory.uniqueId]) {
980
+ if (factory !== void 0) {
981
+ if (Object.hasOwn(this.context.singletons, factory.uniqueId)) {
943
982
  return this.context.singletons[factory.uniqueId];
944
983
  }
945
984
  this.logger?.debug(`Creating provider instance for moniker [${moniker}]${labels ? ` with labels [${JSON.stringify(labels)}]` : ""} using factory [${factory.uniqueId.description}]`);
@@ -1454,7 +1493,9 @@ var DEFAULT_MAX_ATTEMPTS = 10;
1454
1493
  var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
1455
1494
  assertEx12(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
1456
1495
  const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
1457
- const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
1496
+ const currentBlockResult = await viewer.currentBlock();
1497
+ const blockResult = isDefinedNotNull(startBlock) ? startBlock : currentBlockResult;
1498
+ const resolvedStartBlock = blockResult[0];
1458
1499
  const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
1459
1500
  assertEx12(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
1460
1501
  const blocksPerMillisecondRate = 1 / (12 * 1e3);
@@ -1519,7 +1560,7 @@ var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBl
1519
1560
  // src/primitives/state/findMostRecentBlock.ts
1520
1561
  import { isSignedBlockBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
1521
1562
  var DEFAULT_NEXT_OPTIONS = { limit: 50 };
1522
- var findMostRecentBlock = async (chainArchivist, nextOptions = DEFAULT_NEXT_OPTIONS, maxIterations = Number.POSITIVE_INFINITY) => {
1563
+ var findMostRecentBlock = async (chainArchivist, nextOptions = DEFAULT_NEXT_OPTIONS, maxIterations = Infinity) => {
1523
1564
  let mostRecentBlock;
1524
1565
  let cursor;
1525
1566
  let batch;
@@ -1535,9 +1576,8 @@ var findMostRecentBlock = async (chainArchivist, nextOptions = DEFAULT_NEXT_OPTI
1535
1576
  if (last) {
1536
1577
  mostRecentBlock = last;
1537
1578
  break;
1538
- } else {
1539
- cursor = batch.at(-1)?._sequence;
1540
1579
  }
1580
+ cursor = batch.at(-1)?._sequence;
1541
1581
  iterations = iterations + 1;
1542
1582
  } while (batch.length > 0 && iterations < maxIterations);
1543
1583
  return mostRecentBlock;
@@ -1550,7 +1590,7 @@ async function hydratedBlockByNumber(context, blockNumber) {
1550
1590
  if (blockNumber < 0) throw new Error(`Block number ${blockNumber} is less than 0`);
1551
1591
  if (blockNumber > Number.MAX_SAFE_INTEGER) throw new Error(`Block number ${blockNumber} is greater than the maximum safe integer`);
1552
1592
  if (blockNumber % 1 !== 0) throw new Error(`Block number ${blockNumber} is not an integer`);
1553
- const cacheKey = `${blockNumber}`;
1593
+ const cacheKey = String(blockNumber);
1554
1594
  return await withContextCacheResponse(context, "hydratedBlockByNumber", cacheKey, async () => {
1555
1595
  const block = assertEx13(
1556
1596
  await blockFromBlockNumber(context, blockNumber),
@@ -1859,7 +1899,7 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
1859
1899
  }
1860
1900
  async blocksByStep(stepLevel, stepIndex) {
1861
1901
  return await this.spanAsync("blocksByStep", async () => {
1862
- assertEx15(Number.isInteger(stepIndex) && stepIndex >= 0, () => "stepIndex must be a non-negative integer");
1902
+ assertEx15(Number.isSafeInteger(stepIndex) && stepIndex >= 0, () => "stepIndex must be a non-negative integer");
1863
1903
  const size = stepSize2(stepLevel);
1864
1904
  assertEx15(
1865
1905
  stepLevel <= blocksMaxStep,
@@ -1883,7 +1923,12 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
1883
1923
  }
1884
1924
  async chainId(blockNumber = "latest") {
1885
1925
  return await this.spanAsync("chainId", async () => {
1886
- return blockNumber === "latest" ? (await this.finalizationViewer.headBlock()).chain : assertEx15(await this.blockByNumber(blockNumber), () => `Block not found [${blockNumber}]`)[0].chain;
1926
+ if (blockNumber === "latest") {
1927
+ const headBlock = await this.finalizationViewer.headBlock();
1928
+ return headBlock.chain;
1929
+ }
1930
+ const block = assertEx15(await this.blockByNumber(blockNumber), () => `Block not found [${blockNumber}]`);
1931
+ return block[0].chain;
1887
1932
  }, this.context);
1888
1933
  }
1889
1934
  async createHandler() {
@@ -1932,9 +1977,10 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
1932
1977
  };
1933
1978
  }
1934
1979
  async getChainContextRead() {
1980
+ const headBlock = await this.finalizationViewer.head();
1935
1981
  return {
1936
1982
  ...this.getBlockContextRead(),
1937
- head: (await this.finalizationViewer.head())[0]
1983
+ head: headBlock[0]
1938
1984
  };
1939
1985
  }
1940
1986
  async startHandler() {
@@ -1981,10 +2027,11 @@ var SimpleBlockViewer = class extends AbstractCreatableProvider {
1981
2027
  }, this.headPollIntervalMs);
1982
2028
  }
1983
2029
  stopHeadPolling() {
1984
- if (this._headPollTimer) {
1985
- clearInterval(this._headPollTimer);
1986
- this._headPollTimer = null;
2030
+ if (!this._headPollTimer) {
2031
+ return;
1987
2032
  }
2033
+ clearInterval(this._headPollTimer);
2034
+ this._headPollTimer = null;
1988
2035
  }
1989
2036
  };
1990
2037
  __publicField(SimpleBlockViewer, "defaultMoniker", BlockViewerMoniker);
@@ -2007,7 +2054,7 @@ var SimpleChainContractViewer = class extends AbstractCreatableProvider {
2007
2054
  return this.finalizationViewer.chainId();
2008
2055
  }
2009
2056
  async chainIdAtBlockNumber(blockNumber) {
2010
- return await withContextCacheResponse(this.context, "chainIdAtBlockNumber", `${blockNumber}`, async () => {
2057
+ return await withContextCacheResponse(this.context, "chainIdAtBlockNumber", String(blockNumber), async () => {
2011
2058
  let chainId = this.chainId();
2012
2059
  let contractViewer = this;
2013
2060
  let forkedAtBlockNumber = await contractViewer.forkedAtBlockNumber();
@@ -2090,7 +2137,8 @@ var SimpleFinalizationViewer = class extends AbstractCreatableProvider {
2090
2137
  }
2091
2138
  async createHandler() {
2092
2139
  await super.createHandler();
2093
- this._chainId = assertEx17(this.config.chain.id ?? (await findMostRecentBlock(this.params.finalizedArchivist))?.chain, () => "chain.id is required if empty archivist");
2140
+ const mostRecentBlock = await findMostRecentBlock(this.params.finalizedArchivist);
2141
+ this._chainId = assertEx17(this.config.chain.id ?? mostRecentBlock?.chain, () => "chain.id is required if empty archivist");
2094
2142
  this._store = { chainMap: this.params.finalizedArchivist };
2095
2143
  }
2096
2144
  async head() {
@@ -2105,13 +2153,16 @@ var SimpleFinalizationViewer = class extends AbstractCreatableProvider {
2105
2153
  }, this.context);
2106
2154
  }
2107
2155
  async headBlock() {
2108
- return (await this.head())[0];
2156
+ const headBlock = await this.head();
2157
+ return headBlock[0];
2109
2158
  }
2110
2159
  async headHash() {
2111
- return (await this.headBlock())._hash;
2160
+ const headBlock = await this.headBlock();
2161
+ return headBlock._hash;
2112
2162
  }
2113
2163
  async headNumber() {
2114
- return (await this.headBlock()).block;
2164
+ const headBlock = await this.headBlock();
2165
+ return headBlock.block;
2115
2166
  }
2116
2167
  getBlockContextRead() {
2117
2168
  return {
@@ -2120,9 +2171,10 @@ var SimpleFinalizationViewer = class extends AbstractCreatableProvider {
2120
2171
  };
2121
2172
  }
2122
2173
  async getChainContextRead() {
2174
+ const headBlock = await this.head();
2123
2175
  return {
2124
2176
  ...this.getBlockContextRead(),
2125
- head: (await this.head())[0]
2177
+ head: headBlock[0]
2126
2178
  };
2127
2179
  }
2128
2180
  async getCurrentHead() {