@xyo-network/xl1-protocol-sdk 1.16.26 → 1.17.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 (231) hide show
  1. package/dist/neutral/ChainServiceCollectionV2.d.ts +8 -35
  2. package/dist/neutral/ChainServiceCollectionV2.d.ts.map +1 -1
  3. package/dist/neutral/block/hydrate/flattenHydratedBlocks.d.ts +2 -3
  4. package/dist/neutral/block/hydrate/flattenHydratedBlocks.d.ts.map +1 -1
  5. package/dist/neutral/index.d.ts +2 -0
  6. package/dist/neutral/index.d.ts.map +1 -1
  7. package/dist/neutral/index.mjs +1765 -1251
  8. package/dist/neutral/index.mjs.map +1 -1
  9. package/dist/neutral/model/PayloadBundle/bundledPayloadToHydratedBlock.d.ts +4 -0
  10. package/dist/neutral/model/PayloadBundle/bundledPayloadToHydratedBlock.d.ts.map +1 -0
  11. package/dist/neutral/model/PayloadBundle/hydratedBlockToPayloadBundle.d.ts +4 -0
  12. package/dist/neutral/model/PayloadBundle/hydratedBlockToPayloadBundle.d.ts.map +1 -0
  13. package/dist/neutral/model/PayloadBundle/index.d.ts +2 -0
  14. package/dist/neutral/model/PayloadBundle/index.d.ts.map +1 -1
  15. package/dist/neutral/model/Qualified.d.ts +6 -0
  16. package/dist/neutral/model/Qualified.d.ts.map +1 -0
  17. package/dist/neutral/model/index.d.ts +1 -1
  18. package/dist/neutral/model/index.d.ts.map +1 -1
  19. package/dist/neutral/payloads/index.d.ts +0 -1
  20. package/dist/neutral/payloads/index.d.ts.map +1 -1
  21. package/dist/neutral/primitives/index.d.ts +2 -1
  22. package/dist/neutral/primitives/index.d.ts.map +1 -1
  23. package/dist/neutral/primitives/rewardFromBlockNumber.d.ts +3 -0
  24. package/dist/neutral/primitives/rewardFromBlockNumber.d.ts.map +1 -0
  25. package/dist/neutral/primitives/state/findMostRecentBlock.d.ts +11 -0
  26. package/dist/neutral/primitives/state/findMostRecentBlock.d.ts.map +1 -0
  27. package/dist/neutral/primitives/state/hydratedBlockByNumber.d.ts +4 -0
  28. package/dist/neutral/primitives/state/hydratedBlockByNumber.d.ts.map +1 -0
  29. package/dist/neutral/primitives/state/index.d.ts +3 -0
  30. package/dist/neutral/primitives/state/index.d.ts.map +1 -0
  31. package/dist/neutral/provider/XyoRunner.d.ts +5 -1
  32. package/dist/neutral/provider/XyoRunner.d.ts.map +1 -1
  33. package/dist/neutral/provider/viewer/XyoViewer.d.ts +9 -4
  34. package/dist/neutral/provider/viewer/XyoViewer.d.ts.map +1 -1
  35. package/dist/neutral/provider/viewer/index.d.ts +0 -1
  36. package/dist/neutral/provider/viewer/index.d.ts.map +1 -1
  37. package/dist/neutral/runners/Block.d.ts +8 -0
  38. package/dist/neutral/runners/Block.d.ts.map +1 -0
  39. package/dist/neutral/runners/Mempool.d.ts +9 -0
  40. package/dist/neutral/runners/Mempool.d.ts.map +1 -0
  41. package/dist/neutral/runners/index.d.ts +3 -0
  42. package/dist/neutral/runners/index.d.ts.map +1 -0
  43. package/dist/neutral/services/BlockProducerService.d.ts +2 -2
  44. package/dist/neutral/services/BlockProducerService.d.ts.map +1 -1
  45. package/dist/neutral/services/Chain/BaseChainService.d.ts +0 -2
  46. package/dist/neutral/services/Chain/BaseChainService.d.ts.map +1 -1
  47. package/dist/neutral/services/Chain/ChainService.d.ts +2 -3
  48. package/dist/neutral/services/Chain/ChainService.d.ts.map +1 -1
  49. package/dist/neutral/services/Chain/index.d.ts +0 -1
  50. package/dist/neutral/services/Chain/index.d.ts.map +1 -1
  51. package/dist/neutral/services/index.d.ts +0 -2
  52. package/dist/neutral/services/index.d.ts.map +1 -1
  53. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts +9 -5
  54. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts.map +1 -1
  55. package/dist/neutral/simple/block/SimpleBlockViewer.d.ts +55 -0
  56. package/dist/neutral/simple/block/SimpleBlockViewer.d.ts.map +1 -0
  57. package/dist/neutral/simple/block/index.d.ts +2 -0
  58. package/dist/neutral/simple/block/index.d.ts.map +1 -0
  59. package/dist/neutral/simple/blockReward/SimpleBlockRewardViewer.d.ts +16 -0
  60. package/dist/neutral/simple/blockReward/SimpleBlockRewardViewer.d.ts.map +1 -0
  61. package/dist/neutral/simple/blockReward/index.d.ts +2 -0
  62. package/dist/neutral/simple/blockReward/index.d.ts.map +1 -0
  63. package/dist/neutral/simple/chain/SimpleChainViewer.d.ts +12 -0
  64. package/dist/neutral/simple/chain/SimpleChainViewer.d.ts.map +1 -0
  65. package/dist/neutral/simple/chain/index.d.ts +2 -0
  66. package/dist/neutral/simple/chain/index.d.ts.map +1 -0
  67. package/dist/neutral/simple/index.d.ts +3 -0
  68. package/dist/neutral/simple/index.d.ts.map +1 -1
  69. package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts +15 -0
  70. package/dist/neutral/simple/mempool/SimpleMempoolRunner.d.ts.map +1 -0
  71. package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts +10 -4
  72. package/dist/neutral/simple/mempool/SimpleMempoolViewer.d.ts.map +1 -1
  73. package/dist/neutral/simple/mempool/index.d.ts +1 -0
  74. package/dist/neutral/simple/mempool/index.d.ts.map +1 -1
  75. package/dist/neutral/summary/index.d.ts +3 -0
  76. package/dist/neutral/summary/index.d.ts.map +1 -0
  77. package/dist/neutral/summary/model/BalancesStepSummary.d.ts.map +1 -0
  78. package/dist/neutral/summary/model/SchemasStepSummary.d.ts.map +1 -0
  79. package/dist/neutral/summary/model/StepSummary.d.ts.map +1 -0
  80. package/dist/neutral/summary/model/TransfersSummary.d.ts.map +1 -0
  81. package/dist/neutral/{payloads/summary → summary/model}/index.d.ts +1 -0
  82. package/dist/neutral/summary/model/index.d.ts.map +1 -0
  83. package/dist/neutral/{model → summary/model}/summary.d.ts +3 -4
  84. package/dist/neutral/summary/model/summary.d.ts.map +1 -0
  85. package/dist/neutral/{primitives/summary → summary/primitives}/balances/balancesStepSummaryFromRange.d.ts +1 -2
  86. package/dist/neutral/summary/primitives/balances/balancesStepSummaryFromRange.d.ts.map +1 -0
  87. package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts +5 -0
  88. package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts.map +1 -0
  89. package/dist/neutral/summary/primitives/balances/index.d.ts.map +1 -0
  90. package/dist/neutral/{primitives/summary → summary/primitives}/index.d.ts.map +1 -1
  91. package/dist/neutral/summary/primitives/schemas/index.d.ts.map +1 -0
  92. package/dist/neutral/{primitives/summary → summary/primitives}/schemas/schemasStepSummaryFromRange.d.ts +1 -2
  93. package/dist/neutral/summary/primitives/schemas/schemasStepSummaryFromRange.d.ts.map +1 -0
  94. package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts +5 -0
  95. package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts.map +1 -0
  96. package/dist/neutral/summary/primitives/transfers/index.d.ts.map +1 -0
  97. package/dist/neutral/{primitives/summary → summary/primitives}/transfers/transfersStepSummaryFromRange.d.ts +1 -2
  98. package/dist/neutral/summary/primitives/transfers/transfersStepSummaryFromRange.d.ts.map +1 -0
  99. package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts +6 -0
  100. package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts.map +1 -0
  101. package/dist/neutral/utils/HydratedCache.d.ts +16 -0
  102. package/dist/neutral/utils/HydratedCache.d.ts.map +1 -0
  103. package/dist/neutral/utils/index.d.ts +1 -0
  104. package/dist/neutral/utils/index.d.ts.map +1 -1
  105. package/dist/neutral/viewers/AccountBalance.d.ts +5 -2
  106. package/dist/neutral/viewers/AccountBalance.d.ts.map +1 -1
  107. package/dist/neutral/viewers/Block.d.ts +9 -5
  108. package/dist/neutral/viewers/Block.d.ts.map +1 -1
  109. package/dist/neutral/viewers/BlockReward.d.ts +8 -0
  110. package/dist/neutral/viewers/BlockReward.d.ts.map +1 -0
  111. package/dist/neutral/viewers/Chain.d.ts +2 -0
  112. package/dist/neutral/viewers/Chain.d.ts.map +1 -1
  113. package/dist/neutral/viewers/ChainStakeViewer.d.ts +6 -0
  114. package/dist/neutral/viewers/ChainStakeViewer.d.ts.map +1 -0
  115. package/dist/neutral/viewers/Mempool.d.ts +8 -1
  116. package/dist/neutral/viewers/Mempool.d.ts.map +1 -1
  117. package/dist/neutral/viewers/StakeIntent.d.ts +10 -0
  118. package/dist/neutral/viewers/StakeIntent.d.ts.map +1 -0
  119. package/dist/neutral/{provider/viewer → viewers}/StepViewer.d.ts +2 -2
  120. package/dist/neutral/viewers/StepViewer.d.ts.map +1 -0
  121. package/dist/neutral/viewers/index.d.ts +3 -0
  122. package/dist/neutral/viewers/index.d.ts.map +1 -1
  123. package/package.json +18 -18
  124. package/src/ChainServiceCollectionV2.ts +12 -39
  125. package/src/block/hydrate/flattenHydratedBlocks.ts +2 -3
  126. package/src/index.ts +2 -1
  127. package/src/model/PayloadBundle/bundledPayloadToHydratedBlock.ts +14 -0
  128. package/src/model/PayloadBundle/hydratedBlockToPayloadBundle.ts +18 -0
  129. package/src/model/PayloadBundle/index.ts +2 -0
  130. package/src/model/Qualified.ts +9 -0
  131. package/src/model/index.ts +1 -1
  132. package/src/payloads/index.ts +0 -1
  133. package/src/primitives/index.ts +2 -1
  134. package/src/primitives/rewardFromBlockNumber.ts +25 -0
  135. package/src/primitives/state/findMostRecentBlock.ts +44 -0
  136. package/src/primitives/state/hydratedBlockByNumber.ts +19 -0
  137. package/src/primitives/state/index.ts +2 -0
  138. package/src/provider/XyoRunner.ts +7 -1
  139. package/src/provider/viewer/XyoViewer.ts +18 -7
  140. package/src/provider/viewer/index.ts +0 -1
  141. package/src/runners/Block.ts +10 -0
  142. package/src/runners/Mempool.ts +9 -0
  143. package/src/runners/index.ts +2 -0
  144. package/src/services/BlockProducerService.ts +3 -2
  145. package/src/services/Chain/BaseChainService.ts +1 -3
  146. package/src/services/Chain/ChainService.ts +4 -3
  147. package/src/services/Chain/index.ts +0 -1
  148. package/src/services/index.ts +0 -2
  149. package/src/simple/accountBalance/SimpleAccountBalanceViewer.ts +104 -18
  150. package/src/simple/block/SimpleBlockViewer.ts +172 -0
  151. package/src/simple/block/index.ts +1 -0
  152. package/src/simple/blockReward/SimpleBlockRewardViewer.ts +34 -0
  153. package/src/simple/blockReward/index.ts +1 -0
  154. package/src/simple/chain/SimpleChainViewer.ts +25 -0
  155. package/src/simple/chain/index.ts +1 -0
  156. package/src/simple/gateway/SimpleXyoGatewayRunner.ts +1 -1
  157. package/src/simple/index.ts +3 -0
  158. package/src/simple/mempool/SimpleMempoolRunner.ts +47 -0
  159. package/src/simple/mempool/SimpleMempoolViewer.ts +34 -8
  160. package/src/simple/mempool/index.ts +1 -0
  161. package/src/simple/timesync/SimpleTimeSyncViewer.ts +1 -1
  162. package/src/summary/index.ts +2 -0
  163. package/src/{payloads/summary → summary/model}/index.ts +1 -0
  164. package/src/{model → summary/model}/summary.ts +5 -4
  165. package/src/{primitives/summary → summary/primitives}/balances/balancesStepSummaryFromRange.ts +4 -3
  166. package/src/{primitives/summary → summary/primitives}/balances/balancesSummary.ts +6 -5
  167. package/src/{primitives/summary → summary/primitives}/schemas/schemasStepSummaryFromRange.ts +3 -3
  168. package/src/{primitives/summary → summary/primitives}/schemas/schemasSummary.ts +7 -6
  169. package/src/{primitives/summary → summary/primitives}/transfers/transfersStepSummaryFromRange.ts +4 -3
  170. package/src/{primitives/summary → summary/primitives}/transfers/transfersSummary.ts +6 -5
  171. package/src/utils/HydratedCache.ts +38 -0
  172. package/src/utils/index.ts +1 -0
  173. package/src/viewers/AccountBalance.ts +9 -2
  174. package/src/viewers/Block.ts +10 -6
  175. package/src/viewers/BlockReward.ts +9 -0
  176. package/src/viewers/Chain.ts +2 -0
  177. package/src/viewers/ChainStakeViewer.ts +7 -0
  178. package/src/viewers/Mempool.ts +10 -1
  179. package/src/viewers/StakeIntent.ts +14 -0
  180. package/src/{provider/viewer → viewers}/StepViewer.ts +2 -2
  181. package/src/viewers/index.ts +3 -0
  182. package/dist/neutral/model/summary.d.ts.map +0 -1
  183. package/dist/neutral/payloads/summary/BalancesStepSummary.d.ts.map +0 -1
  184. package/dist/neutral/payloads/summary/SchemasStepSummary.d.ts.map +0 -1
  185. package/dist/neutral/payloads/summary/StepSummary.d.ts.map +0 -1
  186. package/dist/neutral/payloads/summary/TransfersSummary.d.ts.map +0 -1
  187. package/dist/neutral/payloads/summary/index.d.ts.map +0 -1
  188. package/dist/neutral/primitives/summary/balances/balancesStepSummaryFromRange.d.ts.map +0 -1
  189. package/dist/neutral/primitives/summary/balances/balancesSummary.d.ts +0 -4
  190. package/dist/neutral/primitives/summary/balances/balancesSummary.d.ts.map +0 -1
  191. package/dist/neutral/primitives/summary/balances/index.d.ts.map +0 -1
  192. package/dist/neutral/primitives/summary/schemas/index.d.ts.map +0 -1
  193. package/dist/neutral/primitives/summary/schemas/schemasStepSummaryFromRange.d.ts.map +0 -1
  194. package/dist/neutral/primitives/summary/schemas/schemasSummary.d.ts +0 -4
  195. package/dist/neutral/primitives/summary/schemas/schemasSummary.d.ts.map +0 -1
  196. package/dist/neutral/primitives/summary/transfers/index.d.ts.map +0 -1
  197. package/dist/neutral/primitives/summary/transfers/transfersStepSummaryFromRange.d.ts.map +0 -1
  198. package/dist/neutral/primitives/summary/transfers/transfersSummary.d.ts +0 -5
  199. package/dist/neutral/primitives/summary/transfers/transfersSummary.d.ts.map +0 -1
  200. package/dist/neutral/provider/viewer/StepViewer.d.ts.map +0 -1
  201. package/dist/neutral/services/BlockRewardService.d.ts +0 -5
  202. package/dist/neutral/services/BlockRewardService.d.ts.map +0 -1
  203. package/dist/neutral/services/BlockRewardServiceV2.d.ts +0 -6
  204. package/dist/neutral/services/BlockRewardServiceV2.d.ts.map +0 -1
  205. package/dist/neutral/services/Chain/interfaces/ChainStakeViewer.d.ts +0 -4
  206. package/dist/neutral/services/Chain/interfaces/ChainStakeViewer.d.ts.map +0 -1
  207. package/dist/neutral/services/Chain/interfaces/ChainStaker.d.ts +0 -6
  208. package/dist/neutral/services/Chain/interfaces/ChainStaker.d.ts.map +0 -1
  209. package/dist/neutral/services/Chain/interfaces/index.d.ts +0 -3
  210. package/dist/neutral/services/Chain/interfaces/index.d.ts.map +0 -1
  211. package/src/services/BlockRewardService.ts +0 -6
  212. package/src/services/BlockRewardServiceV2.ts +0 -8
  213. package/src/services/Chain/interfaces/ChainStakeViewer.ts +0 -5
  214. package/src/services/Chain/interfaces/ChainStaker.ts +0 -5
  215. package/src/services/Chain/interfaces/index.ts +0 -2
  216. /package/dist/neutral/{payloads/summary → summary/model}/BalancesStepSummary.d.ts +0 -0
  217. /package/dist/neutral/{payloads/summary → summary/model}/SchemasStepSummary.d.ts +0 -0
  218. /package/dist/neutral/{payloads/summary → summary/model}/StepSummary.d.ts +0 -0
  219. /package/dist/neutral/{payloads/summary → summary/model}/TransfersSummary.d.ts +0 -0
  220. /package/dist/neutral/{primitives/summary → summary/primitives}/balances/index.d.ts +0 -0
  221. /package/dist/neutral/{primitives/summary → summary/primitives}/index.d.ts +0 -0
  222. /package/dist/neutral/{primitives/summary → summary/primitives}/schemas/index.d.ts +0 -0
  223. /package/dist/neutral/{primitives/summary → summary/primitives}/transfers/index.d.ts +0 -0
  224. /package/src/{payloads/summary → summary/model}/BalancesStepSummary.ts +0 -0
  225. /package/src/{payloads/summary → summary/model}/SchemasStepSummary.ts +0 -0
  226. /package/src/{payloads/summary → summary/model}/StepSummary.ts +0 -0
  227. /package/src/{payloads/summary → summary/model}/TransfersSummary.ts +0 -0
  228. /package/src/{primitives/summary → summary/primitives}/balances/index.ts +0 -0
  229. /package/src/{primitives/summary → summary/primitives}/index.ts +0 -0
  230. /package/src/{primitives/summary → summary/primitives}/schemas/index.ts +0 -0
  231. /package/src/{primitives/summary → summary/primitives}/transfers/index.ts +0 -0
@@ -2,4 +2,3 @@ export * from './AddressPairPayload.ts'
2
2
  export * from './netBalancesForPayloads.ts'
3
3
  export * from './netSchemasForPayloads.ts'
4
4
  export * from './netTransfersForPayloads.ts'
5
- export * from './summary/index.ts'
@@ -1,5 +1,6 @@
1
1
  export * from './readPayloadMapFromStore.ts'
2
+ export * from './rewardFromBlockNumber.ts'
3
+ export * from './state/index.ts'
2
4
  export * from './step/index.ts'
3
- export * from './summary/index.ts'
4
5
  export * from './timeBudget.ts'
5
6
  export * from './transaction/index.ts'
@@ -0,0 +1,25 @@
1
+ import { toFixedPoint } from '@xylabs/sdk-js'
2
+ import { asAttoXL1, type XL1BlockNumber } from '@xyo-network/xl1-protocol'
3
+
4
+ export const rewardFromBlockNumber = (places = 18) => {
5
+ return (
6
+ blockNumber: XL1BlockNumber,
7
+ startingReward = asAttoXL1(toFixedPoint(30_000n, places)),
8
+ blocksPerStep = 1_000_000,
9
+ stepFactorNumerator = 90n,
10
+ stepFactorDenominator = 100n,
11
+ minBlockReward = asAttoXL1(toFixedPoint(30n, places)),
12
+ creatorReward = asAttoXL1(toFixedPoint(20_000_000_000n, places)),
13
+ ) => {
14
+ if (blockNumber === 0) {
15
+ return creatorReward
16
+ }
17
+ const step = Math.floor((blockNumber + blocksPerStep) / blocksPerStep)
18
+ const stepExp = BigInt(step - 1)
19
+ const poweredNumerator = stepExp > 0 ? stepFactorNumerator ** stepExp : 1n
20
+ const poweredDenominator = stepExp > 0 ? stepFactorDenominator ** stepExp : 1n
21
+ let reward = (startingReward * poweredNumerator) / poweredDenominator
22
+ // eslint-disable-next-line unicorn/prefer-math-min-max
23
+ return asAttoXL1((reward < minBlockReward) ? minBlockReward : reward)
24
+ }
25
+ }
@@ -0,0 +1,44 @@
1
+ import type { NextOptions, ReadArchivist } from '@xyo-network/archivist-model'
2
+ import type {
3
+ Payload, Sequence, WithStorageMeta,
4
+ } from '@xyo-network/payload-model'
5
+ import type { SignedBlockBoundWitnessWithHashMeta } from '@xyo-network/xl1-protocol'
6
+ import { isSignedBlockBoundWitnessWithStorageMeta } from '@xyo-network/xl1-protocol'
7
+
8
+ // TODO: Use some smart value relative to DEFAULT_BLOCK_SIZE
9
+ // to ensure we're likely to find it in a single request
10
+ // without bringing back too much data
11
+ const DEFAULT_NEXT_OPTIONS: NextOptions = { limit: 50 }
12
+
13
+ /**
14
+ * Iterates an archivist to find the most recent block
15
+ * @param chainArchivist The archivist to iterate over for the most recent chain block
16
+ * @param nextOptions The options to use when iterating the archivist
17
+ * @param maxIterations The max number of iterations to perform when finding the most recent block
18
+ * @returns The most recent block found in the archivist or undefined if no blocks are found
19
+ */
20
+ export const findMostRecentBlock = async (
21
+ chainArchivist: ReadArchivist,
22
+ nextOptions: NextOptions = DEFAULT_NEXT_OPTIONS,
23
+ maxIterations = Number.POSITIVE_INFINITY,
24
+ ): Promise<SignedBlockBoundWitnessWithHashMeta | undefined> => {
25
+ let mostRecentBlock: SignedBlockBoundWitnessWithHashMeta | undefined
26
+ let cursor: Sequence | undefined
27
+ let batch: WithStorageMeta<Payload>[]
28
+ let iterations = 0
29
+ do {
30
+ batch = await chainArchivist.next({
31
+ ...nextOptions, order: 'desc', cursor,
32
+ })
33
+ const blocks = batch.filter(isSignedBlockBoundWitnessWithStorageMeta)
34
+ const last = blocks?.at(0)
35
+ if (last) {
36
+ mostRecentBlock = last
37
+ break
38
+ } else {
39
+ cursor = batch.at(-1)?._sequence
40
+ }
41
+ iterations = iterations + 1
42
+ } while (batch.length > 0 && iterations < maxIterations)
43
+ return mostRecentBlock
44
+ }
@@ -0,0 +1,19 @@
1
+ import { assertEx } from '@xylabs/sdk-js'
2
+ import type { HydratedBlockWithHashMeta, XL1BlockNumber } from '@xyo-network/xl1-protocol'
3
+
4
+ import { blockFromBlockNumber, hydrateBlock } from '../../block/index.ts'
5
+ import { type ChainContextRead, withContextCacheResponse } from '../../model/index.ts'
6
+
7
+ export async function hydratedBlockByNumber(context: ChainContextRead, blockNumber: XL1BlockNumber): Promise<HydratedBlockWithHashMeta | null> {
8
+ if (blockNumber < 0) throw new Error(`Block number ${blockNumber} is less than 0`)
9
+ if (blockNumber > Number.MAX_SAFE_INTEGER) throw new Error(`Block number ${blockNumber} is greater than the maximum safe integer`)
10
+ if (blockNumber % 1 !== 0) throw new Error(`Block number ${blockNumber} is not an integer`)
11
+ const cacheKey = `${blockNumber}`
12
+ return await withContextCacheResponse(context, 'hydratedBlockByNumber', cacheKey, async () => {
13
+ const block = assertEx(
14
+ await blockFromBlockNumber(context, blockNumber),
15
+ () => `Could not find block for block number ${blockNumber}`,
16
+ )
17
+ return await hydrateBlock(context.store, block._hash)
18
+ })
19
+ }
@@ -0,0 +1,2 @@
1
+ export * from './findMostRecentBlock.ts'
2
+ export * from './hydratedBlockByNumber.ts'
@@ -1,6 +1,12 @@
1
1
  import type { Hash, Promisable } from '@xylabs/sdk-js'
2
2
  import type { SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
3
3
 
4
- export interface XyoRunner {
4
+ import type { MempoolRunner } from '../runners/index.ts'
5
+
6
+ export interface XyoRunnerMethods {
5
7
  broadcastTransaction(transaction: SignedHydratedTransaction): Promisable<Hash>
6
8
  }
9
+
10
+ export interface XyoRunner extends XyoRunnerMethods {
11
+ mempool?: MempoolRunner
12
+ }
@@ -1,26 +1,37 @@
1
1
  import type {
2
+ Address, Hash, Promisable,
3
+ } from '@xylabs/sdk-js'
4
+ import type { AttoXL1, XL1BlockRange } from '@xyo-network/xl1-protocol'
5
+
6
+ import type {
7
+ AccountBalanceHistoryItem,
2
8
  AccountBalanceViewer,
3
- AccountBalanceViewerMethods,
4
- BlockViewierMethods,
9
+ BlockViewer,
10
+ BlockViewerMethods,
5
11
  ChainViewerMethods,
6
12
  ForkViewerMethods,
13
+ MempoolViewer,
7
14
  NetworkStakeStepRewardViewer,
8
15
  StakeViewerMethods,
16
+ StepViewer,
9
17
  TransactionViewerMethods,
10
18
  TransferBalanceViewerMethods,
11
19
  } from '../../viewers/index.ts'
12
20
  import type { NetworkStakeViewer } from './NetworkStake/index.ts'
13
- import type { StepViewer } from './StepViewer.ts'
14
21
 
15
- export interface XyoViewerMethods extends AccountBalanceViewerMethods, TransferBalanceViewerMethods,
16
- NetworkStakeStepRewardViewer, AccountBalanceViewer,
17
- ChainViewerMethods, BlockViewierMethods, TransactionViewerMethods, StakeViewerMethods, ForkViewerMethods {
22
+ export interface XyoViewerMethods extends
23
+ TransferBalanceViewerMethods, NetworkStakeStepRewardViewer,
24
+ Pick<ChainViewerMethods, 'chainId'>, BlockViewerMethods, TransactionViewerMethods, StakeViewerMethods, ForkViewerMethods {
25
+ accountBalance(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<AttoXL1>
26
+ accountBalanceHistory(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<AccountBalanceHistoryItem[]>
18
27
  }
19
28
 
20
- export interface XyoViewer extends XyoViewerMethods {
29
+ export interface XyoViewer extends BlockViewer, XyoViewerMethods {
21
30
  account?: {
22
31
  balance?: AccountBalanceViewer
23
32
  }
33
+ block?: BlockViewer
34
+ mempool?: MempoolViewer
24
35
  networkStake?: NetworkStakeViewer
25
36
  step?: StepViewer
26
37
  }
@@ -1,3 +1,2 @@
1
1
  export * from './NetworkStake/index.ts'
2
- export * from './StepViewer.ts'
3
2
  export * from './XyoViewer.ts'
@@ -0,0 +1,10 @@
1
+ import type { SignedBlockBoundWitnessWithHashMeta, SignedHydratedBlockWithHashMeta } from '@xyo-network/xl1-protocol'
2
+
3
+ export interface BlockRunnerMethods {
4
+ produceNextBlock(head: SignedBlockBoundWitnessWithHashMeta, force: true): Promise<SignedHydratedBlockWithHashMeta>
5
+ produceNextBlock(head: SignedBlockBoundWitnessWithHashMeta, force?: false): Promise<SignedHydratedBlockWithHashMeta | undefined>
6
+ }
7
+
8
+ export interface BlockRunner extends BlockRunnerMethods {
9
+
10
+ }
@@ -0,0 +1,9 @@
1
+ import type { Hash } from '@xylabs/sdk-js'
2
+ import type { SignedHydratedBlock, SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
3
+
4
+ export interface MempoolRunnerMethods {
5
+ submitBlocks(blocks: SignedHydratedBlock[]): Promise<Hash[]>
6
+ submitTransactions(transactions: SignedHydratedTransaction[]): Promise<Hash[]>
7
+ }
8
+
9
+ export interface MempoolRunner extends MempoolRunnerMethods {}
@@ -0,0 +1,2 @@
1
+ export * from './Block.ts'
2
+ export * from './Mempool.ts'
@@ -1,8 +1,9 @@
1
1
  import type {
2
2
  Addressable,
3
- BlockBoundWitness, HydratedBlockWithHashMeta, IterableRepository,
3
+ BlockBoundWitness, IterableRepository,
4
+ SignedHydratedBlockWithHashMeta,
4
5
  } from '@xyo-network/xl1-protocol'
5
6
 
6
- export type NextBlockProducer = IterableRepository<BlockBoundWitness, HydratedBlockWithHashMeta | undefined>
7
+ export type NextBlockProducer = IterableRepository<BlockBoundWitness, SignedHydratedBlockWithHashMeta | undefined>
7
8
 
8
9
  export interface BlockProducerService extends Addressable, NextBlockProducer {}
@@ -1,5 +1,3 @@
1
- import type { ChainId } from '@xyo-network/xl1-protocol'
2
-
3
1
  export interface BaseChainService {
4
- chainId: ChainId
2
+
5
3
  }
@@ -1,5 +1,6 @@
1
- import type { ChainContractViewer } from '../../viewers/index.ts'
1
+ import type {
2
+ ChainContractViewer, ChainStakeViewer, ChainViewer,
3
+ } from '../../viewers/index.ts'
2
4
  import type { BaseChainService } from './BaseChainService.ts'
3
- import type { ChainStaker, ChainStakeViewer } from './interfaces/index.ts'
4
5
 
5
- export interface ChainService extends ChainContractViewer, ChainStakeViewer, ChainStaker, BaseChainService {}
6
+ export interface ChainService extends ChainContractViewer, ChainStakeViewer, ChainViewer, BaseChainService {}
@@ -1,4 +1,3 @@
1
1
  export * from './BaseChainService.ts'
2
2
  export * from './ChainHeadService.ts'
3
3
  export * from './ChainService.ts'
4
- export * from './interfaces/index.ts'
@@ -1,7 +1,5 @@
1
1
  export * from './AccountTransfersService.ts'
2
2
  export * from './BlockProducerService.ts'
3
- export * from './BlockRewardService.ts'
4
- export * from './BlockRewardServiceV2.ts'
5
3
  export * from './Chain/index.ts'
6
4
  export * from './ChainIterator/index.ts'
7
5
  export * from './Election.ts'
@@ -3,6 +3,7 @@ import type {
3
3
  } from '@xylabs/sdk-js'
4
4
  import {
5
5
  AbstractCreatable,
6
+ asHash,
6
7
  assertEx, exists, isDefined,
7
8
  } from '@xylabs/sdk-js'
8
9
  import { spanRootAsync } from '@xylabs/telemetry'
@@ -17,9 +18,15 @@ import {
17
18
  } from '@xyo-network/xl1-protocol'
18
19
 
19
20
  import { deepCalculateFramesFromRange } from '../../block/index.ts'
20
- import type { BalanceStepSummaryContext, TransfersStepSummaryContext } from '../../model/index.ts'
21
- import type { TransfersStepSummary } from '../../payloads/index.ts'
22
- import { balancesSummary, transfersStepSummaryFromRange } from '../../primitives/index.ts'
21
+ import type { Qualified } from '../../model/index.ts'
22
+ import type {
23
+ BalanceStepSummaryContext, TransfersStepSummary,
24
+ TransfersStepSummaryContext,
25
+ } from '../../summary/index.ts'
26
+ import {
27
+ balancesSummary,
28
+ transfersStepSummaryFromRange,
29
+ } from '../../summary/index.ts'
23
30
  import type {
24
31
  AccountBalanceHistoryItem, AccountBalanceViewer, BlockViewer,
25
32
  } from '../../viewers/index.ts'
@@ -27,7 +34,7 @@ import type {
27
34
  export interface SimpleAccountBalanceViewerParams extends CreatableParams {
28
35
  blockViewer: BlockViewer
29
36
  context: BalanceStepSummaryContext
30
- transferContext: TransfersStepSummaryContext
37
+ transfersSummaryContext: TransfersStepSummaryContext
31
38
  }
32
39
 
33
40
  export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountBalanceViewerParams> implements AccountBalanceViewer {
@@ -39,23 +46,27 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
39
46
  return this.params.context!
40
47
  }
41
48
 
42
- get transferContext(): TransfersStepSummaryContext {
43
- return this.params.transferContext!
49
+ get transfersSummaryContext(): TransfersStepSummaryContext {
50
+ return this.params.transfersSummaryContext!
44
51
  }
45
52
 
46
53
  static override async paramsHandler(params: Partial<SimpleAccountBalanceViewerParams>) {
47
54
  assertEx(params.blockViewer, () => 'blockViewer is required')
48
55
  assertEx(params.context, () => 'context is required')
49
- assertEx(params.transferContext, () => 'transferContext is required')
56
+ assertEx(params.transfersSummaryContext, () => 'transfersSummaryContext is required')
50
57
 
51
58
  return { ...await super.paramsHandler(params) }
52
59
  }
53
60
 
54
61
  async accountBalance(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AttoXL1> {
55
- const balances = await this.accountsBalances([address], headOrRange)
62
+ const balances = await this.accountBalances([address], headOrRange)
56
63
  return balances[address] ?? AttoXL1(0n)
57
64
  }
58
65
 
66
+ accountBalanceHistories(_addresses: Address[], _rangeOrHash?: XL1BlockRange | Hash): Promise<Record<Address, AccountBalanceHistoryItem[]>> {
67
+ throw new Error('Method [accountBalanceHistories] not implemented.')
68
+ }
69
+
59
70
  async accountBalanceHistory(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AccountBalanceHistoryItem[]> {
60
71
  const range = asRange(headOrRange)
61
72
  const startingRange = asXL1BlockRange(range ?? [0, await this.blockViewer.currentBlockNumber()], true)
@@ -84,24 +95,64 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
84
95
  return result
85
96
  }
86
97
 
87
- async accountsBalances(address: Address[], _headOrRange?: XL1BlockRange | Hash): Promise<Partial<Record<Address, AttoXL1>>> {
88
- return await spanRootAsync('balances', async () => {
89
- const summary = await balancesSummary(
98
+ async accountBalances(address: Address[], _headOrRange?: XL1BlockRange | Hash): Promise<Record<Address, AttoXL1>> {
99
+ const [result] = (await this.qualifiedAccountBalances(address, _headOrRange))
100
+ return result
101
+ }
102
+
103
+ async qualifiedAccountBalanceHistories(
104
+ addresses: Address[],
105
+ headOrRange?: Hash | XL1BlockRange,
106
+ ): Promise<Qualified<Record<Address, AccountBalanceHistoryItem[]>>> {
107
+ const head = asHash(headOrRange) ?? await this.blockViewer.currentBlockHash()
108
+ const range = asXL1BlockRange(headOrRange) ?? asXL1BlockRange([0,
109
+ assertEx(
110
+ await this.blockViewer.blockByHash(head),
111
+ () => `Error: Could not find block with hash ${head}`,
112
+ )[0].block])
113
+ const qualifiedEntries: [Address, Qualified<AccountBalanceHistoryItem[]>][] = await Promise.all(addresses.map(async address => ([
114
+ address,
115
+ await this.qualifiedAccountBalanceHistory(address, range),
116
+ ])))
117
+
118
+ const entries = qualifiedEntries.map(([address, [history]]) => {
119
+ return [address, history]
120
+ })
121
+ const qualifiedRange = qualifiedEntries[0][1][1]
122
+ const qualifiedHeadHash = qualifiedEntries[0][1][2]
123
+
124
+ // check for drift
125
+ for (const [_, [__, range, headHash]] of qualifiedEntries) {
126
+ assertEx(
127
+ range[0] === qualifiedRange[0] && range[1] === qualifiedRange[1],
128
+ () => 'Inconsistent ranges in qualifiedAccountBalanceHistories',
129
+ )
130
+ assertEx(
131
+ headHash === qualifiedHeadHash,
132
+ () => 'Inconsistent head hashes in qualifiedAccountBalanceHistories',
133
+ )
134
+ }
135
+
136
+ return [Object.fromEntries(entries), qualifiedRange, qualifiedHeadHash]
137
+ }
138
+
139
+ async qualifiedAccountBalances(
140
+ address: Address[],
141
+ _headOrRange?: Hash | XL1BlockRange,
142
+ ): Promise<Qualified<Record<Address, AttoXL1>>> {
143
+ return await spanRootAsync('qualifiedAccountsBalances', async () => {
144
+ const qualifiedSummary = await balancesSummary(
90
145
  this.context,
91
146
  )
92
147
  const result: Record<Address, AttoXL1> = {}
93
148
  for (const addr of address) {
94
- const summaryBalance = summary[addr] ?? 0n
149
+ const summaryBalance = qualifiedSummary[0][addr] ?? 0n
95
150
  result[addr] = AttoXL1(summaryBalance < 0n ? 0n : summaryBalance)
96
151
  }
97
- return result
152
+ return [result, qualifiedSummary[1], qualifiedSummary[2]]
98
153
  })
99
154
  }
100
155
 
101
- accountsBalancesHistory(_addresses: Address[], _rangeOrHash?: XL1BlockRange | Hash): Promise<Partial<Record<Address, AccountBalanceHistoryItem[]>>> {
102
- throw new Error('Method not implemented.')
103
- }
104
-
105
156
  private async distillTransferHistory(address: Address, range: XL1BlockRange, max: number = 50): Promise<XL1BlockNumber[]> {
106
157
  if ((range[1] - range[0]) <= StepSizes[0] || max <= 1) {
107
158
  return Array.from({ length: range[1] - range[0] + 1 }, (_, i) => range[1] - i).slice(0, max).map(n => asXL1BlockNumber(n, true))
@@ -109,7 +160,7 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
109
160
  const frames = deepCalculateFramesFromRange(asXL1BlockRange(range, true))
110
161
  const transferSummaryPairs = await Promise.all(frames.map(
111
162
  async (frame) => {
112
- return [frame, await transfersStepSummaryFromRange(this.transferContext, frame)]
163
+ return [frame, await transfersStepSummaryFromRange(this.transfersSummaryContext, frame)]
113
164
  },
114
165
  )) as [XL1BlockRange, WithStorageMeta<TransfersStepSummary>][]
115
166
 
@@ -139,4 +190,39 @@ export class SimpleAccountBalanceViewer extends AbstractCreatable<SimpleAccountB
139
190
  }
140
191
  return [...resultBlockNumbers].toSorted((a, b) => b - a).slice(0, max)
141
192
  }
193
+
194
+ private async qualifiedAccountBalanceHistory(
195
+ address: Address,
196
+ headOrRange?: Hash | XL1BlockRange,
197
+ ): Promise<Qualified<AccountBalanceHistoryItem[]>> {
198
+ const range = asRange(headOrRange)
199
+ const headHash = asHash(headOrRange)
200
+ const [head] = assertEx(isDefined(headHash)
201
+ ? (await this.blockViewer.blockByHash(headHash))
202
+ : (await this.blockViewer.currentBlock()), () => 'Could not resolve head block')
203
+ const startingRange = asXL1BlockRange(range ?? [0, head.block], true)
204
+ const blockNumbers = await this.distillTransferHistory(address, startingRange)
205
+ const blocks = (await Promise.all(blockNumbers.map(async bn => await this.blockViewer.blockByNumber(bn)))).filter(exists)
206
+ const result: AccountBalanceHistoryItem[] = []
207
+ for (const block of blocks) {
208
+ const transferIndexes = block[0].payload_schemas.map((schema, index) => schema === TransferSchema ? index : undefined).filter(exists)
209
+ const transfers = transferIndexes.map((index) => {
210
+ const hash = block[0].payload_hashes[index]
211
+ return assertEx(
212
+ block[1].find(p => p._hash === hash) as WithStorageMeta<Transfer>,
213
+ () => `Error: Could not find Transfer with hash ${hash} in block ${block[0]._hash}`,
214
+ )
215
+ }).filter(exists).filter(t => ((t.from === address) || (isDefined(t.transfers[address]))))
216
+ if (transfers.length === 0) {
217
+ continue
218
+ }
219
+ const pairs: [SignedBlockBoundWitnessWithHashMeta, WithHashMeta<Transfer>][] = (transfers.map((transfer) => {
220
+ return [block[0], transfer]
221
+ }))
222
+ result.push(...pairs.map(([block, transfer]) => [block,
223
+ null,
224
+ transfer] satisfies AccountBalanceHistoryItem))
225
+ }
226
+ return [result, startingRange, head._hash]
227
+ }
142
228
  }
@@ -0,0 +1,172 @@
1
+ import type { CreatableParams, Hash } from '@xylabs/sdk-js'
2
+ import {
3
+ AbstractCreatable,
4
+ assertEx,
5
+ exists,
6
+ isDefined,
7
+ spanRootAsync,
8
+ } from '@xylabs/sdk-js'
9
+ import type { ReadArchivist } from '@xyo-network/archivist-model'
10
+ import type { Payload, WithHashMeta } from '@xyo-network/payload-model'
11
+ import {
12
+ asSignedHydratedBlockWithHashMeta,
13
+ asXL1BlockNumber,
14
+ type SignedHydratedBlockWithHashMeta,
15
+ type XL1BlockNumber,
16
+ } from '@xyo-network/xl1-protocol'
17
+
18
+ import { hydrateBlock } from '../../block/index.ts'
19
+ import { LruCacheMap } from '../../driver/index.ts'
20
+ import type {
21
+ ChainContextRead,
22
+ ChainStoreRead, PayloadMap,
23
+ } from '../../model/index.ts'
24
+ import { findMostRecentBlock, hydratedBlockByNumber } from '../../primitives/index.ts'
25
+ import { HydratedCache } from '../../utils/index.ts'
26
+ import type { BlockViewer } from '../../viewers/index.ts'
27
+
28
+ export interface SimpleBlockViewerParams extends CreatableParams {
29
+ context: ChainContextRead
30
+ finalizedArchivist?: ReadArchivist
31
+ }
32
+
33
+ export class SimpleBlockViewer extends AbstractCreatable<SimpleBlockViewerParams> implements BlockViewer {
34
+ private _payloadCache: PayloadMap<WithHashMeta<Payload>> | undefined
35
+ private _signedHydratedBlockCache: HydratedCache<SignedHydratedBlockWithHashMeta> | undefined
36
+
37
+ get context(): ChainContextRead {
38
+ return this.params.context!
39
+ }
40
+
41
+ get finalizedArchivist(): ReadArchivist {
42
+ return this.params.finalizedArchivist!
43
+ }
44
+
45
+ protected get hydratedBlockCache(): HydratedCache<SignedHydratedBlockWithHashMeta> {
46
+ if (this._signedHydratedBlockCache) return this._signedHydratedBlockCache
47
+ const chainMap = this.context.store.chainMap
48
+ this._signedHydratedBlockCache = new HydratedCache<SignedHydratedBlockWithHashMeta>(chainMap, async (
49
+ { chainMap }: ChainStoreRead,
50
+ hash: Hash,
51
+ maxDepth?: number,
52
+ minDepth?: number,
53
+ ) => {
54
+ const result = await hydrateBlock({ chainMap }, hash, maxDepth, minDepth)
55
+ return asSignedHydratedBlockWithHashMeta(result, true)
56
+ }, 200)
57
+ return this._signedHydratedBlockCache
58
+ }
59
+
60
+ protected get payloadCache(): PayloadMap<WithHashMeta<Payload>> {
61
+ if (this._payloadCache) return this._payloadCache
62
+ this._payloadCache = new LruCacheMap<Hash, WithHashMeta<Payload>>({ max: 10_000 })
63
+ return this._payloadCache
64
+ }
65
+
66
+ static override async paramsHandler(params: Partial<SimpleBlockViewerParams>) {
67
+ assertEx(params.context, () => 'context is required')
68
+ assertEx(params.finalizedArchivist, () => 'finalizedArchivist is required')
69
+
70
+ return { ...await super.paramsHandler(params) }
71
+ }
72
+
73
+ async blockByHash(hash: Hash): Promise<SignedHydratedBlockWithHashMeta | null> {
74
+ return await spanRootAsync('blockByHash', async () => {
75
+ const cache = this.hydratedBlockCache
76
+ return await cache.get(hash)
77
+ }, this.tracer)
78
+ }
79
+
80
+ async blockByNumber(blockNumber: XL1BlockNumber): Promise<SignedHydratedBlockWithHashMeta | null> {
81
+ return await spanRootAsync('blockByNumber', async () => {
82
+ return asSignedHydratedBlockWithHashMeta(await hydratedBlockByNumber(this.context, blockNumber)) ?? null
83
+ }, this.tracer)
84
+ }
85
+
86
+ async blocksByHash(hash: Hash, limit = 50): Promise<SignedHydratedBlockWithHashMeta[]> {
87
+ return await spanRootAsync('blocksByHash', async () => {
88
+ assertEx(limit > 0, () => 'limit must be greater than 0')
89
+ assertEx(limit <= 100, () => 'limit must be less than 100')
90
+ const blocks: SignedHydratedBlockWithHashMeta[] = []
91
+ let current = await this.blockByHash(hash)
92
+ while (current && blocks.length < limit) {
93
+ blocks.push(current)
94
+ const previousHash = current[0].previous
95
+ if (previousHash === null) break
96
+ current = await this.blockByHash(previousHash)
97
+ }
98
+ return blocks.map(b => asSignedHydratedBlockWithHashMeta(b, true))
99
+ }, this.tracer)
100
+ }
101
+
102
+ async blocksByNumber(blockNumber: XL1BlockNumber, limit = 50): Promise<SignedHydratedBlockWithHashMeta[]> {
103
+ return await spanRootAsync('blocksByHash', async () => {
104
+ assertEx(limit > 0, () => 'limit must be greater than 0')
105
+ assertEx(limit <= 100, () => 'limit must be less than 100')
106
+ const blocks: SignedHydratedBlockWithHashMeta[] = []
107
+ let current = await this.blockByNumber(blockNumber)
108
+ while (current && blocks.length < limit) {
109
+ blocks.push(current)
110
+ if (current[0].block === 0) break
111
+ const previousNumber = asXL1BlockNumber(current[0].block - 1, true)
112
+ current = await this.blockByNumber(previousNumber)
113
+ }
114
+ return blocks.map(b => asSignedHydratedBlockWithHashMeta(b, true))
115
+ }, this.tracer)
116
+ }
117
+
118
+ async currentBlock(): Promise<SignedHydratedBlockWithHashMeta> {
119
+ return await spanRootAsync('currentBlock', async () => {
120
+ const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
121
+ const cache = this.hydratedBlockCache
122
+ const block = await cache.get(currentHead._hash)
123
+ if (!block) {
124
+ console.log(`Could not find current block with hash ${currentHead!._hash}`)
125
+ }
126
+ return assertEx(block, () => 'Could not find current block')
127
+ }, this.tracer)
128
+ }
129
+
130
+ async currentBlockHash(): Promise<Hash> {
131
+ return await spanRootAsync('currentBlockHash', async () => {
132
+ const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
133
+ return currentHead._hash
134
+ }, this.tracer)
135
+ }
136
+
137
+ async currentBlockNumber(): Promise<XL1BlockNumber> {
138
+ return await spanRootAsync('currentBlockNumber', async () => {
139
+ const currentHead = assertEx(await this.getCurrentHead(), () => 'Could not find most recent block')
140
+ return asXL1BlockNumber(currentHead.block, { name: 'currentBlockNumber' })
141
+ }, this.tracer)
142
+ }
143
+
144
+ async payloadByHash(hash: Hash): Promise<WithHashMeta<Payload> | null> {
145
+ const cachedPayload = await this.payloadCache.get(hash)
146
+ if (cachedPayload) {
147
+ return cachedPayload
148
+ } else {
149
+ const [result] = await this.finalizedArchivist.get([hash])
150
+ if (isDefined(result)) {
151
+ await this.payloadCache.set(hash, result)
152
+ }
153
+ return result ?? null
154
+ }
155
+ }
156
+
157
+ async payloadsByHash(hashes: Hash[]): Promise<WithHashMeta<Payload>[]> {
158
+ let remainingHashes = [...hashes]
159
+ const cachedPayloads = await this.payloadCache.getMany(remainingHashes)
160
+ const cachedHashes = new Set(cachedPayloads.map(p => p._hash))
161
+ remainingHashes = remainingHashes.filter(h => !cachedHashes.has(h))
162
+ const remainingPayloads = remainingHashes.length > 0
163
+ ? await this.finalizedArchivist.get(remainingHashes)
164
+ : []
165
+ return [...cachedPayloads, ...remainingPayloads.filter(exists)]
166
+ }
167
+
168
+ protected async getCurrentHead() {
169
+ const chainArchivist = this.finalizedArchivist
170
+ return await findMostRecentBlock(chainArchivist)
171
+ }
172
+ }
@@ -0,0 +1 @@
1
+ export * from './SimpleBlockViewer.ts'
@@ -0,0 +1,34 @@
1
+ import {
2
+ AbstractCreatable,
3
+ creatable, CreatableParams, Promisable,
4
+ } from '@xylabs/sdk-js'
5
+ import { AttoXL1, XL1BlockNumber } from '@xyo-network/xl1-protocol'
6
+
7
+ import { rewardFromBlockNumber } from '../../primitives/index.ts'
8
+ import { BlockRewardViewer } from '../../viewers/index.ts'
9
+
10
+ export interface SimpleBlockRewardViewerParams extends CreatableParams {
11
+ creatorReward: AttoXL1
12
+ initialReward: AttoXL1
13
+ minRewardPerBlock: AttoXL1
14
+ stepFactorDenominator: bigint
15
+ stepFactorNumerator: bigint
16
+ stepSize: XL1BlockNumber
17
+ }
18
+
19
+ @creatable()
20
+ export class SimpleBlockRewardViewer extends AbstractCreatable<SimpleBlockRewardViewerParams> implements BlockRewardViewer {
21
+ protected rewardFromBlockNumber = rewardFromBlockNumber(18)
22
+
23
+ allowedRewardForBlock(block: XL1BlockNumber): Promisable<AttoXL1> {
24
+ return this.rewardFromBlockNumber(
25
+ block,
26
+ this.params.initialReward,
27
+ this.params.stepSize,
28
+ this.params.stepFactorNumerator,
29
+ this.params.stepFactorDenominator,
30
+ this.params.minRewardPerBlock,
31
+ this.params.creatorReward,
32
+ )
33
+ }
34
+ }
@@ -0,0 +1 @@
1
+ export * from './SimpleBlockRewardViewer.ts'