@xyo-network/xl1-cli 1.6.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 (281) hide show
  1. package/LICENSE +165 -0
  2. package/README.md +23 -0
  3. package/build/commands/api/index.d.ts +2 -0
  4. package/build/commands/api/index.d.ts.map +1 -0
  5. package/build/commands/api/runApi.d.ts +2 -0
  6. package/build/commands/api/runApi.d.ts.map +1 -0
  7. package/build/commands/index.d.ts +4 -0
  8. package/build/commands/index.d.ts.map +1 -0
  9. package/build/commands/producer/createDeclaration.d.ts +2 -0
  10. package/build/commands/producer/createDeclaration.d.ts.map +1 -0
  11. package/build/commands/producer/index.d.ts +3 -0
  12. package/build/commands/producer/index.d.ts.map +1 -0
  13. package/build/commands/producer/runProducer.d.ts +3 -0
  14. package/build/commands/producer/runProducer.d.ts.map +1 -0
  15. package/build/commands/validator/index.d.ts +2 -0
  16. package/build/commands/validator/index.d.ts.map +1 -0
  17. package/build/commands/validator/runValidator.d.ts +3 -0
  18. package/build/commands/validator/runValidator.d.ts.map +1 -0
  19. package/build/index.d.ts +4 -0
  20. package/build/index.d.ts.map +1 -0
  21. package/build/initEnv.d.ts +2 -0
  22. package/build/initEnv.d.ts.map +1 -0
  23. package/build/node/index.mjs +1502 -0
  24. package/build/node/index.mjs.map +1 -0
  25. package/build/node/xl1.mjs +1474 -0
  26. package/build/node/xl1.mjs.map +1 -0
  27. package/build/orchestration/actor/implementation/BalanceActor.d.ts +17 -0
  28. package/build/orchestration/actor/implementation/BalanceActor.d.ts.map +1 -0
  29. package/build/orchestration/actor/implementation/ChainHeadUpdateActor.d.ts +16 -0
  30. package/build/orchestration/actor/implementation/ChainHeadUpdateActor.d.ts.map +1 -0
  31. package/build/orchestration/actor/implementation/ProducerActor.d.ts +25 -0
  32. package/build/orchestration/actor/implementation/ProducerActor.d.ts.map +1 -0
  33. package/build/orchestration/actor/implementation/index.d.ts +4 -0
  34. package/build/orchestration/actor/implementation/index.d.ts.map +1 -0
  35. package/build/orchestration/actor/index.d.ts +3 -0
  36. package/build/orchestration/actor/index.d.ts.map +1 -0
  37. package/build/orchestration/actor/model/Actor.d.ts +38 -0
  38. package/build/orchestration/actor/model/Actor.d.ts.map +1 -0
  39. package/build/orchestration/actor/model/Orchestrator.d.ts +24 -0
  40. package/build/orchestration/actor/model/Orchestrator.d.ts.map +1 -0
  41. package/build/orchestration/actor/model/index.d.ts +3 -0
  42. package/build/orchestration/actor/model/index.d.ts.map +1 -0
  43. package/build/orchestration/archivists/ChainFinalized/archivist.d.ts +4 -0
  44. package/build/orchestration/archivists/ChainFinalized/archivist.d.ts.map +1 -0
  45. package/build/orchestration/archivists/ChainFinalized/index.d.ts +2 -0
  46. package/build/orchestration/archivists/ChainFinalized/index.d.ts.map +1 -0
  47. package/build/orchestration/archivists/ChainFinalized/local.d.ts +4 -0
  48. package/build/orchestration/archivists/ChainFinalized/local.d.ts.map +1 -0
  49. package/build/orchestration/archivists/ChainFinalized/remote.d.ts +4 -0
  50. package/build/orchestration/archivists/ChainFinalized/remote.d.ts.map +1 -0
  51. package/build/orchestration/archivists/ChainSubmissions/archivist.d.ts +4 -0
  52. package/build/orchestration/archivists/ChainSubmissions/archivist.d.ts.map +1 -0
  53. package/build/orchestration/archivists/ChainSubmissions/index.d.ts +2 -0
  54. package/build/orchestration/archivists/ChainSubmissions/index.d.ts.map +1 -0
  55. package/build/orchestration/archivists/ChainSubmissions/remote.d.ts +4 -0
  56. package/build/orchestration/archivists/ChainSubmissions/remote.d.ts.map +1 -0
  57. package/build/orchestration/archivists/PendingTransactions/archivist.d.ts +4 -0
  58. package/build/orchestration/archivists/PendingTransactions/archivist.d.ts.map +1 -0
  59. package/build/orchestration/archivists/PendingTransactions/index.d.ts +2 -0
  60. package/build/orchestration/archivists/PendingTransactions/index.d.ts.map +1 -0
  61. package/build/orchestration/archivists/PendingTransactions/local.d.ts +4 -0
  62. package/build/orchestration/archivists/PendingTransactions/local.d.ts.map +1 -0
  63. package/build/orchestration/archivists/PendingTransactions/remote.d.ts +4 -0
  64. package/build/orchestration/archivists/PendingTransactions/remote.d.ts.map +1 -0
  65. package/build/orchestration/archivists/RejectedTransactions/archivist.d.ts +4 -0
  66. package/build/orchestration/archivists/RejectedTransactions/archivist.d.ts.map +1 -0
  67. package/build/orchestration/archivists/RejectedTransactions/index.d.ts +2 -0
  68. package/build/orchestration/archivists/RejectedTransactions/index.d.ts.map +1 -0
  69. package/build/orchestration/archivists/RejectedTransactions/local.d.ts +4 -0
  70. package/build/orchestration/archivists/RejectedTransactions/local.d.ts.map +1 -0
  71. package/build/orchestration/archivists/StakeIntentState/archivist.d.ts +4 -0
  72. package/build/orchestration/archivists/StakeIntentState/archivist.d.ts.map +1 -0
  73. package/build/orchestration/archivists/StakeIntentState/index.d.ts +2 -0
  74. package/build/orchestration/archivists/StakeIntentState/index.d.ts.map +1 -0
  75. package/build/orchestration/archivists/StakeIntentState/local.d.ts +4 -0
  76. package/build/orchestration/archivists/StakeIntentState/local.d.ts.map +1 -0
  77. package/build/orchestration/archivists/index.d.ts +6 -0
  78. package/build/orchestration/archivists/index.d.ts.map +1 -0
  79. package/build/orchestration/archivists/lib/index.d.ts +2 -0
  80. package/build/orchestration/archivists/lib/index.d.ts.map +1 -0
  81. package/build/orchestration/archivists/lib/localPersistentArchivist.d.ts +12 -0
  82. package/build/orchestration/archivists/lib/localPersistentArchivist.d.ts.map +1 -0
  83. package/build/orchestration/health/index.d.ts +2 -0
  84. package/build/orchestration/health/index.d.ts.map +1 -0
  85. package/build/orchestration/health/initHealthEndpoints.d.ts +7 -0
  86. package/build/orchestration/health/initHealthEndpoints.d.ts.map +1 -0
  87. package/build/orchestration/host/implementation/DefaultHost.d.ts +12 -0
  88. package/build/orchestration/host/implementation/DefaultHost.d.ts.map +1 -0
  89. package/build/orchestration/host/implementation/DefaultServiceCollection.d.ts +24 -0
  90. package/build/orchestration/host/implementation/DefaultServiceCollection.d.ts.map +1 -0
  91. package/build/orchestration/host/implementation/DefaultServiceProvider.d.ts +7 -0
  92. package/build/orchestration/host/implementation/DefaultServiceProvider.d.ts.map +1 -0
  93. package/build/orchestration/host/implementation/index.d.ts +3 -0
  94. package/build/orchestration/host/implementation/index.d.ts.map +1 -0
  95. package/build/orchestration/host/index.d.ts +3 -0
  96. package/build/orchestration/host/index.d.ts.map +1 -0
  97. package/build/orchestration/host/model/Host.d.ts +19 -0
  98. package/build/orchestration/host/model/Host.d.ts.map +1 -0
  99. package/build/orchestration/host/model/ServiceCollection.d.ts +20 -0
  100. package/build/orchestration/host/model/ServiceCollection.d.ts.map +1 -0
  101. package/build/orchestration/host/model/ServiceProvider.d.ts +4 -0
  102. package/build/orchestration/host/model/ServiceProvider.d.ts.map +1 -0
  103. package/build/orchestration/host/model/index.d.ts +4 -0
  104. package/build/orchestration/host/model/index.d.ts.map +1 -0
  105. package/build/orchestration/index.d.ts +6 -0
  106. package/build/orchestration/index.d.ts.map +1 -0
  107. package/build/orchestration/initServices.d.ts +4 -0
  108. package/build/orchestration/initServices.d.ts.map +1 -0
  109. package/build/orchestration/map/BalanceSummary/index.d.ts +2 -0
  110. package/build/orchestration/map/BalanceSummary/index.d.ts.map +1 -0
  111. package/build/orchestration/map/BalanceSummary/initBalanceSummaryMap.d.ts +7 -0
  112. package/build/orchestration/map/BalanceSummary/initBalanceSummaryMap.d.ts.map +1 -0
  113. package/build/orchestration/map/BalanceSummary/local.d.ts +6 -0
  114. package/build/orchestration/map/BalanceSummary/local.d.ts.map +1 -0
  115. package/build/orchestration/map/driver/index.d.ts +2 -0
  116. package/build/orchestration/map/driver/index.d.ts.map +1 -0
  117. package/build/orchestration/map/driver/lmdb/Params.d.ts +7 -0
  118. package/build/orchestration/map/driver/lmdb/Params.d.ts.map +1 -0
  119. package/build/orchestration/map/driver/lmdb/SynchronousLmdbMap.d.ts +32 -0
  120. package/build/orchestration/map/driver/lmdb/SynchronousLmdbMap.d.ts.map +1 -0
  121. package/build/orchestration/map/driver/lmdb/index.d.ts +2 -0
  122. package/build/orchestration/map/driver/lmdb/index.d.ts.map +1 -0
  123. package/build/orchestration/map/index.d.ts +3 -0
  124. package/build/orchestration/map/index.d.ts.map +1 -0
  125. package/build/orchestration/map/localPersistentMap.d.ts +12 -0
  126. package/build/orchestration/map/localPersistentMap.d.ts.map +1 -0
  127. package/build/orchestration/repository/index.d.ts +2 -0
  128. package/build/orchestration/repository/index.d.ts.map +1 -0
  129. package/build/orchestration/repository/lib/index.d.ts +2 -0
  130. package/build/orchestration/repository/lib/index.d.ts.map +1 -0
  131. package/build/orchestration/repository/lib/repositoryFromArchivist.d.ts +6 -0
  132. package/build/orchestration/repository/lib/repositoryFromArchivist.d.ts.map +1 -0
  133. package/build/orchestration/services/implementation/account.d.ts +4 -0
  134. package/build/orchestration/services/implementation/account.d.ts.map +1 -0
  135. package/build/orchestration/services/implementation/balance.d.ts +4 -0
  136. package/build/orchestration/services/implementation/balance.d.ts.map +1 -0
  137. package/build/orchestration/services/implementation/chain/evm.d.ts +6 -0
  138. package/build/orchestration/services/implementation/chain/evm.d.ts.map +1 -0
  139. package/build/orchestration/services/implementation/chain/index.d.ts +4 -0
  140. package/build/orchestration/services/implementation/chain/index.d.ts.map +1 -0
  141. package/build/orchestration/services/implementation/evm/index.d.ts +2 -0
  142. package/build/orchestration/services/implementation/evm/index.d.ts.map +1 -0
  143. package/build/orchestration/services/implementation/evm/initChainId.d.ts +3 -0
  144. package/build/orchestration/services/implementation/evm/initChainId.d.ts.map +1 -0
  145. package/build/orchestration/services/implementation/evm/initEvmProvider.d.ts +4 -0
  146. package/build/orchestration/services/implementation/evm/initEvmProvider.d.ts.map +1 -0
  147. package/build/orchestration/services/implementation/evm/initGanacheProvider.d.ts +5 -0
  148. package/build/orchestration/services/implementation/evm/initGanacheProvider.d.ts.map +1 -0
  149. package/build/orchestration/services/implementation/evm/initInfuraProvider.d.ts +5 -0
  150. package/build/orchestration/services/implementation/evm/initInfuraProvider.d.ts.map +1 -0
  151. package/build/orchestration/services/implementation/head.d.ts +10 -0
  152. package/build/orchestration/services/implementation/head.d.ts.map +1 -0
  153. package/build/orchestration/services/implementation/index.d.ts +11 -0
  154. package/build/orchestration/services/implementation/index.d.ts.map +1 -0
  155. package/build/orchestration/services/implementation/iterator.d.ts +6 -0
  156. package/build/orchestration/services/implementation/iterator.d.ts.map +1 -0
  157. package/build/orchestration/services/implementation/pendingTransactions.d.ts +4 -0
  158. package/build/orchestration/services/implementation/pendingTransactions.d.ts.map +1 -0
  159. package/build/orchestration/services/implementation/producer.d.ts +4 -0
  160. package/build/orchestration/services/implementation/producer.d.ts.map +1 -0
  161. package/build/orchestration/services/implementation/reward.d.ts +4 -0
  162. package/build/orchestration/services/implementation/reward.d.ts.map +1 -0
  163. package/build/orchestration/services/implementation/validator.d.ts +4 -0
  164. package/build/orchestration/services/implementation/validator.d.ts.map +1 -0
  165. package/build/orchestration/services/index.d.ts +2 -0
  166. package/build/orchestration/services/index.d.ts.map +1 -0
  167. package/build/orchestration/status/RuntimeStatusMonitor.d.ts +31 -0
  168. package/build/orchestration/status/RuntimeStatusMonitor.d.ts.map +1 -0
  169. package/build/orchestration/status/ServiceStatus.d.ts +9 -0
  170. package/build/orchestration/status/ServiceStatus.d.ts.map +1 -0
  171. package/build/orchestration/status/index.d.ts +3 -0
  172. package/build/orchestration/status/index.d.ts.map +1 -0
  173. package/build/orchestration/store/StoreKind.d.ts +2 -0
  174. package/build/orchestration/store/StoreKind.d.ts.map +1 -0
  175. package/build/orchestration/store/getStoreDirectory.d.ts +9 -0
  176. package/build/orchestration/store/getStoreDirectory.d.ts.map +1 -0
  177. package/build/orchestration/store/index.d.ts +3 -0
  178. package/build/orchestration/store/index.d.ts.map +1 -0
  179. package/build/runCLI.d.ts +3 -0
  180. package/build/runCLI.d.ts.map +1 -0
  181. package/build/start.d.ts +2 -0
  182. package/build/start.d.ts.map +1 -0
  183. package/build/xl1.d.ts +2 -0
  184. package/build/xl1.d.ts.map +1 -0
  185. package/dist/cli-min.mjs +400 -0
  186. package/nodemon.json +9 -0
  187. package/package.json +97 -0
  188. package/rollup.config.mjs +73 -0
  189. package/scripts/xl1.mjs +3 -0
  190. package/src/commands/api/index.ts +1 -0
  191. package/src/commands/api/runApi.ts +7 -0
  192. package/src/commands/index.ts +3 -0
  193. package/src/commands/producer/createDeclaration.ts +17 -0
  194. package/src/commands/producer/index.ts +2 -0
  195. package/src/commands/producer/runProducer.ts +25 -0
  196. package/src/commands/validator/index.ts +1 -0
  197. package/src/commands/validator/runValidator.ts +13 -0
  198. package/src/index.ts +3 -0
  199. package/src/initEnv.ts +8 -0
  200. package/src/orchestration/actor/implementation/BalanceActor.ts +51 -0
  201. package/src/orchestration/actor/implementation/ChainHeadUpdateActor.ts +65 -0
  202. package/src/orchestration/actor/implementation/ProducerActor.ts +250 -0
  203. package/src/orchestration/actor/implementation/index.ts +3 -0
  204. package/src/orchestration/actor/index.ts +2 -0
  205. package/src/orchestration/actor/model/Actor.ts +113 -0
  206. package/src/orchestration/actor/model/Orchestrator.ts +65 -0
  207. package/src/orchestration/actor/model/index.ts +2 -0
  208. package/src/orchestration/archivists/ChainFinalized/archivist.ts +27 -0
  209. package/src/orchestration/archivists/ChainFinalized/index.ts +1 -0
  210. package/src/orchestration/archivists/ChainFinalized/local.ts +16 -0
  211. package/src/orchestration/archivists/ChainFinalized/remote.ts +18 -0
  212. package/src/orchestration/archivists/ChainSubmissions/archivist.ts +19 -0
  213. package/src/orchestration/archivists/ChainSubmissions/index.ts +1 -0
  214. package/src/orchestration/archivists/ChainSubmissions/remote.ts +18 -0
  215. package/src/orchestration/archivists/PendingTransactions/archivist.ts +29 -0
  216. package/src/orchestration/archivists/PendingTransactions/index.ts +1 -0
  217. package/src/orchestration/archivists/PendingTransactions/local.ts +20 -0
  218. package/src/orchestration/archivists/PendingTransactions/remote.ts +18 -0
  219. package/src/orchestration/archivists/RejectedTransactions/archivist.ts +18 -0
  220. package/src/orchestration/archivists/RejectedTransactions/index.ts +1 -0
  221. package/src/orchestration/archivists/RejectedTransactions/local.ts +20 -0
  222. package/src/orchestration/archivists/StakeIntentState/archivist.ts +19 -0
  223. package/src/orchestration/archivists/StakeIntentState/index.ts +1 -0
  224. package/src/orchestration/archivists/StakeIntentState/local.ts +19 -0
  225. package/src/orchestration/archivists/index.ts +5 -0
  226. package/src/orchestration/archivists/lib/index.ts +1 -0
  227. package/src/orchestration/archivists/lib/localPersistentArchivist.ts +44 -0
  228. package/src/orchestration/health/index.ts +1 -0
  229. package/src/orchestration/health/initHealthEndpoints.ts +70 -0
  230. package/src/orchestration/host/implementation/DefaultHost.ts +25 -0
  231. package/src/orchestration/host/implementation/DefaultServiceCollection.ts +60 -0
  232. package/src/orchestration/host/implementation/DefaultServiceProvider.ts +12 -0
  233. package/src/orchestration/host/implementation/index.ts +2 -0
  234. package/src/orchestration/host/index.ts +2 -0
  235. package/src/orchestration/host/model/Host.ts +21 -0
  236. package/src/orchestration/host/model/ServiceCollection.ts +22 -0
  237. package/src/orchestration/host/model/ServiceProvider.ts +3 -0
  238. package/src/orchestration/host/model/index.ts +3 -0
  239. package/src/orchestration/index.ts +5 -0
  240. package/src/orchestration/initServices.ts +237 -0
  241. package/src/orchestration/map/BalanceSummary/index.ts +1 -0
  242. package/src/orchestration/map/BalanceSummary/initBalanceSummaryMap.ts +22 -0
  243. package/src/orchestration/map/BalanceSummary/local.ts +19 -0
  244. package/src/orchestration/map/driver/index.ts +1 -0
  245. package/src/orchestration/map/driver/lmdb/Params.ts +7 -0
  246. package/src/orchestration/map/driver/lmdb/SynchronousLmdbMap.ts +67 -0
  247. package/src/orchestration/map/driver/lmdb/index.ts +1 -0
  248. package/src/orchestration/map/index.ts +2 -0
  249. package/src/orchestration/map/localPersistentMap.ts +39 -0
  250. package/src/orchestration/repository/index.ts +1 -0
  251. package/src/orchestration/repository/lib/index.ts +1 -0
  252. package/src/orchestration/repository/lib/repositoryFromArchivist.ts +27 -0
  253. package/src/orchestration/services/implementation/account.ts +23 -0
  254. package/src/orchestration/services/implementation/balance.ts +13 -0
  255. package/src/orchestration/services/implementation/chain/evm.ts +35 -0
  256. package/src/orchestration/services/implementation/chain/index.ts +27 -0
  257. package/src/orchestration/services/implementation/evm/index.ts +1 -0
  258. package/src/orchestration/services/implementation/evm/initChainId.ts +18 -0
  259. package/src/orchestration/services/implementation/evm/initEvmProvider.ts +21 -0
  260. package/src/orchestration/services/implementation/evm/initGanacheProvider.ts +19 -0
  261. package/src/orchestration/services/implementation/evm/initInfuraProvider.ts +25 -0
  262. package/src/orchestration/services/implementation/head.ts +44 -0
  263. package/src/orchestration/services/implementation/index.ts +10 -0
  264. package/src/orchestration/services/implementation/iterator.ts +36 -0
  265. package/src/orchestration/services/implementation/pendingTransactions.ts +14 -0
  266. package/src/orchestration/services/implementation/producer.ts +13 -0
  267. package/src/orchestration/services/implementation/reward.ts +37 -0
  268. package/src/orchestration/services/implementation/validator.ts +14 -0
  269. package/src/orchestration/services/index.ts +1 -0
  270. package/src/orchestration/status/RuntimeStatusMonitor.ts +117 -0
  271. package/src/orchestration/status/ServiceStatus.ts +21 -0
  272. package/src/orchestration/status/index.ts +2 -0
  273. package/src/orchestration/store/StoreKind.ts +1 -0
  274. package/src/orchestration/store/getStoreDirectory.ts +15 -0
  275. package/src/orchestration/store/index.ts +2 -0
  276. package/src/runCLI.ts +96 -0
  277. package/src/spec/MultiProducer.ChainOutput.json +864 -0
  278. package/src/start.ts +26 -0
  279. package/src/xl1.ts +6 -0
  280. package/vitest.config.ts +11 -0
  281. package/xy.config.ts +11 -0
@@ -0,0 +1,113 @@
1
+ import type { TracerProvider } from '@opentelemetry/api'
2
+ import type { BaseParams } from '@xylabs/base'
3
+ import { BaseEmitter } from '@xylabs/events'
4
+ import { forget } from '@xylabs/forget'
5
+ import { IdLogger } from '@xylabs/logger'
6
+ import type { Promisable } from '@xylabs/promise'
7
+ import { span, spanAsync } from '@xylabs/telemetry'
8
+
9
+ export interface IActor {
10
+ start(): Promise<void>
11
+ stop(): Promise<void>
12
+ }
13
+
14
+ export type ActorParams = BaseParams<{
15
+ traceProvider?: TracerProvider
16
+ }>
17
+
18
+ export class Actor<TParams extends ActorParams = ActorParams> extends BaseEmitter<TParams> implements IActor {
19
+ protected readonly _timers: Map<string, ReturnType<typeof setTimeout>> = new Map()
20
+ private _active = false
21
+ private readonly _displayName: string
22
+ private readonly _id: string
23
+
24
+ constructor(id: string, displayName: string = 'Actor', params: TParams) {
25
+ const logger = params.logger ?? new IdLogger(console, () => `[${displayName} (${id})] `)
26
+ super({ ...params, logger })
27
+ this._displayName = displayName
28
+ this._id = id
29
+ }
30
+
31
+ get displayName() {
32
+ return this._displayName
33
+ }
34
+
35
+ get id() {
36
+ return this._id
37
+ }
38
+
39
+ get name() {
40
+ return this.constructor.name
41
+ }
42
+
43
+ protected get logPrefix() {
44
+ return `[${this.displayName} (${this.id})] `
45
+ }
46
+
47
+ /**
48
+ * The timer runs until the actor is deactivated (or you manually stop it).
49
+ */
50
+ registerTimer(timerName: string, callback: () => Promisable<void>, dueTimeMs: number, periodMs: number) {
51
+ if (!this._active) {
52
+ this.logger?.warn(
53
+ `Cannot register timer '${timerName}' because actor is not active.`,
54
+ )
55
+ return
56
+ }
57
+
58
+ // Function to handle recursive scheduling
59
+ const schedulePeriodicRun = async () => {
60
+ // Stop if actor is deactivated or timer is removed
61
+ if (!this._active || !this._timers.has(timerName)) return
62
+ try {
63
+ // Run the callback
64
+ await callback()
65
+ } catch (error) {
66
+ // Catch and log any errors
67
+ this.logger?.error(`Error in timer '${this.name}:${timerName}': ${error}`)
68
+ } finally {
69
+ // Always schedule subsequent executions based on the desired period
70
+ this._timers.set(timerName, setTimeout(() => forget(schedulePeriodicRun(), { name: `schedulePeriodicRun:${this.name}:${timerName}` }), periodMs))
71
+ }
72
+ }
73
+
74
+ // Schedule the 1st execution after the desired initial delay
75
+ this._timers.set(timerName, setTimeout(() => forget(schedulePeriodicRun(), { name: `schedulePeriodicRun(initial):${this.name}:${timerName}` }), dueTimeMs))
76
+
77
+ this.logger?.log(
78
+ `Timer '${this.name}:${timerName}' registered: first call after ${dueTimeMs}ms, recurring every ${periodMs}ms.`,
79
+ )
80
+ }
81
+
82
+ span<T>(name: string, fn: () => T): T {
83
+ return span(`${this.name}:${name}`, fn, this.tracer)
84
+ }
85
+
86
+ async spanAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {
87
+ return await spanAsync(`${this.name}:${name}`, fn, this.tracer)
88
+ }
89
+
90
+ /**
91
+ * Called by the Orchestrator when the actor is activated.
92
+ */
93
+ async start() {
94
+ await Promise.resolve()
95
+ this._active = true
96
+ this.logger?.log('Started.')
97
+ }
98
+
99
+ /**
100
+ * Called by the Orchestrator when the actor is deactivated.
101
+ * Stop all running timers.
102
+ */
103
+ async stop() {
104
+ await Promise.resolve()
105
+ this._active = false
106
+ this.logger?.log('Stopping all timers...')
107
+ for (const [, timerRef] of this._timers.entries()) {
108
+ clearTimeout(timerRef)
109
+ }
110
+ this._timers.clear()
111
+ this.logger?.log('Stopped.')
112
+ }
113
+ }
@@ -0,0 +1,65 @@
1
+ export interface IOrchestrator {
2
+ start(): Promise<void>
3
+ stop(): Promise<void>
4
+ }
5
+
6
+ import type { IActor } from './Actor.ts'
7
+
8
+ // TODO: Inject logger
9
+ export class Orchestrator implements IOrchestrator {
10
+ private actors: IActor[] = []
11
+ private keepAliveHandle: NodeJS.Timeout | null = null
12
+ private running = false
13
+
14
+ /**
15
+ * Registers an actor.
16
+ * (We won't activate the actor until `start()` is called.)
17
+ */
18
+ async registerActor(actor: IActor) {
19
+ if (this.running) {
20
+ // If the orchestrator is already running, activate the actor immediately
21
+ await actor.start()
22
+ }
23
+ this.actors.push(actor)
24
+ }
25
+
26
+ /**
27
+ * Starts the orchestrator: activates all actors.
28
+ */
29
+ async start() {
30
+ await Promise.resolve()
31
+ if (this.running) {
32
+ console.log('[Orchestrator] Already started.')
33
+ return
34
+ }
35
+
36
+ console.log('[Orchestrator] Starting...')
37
+ this.running = true
38
+ for (const actor of this.actors) {
39
+ await actor.start()
40
+ }
41
+ // This interval will fire every 24.8 days (2^31 - 1 ms), effectively never finishing
42
+ this.keepAliveHandle = setInterval(() => {
43
+ // No-op
44
+ }, 2_147_483_647)
45
+ }
46
+
47
+ /**
48
+ * Stops the orchestrator: deactivates all actors.
49
+ */
50
+ async stop() {
51
+ await Promise.resolve()
52
+ if (!this.running) {
53
+ console.log('[Orchestrator] Already stopped.')
54
+ return
55
+ }
56
+
57
+ console.log('[Orchestrator] Stopping...')
58
+ for (const actor of this.actors) {
59
+ await actor.stop()
60
+ }
61
+ this.running = false
62
+ if (this.keepAliveHandle) clearInterval(this.keepAliveHandle)
63
+ console.log('[Orchestrator] Stopped...')
64
+ }
65
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Actor.ts'
2
+ export * from './Orchestrator.ts'
@@ -0,0 +1,27 @@
1
+ import type { TracerProvider } from '@opentelemetry/api'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { initArchivistSync } from '@xyo-network/chain-orchestration'
4
+ import { startupSpanAsync } from '@xyo-network/chain-utils'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ import { initLocalChainFinalizedArchivist } from './local.ts'
8
+ import { initRemoteChainFinalizedArchivist } from './remote.ts'
9
+
10
+ const mutex = new Mutex()
11
+ let singleton: ArchivistInstance | undefined
12
+
13
+ export async function initChainFinalizedArchivist(traceProvider: TracerProvider) {
14
+ return await mutex.runExclusive(async () => {
15
+ if (singleton) return singleton
16
+ const [remote, local] = await Promise.all([
17
+ startupSpanAsync('ChainFinalizedArchivist:initRemote', () => initRemoteChainFinalizedArchivist()),
18
+ startupSpanAsync('ChainFinalizedArchivist:initLocal', () => initLocalChainFinalizedArchivist()),
19
+ ])
20
+ await startupSpanAsync(
21
+ 'ChainFinalizedArchivist:initArchivistSync',
22
+ () => initArchivistSync('ChainFinalizedArchivist', remote, local, 200, Number.MAX_SAFE_INTEGER, traceProvider),
23
+ )
24
+ singleton = local
25
+ return singleton
26
+ })
27
+ }
@@ -0,0 +1 @@
1
+ export * from './archivist.ts'
@@ -0,0 +1,16 @@
1
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
2
+ import type { Initializable } from '@xyo-network/xl1-protocol'
3
+ import { Mutex } from 'async-mutex'
4
+
5
+ import { getLocalPersistentArchivist } from '../lib/index.ts'
6
+
7
+ const mutex = new Mutex()
8
+ let singleton: ArchivistInstance | undefined
9
+
10
+ export const initLocalChainFinalizedArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
11
+ return await mutex.runExclusive(async () => {
12
+ if (singleton) return singleton
13
+ singleton = await getLocalPersistentArchivist('chain', 'finalized')
14
+ return singleton
15
+ })
16
+ }
@@ -0,0 +1,18 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { initBridge, initBridgedArchivistModule } from '@xyo-network/chain-orchestration'
4
+ import type { Initializable } from '@xyo-network/xl1-protocol'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ const nodeUrl = process.env.XYO_CHAIN_ARCHIVIST_NODE_URL ?? 'http://localhost:8080'
8
+ const mutex = new Mutex()
9
+ let singleton: ArchivistInstance | undefined
10
+
11
+ export const initRemoteChainFinalizedArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
12
+ return await mutex.runExclusive(async () => {
13
+ if (singleton) return singleton
14
+ const bridge = await initBridge(nodeUrl)
15
+ singleton = await initBridgedArchivistModule({ bridge, moduleName: 'XYOChain:Chain:Finalized' })
16
+ return assertEx(singleton, () => 'Error: RemoteChainFinalizedArchivist failed to initialize')
17
+ })
18
+ }
@@ -0,0 +1,19 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { startupSpanAsync } from '@xyo-network/chain-utils'
4
+ import type { Initializable } from '@xyo-network/xl1-protocol'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ import { initRemoteChainSubmissionsArchivist } from './remote.ts'
8
+
9
+ const mutex = new Mutex()
10
+ let singleton: ArchivistInstance | undefined
11
+
12
+ export const initChainSubmissionsArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
13
+ return await mutex.runExclusive(async () => {
14
+ if (singleton) return singleton
15
+ const remote = await startupSpanAsync('ChainSubmissionsArchivist:initRemote', () => initRemoteChainSubmissionsArchivist())
16
+ singleton = remote
17
+ return assertEx(singleton, () => new Error('Failed to initialize ChainSubmissionsArchivist'))
18
+ })
19
+ }
@@ -0,0 +1 @@
1
+ export * from './archivist.ts'
@@ -0,0 +1,18 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { initBridge, initBridgedArchivistModule } from '@xyo-network/chain-orchestration'
4
+ import type { Initializable } from '@xyo-network/xl1-protocol'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ const nodeUrl = process.env.XYO_CHAIN_ARCHIVIST_NODE_URL ?? 'http://localhost:8080'
8
+ const mutex = new Mutex()
9
+ let singleton: ArchivistInstance | undefined
10
+
11
+ export const initRemoteChainSubmissionsArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
12
+ return await mutex.runExclusive(async () => {
13
+ if (singleton) return singleton
14
+ const bridge = await initBridge(nodeUrl)
15
+ singleton = await initBridgedArchivistModule({ bridge, moduleName: 'XYOChain:Chain:Submissions' })
16
+ return assertEx(singleton, () => new Error('Failed to initialize RemoteChainSubmissionsArchivist'))
17
+ })
18
+ }
@@ -0,0 +1,29 @@
1
+ import type { TracerProvider } from '@opentelemetry/api'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { initArchivistSync } from '@xyo-network/chain-orchestration'
4
+ import { startupSpanAsync } from '@xyo-network/chain-utils'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ import { initLocalPendingTransactionsArchivist } from './local.ts'
8
+ import { initRemotePendingTransactionsArchivist } from './remote.ts'
9
+
10
+ const mutex = new Mutex()
11
+ let singleton: [local: ArchivistInstance, remote: ArchivistInstance] | undefined
12
+
13
+ export async function initPendingBundledTransactionsArchivist(_: TracerProvider): Promise<[local: ArchivistInstance, remote: ArchivistInstance]> {
14
+ return await mutex.runExclusive(async () => {
15
+ if (singleton) return singleton
16
+ const remote = await startupSpanAsync('PendingBundledTransactionsArchivist:initRemote', () => initRemotePendingTransactionsArchivist())
17
+ const local = await startupSpanAsync('PendingBundledTransactionsArchivist:initLocal', () => initLocalPendingTransactionsArchivist())
18
+ // Grab the most recent payload from the remote archivist
19
+ const start = await remote.next({ limit: 1, order: 'desc' })
20
+ // Write it locally so we have a starting point for syncing
21
+ await local.insert(start)
22
+ await startupSpanAsync(
23
+ 'PendingBundledTransactionsArchivist:initArchivistSync',
24
+ () => initArchivistSync('PendingBundledTransactionsArchivist', remote, local),
25
+ )
26
+ singleton = [local, remote]
27
+ return singleton
28
+ })
29
+ }
@@ -0,0 +1 @@
1
+ export * from './archivist.ts'
@@ -0,0 +1,20 @@
1
+ import { MemoryArchivist, MemoryArchivistConfigSchema } from '@xyo-network/archivist-memory'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import type { Initializable } from '@xyo-network/xl1-protocol'
4
+ import { Mutex } from 'async-mutex'
5
+
6
+ const mutex = new Mutex()
7
+ let singleton: ArchivistInstance | undefined
8
+
9
+ export const initLocalPendingTransactionsArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
10
+ return await mutex.runExclusive(async () => {
11
+ if (singleton) return singleton
12
+ singleton = await MemoryArchivist.create({
13
+ account: 'random',
14
+ config: {
15
+ schema: MemoryArchivistConfigSchema, max: 1000, name: 'localPendingTransactions',
16
+ },
17
+ })
18
+ return singleton
19
+ })
20
+ }
@@ -0,0 +1,18 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { initBridge, initBridgedArchivistModule } from '@xyo-network/chain-orchestration'
4
+ import type { Initializable } from '@xyo-network/xl1-protocol'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ const bridgeUrl = process.env.XYO_PENDING_ARCHIVIST_NODE_URL ?? 'http://localhost:8080'
8
+ const mutex = new Mutex()
9
+ let singleton: ArchivistInstance | undefined
10
+
11
+ export const initRemotePendingTransactionsArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
12
+ return await mutex.runExclusive(async () => {
13
+ if (singleton) return singleton
14
+ const bridge = await initBridge(bridgeUrl)
15
+ singleton = await initBridgedArchivistModule({ bridge, moduleName: 'XYOChain:Pending:PendingTransactions' })
16
+ return assertEx(singleton, () => 'Error: RemotePendingBundledTransactionsArchivist is undefined')
17
+ })
18
+ }
@@ -0,0 +1,18 @@
1
+ import type { TracerProvider } from '@opentelemetry/api'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { startupSpanAsync } from '@xyo-network/chain-utils'
4
+ import { Mutex } from 'async-mutex'
5
+
6
+ import { initLocalRejectedTransactionsArchivist } from './local.ts'
7
+
8
+ const mutex = new Mutex()
9
+ let singleton: ArchivistInstance | undefined
10
+
11
+ export async function initRejectedTransactionsArchivist(_traceProvider: TracerProvider) {
12
+ return await mutex.runExclusive(async () => {
13
+ if (singleton) return singleton
14
+ const local = await startupSpanAsync('RejectedTransactionsArchivist:initLocal', () => initLocalRejectedTransactionsArchivist())
15
+ singleton = local
16
+ return singleton
17
+ })
18
+ }
@@ -0,0 +1 @@
1
+ export * from './archivist.ts'
@@ -0,0 +1,20 @@
1
+ import { MemoryArchivist, MemoryArchivistConfigSchema } from '@xyo-network/archivist-memory'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import type { Initializable } from '@xyo-network/xl1-protocol'
4
+ import { Mutex } from 'async-mutex'
5
+
6
+ const mutex = new Mutex()
7
+ let singleton: ArchivistInstance | undefined
8
+
9
+ export const initLocalRejectedTransactionsArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
10
+ return await mutex.runExclusive(async () => {
11
+ if (singleton) return singleton
12
+ singleton = await MemoryArchivist.create({
13
+ account: 'random',
14
+ config: {
15
+ schema: MemoryArchivistConfigSchema, max: 1000, name: 'localRejectedTransactions',
16
+ },
17
+ })
18
+ return singleton
19
+ })
20
+ }
@@ -0,0 +1,19 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import { startupSpanAsync } from '@xyo-network/chain-utils'
4
+ import type { Initializable } from '@xyo-network/xl1-protocol'
5
+ import { Mutex } from 'async-mutex'
6
+
7
+ import { initLocalStakeIntentStateArchivist } from './local.ts'
8
+
9
+ const mutex = new Mutex()
10
+ let singleton: ArchivistInstance | undefined
11
+
12
+ export const initStakeIntentStateArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
13
+ return await mutex.runExclusive(async () => {
14
+ if (singleton) return singleton
15
+ const local = await startupSpanAsync('StakeIntentStateArchivist:initLocal', () => initLocalStakeIntentStateArchivist())
16
+ singleton = local
17
+ return assertEx(singleton, () => 'Error: StakeIntentStateArchivist is undefined')
18
+ })
19
+ }
@@ -0,0 +1 @@
1
+ export * from './archivist.ts'
@@ -0,0 +1,19 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
3
+ import type { Initializable } from '@xyo-network/xl1-protocol'
4
+ import { Mutex } from 'async-mutex'
5
+
6
+ import { getLocalPersistentArchivist } from '../lib/index.ts'
7
+
8
+ const mutex = new Mutex()
9
+ let singleton: ArchivistInstance | undefined
10
+
11
+ export const initLocalStakeIntentStateArchivist: Initializable<void, ArchivistInstance> = async (): Promise<ArchivistInstance> => {
12
+ return await mutex.runExclusive(async () => {
13
+ if (singleton) return singleton
14
+ console.log('[InitServices:LocalStakeIntentStateArchivist:Initializing]')
15
+ singleton = await getLocalPersistentArchivist('stakeIntent', 'state')
16
+ console.log('[InitServices:LocalStakeIntentStateArchivist:Initialized]')
17
+ return assertEx(singleton, () => new Error('Failed to initialize stake intent state archivist'))
18
+ })
19
+ }
@@ -0,0 +1,5 @@
1
+ export * from './ChainFinalized/index.ts'
2
+ export * from './ChainSubmissions/index.ts'
3
+ export * from './PendingTransactions/index.ts'
4
+ export * from './RejectedTransactions/index.ts'
5
+ export * from './StakeIntentState/index.ts'
@@ -0,0 +1 @@
1
+ export * from './localPersistentArchivist.ts'
@@ -0,0 +1,44 @@
1
+ import { rm } from 'node:fs/promises'
2
+
3
+ import { LmdbArchivist, LmdbArchivistConfigSchema } from '@xyo-network/archivist-lmdb'
4
+ import type { ArchivistInstance } from '@xyo-network/archivist-model'
5
+
6
+ import type { StoreKind } from '../../store/index.ts'
7
+ import { getStoreDirectory } from '../../store/index.ts'
8
+
9
+ /**
10
+ * Returns a local persistent archivist
11
+ * @param dbName The name of the database
12
+ * @param storeName The name of the store
13
+ * @param kind The kind of the archivist
14
+ * @returns an archivist instance
15
+ */
16
+ export const getLocalPersistentArchivist = (dbName: string, storeName: string, kind: StoreKind = 'lmdb'): Promise<ArchivistInstance> => {
17
+ switch (kind) {
18
+ case 'lmdb': {
19
+ return LmdbArchivist.create({
20
+ account: 'random',
21
+ config: {
22
+ clearStoreOnStart: false,
23
+ dbName,
24
+ location: getStoreDirectory(dbName, 'lmdb'),
25
+ schema: LmdbArchivistConfigSchema,
26
+ storeName,
27
+ },
28
+ })
29
+ }
30
+ }
31
+ }
32
+
33
+ export const deleteLocalPersistentArchivist = async (dbName: string, _storeName: string, kind: StoreKind = 'lmdb'): Promise<void> => {
34
+ await Promise.resolve()
35
+ console.warn(`Deleting local persistent archivist for ${dbName} of kind ${kind}.`)
36
+ let location = ''
37
+ switch (kind) {
38
+ case 'lmdb': {
39
+ location = getStoreDirectory(dbName, 'lmdb')
40
+ break
41
+ }
42
+ }
43
+ await rm(location, { recursive: true, force: true })
44
+ }
@@ -0,0 +1 @@
1
+ export * from './initHealthEndpoints.ts'
@@ -0,0 +1,70 @@
1
+ import type {
2
+ IncomingMessage, Server, ServerResponse,
3
+ } from 'node:http'
4
+ import http from 'node:http'
5
+
6
+ import type { CreatableStatus } from '@xylabs/creatable'
7
+ import { isDefined, isEmptyString } from '@xylabs/typeof'
8
+ import type { Initializable } from '@xyo-network/xl1-protocol'
9
+
10
+ import type { RuntimeStatusMonitor } from '../status/index.ts'
11
+
12
+ const sendStatus = (res: ServerResponse, status: CreatableStatus, errorCode: number) => {
13
+ const statusCode = status === 'started' ? 200 : errorCode
14
+ res.writeHead(statusCode, { 'Content-Type': 'application/json' })
15
+ res.end(JSON.stringify({ status }))
16
+ }
17
+
18
+ const notFound = (res: ServerResponse) => {
19
+ res.writeHead(404, { 'Content-Type': 'application/json' })
20
+ res.end(JSON.stringify({ status: 'not found' }))
21
+ }
22
+
23
+ /**
24
+ * Starts an HTTP server with Kubernetes health endpoints:
25
+ * - /healthz
26
+ * - /livez
27
+ * - /readyz
28
+ * @param port The port to listen on (default: 8080)
29
+ */
30
+ const createHealthServer = (port: number = 8080, statusMonitor: RuntimeStatusMonitor) => {
31
+ const server = http.createServer((req: IncomingMessage, res: ServerResponse) => {
32
+ const url = req.url ?? ''
33
+
34
+ const status = statusMonitor.getGlobalStatus()
35
+
36
+ switch (url) {
37
+ case '/healthz': {
38
+ sendStatus(res, status, 500)
39
+ break
40
+ }
41
+ case '/livez': {
42
+ sendStatus(res, status, 503)
43
+ break
44
+ }
45
+ case '/readyz': {
46
+ sendStatus(res, status, 503)
47
+ break
48
+ }
49
+ default: {
50
+ notFound(res)
51
+ }
52
+ }
53
+ })
54
+
55
+ server.listen(port, () => {
56
+ console.log(`Health server running on http://localhost:${port}`)
57
+ console.log(' - /healthz')
58
+ console.log(' - /livez')
59
+ console.log(' - /readyz')
60
+ })
61
+ return server
62
+ }
63
+
64
+ export const initHealthEndpoints: Initializable<{ statusReporter: RuntimeStatusMonitor }, Server | undefined> = (params) => {
65
+ const healthCheckEnvVarPort = process.env.XYO_PRODUCER_HEALTH_CHECK_PORT
66
+ if (isDefined(healthCheckEnvVarPort) && !isEmptyString(healthCheckEnvVarPort)) {
67
+ const healthCheckPort = Number.parseInt(healthCheckEnvVarPort, 10)
68
+ return createHealthServer(healthCheckPort, params.statusReporter)
69
+ }
70
+ }
@@ -0,0 +1,25 @@
1
+ import type { Host, ServiceProvider } from '../model/index.ts'
2
+
3
+ /**
4
+ * A generic host implementation that can be used as a starting point for
5
+ * more complex host implementations.
6
+ */
7
+ export class GenericHost implements Host {
8
+ services: ServiceProvider
9
+
10
+ constructor(services: ServiceProvider) {
11
+ this.services = services
12
+ }
13
+
14
+ async start(): Promise<void> {
15
+ await Promise.resolve()
16
+ // Initialize or start your services here
17
+ console.log('Host is starting...')
18
+ }
19
+
20
+ async stop(): Promise<void> {
21
+ await Promise.resolve()
22
+ // Stop or clean up services here
23
+ console.log('Host is stopping...')
24
+ }
25
+ }