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

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 (100) hide show
  1. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts +6 -5
  2. package/dist/neutral/CreatableProvider/AbstractCreatableProvider.d.ts.map +1 -1
  3. package/dist/neutral/CreatableProvider/CreatableProvider.d.ts +5 -5
  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.map +1 -1
  7. package/dist/neutral/CreatableProvider/ProviderFactoryLocator.d.ts.map +1 -1
  8. package/dist/neutral/config/Config.d.ts +2 -2
  9. package/dist/neutral/config/Services.d.ts +2 -2
  10. package/dist/neutral/config/Services.d.ts.map +1 -1
  11. package/dist/neutral/index.mjs +537 -211
  12. package/dist/neutral/index.mjs.map +1 -1
  13. package/dist/neutral/model/ChainQualification.d.ts +42 -0
  14. package/dist/neutral/model/ChainQualification.d.ts.map +1 -0
  15. package/dist/neutral/model/index.d.ts +1 -1
  16. package/dist/neutral/model/index.d.ts.map +1 -1
  17. package/dist/neutral/primitives/chain/getWindowedChain.d.ts +26 -0
  18. package/dist/neutral/primitives/chain/getWindowedChain.d.ts.map +1 -0
  19. package/dist/neutral/primitives/chain/index.d.ts +1 -0
  20. package/dist/neutral/primitives/chain/index.d.ts.map +1 -1
  21. package/dist/neutral/primitives/index.d.ts +1 -0
  22. package/dist/neutral/primitives/index.d.ts.map +1 -1
  23. package/dist/neutral/primitives/rewards/networkStakeStepRewardPositionWeight.d.ts +1 -1
  24. package/dist/neutral/primitives/uncle/findBestUncle.d.ts +24 -0
  25. package/dist/neutral/primitives/uncle/findBestUncle.d.ts.map +1 -0
  26. package/dist/neutral/primitives/uncle/findUncles.d.ts +26 -0
  27. package/dist/neutral/primitives/uncle/findUncles.d.ts.map +1 -0
  28. package/dist/neutral/primitives/uncle/index.d.ts +4 -0
  29. package/dist/neutral/primitives/uncle/index.d.ts.map +1 -0
  30. package/dist/neutral/primitives/uncle/scoreUncle.d.ts +3 -0
  31. package/dist/neutral/primitives/uncle/scoreUncle.d.ts.map +1 -0
  32. package/dist/neutral/provider/viewer/XyoViewer.d.ts +7 -5
  33. package/dist/neutral/provider/viewer/XyoViewer.d.ts.map +1 -1
  34. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts +61 -10
  35. package/dist/neutral/simple/accountBalance/SimpleAccountBalanceViewer.d.ts.map +1 -1
  36. package/dist/neutral/simple/blockValidation/SimpleBlockValidationViewer.d.ts +31 -0
  37. package/dist/neutral/simple/blockValidation/SimpleBlockValidationViewer.d.ts.map +1 -0
  38. package/dist/neutral/simple/blockValidation/index.d.ts +2 -0
  39. package/dist/neutral/simple/blockValidation/index.d.ts.map +1 -0
  40. package/dist/neutral/simple/datalake/AbstractSimpleDataLake.d.ts +1 -1
  41. package/dist/neutral/simple/datalake/AbstractSimpleDataLake.d.ts.map +1 -1
  42. package/dist/neutral/simple/datalake/SimpleDataLakeViewer.d.ts.map +1 -1
  43. package/dist/neutral/simple/index.d.ts +1 -0
  44. package/dist/neutral/simple/index.d.ts.map +1 -1
  45. package/dist/neutral/simple/timesync/SimpleTimeSyncViewer.d.ts.map +1 -1
  46. package/dist/neutral/summary/model/summary.d.ts +0 -1
  47. package/dist/neutral/summary/model/summary.d.ts.map +1 -1
  48. package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts +2 -2
  49. package/dist/neutral/summary/primitives/balances/balancesSummary.d.ts.map +1 -1
  50. package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts +2 -2
  51. package/dist/neutral/summary/primitives/schemas/schemasSummary.d.ts.map +1 -1
  52. package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts +2 -2
  53. package/dist/neutral/summary/primitives/transfers/transfersSummary.d.ts.map +1 -1
  54. package/dist/neutral/viewers/AccountBalance.d.ts +35 -15
  55. package/dist/neutral/viewers/AccountBalance.d.ts.map +1 -1
  56. package/dist/neutral/viewers/BlockValidation.d.ts +54 -0
  57. package/dist/neutral/viewers/BlockValidation.d.ts.map +1 -0
  58. package/dist/neutral/viewers/StakeIntent.d.ts +2 -2
  59. package/dist/neutral/viewers/StakeIntent.d.ts.map +1 -1
  60. package/dist/neutral/viewers/TransactionValidation.d.ts +35 -0
  61. package/dist/neutral/viewers/TransactionValidation.d.ts.map +1 -0
  62. package/dist/neutral/viewers/index.d.ts +2 -0
  63. package/dist/neutral/viewers/index.d.ts.map +1 -1
  64. package/package.json +3 -3
  65. package/src/CreatableProvider/AbstractCreatableProvider.ts +22 -6
  66. package/src/CreatableProvider/CreatableProvider.ts +5 -5
  67. package/src/CreatableProvider/CreatableProviderRegistry.ts +1 -0
  68. package/src/CreatableProvider/ProviderFactory.ts +3 -2
  69. package/src/CreatableProvider/ProviderFactoryLocator.ts +2 -1
  70. package/src/config/Services.ts +4 -2
  71. package/src/model/ChainQualification.ts +33 -0
  72. package/src/model/index.ts +1 -1
  73. package/src/primitives/chain/getWindowedChain.ts +23 -0
  74. package/src/primitives/chain/index.ts +1 -0
  75. package/src/primitives/index.ts +1 -0
  76. package/src/primitives/rewards/networkStakeStepRewardPositionWeight.ts +1 -1
  77. package/src/primitives/uncle/findBestUncle.ts +8 -0
  78. package/src/primitives/uncle/findUncles.ts +75 -0
  79. package/src/primitives/uncle/index.ts +3 -0
  80. package/src/primitives/uncle/scoreUncle.ts +6 -0
  81. package/src/provider/viewer/XyoViewer.ts +7 -7
  82. package/src/simple/accountBalance/SimpleAccountBalanceViewer.ts +46 -30
  83. package/src/simple/blockValidation/SimpleBlockValidationViewer.ts +126 -0
  84. package/src/simple/blockValidation/index.ts +1 -0
  85. package/src/simple/datalake/AbstractSimpleDataLake.ts +2 -1
  86. package/src/simple/datalake/SimpleDataLakeViewer.ts +0 -1
  87. package/src/simple/index.ts +1 -0
  88. package/src/simple/timesync/SimpleTimeSyncViewer.ts +1 -1
  89. package/src/summary/model/summary.ts +0 -1
  90. package/src/summary/primitives/balances/balancesSummary.ts +12 -12
  91. package/src/summary/primitives/schemas/schemasSummary.ts +12 -10
  92. package/src/summary/primitives/transfers/transfersSummary.ts +14 -16
  93. package/src/viewers/AccountBalance.ts +22 -14
  94. package/src/viewers/BlockValidation.ts +47 -0
  95. package/src/viewers/StakeIntent.ts +2 -2
  96. package/src/viewers/TransactionValidation.ts +35 -0
  97. package/src/viewers/index.ts +2 -0
  98. package/dist/neutral/model/Qualified.d.ts +0 -6
  99. package/dist/neutral/model/Qualified.d.ts.map +0 -1
  100. package/src/model/Qualified.ts +0 -9
@@ -2,6 +2,7 @@ import type { Address, Hash } from '@xylabs/sdk-js'
2
2
  import {
3
3
  asHash,
4
4
  assertEx, exists, isDefined, spanRootAsync,
5
+ ZERO_ADDRESS,
5
6
  } from '@xylabs/sdk-js'
6
7
  import type { WithHashMeta, WithStorageMeta } from '@xyo-network/payload-model'
7
8
  import type {
@@ -16,7 +17,9 @@ import {
16
17
  import { deepCalculateFramesFromRange } from '../../block/index.ts'
17
18
  import type { CreatableProviderParams } from '../../CreatableProvider/index.ts'
18
19
  import { AbstractCreatableProvider, creatableProvider } from '../../CreatableProvider/index.ts'
19
- import type { Qualified } from '../../model/index.ts'
20
+ import {
21
+ ChainQualification, type ChainQualified, isChainQualifiedHeadConfig, isChainQualifiedRangeConfig,
22
+ } from '../../model/index.ts'
20
23
  import type {
21
24
  BalanceStepSummaryContext,
22
25
  TransfersStepSummary,
@@ -27,6 +30,7 @@ import {
27
30
  transfersStepSummaryFromRange,
28
31
  } from '../../summary/index.ts'
29
32
  import {
33
+ AccountBalanceConfig,
30
34
  type AccountBalanceHistoryItem, type AccountBalanceViewer, AccountBalanceViewerMoniker,
31
35
  type BlockViewer,
32
36
  BlockViewerMoniker,
@@ -64,17 +68,17 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
64
68
  return await super.paramsHandler({ ...params })
65
69
  }
66
70
 
67
- async accountBalance(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AttoXL1> {
68
- const balances = await this.accountBalances([address], headOrRange)
71
+ async accountBalance(address: Address, config?: AccountBalanceConfig) {
72
+ const balances = await this.accountBalances([address], config)
69
73
  return balances[address] ?? AttoXL1(0n)
70
74
  }
71
75
 
72
- accountBalanceHistories(_addresses: Address[], _rangeOrHash?: XL1BlockRange | Hash): Promise<Record<Address, AccountBalanceHistoryItem[]>> {
73
- throw new Error('Method [accountBalanceHistories] not implemented.')
76
+ async accountBalanceHistories(addresses: Address[], config: AccountBalanceConfig = {}) {
77
+ return (await this.qualifiedAccountBalanceHistories(addresses, config))[0]
74
78
  }
75
79
 
76
- async accountBalanceHistory(address: Address, headOrRange?: XL1BlockRange | Hash): Promise<AccountBalanceHistoryItem[]> {
77
- const range = asRange(headOrRange)
80
+ async accountBalanceHistory(address: Address, config?: AccountBalanceConfig) {
81
+ const range = isChainQualifiedRangeConfig(config) ? config.range : undefined
78
82
  const startingRange = asXL1BlockRange(range ?? [0, await this.blockViewer.currentBlockNumber()], true)
79
83
  const blockNumbers = await this.distillTransferHistory(address, startingRange)
80
84
  const blocks = (await Promise.all(blockNumbers.map(async bn => await this.blockViewer.blockByNumber(bn)))).filter(exists)
@@ -101,8 +105,8 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
101
105
  return result
102
106
  }
103
107
 
104
- async accountBalances(address: Address[], _headOrRange?: XL1BlockRange | Hash): Promise<Record<Address, AttoXL1>> {
105
- const [result] = (await this.qualifiedAccountBalances(address, _headOrRange))
108
+ async accountBalances(address: Address[], config?: AccountBalanceConfig) {
109
+ const [result] = (await this.qualifiedAccountBalances(address, config ?? {}))
106
110
  return result
107
111
  }
108
112
 
@@ -113,57 +117,69 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
113
117
 
114
118
  async qualifiedAccountBalanceHistories(
115
119
  addresses: Address[],
116
- headOrRange?: Hash | XL1BlockRange,
117
- ): Promise<Qualified<Record<Address, AccountBalanceHistoryItem[]>>> {
118
- const head = asHash(headOrRange) ?? await this.blockViewer.currentBlockHash()
119
- const range = asXL1BlockRange(headOrRange) ?? asXL1BlockRange([0,
120
- assertEx(
121
- await this.blockViewer.blockByHash(head),
122
- () => `Error: Could not find block with hash ${head}`,
123
- )[0].block])
124
- const qualifiedEntries: [Address, Qualified<AccountBalanceHistoryItem[]>][] = await Promise.all(addresses.map(async address => ([
120
+ config: AccountBalanceConfig,
121
+ ) {
122
+ const head = isChainQualifiedHeadConfig(config) ? config.head : await this.blockViewer.currentBlockHash()
123
+ const range = isChainQualifiedRangeConfig(config)
124
+ ? config.range
125
+ : asXL1BlockRange([0,
126
+ assertEx(
127
+ await this.blockViewer.blockByHash(head),
128
+ () => `Error: Could not find block with hash ${head}`,
129
+ )[0].block])
130
+ const qualifiedEntries = await Promise.all(addresses.map(async address => ([
125
131
  address,
126
132
  await this.qualifiedAccountBalanceHistory(address, range),
127
- ])))
133
+ ]))) satisfies [Address, ChainQualified<AccountBalanceHistoryItem[]>][]
128
134
 
129
135
  const entries = qualifiedEntries.map(([address, [history]]) => {
130
136
  return [address, history]
131
137
  })
132
- const qualifiedRange = qualifiedEntries[0][1][1]
133
- const qualifiedHeadHash = qualifiedEntries[0][1][2]
138
+ const qualifiedRange = qualifiedEntries[0][1][1].range
139
+ const qualifiedHeadHash = qualifiedEntries[0][1][1].head
134
140
 
135
141
  // check for drift
136
- for (const [_, [__, range, headHash]] of qualifiedEntries) {
142
+ for (const [_, [__, { range, head }]] of qualifiedEntries) {
137
143
  assertEx(
138
144
  range[0] === qualifiedRange[0] && range[1] === qualifiedRange[1],
139
145
  () => 'Inconsistent ranges in qualifiedAccountBalanceHistories',
140
146
  )
141
147
  assertEx(
142
- headHash === qualifiedHeadHash,
148
+ head === qualifiedHeadHash,
143
149
  () => 'Inconsistent head hashes in qualifiedAccountBalanceHistories',
144
150
  )
145
151
  }
146
152
 
147
- return [Object.fromEntries(entries), qualifiedRange, qualifiedHeadHash]
153
+ return [Object.fromEntries(entries), { range: qualifiedRange, head: qualifiedHeadHash }] satisfies
154
+ [Record<Address, AccountBalanceHistoryItem[]>, ChainQualification]
148
155
  }
149
156
 
150
157
  async qualifiedAccountBalances(
151
158
  address: Address[],
152
- _headOrRange?: Hash | XL1BlockRange,
153
- ): Promise<Qualified<Record<Address, AttoXL1>>> {
159
+ config: AccountBalanceConfig,
160
+ ): Promise<ChainQualified<Record<Address, AttoXL1>>> {
154
161
  return await spanRootAsync('qualifiedAccountsBalances', async () => {
155
162
  const qualifiedSummary = await balancesSummary(
156
- this.balanceSummaryContext,
163
+ { ...this.balanceSummaryContext },
164
+ config,
157
165
  )
158
166
  const result: Record<Address, AttoXL1> = {}
159
167
  for (const addr of address) {
160
168
  const summaryBalance = qualifiedSummary[0][addr] ?? 0n
161
169
  result[addr] = AttoXL1(summaryBalance < 0n ? 0n : summaryBalance)
162
170
  }
163
- return [result, qualifiedSummary[1], qualifiedSummary[2]]
171
+ return [result, qualifiedSummary[1]]
164
172
  })
165
173
  }
166
174
 
175
+ override async startHandler() {
176
+ await super.startHandler()
177
+ await Promise.all([
178
+ this.accountBalance(ZERO_ADDRESS),
179
+ this.accountBalanceHistory(ZERO_ADDRESS),
180
+ ])
181
+ }
182
+
167
183
  private async distillTransferHistory(address: Address, range: XL1BlockRange, max: number = 50): Promise<XL1BlockNumber[]> {
168
184
  if ((range[1] - range[0]) <= StepSizes[0] || max <= 1) {
169
185
  return Array.from({ length: range[1] - range[0] + 1 }, (_, i) => range[1] - i).slice(0, max).map(n => asXL1BlockNumber(n, true))
@@ -205,7 +221,7 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
205
221
  private async qualifiedAccountBalanceHistory(
206
222
  address: Address,
207
223
  headOrRange?: Hash | XL1BlockRange,
208
- ): Promise<Qualified<AccountBalanceHistoryItem[]>> {
224
+ ): Promise<ChainQualified<AccountBalanceHistoryItem[]>> {
209
225
  const range = asRange(headOrRange)
210
226
  const headHash = asHash(headOrRange)
211
227
  const [head] = assertEx(isDefined(headHash)
@@ -234,6 +250,6 @@ export class SimpleAccountBalanceViewer extends AbstractCreatableProvider<Simple
234
250
  null,
235
251
  transfer] satisfies AccountBalanceHistoryItem))
236
252
  }
237
- return [result, startingRange, head._hash]
253
+ return [result, { range: startingRange, head: head._hash }]
238
254
  }
239
255
  }
@@ -0,0 +1,126 @@
1
+ import { exists } from '@xylabs/sdk-js'
2
+ import {
3
+ asXL1BlockRange,
4
+ ChainId,
5
+ type SignedHydratedBlockWithHashMeta,
6
+ } from '@xyo-network/xl1-protocol'
7
+
8
+ import type { CreatableProviderParams } from '../../CreatableProvider/index.ts'
9
+ import { AbstractCreatableProvider, creatableProvider } from '../../CreatableProvider/index.ts'
10
+ import { findUncles, getWindowedChain } from '../../primitives/index.ts'
11
+ import type {
12
+ HydratedBlockStateValidationFunction, HydratedBlockValidationError, HydratedBlockValidationFunction,
13
+ } from '../../validation/index.ts'
14
+ import type {
15
+ AccountBalanceViewer,
16
+ BlockValidationConfig,
17
+ BlockValidationQualification,
18
+ BlockValidationViewer,
19
+ } from '../../viewers/index.ts'
20
+ import {
21
+ AccountBalanceViewerMoniker,
22
+ BlockValidationViewerMoniker, BlockViewer, BlockViewerMoniker,
23
+ } from '../../viewers/index.ts'
24
+
25
+ export interface SimpleBlockValidationViewerParams extends CreatableProviderParams {
26
+ maxUncleWindowSize: number
27
+ state?: HydratedBlockStateValidationFunction
28
+ value?: HydratedBlockValidationFunction
29
+ }
30
+
31
+ @creatableProvider()
32
+ export class SimpleBlockValidationViewer extends AbstractCreatableProvider<SimpleBlockValidationViewerParams> implements BlockValidationViewer {
33
+ static readonly defaultMoniker = BlockValidationViewerMoniker
34
+ static readonly monikers = [BlockValidationViewerMoniker]
35
+ moniker = SimpleBlockValidationViewer.defaultMoniker
36
+
37
+ private _accountBalanceViewer!: AccountBalanceViewer
38
+ private _blockViewer!: BlockViewer
39
+ private _uncleWindowedChainCache: SignedHydratedBlockWithHashMeta[] | null = null
40
+
41
+ protected get blockViewer() {
42
+ return this._blockViewer
43
+ }
44
+
45
+ protected get maxUncleWindowSize() {
46
+ return this.params.maxUncleWindowSize
47
+ }
48
+
49
+ static override async paramsHandler(params: Partial<SimpleBlockValidationViewerParams>): Promise<SimpleBlockValidationViewerParams> {
50
+ return {
51
+ ...await super.paramsHandler(params),
52
+ maxUncleWindowSize: params.maxUncleWindowSize ?? 100,
53
+ } satisfies SimpleBlockValidationViewerParams
54
+ }
55
+
56
+ override async createHandler() {
57
+ await super.createHandler()
58
+ this._accountBalanceViewer = await this.locator.getInstance<AccountBalanceViewer>(AccountBalanceViewerMoniker)
59
+ this._blockViewer = await this.locator.getInstance<BlockViewer>(BlockViewerMoniker)
60
+ }
61
+
62
+ async qualifiedValidateBlock(
63
+ block: SignedHydratedBlockWithHashMeta,
64
+ config?: BlockValidationConfig,
65
+ ): Promise<[HydratedBlockValidationError[], BlockValidationQualification]> {
66
+ return (await this.qualifiedValidateBlocks([block], config))
67
+ }
68
+
69
+ async qualifiedValidateBlocks(
70
+ blocks: SignedHydratedBlockWithHashMeta[],
71
+ config?: BlockValidationConfig,
72
+ ): Promise<[HydratedBlockValidationError[], BlockValidationQualification]> {
73
+ const { value, state } = config ?? {
74
+ shape: true, links: true, state: true,
75
+ }
76
+
77
+ const [headBlock] = await this.blockViewer.currentBlock()
78
+ const chainId = headBlock.chain
79
+
80
+ const validateValue = value ? this.doValidateValue.bind(this) : undefined
81
+ const validateState = state ? this.doValidateState.bind(this) : undefined
82
+
83
+ return [(await Promise.all([
84
+ validateValue?.(blocks, chainId), validateState?.(blocks, chainId),
85
+ ].filter(exists))).flat(), { head: headBlock._hash, range: asXL1BlockRange([0, headBlock.block], true) }]
86
+ }
87
+
88
+ async validateBlock(block: SignedHydratedBlockWithHashMeta, config?: BlockValidationConfig): Promise<HydratedBlockValidationError[]> {
89
+ return (await this.validateBlocks([block], config))
90
+ }
91
+
92
+ async validateBlocks(blocks: SignedHydratedBlockWithHashMeta[], config?: BlockValidationConfig): Promise<HydratedBlockValidationError[]> {
93
+ return (await this.qualifiedValidateBlocks(blocks, config))[0]
94
+ }
95
+
96
+ private async doValidateState(blocks: SignedHydratedBlockWithHashMeta[], chainId: ChainId): Promise<HydratedBlockValidationError[]> {
97
+ const windowedUncleChain = await this.updateWindowedChainCache()
98
+
99
+ const uncles = findUncles(this.context, windowedUncleChain, blocks)
100
+
101
+ if (uncles.length !== 1) {
102
+ throw new Error(`No uncles or greater than one uncle found in block validation, which is not supported [${uncles.length}]`)
103
+ }
104
+ return (await Promise.all(uncles[0].map(async (block) => {
105
+ return await this.params.state!(
106
+ block,
107
+ chainId,
108
+ { accountBalance: this._accountBalanceViewer },
109
+ )
110
+ }))).flat()
111
+ }
112
+
113
+ private async doValidateValue(blocks: SignedHydratedBlockWithHashMeta[], chainId: ChainId): Promise<HydratedBlockValidationError[]> {
114
+ return (await Promise.all(blocks.map(async (block) => {
115
+ return await this.params.value!(
116
+ block,
117
+ chainId,
118
+ )
119
+ }))).flat()
120
+ }
121
+
122
+ private async updateWindowedChainCache() {
123
+ this._uncleWindowedChainCache = await getWindowedChain(this.blockViewer, this.maxUncleWindowSize, this._uncleWindowedChainCache ?? [])
124
+ return [...this._uncleWindowedChainCache]
125
+ }
126
+ }
@@ -0,0 +1 @@
1
+ export * from './SimpleBlockValidationViewer.ts'
@@ -14,7 +14,8 @@ MapTypeRead<Hash, DataLakeData> = MapTypeRead<Hash, DataLakeData>> extends
14
14
  map: TMap
15
15
  }
16
16
 
17
- export class AbstractSimpleDataLake<TParams extends AbstractSimpleDataLakeParams = AbstractSimpleDataLakeParams> extends AbstractCreatableProvider<TParams> {
17
+ export abstract class AbstractSimpleDataLake<TParams extends AbstractSimpleDataLakeParams = AbstractSimpleDataLakeParams> extends
18
+ AbstractCreatableProvider<TParams> {
18
19
  get allowedSchemas(): Schema[] | undefined {
19
20
  return this.params.allowedSchemas
20
21
  }
@@ -1,5 +1,4 @@
1
1
  import type { Hash } from '@xylabs/sdk-js'
2
- import { isAnyPayload } from '@xyo-network/payload-model'
3
2
 
4
3
  import { creatableProvider } from '../../CreatableProvider/index.ts'
5
4
  import type { MapTypeRead } from '../../map/index.ts'
@@ -1,6 +1,7 @@
1
1
  export * from './accountBalance/index.ts'
2
2
  export * from './block/index.ts'
3
3
  export * from './blockReward/index.ts'
4
+ export * from './blockValidation/index.ts'
4
5
  export * from './chainStake/index.ts'
5
6
  export * from './client/index.ts'
6
7
  export * from './datalake/index.ts'
@@ -1,4 +1,4 @@
1
- import type { Hash, Promisable } from '@xylabs/sdk-js'
1
+ import type { Hash } from '@xylabs/sdk-js'
2
2
  import {
3
3
  asHash, assertEx, isDefined,
4
4
  } from '@xylabs/sdk-js'
@@ -13,7 +13,6 @@ export interface ChainSummaryContextBase<TPayload extends Payload,
13
13
  T extends (MapTypeRead<string, TPayload>)> extends BaseContext {
14
14
  stepSemaphores: Semaphore[]
15
15
  summaryMap: T
16
- windowSize?: number
17
16
  }
18
17
 
19
18
  export interface ChainSummaryContextRead<T extends Payload> extends ChainSummaryContextBase<T, MapTypeRead<string, T>>, ChainContextRead {}
@@ -1,27 +1,27 @@
1
1
  import type { Address } from '@xylabs/sdk-js'
2
- import {
3
- asAddress, isDefined, spanRootAsync,
4
- } from '@xylabs/sdk-js'
5
- import {
6
- asBlockBoundWitnessWithStorageMeta, asXL1BlockNumber, asXL1BlockRange,
7
- } from '@xyo-network/xl1-protocol'
2
+ import { asAddress, spanRootAsync } from '@xylabs/sdk-js'
3
+ import { asBlockBoundWitnessWithStorageMeta, asXL1BlockRange } from '@xyo-network/xl1-protocol'
8
4
 
9
5
  import { deepCalculateFramesFromRange } from '../../../block/index.ts'
10
- import type { Qualified } from '../../../model/index.ts'
6
+ import {
7
+ type ChainQualified, type ChainQualifiedConfig, isChainQualifiedHeadConfig,
8
+ isChainQualifiedRangeConfig,
9
+ } from '../../../model/index.ts'
11
10
  import { parseSignedBigInt } from '../../../SignedBigInt.ts'
12
11
  import type { BalanceStepSummaryContext } from '../../model/index.ts'
13
12
  import { balancesStepSummaryFromRange } from './balancesStepSummaryFromRange.ts'
14
13
 
15
14
  export async function balancesSummary(
16
15
  context: BalanceStepSummaryContext,
17
- ): Promise<Qualified<Record<Address, bigint>>> {
16
+ config?: ChainQualifiedConfig,
17
+ ): Promise<ChainQualified<Record<Address, bigint>>> {
18
18
  return await spanRootAsync('balancesSummary', async () => {
19
- const [headHash] = await context.head()
19
+ const [headHash] = isChainQualifiedHeadConfig(config) ? [config.head] : await context.head()
20
20
  const headResult = await context.store.chainMap.get(headHash)
21
21
  const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${headHash}`)
22
- const rangeStart = asXL1BlockNumber(isDefined(context.windowSize) ? Math.max(headBoundWitness.block - context.windowSize + 1, 0) : 0, true)
22
+ const range = isChainQualifiedRangeConfig(config) ? config.range : asXL1BlockRange([0, headBoundWitness.block], true)
23
23
  const ranges = deepCalculateFramesFromRange(asXL1BlockRange(
24
- [rangeStart, headBoundWitness.block],
24
+ range,
25
25
  { name: 'balancesSummary' },
26
26
  ))
27
27
  const summaries = await Promise.all(ranges.map(range => balancesStepSummaryFromRange(context, range)))
@@ -32,6 +32,6 @@ export async function balancesSummary(
32
32
  balances[validAddress] = (balances[validAddress] ?? 0n) + parseSignedBigInt(balance)
33
33
  }
34
34
  }
35
- return [balances, [rangeStart, headBoundWitness.block], headHash]
35
+ return [balances, { range, head: headHash }]
36
36
  })
37
37
  }
@@ -1,24 +1,26 @@
1
- import { isDefined, spanRootAsync } from '@xylabs/sdk-js'
1
+ import { spanRootAsync } from '@xylabs/sdk-js'
2
2
  import type { Schema } from '@xyo-network/payload-model'
3
- import {
4
- asBlockBoundWitnessWithStorageMeta, asXL1BlockNumber, asXL1BlockRange,
5
- } from '@xyo-network/xl1-protocol'
3
+ import { asBlockBoundWitnessWithStorageMeta, asXL1BlockRange } from '@xyo-network/xl1-protocol'
6
4
 
7
5
  import { deepCalculateFramesFromRange } from '../../../block/index.ts'
8
- import type { Qualified } from '../../../model/index.ts'
6
+ import {
7
+ type ChainQualified, type ChainQualifiedConfig, isChainQualifiedHeadConfig,
8
+ isChainQualifiedRangeConfig,
9
+ } from '../../../model/index.ts'
9
10
  import type { SchemasStepSummaryContext } from '../../model/index.ts'
10
11
  import { schemasStepSummaryFromRange } from './schemasStepSummaryFromRange.ts'
11
12
 
12
13
  export async function schemasSummary(
13
14
  context: SchemasStepSummaryContext,
14
- ): Promise<Qualified<Record<Schema, number>>> {
15
+ config?: ChainQualifiedConfig,
16
+ ): Promise<ChainQualified<Record<Schema, number>>> {
15
17
  return await spanRootAsync('schemasSummary', async () => {
16
- const [headHash] = await context.head()
18
+ const [headHash] = isChainQualifiedHeadConfig(config) ? [config.head] : await context.head()
17
19
  const headResult = await context.store.chainMap.get(headHash)
18
20
  const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${headHash}`)
19
- const rangeStart = asXL1BlockNumber(isDefined(context.windowSize) ? Math.max(headBoundWitness.block - context.windowSize + 1, 0) : 0, true)
21
+ const range = isChainQualifiedRangeConfig(config) ? config.range : asXL1BlockRange([0, headBoundWitness.block], true)
20
22
  const ranges = deepCalculateFramesFromRange(asXL1BlockRange(
21
- [rangeStart, headBoundWitness.block],
23
+ range,
22
24
  { name: 'schemasSummary' },
23
25
  ))
24
26
  const summaries = await Promise.all(ranges.map(range => schemasStepSummaryFromRange(context, range)))
@@ -28,6 +30,6 @@ export async function schemasSummary(
28
30
  results[schema] = (results[schema] ?? 0) + count
29
31
  }
30
32
  }
31
- return [results, [rangeStart, headBoundWitness.block], headHash]
33
+ return [results, { range, head: headHash }]
32
34
  })
33
35
  }
@@ -1,31 +1,29 @@
1
1
  import type { Address, Hash } from '@xylabs/sdk-js'
2
- import {
3
- asAddress, isDefined, spanRootAsync,
4
- } from '@xylabs/sdk-js'
5
- import {
6
- asBlockBoundWitnessWithStorageMeta, asXL1BlockNumber, asXL1BlockRange,
7
- } from '@xyo-network/xl1-protocol'
2
+ import { asAddress, spanRootAsync } from '@xylabs/sdk-js'
3
+ import { asBlockBoundWitnessWithStorageMeta, asXL1BlockRange } from '@xyo-network/xl1-protocol'
8
4
 
9
5
  import { deepCalculateFramesFromRange } from '../../../block/index.ts'
10
- import type { Qualified } from '../../../model/index.ts'
6
+ import type { ChainQualified, ChainQualifiedConfig } from '../../../model/index.ts'
7
+ import { isChainQualifiedHeadConfig, isChainQualifiedRangeConfig } from '../../../model/index.ts'
11
8
  import { parseSignedBigInt } from '../../../SignedBigInt.ts'
12
9
  import type { TransfersStepSummaryContext } from '../../index.ts'
13
10
  import { transfersStepSummaryFromRange } from './transfersStepSummaryFromRange.ts'
14
11
 
15
12
  // the summary of amount of rewards claimed from the step reward pool by addresses
16
13
  export async function transfersSummary(
17
- transferContext: TransfersStepSummaryContext,
18
- ): Promise<Qualified<Record<Address, Record<Address, bigint>>>> {
14
+ context: TransfersStepSummaryContext,
15
+ config?: ChainQualifiedConfig,
16
+ ): Promise<ChainQualified<Record<Address, Record<Address, bigint>>>> {
19
17
  return await spanRootAsync('transferSummary', async () => {
20
- const [headHash] = await transferContext.head()
21
- const headResult = await transferContext.store.chainMap.get(headHash)
22
- const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${transferContext.head}`)
23
- const rangeStart = asXL1BlockNumber(isDefined(transferContext.windowSize) ? Math.max(headBoundWitness.block - transferContext.windowSize + 1, 0) : 0, true)
18
+ const [headHash] = isChainQualifiedHeadConfig(config) ? [config.head] : await context.head()
19
+ const headResult = await context.store.chainMap.get(headHash)
20
+ const headBoundWitness = asBlockBoundWitnessWithStorageMeta(headResult, () => `Head block not found for hash: ${headHash}`)
21
+ const range = isChainQualifiedRangeConfig(config) ? config.range : asXL1BlockRange([0, headBoundWitness.block], true)
24
22
  const ranges = deepCalculateFramesFromRange(asXL1BlockRange(
25
- [rangeStart, headBoundWitness.block],
23
+ range,
26
24
  { name: 'transfersSummary' },
27
25
  ))
28
- const summaries = await Promise.all(ranges.map(range => transfersStepSummaryFromRange(transferContext, range)))
26
+ const summaries = await Promise.all(ranges.map(range => transfersStepSummaryFromRange(context, range)))
29
27
  const transfers: Record<Address, Record<Address, bigint>> = {}
30
28
  for (let summary of summaries) {
31
29
  for (const [from, toMap] of Object.entries(summary.transfers)) {
@@ -37,7 +35,7 @@ export async function transfersSummary(
37
35
  }
38
36
  }
39
37
  }
40
- return [transfers, [rangeStart, headBoundWitness.block], headHash]
38
+ return [transfers, { range, head: headHash }]
41
39
  })
42
40
  }
43
41
 
@@ -1,18 +1,18 @@
1
- import type {
2
- Address, Hash, Promisable,
3
- } from '@xylabs/sdk-js'
1
+ import { type Address, type Promisable } from '@xylabs/sdk-js'
2
+ import { zodIsFactory } from '@xylabs/zod'
4
3
  import { WithHashMetaZod } from '@xyo-network/payload-model'
5
4
  import {
6
5
  type AttoXL1,
7
6
  TransferZod,
8
- type XL1BlockRange,
9
7
  } from '@xyo-network/xl1-protocol'
10
8
  import { BlockBoundWitnessZod, TransactionBoundWitnessZod } from '@xyo-network/xl1-protocol'
11
9
  import z from 'zod'
12
10
 
13
- import type {
14
- Provider,
15
- Qualified,
11
+ import {
12
+ ChainQualificationZod,
13
+ type ChainQualified,
14
+ ChainQualifiedConfigZod,
15
+ type Provider,
16
16
  } from '../model/index.ts'
17
17
 
18
18
  export const AccountBalanceHistoryItemZod = z.tuple([
@@ -23,19 +23,27 @@ export const AccountBalanceHistoryItemZod = z.tuple([
23
23
 
24
24
  export type AccountBalanceHistoryItem = z.infer<typeof AccountBalanceHistoryItemZod>
25
25
 
26
+ export const AccountBalanceQualificationZod = ChainQualificationZod
27
+ export type AccountBalanceQualification = z.infer<typeof AccountBalanceQualificationZod>
28
+ export const isAccountBalanceQualification = zodIsFactory(AccountBalanceQualificationZod)
29
+
30
+ export const AccountBalanceConfigZod = ChainQualifiedConfigZod
31
+ export type AccountBalanceConfig = z.infer<typeof AccountBalanceConfigZod>
32
+ export const isAccountBalanceCOnfig = zodIsFactory(AccountBalanceConfigZod)
33
+
26
34
  export interface AccountBalanceViewerMethods {
27
35
  qualifiedAccountBalanceHistories(
28
36
  address: Address[],
29
- headOrRange?: Hash | XL1BlockRange
30
- ): Promisable<Qualified<Record<Address, AccountBalanceHistoryItem[]>>>
31
- qualifiedAccountBalances(address: Address[], headOrRange?: Hash | XL1BlockRange): Promisable<Qualified<Record<Address, AttoXL1>>>
37
+ config: AccountBalanceConfig
38
+ ): Promisable<ChainQualified<Record<Address, AccountBalanceHistoryItem[]>>>
39
+ qualifiedAccountBalances(address: Address[], config: AccountBalanceConfig): Promisable<ChainQualified<Record<Address, AttoXL1>>>
32
40
  }
33
41
 
34
42
  export interface AccountBalanceViewer extends AccountBalanceViewerMethods, Provider<AccountBalanceViewerMoniker> {
35
- accountBalance(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<AttoXL1>
36
- accountBalanceHistories(address: Address[], headOrRange?: Hash | XL1BlockRange): Promisable<Record<Address, AccountBalanceHistoryItem[]>>
37
- accountBalanceHistory(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<AccountBalanceHistoryItem[]>
38
- accountBalances(address: Address[], headOrRange?: Hash | XL1BlockRange): Promisable<Record<Address, AttoXL1>>
43
+ accountBalance(address: Address, config?: AccountBalanceConfig): Promisable<AttoXL1>
44
+ accountBalanceHistories(address: Address[], config?: AccountBalanceConfig): Promisable<Record<Address, AccountBalanceHistoryItem[]>>
45
+ accountBalanceHistory(address: Address, config?: AccountBalanceConfig): Promisable<AccountBalanceHistoryItem[]>
46
+ accountBalances(address: Address[], config?: AccountBalanceConfig): Promisable<Record<Address, AttoXL1>>
39
47
  }
40
48
 
41
49
  export const AccountBalanceViewerMoniker = 'AccountBalanceViewer' as const
@@ -0,0 +1,47 @@
1
+ import { type Promisable } from '@xylabs/sdk-js'
2
+ import { zodIsFactory } from '@xylabs/zod'
3
+ import type { HydratedBlock, SignedHydratedBlockWithHashMeta } from '@xyo-network/xl1-protocol'
4
+ import z from 'zod'
5
+
6
+ import {
7
+ ChainQualificationZod, ChainQualifiedHeadConfigZod, ChainQualifiedRangeConfigZod, type Provider,
8
+ } from '../model/index.ts'
9
+ import type { HydratedBlockValidationError } from '../validation/index.ts'
10
+
11
+ export const BlockValidationQualificationZod = ChainQualificationZod
12
+ export type BlockValidationQualification = z.infer<typeof BlockValidationQualificationZod>
13
+ export const isBlockValidationQualification = zodIsFactory(BlockValidationQualificationZod)
14
+
15
+ export const BlockValidationConfigFieldsZod = z.object({
16
+ value: z.boolean().optional(),
17
+ state: z.boolean().optional(),
18
+ })
19
+
20
+ export const BlockValidationConfigZod = z.union([
21
+ BlockValidationConfigFieldsZod.extend(ChainQualifiedHeadConfigZod.shape),
22
+ BlockValidationConfigFieldsZod.extend(ChainQualifiedRangeConfigZod.shape),
23
+ BlockValidationConfigFieldsZod,
24
+ z.object({}),
25
+ ])
26
+
27
+ export type BlockValidationConfig = z.infer<typeof BlockValidationConfigZod>
28
+ export const isBlockValidationConfig = zodIsFactory(BlockValidationConfigZod)
29
+
30
+ export interface BlockValidationViewerMethods {
31
+ qualifiedValidateBlocks(
32
+ blocks: HydratedBlock[],
33
+ config?: BlockValidationConfig
34
+ ): Promisable<[HydratedBlockValidationError[], BlockValidationQualification]>
35
+ }
36
+
37
+ export const BlockValidationViewerMoniker = 'BlockValidationViewer' as const
38
+ export type BlockValidationViewerMoniker = typeof BlockValidationViewerMoniker
39
+
40
+ export interface BlockValidationViewer extends BlockValidationViewerMethods, Provider<BlockValidationViewerMoniker> {
41
+ qualifiedValidateBlock(
42
+ block: SignedHydratedBlockWithHashMeta,
43
+ config?: BlockValidationConfig
44
+ ): Promisable<[HydratedBlockValidationError[], BlockValidationQualification]>
45
+ validateBlock(block: SignedHydratedBlockWithHashMeta, config?: BlockValidationConfig): Promisable<HydratedBlockValidationError[]>
46
+ validateBlocks(blocks: SignedHydratedBlockWithHashMeta[], config?: BlockValidationConfig): Promisable<HydratedBlockValidationError[]>
47
+ }
@@ -3,10 +3,10 @@ import type {
3
3
  } from '@xylabs/sdk-js'
4
4
  import type { ChainStakeIntent, XL1BlockRange } from '@xyo-network/xl1-protocol'
5
5
 
6
- import type { Provider, Qualified } from '../model/index.ts'
6
+ import type { ChainQualified, Provider } from '../model/index.ts'
7
7
 
8
8
  export interface StakeIntentViewerMethods {
9
- qualifiedIntentByAddress(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<Qualified<ChainStakeIntent | null>>
9
+ qualifiedIntentByAddress(address: Address, headOrRange?: Hash | XL1BlockRange): Promisable<ChainQualified<ChainStakeIntent | null>>
10
10
  }
11
11
 
12
12
  export const StakeIntentViewerMoniker = 'StakeIntentViewer' as const
@@ -0,0 +1,35 @@
1
+ import { type Promisable } from '@xylabs/sdk-js'
2
+ import { zodIsFactory } from '@xylabs/zod'
3
+ import { type HydratedTransaction, type ValidationError } from '@xyo-network/xl1-protocol'
4
+ import type z from 'zod'
5
+
6
+ import {
7
+ ChainQualificationZod, ChainQualifiedConfigZod, type Provider,
8
+ } from '../model/index.ts'
9
+
10
+ export const TransactionValidationQualificationZod = ChainQualificationZod
11
+ export type TransactionValidationQualification = z.infer<typeof TransactionValidationQualificationZod>
12
+ export const isTransactionValidationQualification = zodIsFactory(TransactionValidationQualificationZod)
13
+
14
+ export const TransactionValidationConfigZod = ChainQualifiedConfigZod
15
+ export type TransactionValidationConfig = z.infer<typeof TransactionValidationConfigZod>
16
+ export const isTransactionValidationConfig = zodIsFactory(TransactionValidationConfigZod)
17
+
18
+ export interface TransactionValidationViewerMethods {
19
+ qualifiedValidateTransactions(
20
+ transactions: HydratedTransaction[],
21
+ config?: TransactionValidationConfig
22
+ ): Promisable<[ValidationError[][], TransactionValidationQualification]>
23
+ }
24
+
25
+ export const TransactionValidationViewerMoniker = 'TransactionValidationViewer' as const
26
+ export type TransactionValidationViewerMoniker = typeof TransactionValidationViewerMoniker
27
+
28
+ export interface TransactionValidationViewer extends TransactionValidationViewerMethods, Provider<TransactionValidationViewerMoniker> {
29
+ qualifiedValidateTransaction(
30
+ transaction: HydratedTransaction,
31
+ config?: TransactionValidationConfig
32
+ ): Promisable<[ValidationError[], TransactionValidationQualification]>
33
+ validateTransaction(transaction: HydratedTransaction[], config?: TransactionValidationConfig): Promisable<ValidationError[]>
34
+ validateTransactions(transactions: HydratedTransaction[], config?: TransactionValidationConfig): Promisable<ValidationError[][]>
35
+ }