@xyo-network/xl1-protocol-sdk 1.17.7 → 1.18.0-rc.1

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 (255) hide show
  1. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts +103 -1
  2. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts.map +1 -1
  3. package/dist/neutral/CreatableProvider/CreatableProvider.d.ts +25 -8
  4. package/dist/neutral/CreatableProvider/CreatableProvider.d.ts.map +1 -1
  5. package/dist/neutral/CreatableProvider/CreatableProviderRegistry.d.ts.map +1 -1
  6. package/dist/neutral/CreatableProvider/ProviderFactory.d.ts +11 -3
  7. package/dist/neutral/CreatableProvider/ProviderFactory.d.ts.map +1 -1
  8. package/dist/neutral/CreatableProvider/ProviderFactoryLocator.d.ts +19 -13
  9. package/dist/neutral/CreatableProvider/ProviderFactoryLocator.d.ts.map +1 -1
  10. package/dist/neutral/CreatableProvider/ProviderFactoryLocatorInstance.d.ts +14 -10
  11. package/dist/neutral/CreatableProvider/ProviderFactoryLocatorInstance.d.ts.map +1 -1
  12. package/dist/neutral/config/Bridge.d.ts +3 -0
  13. package/dist/neutral/config/Bridge.d.ts.map +1 -1
  14. package/dist/neutral/config/Chain.d.ts +1 -1
  15. package/dist/neutral/config/Config.d.ts +6 -3
  16. package/dist/neutral/config/Config.d.ts.map +1 -1
  17. package/dist/neutral/config/Log.d.ts +1 -1
  18. package/dist/neutral/createDeclarationPayload.d.ts +4 -0
  19. package/dist/neutral/createDeclarationPayload.d.ts.map +1 -0
  20. package/dist/neutral/createTransferPayload.d.ts +4 -0
  21. package/dist/neutral/createTransferPayload.d.ts.map +1 -0
  22. package/dist/neutral/driver/cache/LruCacheMap.d.ts +2 -2
  23. package/dist/neutral/driver/cache/LruCacheMap.d.ts.map +1 -1
  24. package/dist/neutral/driver/memory/MemoryMap.d.ts +2 -2
  25. package/dist/neutral/driver/memory/MemoryMap.d.ts.map +1 -1
  26. package/dist/neutral/index.d.ts +3 -0
  27. package/dist/neutral/index.d.ts.map +1 -1
  28. package/dist/neutral/index.mjs +1584 -655
  29. package/dist/neutral/index.mjs.map +1 -1
  30. package/dist/neutral/map/MapType.d.ts +3 -2
  31. package/dist/neutral/map/MapType.d.ts.map +1 -1
  32. package/dist/neutral/model/ChainContext/ChainContext.d.ts +4 -4
  33. package/dist/neutral/model/ChainContext/ChainContext.d.ts.map +1 -1
  34. package/dist/neutral/model/PayloadBundle/bundledPayloadToHydratedTransaction.d.ts +2 -2
  35. package/dist/neutral/model/PayloadBundle/bundledPayloadToHydratedTransaction.d.ts.map +1 -1
  36. package/dist/neutral/primitives/block/index.d.ts +2 -0
  37. package/dist/neutral/primitives/block/index.d.ts.map +1 -0
  38. package/dist/neutral/primitives/block/range/blockRangeSteps.d.ts +3 -0
  39. package/dist/neutral/primitives/block/range/blockRangeSteps.d.ts.map +1 -0
  40. package/dist/neutral/primitives/block/range/index.d.ts +2 -0
  41. package/dist/neutral/primitives/block/range/index.d.ts.map +1 -0
  42. package/dist/neutral/primitives/chain/index.d.ts +3 -0
  43. package/dist/neutral/primitives/chain/index.d.ts.map +1 -0
  44. package/dist/neutral/primitives/chain/step/chainStepRewardAddress.d.ts +5 -0
  45. package/dist/neutral/primitives/chain/step/chainStepRewardAddress.d.ts.map +1 -0
  46. package/dist/neutral/primitives/chain/step/index.d.ts +5 -0
  47. package/dist/neutral/primitives/chain/step/index.d.ts.map +1 -0
  48. package/dist/neutral/primitives/chain/step/stepRewardBlock.d.ts +4 -0
  49. package/dist/neutral/primitives/chain/step/stepRewardBlock.d.ts.map +1 -0
  50. package/dist/neutral/primitives/chain/step/stepRewardTotal.d.ts +4 -0
  51. package/dist/neutral/primitives/chain/step/stepRewardTotal.d.ts.map +1 -0
  52. package/dist/neutral/primitives/chain/step/stepsRewardTotal.d.ts +6 -0
  53. package/dist/neutral/primitives/chain/step/stepsRewardTotal.d.ts.map +1 -0
  54. package/dist/neutral/primitives/chain/time/externalBlockNumberFromXL1BlockNumber.d.ts +5 -0
  55. package/dist/neutral/primitives/chain/time/externalBlockNumberFromXL1BlockNumber.d.ts.map +1 -0
  56. package/dist/neutral/primitives/chain/time/externalBlockRangeFromStep.d.ts +5 -0
  57. package/dist/neutral/primitives/chain/time/externalBlockRangeFromStep.d.ts.map +1 -0
  58. package/dist/neutral/primitives/chain/time/externalBlockRangeFromXL1BlockRange.d.ts +5 -0
  59. package/dist/neutral/primitives/chain/time/externalBlockRangeFromXL1BlockRange.d.ts.map +1 -0
  60. package/dist/neutral/primitives/chain/time/index.d.ts +4 -0
  61. package/dist/neutral/primitives/chain/time/index.d.ts.map +1 -0
  62. package/dist/neutral/primitives/index.d.ts +6 -0
  63. package/dist/neutral/primitives/index.d.ts.map +1 -1
  64. package/dist/neutral/primitives/mapToMapType.d.ts +3 -0
  65. package/dist/neutral/primitives/mapToMapType.d.ts.map +1 -0
  66. package/dist/neutral/primitives/payload/index.d.ts +2 -0
  67. package/dist/neutral/primitives/payload/index.d.ts.map +1 -0
  68. package/dist/neutral/primitives/payload/mergeTransfers.d.ts +4 -0
  69. package/dist/neutral/primitives/payload/mergeTransfers.d.ts.map +1 -0
  70. package/dist/neutral/primitives/readPayloadMapFromStore.d.ts +5 -4
  71. package/dist/neutral/primitives/readPayloadMapFromStore.d.ts.map +1 -1
  72. package/dist/neutral/primitives/rewards/index.d.ts +2 -0
  73. package/dist/neutral/primitives/rewards/index.d.ts.map +1 -0
  74. package/dist/neutral/primitives/rewards/networkStakeStepRewardPositionWeight.d.ts +5 -0
  75. package/dist/neutral/primitives/rewards/networkStakeStepRewardPositionWeight.d.ts.map +1 -0
  76. package/dist/neutral/primitives/stake/activeStakeAtTimeByAddress.d.ts +4 -0
  77. package/dist/neutral/primitives/stake/activeStakeAtTimeByAddress.d.ts.map +1 -0
  78. package/dist/neutral/primitives/stake/activeStakeAtTimeByPosition.d.ts +3 -0
  79. package/dist/neutral/primitives/stake/activeStakeAtTimeByPosition.d.ts.map +1 -0
  80. package/dist/neutral/primitives/stake/allStakersForRange.d.ts +4 -0
  81. package/dist/neutral/primitives/stake/allStakersForRange.d.ts.map +1 -0
  82. package/dist/neutral/primitives/stake/allStakersForStep.d.ts +6 -0
  83. package/dist/neutral/primitives/stake/allStakersForStep.d.ts.map +1 -0
  84. package/dist/neutral/primitives/stake/index.d.ts +7 -0
  85. package/dist/neutral/primitives/stake/index.d.ts.map +1 -0
  86. package/dist/neutral/primitives/stake/mergedAddRemoveStakeEventsByPosition.d.ts +3 -0
  87. package/dist/neutral/primitives/stake/mergedAddRemoveStakeEventsByPosition.d.ts.map +1 -0
  88. package/dist/neutral/primitives/stake/mergedAddRemoveStakeEventsByStaker.d.ts +4 -0
  89. package/dist/neutral/primitives/stake/mergedAddRemoveStakeEventsByStaker.d.ts.map +1 -0
  90. package/dist/neutral/primitives/stake/weightedStakeForRangeByPosition.d.ts +6 -0
  91. package/dist/neutral/primitives/stake/weightedStakeForRangeByPosition.d.ts.map +1 -0
  92. package/dist/neutral/provider/DataLake.d.ts +10 -9
  93. package/dist/neutral/provider/DataLake.d.ts.map +1 -1
  94. package/dist/neutral/provider/XyoConnection.d.ts +4 -1
  95. package/dist/neutral/provider/XyoConnection.d.ts.map +1 -1
  96. package/dist/neutral/provider/XyoGatewayRunner.d.ts +3 -3
  97. package/dist/neutral/provider/XyoGatewayRunner.d.ts.map +1 -1
  98. package/dist/neutral/provider/XyoRunner.d.ts +5 -2
  99. package/dist/neutral/provider/XyoRunner.d.ts.map +1 -1
  100. package/dist/neutral/provider/viewer/XyoViewer.d.ts +9 -8
  101. package/dist/neutral/provider/viewer/XyoViewer.d.ts.map +1 -1
  102. package/dist/neutral/runners/Block.d.ts +7 -2
  103. package/dist/neutral/runners/Block.d.ts.map +1 -1
  104. package/dist/neutral/runners/Mempool.d.ts +4 -1
  105. package/dist/neutral/runners/Mempool.d.ts.map +1 -1
  106. package/dist/neutral/services/Chain/ChainService.d.ts +2 -2
  107. package/dist/neutral/services/Chain/ChainService.d.ts.map +1 -1
  108. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts +5 -12
  109. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts.map +1 -1
  110. package/dist/neutral/simple/block/SimpleBlockViewer.d.ts +9 -6
  111. package/dist/neutral/simple/block/SimpleBlockViewer.d.ts.map +1 -1
  112. package/dist/neutral/simple/chainStake/{SimpleChainStakeViewer.d.ts → SimpleStakeViewer.d.ts} +3 -5
  113. package/dist/neutral/simple/chainStake/SimpleStakeViewer.d.ts.map +1 -0
  114. package/dist/neutral/simple/chainStake/index.d.ts +1 -1
  115. package/dist/neutral/simple/chainStake/index.d.ts.map +1 -1
  116. package/dist/neutral/simple/datalake/AbstractSimpleDataLake.d.ts +5 -2
  117. package/dist/neutral/simple/datalake/AbstractSimpleDataLake.d.ts.map +1 -1
  118. package/dist/neutral/simple/datalake/SimpleDataLakeRunner.d.ts +4 -3
  119. package/dist/neutral/simple/datalake/SimpleDataLakeRunner.d.ts.map +1 -1
  120. package/dist/neutral/simple/datalake/SimpleDataLakeViewer.d.ts +0 -3
  121. package/dist/neutral/simple/datalake/SimpleDataLakeViewer.d.ts.map +1 -1
  122. package/dist/neutral/simple/index.d.ts +1 -0
  123. package/dist/neutral/simple/index.d.ts.map +1 -1
  124. package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts +8 -4
  125. package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts.map +1 -1
  126. package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts.map +1 -1
  127. package/dist/neutral/simple/runner/SimpleXyoRunner.d.ts +24 -6
  128. package/dist/neutral/simple/runner/SimpleXyoRunner.d.ts.map +1 -1
  129. package/dist/neutral/simple/{chainStakeEvents/SimpleChainStakeEventsViewer.d.ts → stakeEvents/SimpleStakeEventsViewer.d.ts} +3 -3
  130. package/dist/neutral/simple/stakeEvents/SimpleStakeEventsViewer.d.ts.map +1 -0
  131. package/dist/neutral/simple/stakeEvents/index.d.ts +2 -0
  132. package/dist/neutral/simple/stakeEvents/index.d.ts.map +1 -0
  133. package/dist/neutral/simple/timesync/SimpleTimeSyncViewer.d.ts +4 -3
  134. package/dist/neutral/simple/timesync/SimpleTimeSyncViewer.d.ts.map +1 -1
  135. package/dist/neutral/status/RuntimeStatusMonitor.d.ts +31 -0
  136. package/dist/neutral/status/RuntimeStatusMonitor.d.ts.map +1 -0
  137. package/dist/neutral/status/ServiceStatus.d.ts +8 -0
  138. package/dist/neutral/status/ServiceStatus.d.ts.map +1 -0
  139. package/dist/neutral/status/index.d.ts +3 -0
  140. package/dist/neutral/status/index.d.ts.map +1 -0
  141. package/dist/neutral/summary/model/summary.d.ts +4 -4
  142. package/dist/neutral/summary/model/summary.d.ts.map +1 -1
  143. package/dist/neutral/summary/primitives/balances/balancesStepSummaryFromRange.d.ts +1 -1
  144. package/dist/neutral/summary/primitives/balances/balancesStepSummaryFromRange.d.ts.map +1 -1
  145. package/dist/neutral/transaction/TransactionBuilder.d.ts +82 -0
  146. package/dist/neutral/transaction/TransactionBuilder.d.ts.map +1 -0
  147. package/dist/neutral/transaction/buildRandomTransaction.d.ts +6 -0
  148. package/dist/neutral/transaction/buildRandomTransaction.d.ts.map +1 -0
  149. package/dist/neutral/transaction/index.d.ts +2 -0
  150. package/dist/neutral/transaction/index.d.ts.map +1 -1
  151. package/dist/neutral/viewers/Block.d.ts +4 -1
  152. package/dist/neutral/viewers/Block.d.ts.map +1 -1
  153. package/dist/neutral/viewers/ChainStakeViewer.d.ts +1 -2
  154. package/dist/neutral/viewers/ChainStakeViewer.d.ts.map +1 -1
  155. package/dist/neutral/viewers/Fork.d.ts +0 -1
  156. package/dist/neutral/viewers/Fork.d.ts.map +1 -1
  157. package/dist/neutral/viewers/Stake.d.ts +0 -1
  158. package/dist/neutral/viewers/Stake.d.ts.map +1 -1
  159. package/dist/neutral/viewers/index.d.ts +0 -1
  160. package/dist/neutral/viewers/index.d.ts.map +1 -1
  161. package/package.json +9 -7
  162. package/src/CreatableProvider/AbstractCreatableProvider.ts +44 -3
  163. package/src/CreatableProvider/CreatableProvider.ts +36 -9
  164. package/src/CreatableProvider/CreatableProviderRegistry.ts +9 -5
  165. package/src/CreatableProvider/ProviderFactory.ts +72 -10
  166. package/src/CreatableProvider/ProviderFactoryLocator.ts +78 -19
  167. package/src/CreatableProvider/ProviderFactoryLocatorInstance.ts +33 -10
  168. package/src/config/Bridge.ts +22 -4
  169. package/src/config/Chain.ts +2 -2
  170. package/src/createDeclarationPayload.ts +14 -0
  171. package/src/createTransferPayload.ts +15 -0
  172. package/src/driver/cache/LruCacheMap.ts +2 -2
  173. package/src/driver/memory/MemoryMap.ts +2 -2
  174. package/src/index.ts +3 -0
  175. package/src/map/MapType.ts +4 -2
  176. package/src/model/ChainContext/ChainContext.ts +4 -4
  177. package/src/model/PayloadBundle/bundledPayloadToHydratedTransaction.ts +2 -2
  178. package/src/primitives/block/index.ts +1 -0
  179. package/src/primitives/block/range/blockRangeSteps.ts +22 -0
  180. package/src/primitives/block/range/index.ts +1 -0
  181. package/src/primitives/chain/index.ts +2 -0
  182. package/src/primitives/chain/step/chainStepRewardAddress.ts +28 -0
  183. package/src/primitives/chain/step/index.ts +4 -0
  184. package/src/primitives/chain/step/stepRewardBlock.ts +11 -0
  185. package/src/primitives/chain/step/stepRewardTotal.ts +45 -0
  186. package/src/primitives/chain/step/stepsRewardTotal.ts +34 -0
  187. package/src/primitives/chain/time/externalBlockNumberFromXL1BlockNumber.ts +31 -0
  188. package/src/primitives/chain/time/externalBlockRangeFromStep.ts +19 -0
  189. package/src/primitives/chain/time/externalBlockRangeFromXL1BlockRange.ts +16 -0
  190. package/src/primitives/chain/time/index.ts +3 -0
  191. package/src/primitives/index.ts +6 -0
  192. package/src/primitives/mapToMapType.ts +35 -0
  193. package/src/primitives/payload/index.ts +1 -0
  194. package/src/primitives/payload/mergeTransfers.ts +15 -0
  195. package/src/primitives/readPayloadMapFromStore.ts +38 -8
  196. package/src/primitives/rewards/index.ts +1 -0
  197. package/src/primitives/rewards/networkStakeStepRewardPositionWeight.ts +21 -0
  198. package/src/primitives/stake/activeStakeAtTimeByAddress.ts +26 -0
  199. package/src/primitives/stake/activeStakeAtTimeByPosition.ts +24 -0
  200. package/src/primitives/stake/allStakersForRange.ts +31 -0
  201. package/src/primitives/stake/allStakersForStep.ts +22 -0
  202. package/src/primitives/stake/index.ts +6 -0
  203. package/src/primitives/stake/mergedAddRemoveStakeEventsByPosition.ts +14 -0
  204. package/src/primitives/stake/mergedAddRemoveStakeEventsByStaker.ts +17 -0
  205. package/src/primitives/stake/weightedStakeForRangeByPosition.ts +54 -0
  206. package/src/provider/DataLake.ts +12 -11
  207. package/src/provider/XyoConnection.ts +5 -1
  208. package/src/provider/XyoGatewayRunner.ts +3 -3
  209. package/src/provider/XyoRunner.ts +6 -2
  210. package/src/provider/viewer/XyoViewer.ts +9 -8
  211. package/src/runners/Block.ts +10 -2
  212. package/src/runners/Mempool.ts +6 -1
  213. package/src/services/Chain/ChainService.ts +2 -4
  214. package/src/simple/accountBalance/SimpleAccountBalanceViewer.ts +21 -14
  215. package/src/simple/block/SimpleBlockViewer.ts +47 -14
  216. package/src/simple/chainStake/{SimpleChainStakeViewer.ts → SimpleStakeViewer.ts} +11 -16
  217. package/src/simple/chainStake/index.ts +1 -1
  218. package/src/simple/datalake/AbstractSimpleDataLake.ts +17 -17
  219. package/src/simple/datalake/SimpleDataLakeRunner.ts +4 -3
  220. package/src/simple/datalake/SimpleDataLakeViewer.ts +0 -18
  221. package/src/simple/index.ts +1 -0
  222. package/src/simple/mempool/SimpleMempoolRunner.ts +13 -8
  223. package/src/simple/mempool/SimpleMempoolViewer.ts +6 -1
  224. package/src/simple/runner/SimpleXyoRunner.ts +41 -16
  225. package/src/simple/{chainStakeEvents/SimpleChainStakeEventsViewer.ts → stakeEvents/SimpleStakeEventsViewer.ts} +5 -5
  226. package/src/simple/stakeEvents/index.ts +1 -0
  227. package/src/simple/timesync/SimpleTimeSyncViewer.ts +26 -5
  228. package/src/status/RuntimeStatusMonitor.ts +117 -0
  229. package/src/status/ServiceStatus.ts +20 -0
  230. package/src/status/index.ts +2 -0
  231. package/src/summary/model/summary.ts +6 -4
  232. package/src/summary/primitives/balances/balancesStepSummaryFromRange.ts +2 -3
  233. package/src/transaction/TransactionBuilder.ts +162 -0
  234. package/src/transaction/buildRandomTransaction.ts +36 -0
  235. package/src/transaction/hydrateTransaction.ts +1 -1
  236. package/src/transaction/index.ts +2 -0
  237. package/src/viewers/Block.ts +6 -1
  238. package/src/viewers/ChainStakeViewer.ts +1 -2
  239. package/src/viewers/Fork.ts +0 -1
  240. package/src/viewers/Stake.ts +0 -1
  241. package/src/viewers/index.ts +0 -1
  242. package/dist/neutral/simple/chain/SimpleChainViewer.d.ts +0 -15
  243. package/dist/neutral/simple/chain/SimpleChainViewer.d.ts.map +0 -1
  244. package/dist/neutral/simple/chain/index.d.ts +0 -2
  245. package/dist/neutral/simple/chain/index.d.ts.map +0 -1
  246. package/dist/neutral/simple/chainStake/SimpleChainStakeViewer.d.ts.map +0 -1
  247. package/dist/neutral/simple/chainStakeEvents/SimpleChainStakeEventsViewer.d.ts.map +0 -1
  248. package/dist/neutral/simple/chainStakeEvents/index.d.ts +0 -2
  249. package/dist/neutral/simple/chainStakeEvents/index.d.ts.map +0 -1
  250. package/dist/neutral/viewers/Chain.d.ts +0 -11
  251. package/dist/neutral/viewers/Chain.d.ts.map +0 -1
  252. package/src/simple/chain/SimpleChainViewer.ts +0 -28
  253. package/src/simple/chain/index.ts +0 -1
  254. package/src/simple/chainStakeEvents/index.ts +0 -1
  255. package/src/viewers/Chain.ts +0 -13
@@ -3,6 +3,7 @@ import {
3
3
  assertEx,
4
4
  exists,
5
5
  isDefined,
6
+ isUndefined,
6
7
  spanRootAsync,
7
8
  } from '@xylabs/sdk-js'
8
9
  import type { ReadArchivist } from '@xyo-network/archivist-model'
@@ -10,6 +11,7 @@ import type { Payload, WithHashMeta } from '@xyo-network/payload-model'
10
11
  import {
11
12
  asSignedHydratedBlockWithHashMeta,
12
13
  asXL1BlockNumber,
14
+ ChainId,
13
15
  type SignedHydratedBlockWithHashMeta,
14
16
  type XL1BlockNumber,
15
17
  } from '@xyo-network/xl1-protocol'
@@ -22,12 +24,13 @@ import type {
22
24
  ChainContextRead,
23
25
  ChainStoreRead, PayloadMap,
24
26
  } from '../../model/index.ts'
25
- import { findMostRecentBlock, hydratedBlockByNumber } from '../../primitives/index.ts'
27
+ import {
28
+ findMostRecentBlock, hydratedBlockByNumber, readPayloadMapFromStore,
29
+ } from '../../primitives/index.ts'
26
30
  import { HydratedCache } from '../../utils/index.ts'
27
31
  import { type BlockViewer, BlockViewerMoniker } from '../../viewers/index.ts'
28
32
 
29
33
  export interface SimpleBlockViewerParams extends CreatableProviderParams {
30
- context: ChainContextRead
31
34
  finalizedArchivist: ReadArchivist
32
35
  }
33
36
 
@@ -37,27 +40,25 @@ export class SimpleBlockViewer extends AbstractCreatableProvider<SimpleBlockView
37
40
  static readonly monikers = [BlockViewerMoniker]
38
41
  moniker = SimpleBlockViewer.defaultMoniker
39
42
 
43
+ protected _store: ChainStoreRead | undefined
44
+
40
45
  private _payloadCache: PayloadMap<WithHashMeta<Payload>> | undefined
41
46
  private _signedHydratedBlockCache: HydratedCache<SignedHydratedBlockWithHashMeta> | undefined
42
47
 
43
- get context(): ChainContextRead {
44
- return this.params.context!
45
- }
46
-
47
48
  get finalizedArchivist(): ReadArchivist {
48
49
  return this.params.finalizedArchivist!
49
50
  }
50
51
 
51
52
  protected get hydratedBlockCache(): HydratedCache<SignedHydratedBlockWithHashMeta> {
52
53
  if (this._signedHydratedBlockCache) return this._signedHydratedBlockCache
53
- const chainMap = this.context.store.chainMap
54
+ const chainMap = this.store.chainMap
54
55
  this._signedHydratedBlockCache = new HydratedCache<SignedHydratedBlockWithHashMeta>(chainMap, async (
55
- { chainMap }: ChainStoreRead,
56
+ store: ChainStoreRead,
56
57
  hash: Hash,
57
58
  maxDepth?: number,
58
59
  minDepth?: number,
59
60
  ) => {
60
- const result = await hydrateBlock({ chainMap }, hash, maxDepth, minDepth)
61
+ const result = await hydrateBlock(store, hash, maxDepth, minDepth)
61
62
  return asSignedHydratedBlockWithHashMeta(result, true)
62
63
  }, 200)
63
64
  return this._signedHydratedBlockCache
@@ -69,8 +70,11 @@ export class SimpleBlockViewer extends AbstractCreatableProvider<SimpleBlockView
69
70
  return this._payloadCache
70
71
  }
71
72
 
73
+ protected get store() {
74
+ return this._store!
75
+ }
76
+
72
77
  static override async paramsHandler(params: Partial<SimpleBlockViewerParams>) {
73
- assertEx(params.context, () => 'context is required')
74
78
  assertEx(params.finalizedArchivist, () => 'finalizedArchivist is required')
75
79
 
76
80
  return { ...await super.paramsHandler(params) }
@@ -85,7 +89,18 @@ export class SimpleBlockViewer extends AbstractCreatableProvider<SimpleBlockView
85
89
 
86
90
  async blockByNumber(blockNumber: XL1BlockNumber): Promise<SignedHydratedBlockWithHashMeta | null> {
87
91
  return await spanRootAsync('blockByNumber', async () => {
88
- return asSignedHydratedBlockWithHashMeta(await hydratedBlockByNumber(this.context, blockNumber)) ?? null
92
+ const head = await this.getCurrentHead()
93
+ if (isUndefined(head)) {
94
+ return null
95
+ }
96
+ return asSignedHydratedBlockWithHashMeta(await hydratedBlockByNumber({
97
+ chainId: head.chain,
98
+ head: () => {
99
+ return [head._hash, head.block]
100
+ },
101
+ store: this.store,
102
+ singletons: this.context.singletons,
103
+ } satisfies ChainContextRead, blockNumber)) ?? null
89
104
  }, this.tracer)
90
105
  }
91
106
 
@@ -121,9 +136,27 @@ export class SimpleBlockViewer extends AbstractCreatableProvider<SimpleBlockView
121
136
  }, this.tracer)
122
137
  }
123
138
 
139
+ chainId(): Promise<ChainId>
140
+ chainId(blockNumber: XL1BlockNumber): Promise<ChainId>
141
+ chainId(blockNumber: 'latest'): Promise<ChainId>
142
+ async chainId(blockNumber: XL1BlockNumber | 'latest' = 'latest'): Promise<ChainId> {
143
+ return await spanRootAsync('chainId', async () => {
144
+ const block = assertEx(
145
+ blockNumber === 'latest' ? await this.currentBlock() : await this.blockByNumber(blockNumber),
146
+ () => `Could not find block for block number ${blockNumber}`,
147
+ )
148
+ return block[0].chain
149
+ })
150
+ }
151
+
152
+ override async createHandler() {
153
+ await super.createHandler()
154
+ this._store = { chainMap: readPayloadMapFromStore(this.params.finalizedArchivist) }
155
+ }
156
+
124
157
  async currentBlock(): Promise<SignedHydratedBlockWithHashMeta> {
125
158
  return await spanRootAsync('currentBlock', async () => {
126
- const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
159
+ const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block [currentBlock]')
127
160
  const cache = this.hydratedBlockCache
128
161
  const block = await cache.get(currentHead._hash)
129
162
  if (!block) {
@@ -135,14 +168,14 @@ export class SimpleBlockViewer extends AbstractCreatableProvider<SimpleBlockView
135
168
 
136
169
  async currentBlockHash(): Promise<Hash> {
137
170
  return await spanRootAsync('currentBlockHash', async () => {
138
- const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
171
+ const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block [currentBlockHash]')
139
172
  return currentHead._hash
140
173
  }, this.tracer)
141
174
  }
142
175
 
143
176
  async currentBlockNumber(): Promise<XL1BlockNumber> {
144
177
  return await spanRootAsync('currentBlockNumber', async () => {
145
- const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
178
+ const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block [currentBlockNumber]')
146
179
  return asXL1BlockNumber(currentHead.block, { name: 'currentBlockNumber' })
147
180
  }, this.tracer)
148
181
  }
@@ -2,16 +2,14 @@ import {
2
2
  type Address, asAddress, toAddress,
3
3
  } from '@xylabs/sdk-js'
4
4
  import { assertEx } from '@xylabs/sdk-js'
5
- import { Account } from '@xyo-network/account'
6
5
 
7
6
  import {
8
7
  AbstractCreatableProvider, creatableProvider, CreatableProviderParams,
9
8
  } from '../../CreatableProvider/index.ts'
10
9
  import { PayloadMap, Position } from '../../model/index.ts'
11
10
  import {
12
- StakeEventsViewer, StakeViewer, StakeViewerMoniker,
11
+ StakeEventsViewer, StakeEventsViewerMoniker, StakeViewer, StakeViewerMoniker,
13
12
  } from '../../viewers/index.ts'
14
- import { SimpleChainStakeEventsViewer } from '../chainStakeEvents/index.ts'
15
13
 
16
14
  export interface SimpleChainStakeParams extends CreatableProviderParams {
17
15
  chainId?: Address
@@ -21,18 +19,13 @@ export interface SimpleChainStakeParams extends CreatableProviderParams {
21
19
  }
22
20
 
23
21
  @creatableProvider()
24
- export class SimpleChainStakeViewer extends AbstractCreatableProvider<SimpleChainStakeParams> implements StakeViewer {
22
+ export class SimpleStakeViewer extends AbstractCreatableProvider<SimpleChainStakeParams> implements StakeViewer {
25
23
  static readonly defaultMoniker = StakeViewerMoniker
26
24
  static readonly monikers = [StakeViewerMoniker]
27
- moniker = SimpleChainStakeViewer.defaultMoniker
25
+ moniker = SimpleStakeViewer.defaultMoniker
28
26
 
29
- private _chainId: Address | undefined
30
27
  private _chainStakeEventsViewer: StakeEventsViewer | undefined
31
28
 
32
- get chainId(): Address {
33
- return assertEx(this._chainId, () => 'Chain ID not set')
34
- }
35
-
36
29
  get chainMap() {
37
30
  return this.params.chainMap
38
31
  }
@@ -87,6 +80,14 @@ export class SimpleChainStakeViewer extends AbstractCreatableProvider<SimpleChai
87
80
  return active
88
81
  }
89
82
 
83
+ override async createHandler() {
84
+ await super.createHandler()
85
+ this._chainStakeEventsViewer = assertEx(
86
+ (await this.locateAndCreate<StakeEventsViewer>(StakeEventsViewerMoniker)),
87
+ () => 'Failed to create StakeEventsViewer',
88
+ )
89
+ }
90
+
90
91
  pending(): bigint {
91
92
  let pending = 0n
92
93
  for (const position of this.positions) {
@@ -144,10 +145,4 @@ export class SimpleChainStakeViewer extends AbstractCreatableProvider<SimpleChai
144
145
  }
145
146
  return withdrawn
146
147
  }
147
-
148
- protected override async startHandler(): Promise<void> {
149
- await super.startHandler()
150
- this._chainId = this.params.chainId ?? (await Account.random()).address
151
- this._chainStakeEventsViewer = await SimpleChainStakeEventsViewer.create({ positions: this.positions })
152
- }
153
148
  }
@@ -1 +1 @@
1
- export * from './SimpleChainStakeViewer.ts'
1
+ export * from './SimpleStakeViewer.ts'
@@ -2,11 +2,11 @@ import type { Hash } from '@xylabs/sdk-js'
2
2
  import { isAnyPayload, type Schema } from '@xyo-network/payload-model'
3
3
 
4
4
  import { AbstractCreatableProvider, type CreatableProviderParams } from '../../CreatableProvider/index.ts'
5
- import type { MapTypeRead, MapTypeWrite } from '../../map/index.ts'
5
+ import type { MapTypeRead } from '../../map/index.ts'
6
6
  import { type DataLakeData } from '../../provider/index.ts'
7
7
 
8
8
  export interface AbstractSimpleDataLakeParams<TMap extends
9
- MapTypeRead<Hash, DataLakeData> | MapTypeWrite<Hash, DataLakeData> = MapTypeRead<Hash, DataLakeData> | MapTypeWrite<Hash, DataLakeData>> extends
9
+ MapTypeRead<Hash, DataLakeData> = MapTypeRead<Hash, DataLakeData>> extends
10
10
  CreatableProviderParams {
11
11
 
12
12
  allowedSchemas?: Schema[]
@@ -27,23 +27,23 @@ export class AbstractSimpleDataLake<TParams extends AbstractSimpleDataLakeParams
27
27
  return this.params.map
28
28
  }
29
29
 
30
- // async get(hash: Hash): Promise<DataLakeData | undefined> {
31
- // const result = await this.map.get(hash)
32
- // return this.isAllowed(result) ? result : undefined
33
- // }
30
+ async get(hash: Hash): Promise<DataLakeData | undefined> {
31
+ const result = await this.map.get(hash)
32
+ return this.isAllowed(result) ? result : undefined
33
+ }
34
34
 
35
- // async getMany(hashes: Hash[]): Promise<DataLakeData[]> {
36
- // const result = await this.map.getMany(hashes)
37
- // return result.filter(data => this.isAllowed(data))
38
- // }
35
+ async getMany(hashes: Hash[]): Promise<DataLakeData[]> {
36
+ const result = await this.map.getMany(hashes)
37
+ return result.filter(data => this.isAllowed(data))
38
+ }
39
39
 
40
- // async has(hash: Hash): Promise<boolean> {
41
- // const value = await this.get(hash)
42
- // if (isAnyPayload(value)) {
43
- // return this.isAllowed(value)
44
- // }
45
- // return value !== undefined
46
- // }
40
+ async has(hash: Hash): Promise<boolean> {
41
+ const value = await this.get(hash)
42
+ if (isAnyPayload(value)) {
43
+ return this.isAllowed(value)
44
+ }
45
+ return value !== undefined
46
+ }
47
47
 
48
48
  protected isAllowed(value: DataLakeData | undefined): boolean {
49
49
  if (isAnyPayload(value)) {
@@ -1,15 +1,16 @@
1
1
  import type { Hash } from '@xylabs/sdk-js'
2
2
 
3
3
  import { creatableProvider } from '../../CreatableProvider/index.ts'
4
- import type { MapTypeWrite } from '../../map/index.ts'
4
+ import type { MapType } from '../../map/index.ts'
5
5
  import {
6
6
  type DataLakeData,
7
7
  type DataLakeRunner,
8
8
  DataLakeRunnerMoniker,
9
9
  } from '../../provider/index.ts'
10
- import { AbstractSimpleDataLake, AbstractSimpleDataLakeParams } from './AbstractSimpleDataLake.ts'
10
+ import { AbstractSimpleDataLake } from './AbstractSimpleDataLake.ts'
11
+ import { DataLakeViewerParams } from './SimpleDataLakeViewer.ts'
11
12
 
12
- export interface DataLakeRunnerParams extends AbstractSimpleDataLakeParams<MapTypeWrite<Hash, DataLakeData>> {}
13
+ export interface DataLakeRunnerParams extends DataLakeViewerParams<MapType<Hash, DataLakeData>> {}
13
14
 
14
15
  @creatableProvider()
15
16
  export class SimpleDataLakeRunner<TParams extends DataLakeRunnerParams> extends
@@ -20,22 +20,4 @@ export class SimpleDataLakeViewer<TParams extends DataLakeViewerParams = DataLak
20
20
  static readonly defaultMoniker = DataLakeViewerMoniker
21
21
  static readonly monikers = [DataLakeViewerMoniker]
22
22
  moniker = SimpleDataLakeViewer.defaultMoniker
23
-
24
- async get(hash: Hash): Promise<DataLakeData | undefined> {
25
- const result = await this.map.get(hash)
26
- return this.isAllowed(result) ? result : undefined
27
- }
28
-
29
- async getMany(hashes: Hash[]): Promise<DataLakeData[]> {
30
- const result = await this.map.getMany(hashes)
31
- return result.filter(data => this.isAllowed(data))
32
- }
33
-
34
- async has(hash: Hash): Promise<boolean> {
35
- const value = await this.get(hash)
36
- if (isAnyPayload(value)) {
37
- return this.isAllowed(value)
38
- }
39
- return value !== undefined
40
- }
41
23
  }
@@ -10,4 +10,5 @@ export * from './network/index.ts'
10
10
  export * from './permissions/index.ts'
11
11
  export * from './runner/index.ts'
12
12
  export * from './signer/index.ts'
13
+ export * from './stakeEvents/index.ts'
13
14
  export * from './timesync/index.ts'
@@ -1,20 +1,25 @@
1
- import {
2
- AbstractCreatable, creatable, CreatableParams, type Hash,
3
- } from '@xylabs/sdk-js'
1
+ import { type Hash } from '@xylabs/sdk-js'
4
2
  import type { ArchivistInstance } from '@xyo-network/archivist-model'
5
3
  import { PayloadBuilder } from '@xyo-network/payload-builder'
6
4
  import { type SignedHydratedBlock, type SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
7
5
 
6
+ import {
7
+ AbstractCreatableProvider, creatableProvider, CreatableProviderParams,
8
+ } from '../../CreatableProvider/index.ts'
8
9
  import { hydratedBlockToPayloadBundle, hydratedTransactionToPayloadBundle } from '../../model/index.ts'
9
- import type { MempoolRunner } from '../../runners/index.ts'
10
+ import { type MempoolRunner, MempoolRunnerMoniker } from '../../runners/index.ts'
10
11
 
11
- export interface SimpleMempoolRunnerParams extends CreatableParams {
12
+ export interface SimpleMempoolRunnerParams extends CreatableProviderParams {
12
13
  pendingBlocksArchivist: ArchivistInstance
13
14
  pendingTransactionsArchivist: ArchivistInstance
14
15
  }
15
16
 
16
- @creatable()
17
- export class SimpleMempoolRunner extends AbstractCreatable<SimpleMempoolRunnerParams> implements MempoolRunner {
17
+ @creatableProvider()
18
+ export class SimpleMempoolRunner extends AbstractCreatableProvider<SimpleMempoolRunnerParams> implements MempoolRunner {
19
+ static readonly defaultMoniker = MempoolRunnerMoniker
20
+ static readonly monikers = [MempoolRunnerMoniker]
21
+ moniker = SimpleMempoolRunner.defaultMoniker
22
+
18
23
  protected get pendingBlocksArchivist() {
19
24
  return this.params.pendingBlocksArchivist
20
25
  }
@@ -41,7 +46,7 @@ export class SimpleMempoolRunner extends AbstractCreatable<SimpleMempoolRunnerPa
41
46
  await PayloadBuilder.addHashMeta(payloads),
42
47
  ])
43
48
  }))
44
- const inserted = await this.pendingBlocksArchivist.insert(bundles)
49
+ const inserted = await this.pendingTransactionsArchivist.insert(bundles)
45
50
  return inserted.map(p => p._hash)
46
51
  }
47
52
  }
@@ -58,10 +58,15 @@ export class SimpleMempoolViewer extends AbstractCreatableProvider<SimpleMempool
58
58
  cursor = p._sequence
59
59
  }
60
60
  }
61
+ this.logger?.info(`Fetching pending transactions from cursor: ${cursor}`)
61
62
  const bundles = await this.pendingTransactionsArchivist.next({
62
63
  order: 'asc', limit: 100, cursor,
63
64
  })
65
+ this.logger?.info(`Fetched pending transactions: ${bundles.length} bundles`)
64
66
  const filteredBundles = bundles.filter(isPayloadBundle).filter(isHashMeta)
65
- return (await Promise.all(filteredBundles.map(async bundle => await bundledPayloadToHydratedTransaction(bundle)))).filter(exists)
67
+ this.logger?.info(`Filtered pending transactions: ${JSON.stringify(bundles, null, 2)} filteredBundles`)
68
+ const result = (await Promise.all(filteredBundles.map(async bundle => await bundledPayloadToHydratedTransaction(bundle)))).filter(exists)
69
+ this.logger?.info(`Converted pending transactions: ${JSON.stringify(result, null, 2)} results`)
70
+ return result
66
71
  }
67
72
  }
@@ -1,29 +1,54 @@
1
- import type { Hash } from '@xylabs/sdk-js'
2
- import { MemoryArchivist } from '@xyo-network/archivist-memory'
1
+ import {
2
+ assertEx,
3
+ type Hash,
4
+ } from '@xylabs/sdk-js'
3
5
  import type { ArchivistInstance } from '@xyo-network/archivist-model'
4
6
  import { PayloadBuilder } from '@xyo-network/payload-builder'
5
7
  import type { SignedHydratedTransactionWithStorageMeta } from '@xyo-network/xl1-protocol'
6
8
 
7
- import type { XyoRunner } from '../../provider/index.ts'
8
- import { flattenHydratedTransaction } from '../../transaction/index.ts'
9
+ import type { CreatableProviderParams } from '../../CreatableProvider/index.ts'
10
+ import { AbstractCreatableProvider } from '../../CreatableProvider/index.ts'
11
+ import { hydratedTransactionToPayloadBundle } from '../../model/index.ts'
12
+ import { type XyoRunner, XyoRunnerMoniker } from '../../provider/index.ts'
13
+ import { type MempoolRunner, MempoolRunnerMoniker } from '../../runners/index.ts'
9
14
 
10
- export class SimpleXyoRunner implements XyoRunner {
11
- private _mempoolArchivist?: ArchivistInstance
15
+ export interface SimpleXyoRunnerParams extends CreatableProviderParams {
16
+ pendingTransactionsArchivist: ArchivistInstance
17
+ }
18
+
19
+ export class SimpleXyoRunner extends AbstractCreatableProvider<SimpleXyoRunnerParams> implements XyoRunner {
20
+ static readonly defaultMoniker = XyoRunnerMoniker
21
+ static readonly monikers = [XyoRunnerMoniker]
22
+ moniker = SimpleXyoRunner.defaultMoniker
12
23
 
13
- constructor(mempoolArchivist?: ArchivistInstance) {
14
- this._mempoolArchivist = mempoolArchivist
24
+ private _mempoolRunner?: MempoolRunner
25
+
26
+ get mempool() {
27
+ return this._mempoolRunner!
28
+ }
29
+
30
+ static override async paramsHandler(params?: SimpleXyoRunnerParams) {
31
+ return {
32
+ ...await super.paramsHandler(params),
33
+ pendingTransactionsArchivist: assertEx(
34
+ params?.pendingTransactionsArchivist,
35
+ () => 'A pendingTransactionsArchivist is required to create a SimpleXyoRunner',
36
+ ),
37
+ }
15
38
  }
16
39
 
17
40
  async broadcastTransaction(transaction: SignedHydratedTransactionWithStorageMeta): Promise<Hash> {
18
- const archivist = await this.getMempoolArchivist()
19
- await archivist.insert(flattenHydratedTransaction(transaction))
20
- return await PayloadBuilder.hash(transaction[0])
41
+ const archivist = this.params.pendingTransactionsArchivist
42
+ const bundle = hydratedTransactionToPayloadBundle(transaction)
43
+ await archivist.insert([bundle])
44
+ await this.mempool.submitTransactions([transaction])
45
+ const hash = await PayloadBuilder.hash(transaction[0])
46
+ this.logger?.info(`Broadcasted transaction with hash ${hash}`)
47
+ return hash
21
48
  }
22
49
 
23
- protected async getMempoolArchivist(): Promise<ArchivistInstance> {
24
- if (!this._mempoolArchivist) {
25
- this._mempoolArchivist = await MemoryArchivist.create({ account: 'random' })
26
- }
27
- return this._mempoolArchivist
50
+ override async createHandler() {
51
+ await super.createHandler()
52
+ this._mempoolRunner = await this.locator.getInstance<MempoolRunner>(MempoolRunnerMoniker)
28
53
  }
29
54
  }
@@ -9,15 +9,15 @@ import {
9
9
  StakeEventsViewerMoniker,
10
10
  } from '../../viewers/index.ts'
11
11
 
12
- export interface SimpleChainStakeEventsParams extends CreatableProviderParams {
12
+ export interface SimpleStakeEventsParams extends CreatableProviderParams {
13
13
  positions: Position[]
14
14
  }
15
15
 
16
16
  @creatableProvider()
17
- export class SimpleChainStakeEventsViewer extends AbstractCreatableProvider<SimpleChainStakeEventsParams> implements StakeEventsViewer {
17
+ export class SimpleStakeEventsViewer extends AbstractCreatableProvider<SimpleStakeEventsParams> implements StakeEventsViewer {
18
18
  static readonly defaultMoniker = StakeEventsViewerMoniker
19
19
  static readonly monikers = [StakeEventsViewerMoniker]
20
- moniker = SimpleChainStakeEventsViewer.defaultMoniker
20
+ moniker = SimpleStakeEventsViewer.defaultMoniker
21
21
 
22
22
  protected get positions() {
23
23
  return this.params.positions
@@ -84,9 +84,9 @@ export class SimpleChainStakeEventsViewer extends AbstractCreatableProvider<Simp
84
84
  private positionsFromRange(range: [number, number | 'latest']): Position[] {
85
85
  const startBlock = range[0]
86
86
  const endBlock = range[1] === 'latest' ? Number.MAX_SAFE_INTEGER : range[1]
87
- const filteredPositions = this.positions.filter((position) => {
87
+ const filteredPositions = this.positions?.filter((position) => {
88
88
  return position.addBlock <= endBlock && (position.removeBlock === 0 || position.removeBlock >= startBlock)
89
- })
89
+ }) ?? []
90
90
  return filteredPositions
91
91
  }
92
92
  }
@@ -0,0 +1 @@
1
+ export * from './SimpleStakeEventsViewer.ts'
@@ -11,11 +11,10 @@ import type { Provider } from 'ethers'
11
11
  import type { CreatableProviderParams } from '../../CreatableProvider/index.ts'
12
12
  import { AbstractCreatableProvider } from '../../CreatableProvider/index.ts'
13
13
  import {
14
- type BlockViewer, type TimeSyncViewer, TimeSyncViewerMoniker,
14
+ type BlockViewer, BlockViewerMoniker, type TimeSyncViewer, TimeSyncViewerMoniker,
15
15
  } from '../../viewers/index.ts'
16
16
 
17
17
  export interface SimpleTimeSyncViewerParams extends CreatableProviderParams {
18
- blockViewer: BlockViewer
19
18
  ethProvider?: Provider
20
19
  }
21
20
 
@@ -24,8 +23,10 @@ export class SimpleTimeSyncViewer extends AbstractCreatableProvider<SimpleTimeSy
24
23
  static readonly monikers = [TimeSyncViewerMoniker]
25
24
  moniker = SimpleTimeSyncViewer.defaultMoniker
26
25
 
26
+ private _blockViewer?: BlockViewer
27
+
27
28
  protected get blockViewer() {
28
- return this.params.blockViewer
29
+ return this._blockViewer!
29
30
  }
30
31
 
31
32
  protected get ethProvider() {
@@ -61,6 +62,11 @@ export class SimpleTimeSyncViewer extends AbstractCreatableProvider<SimpleTimeSy
61
62
  }
62
63
  }
63
64
 
65
+ override async createHandler() {
66
+ await super.createHandler()
67
+ this._blockViewer = await this.locator.getInstance<BlockViewer>(BlockViewerMoniker)
68
+ }
69
+
64
70
  async currentTime(domain: TimeDomain): Promise<[string, number]> {
65
71
  switch (domain) {
66
72
  case 'xl1': {
@@ -100,7 +106,22 @@ export class SimpleTimeSyncViewer extends AbstractCreatableProvider<SimpleTimeSy
100
106
  }
101
107
  }
102
108
 
103
- currentTimePayload(): Promisable<TimePayload> {
104
- throw new Error('Method [currentTimePayload] not implemented.')
109
+ async currentTimePayload(): Promise<TimePayload> {
110
+ const [xl1, xl1Hash] = await this.currentTimeAndHash('xl1')
111
+ const timePayload: TimePayload = {
112
+ schema: TimeSchema,
113
+ // this is for the previous block
114
+ xl1,
115
+ // this is for the previous block
116
+ xl1Hash: assertEx(xl1Hash, () => 'No xl1 hash available from time sync service'),
117
+ epoch: Date.now(),
118
+ }
119
+ if (isDefined(this.ethProvider)) {
120
+ const [ethereum, ethHashOrNull] = await this.currentTimeAndHash('ethereum')
121
+ const ethereumHash = asHash(ethHashOrNull, () => 'No ethereum hash available from time sync service')
122
+ timePayload.ethereum = ethereum
123
+ timePayload.ethereumHash = ethereumHash
124
+ }
125
+ return timePayload
105
126
  }
106
127
  }
@@ -0,0 +1,117 @@
1
+ import type { CreatableName, CreatableStatus } from '@xylabs/sdk-js'
2
+
3
+ import { LoggerStatusReporter } from './ServiceStatus.ts'
4
+
5
+ /**
6
+ * Enum-like record for statuses with priority allowing
7
+ * for determination of the aggregated status.
8
+ */
9
+ const statusPriority: Record<CreatableStatus, number> = {
10
+ error: 0,
11
+ stopped: 1,
12
+ stopping: 2,
13
+ creating: 3,
14
+ created: 4,
15
+ starting: 5,
16
+ started: 6,
17
+ }
18
+
19
+ /**
20
+ * A sentinel status that represents the initial state
21
+ * before any statuses are reported.
22
+ * It is used to ensure that the monitor has a valid status
23
+ * even when no statuses have been reported yet and to
24
+ * prevent the system from showing an "error" state
25
+ * when no statuses are available.
26
+ */
27
+ const SENTINEL_STATUS: CreatableStatus = 'starting'
28
+
29
+ /**
30
+ * Given an array of statuses, this function reduces them
31
+ * to the minimum status based on the defined priority.
32
+ * @param statuses An array of statuses to reduce.
33
+ * @returns The minimum status based on priority.
34
+ */
35
+ const reduceToMinimumStatus = (statuses: CreatableStatus[]): CreatableStatus => {
36
+ let minStatus: CreatableStatus = SENTINEL_STATUS
37
+ let minPriority = Infinity
38
+
39
+ for (const status of statuses) {
40
+ const priority = statusPriority[status]
41
+ if (priority < minPriority) {
42
+ minPriority = priority
43
+ minStatus = status
44
+ }
45
+ }
46
+ return minStatus
47
+ }
48
+
49
+ export type GlobalTransitionHandler = {
50
+ from?: CreatableStatus
51
+ handler: (from: CreatableStatus, to: CreatableStatus) => void
52
+ to?: CreatableStatus
53
+ }
54
+ export type TransitionHandler = GlobalTransitionHandler & {
55
+ name?: string
56
+ }
57
+
58
+ export class RuntimeStatusMonitor extends LoggerStatusReporter {
59
+ private globalTransitions: GlobalTransitionHandler[] = []
60
+ private transitions: TransitionHandler[] = []
61
+
62
+ getGlobalStatus(): CreatableStatus {
63
+ // If no statuses have been reported, return the sentinel status
64
+ if (Object.keys(this.statusMap).length === 0) return SENTINEL_STATUS
65
+ return reduceToMinimumStatus(Object.values(this.statusMap))
66
+ }
67
+
68
+ getStatus(name: CreatableName): CreatableStatus | undefined {
69
+ return this.statusMap[name]
70
+ }
71
+
72
+ onGlobalTransition(match: { from?: CreatableStatus; to?: CreatableStatus }, handler: (from: CreatableStatus, to: CreatableStatus) => void) {
73
+ this.globalTransitions.push({ ...match, handler })
74
+ }
75
+
76
+ /**
77
+ * Register a callback to be called on a specific transition.
78
+ */
79
+ onTransition(match: { from?: CreatableStatus; name: string; to?: CreatableStatus }, handler: (from: CreatableStatus, to: CreatableStatus) => void) {
80
+ this.transitions.push({ ...match, handler })
81
+ }
82
+
83
+ override report(name: CreatableName, status: CreatableStatus, progress?: number | Error): void {
84
+ // Capture the current status before updating
85
+ const previous = this.statusMap[name]
86
+ const previousGlobal = this.getGlobalStatus()
87
+
88
+ // Update the status map with the new status
89
+ super.report(name, status, progress)
90
+
91
+ // If the status hasn't changed, do not run handlers
92
+ if (previous === status) return
93
+ this.runTransitions(this.transitions, previous, status, name)
94
+
95
+ // If the global status hasn't changed, do not run handlers
96
+ const globalStatus = this.getGlobalStatus()
97
+ if (previousGlobal === globalStatus) return
98
+ this.runTransitions(this.globalTransitions, previousGlobal, globalStatus)
99
+ }
100
+
101
+ private runTransitions(
102
+ transitions: (TransitionHandler | GlobalTransitionHandler)[],
103
+ prev: CreatableStatus,
104
+ next: CreatableStatus,
105
+ name?: string,
106
+ ) {
107
+ for (const {
108
+ from, to, name: matchName, handler,
109
+ } of transitions as TransitionHandler[]) {
110
+ if ((matchName === undefined || matchName === name)
111
+ && (from === undefined || from === prev)
112
+ && (to === undefined || to === next)) {
113
+ handler(prev, next)
114
+ }
115
+ }
116
+ }
117
+ }