@xyo-network/chain-services 1.14.1 → 1.14.3

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 (36) hide show
  1. package/dist/neutral/AccountBalance/BaseAccountBalanceService.d.ts.map +1 -1
  2. package/dist/neutral/BaseService.d.ts +5 -3
  3. package/dist/neutral/BaseService.d.ts.map +1 -1
  4. package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts +5 -1
  5. package/dist/neutral/BlockProducer/BaseBlockProducerService.d.ts.map +1 -1
  6. package/dist/neutral/BlockReward/spec/MemoryBlockRewardService.spec.d.ts +2 -0
  7. package/dist/neutral/BlockReward/spec/MemoryBlockRewardService.spec.d.ts.map +1 -0
  8. package/dist/neutral/Bridge/BaseBridgeService.d.ts +15 -0
  9. package/dist/neutral/Bridge/BaseBridgeService.d.ts.map +1 -0
  10. package/dist/neutral/Bridge/index.d.ts +2 -0
  11. package/dist/neutral/Bridge/index.d.ts.map +1 -0
  12. package/dist/neutral/StepStake/BaseStepStakeService.d.ts +14 -0
  13. package/dist/neutral/StepStake/BaseStepStakeService.d.ts.map +1 -0
  14. package/dist/neutral/StepStake/index.d.ts +2 -0
  15. package/dist/neutral/StepStake/index.d.ts.map +1 -0
  16. package/dist/neutral/Time/BaseTimeSyncService.d.ts +22 -0
  17. package/dist/neutral/Time/BaseTimeSyncService.d.ts.map +1 -0
  18. package/dist/neutral/Time/index.d.ts +2 -0
  19. package/dist/neutral/Time/index.d.ts.map +1 -0
  20. package/dist/neutral/index.d.ts +3 -0
  21. package/dist/neutral/index.d.ts.map +1 -1
  22. package/dist/neutral/index.mjs +232 -58
  23. package/dist/neutral/index.mjs.map +1 -1
  24. package/package.json +24 -24
  25. package/src/AccountBalance/BaseAccountBalanceService.ts +11 -8
  26. package/src/BaseService.ts +11 -6
  27. package/src/BlockProducer/BaseBlockProducerService.ts +63 -23
  28. package/src/BlockProducer/spec/BaseBlockProducerService.spec.ts +5 -0
  29. package/src/BlockReward/spec/MemoryBlockRewardService.spec.ts +64 -0
  30. package/src/Bridge/BaseBridgeService.ts +35 -0
  31. package/src/Bridge/index.ts +1 -0
  32. package/src/StepStake/BaseStepStakeService.ts +26 -0
  33. package/src/StepStake/index.ts +1 -0
  34. package/src/Time/BaseTimeSyncService.ts +79 -0
  35. package/src/Time/index.ts +1 -0
  36. package/src/index.ts +3 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json.schemastore.org/package.json",
3
3
  "name": "@xyo-network/chain-services",
4
- "version": "1.14.1",
4
+ "version": "1.14.3",
5
5
  "description": "XYO Layer One SDK Services",
6
6
  "homepage": "https://xylabs.com",
7
7
  "bugs": {
@@ -48,37 +48,37 @@
48
48
  "@xylabs/promise": "~5.0.11",
49
49
  "@xylabs/telemetry": "~5.0.11",
50
50
  "@xylabs/typeof": "~5.0.11",
51
- "@xyo-network/account-model": "~5.1.0",
52
- "@xyo-network/archivist-memory": "~5.1.0",
53
- "@xyo-network/archivist-model": "~5.1.0",
54
- "@xyo-network/boundwitness-model": "~5.1.0",
55
- "@xyo-network/boundwitness-validator": "~5.1.0",
56
- "@xyo-network/boundwitness-wrapper": "~5.1.0",
57
- "@xyo-network/chain-analyze": "~1.14.1",
58
- "@xyo-network/chain-modules": "~1.14.1",
59
- "@xyo-network/chain-protocol": "~1.14.1",
60
- "@xyo-network/chain-utils": "~1.14.1",
61
- "@xyo-network/payload-builder": "~5.1.0",
62
- "@xyo-network/payload-model": "~5.1.0",
63
- "@xyo-network/typechain": "~4.0.3",
64
- "@xyo-network/xl1-protocol": "~1.11.0",
65
- "@xyo-network/xl1-protocol-sdk": "~1.14.1",
66
- "@xyo-network/xl1-validation": "~1.14.1",
67
- "@xyo-network/xl1-wrappers": "~1.14.1",
51
+ "@xyo-network/account-model": "~5.1.2",
52
+ "@xyo-network/archivist-memory": "~5.1.2",
53
+ "@xyo-network/archivist-model": "~5.1.2",
54
+ "@xyo-network/boundwitness-model": "~5.1.2",
55
+ "@xyo-network/boundwitness-validator": "~5.1.2",
56
+ "@xyo-network/boundwitness-wrapper": "~5.1.2",
57
+ "@xyo-network/chain-analyze": "~1.14.3",
58
+ "@xyo-network/chain-modules": "~1.14.3",
59
+ "@xyo-network/chain-protocol": "~1.14.3",
60
+ "@xyo-network/chain-utils": "~1.14.3",
61
+ "@xyo-network/payload-builder": "~5.1.2",
62
+ "@xyo-network/payload-model": "~5.1.2",
63
+ "@xyo-network/typechain": "~4.0.8",
64
+ "@xyo-network/xl1-protocol": "~1.12.22",
65
+ "@xyo-network/xl1-protocol-sdk": "~1.14.3",
66
+ "@xyo-network/xl1-validation": "~1.14.3",
67
+ "@xyo-network/xl1-wrappers": "~1.14.3",
68
68
  "async-mutex": "~0.5.0",
69
69
  "ethers": "6.15.0",
70
- "lru-cache": "~11.1.0"
70
+ "lru-cache": "~11.2.1"
71
71
  },
72
72
  "devDependencies": {
73
- "@types/node": "~24.3.0",
73
+ "@types/node": "~24.3.1",
74
74
  "@xylabs/delay": "~5.0.11",
75
75
  "@xylabs/ts-scripts-yarn3": "~7.1.7",
76
76
  "@xylabs/tsconfig": "~7.1.7",
77
77
  "@xylabs/vitest-extended": "~5.0.11",
78
- "@xyo-network/account": "~5.1.0",
79
- "@xyo-network/account-model": "~5.1.0",
80
- "@xyo-network/chain-validation": "~1.14.1",
81
- "@xyo-network/wallet": "~5.1.0",
78
+ "@xyo-network/account": "~5.1.2",
79
+ "@xyo-network/account-model": "~5.1.2",
80
+ "@xyo-network/chain-validation": "~1.14.3",
81
+ "@xyo-network/wallet": "~5.1.2",
82
82
  "eslint": "^9.34.0",
83
83
  "tslib": "~2.8.1",
84
84
  "typescript": "~5.9.2",
@@ -1,5 +1,6 @@
1
1
  import { creatable } from '@xylabs/creatable'
2
2
  import { Address, Hash } from '@xylabs/hex'
3
+ import { spanRootAsync } from '@xylabs/telemetry'
3
4
  import { ReadArchivist } from '@xyo-network/archivist-model'
4
5
  import {
5
6
  AccountBalanceServiceV2,
@@ -21,14 +22,16 @@ export interface BaseAccountBalanceServiceParams extends BaseServiceParams {
21
22
  @creatable()
22
23
  export class BaseAccountBalanceService extends BaseService<BaseAccountBalanceServiceParams> implements AccountBalanceServiceV2 {
23
24
  async balances(head: Hash, address: Address[]): Promise<Partial<Record<Address, AttoXL1>>> {
24
- const summary = await balanceSummary({
25
- chainArchivist: this.params.chainArchivist, summaryRepository: this.params.summaryRepository, head,
25
+ return await spanRootAsync('balances', async () => {
26
+ const summary = await balanceSummary({
27
+ chainArchivist: this.params.chainArchivist, summaryRepository: this.params.summaryRepository, head,
28
+ })
29
+ const result: Record<Address, AttoXL1> = {}
30
+ for (const addr of address) {
31
+ const summaryBalance = summary[addr] ?? 0n
32
+ result[addr] = AttoXL1(summaryBalance < 0n ? 0n : summaryBalance)
33
+ }
34
+ return result
26
35
  })
27
- const result: Record<Address, AttoXL1> = {}
28
- for (const addr of address) {
29
- const summaryBalance = summary[addr] ?? 0n
30
- result[addr] = AttoXL1(summaryBalance < 0n ? 0n : summaryBalance)
31
- }
32
- return result
33
36
  }
34
37
  }
@@ -1,8 +1,9 @@
1
1
  import { AbstractCreatable, creatable } from '@xylabs/creatable'
2
2
  import type { EventData } from '@xylabs/events'
3
+ import { Hash } from '@xylabs/hex'
3
4
  import type { Promisable } from '@xylabs/promise'
4
- import { span, spanAsync } from '@xylabs/telemetry'
5
- import type { Service } from '@xyo-network/xl1-protocol'
5
+ import { spanRoot, spanRootAsync } from '@xylabs/telemetry'
6
+ import type { ServiceInterface } from '@xyo-network/xl1-protocol'
6
7
  import { Mutex } from 'async-mutex'
7
8
 
8
9
  import type { BaseAccountableServiceParams, BaseServiceParams } from './model/index.ts'
@@ -13,7 +14,7 @@ declare global {
13
14
 
14
15
  @creatable()
15
16
  export class BaseService<TParams extends BaseServiceParams = BaseServiceParams, TEventData extends EventData = EventData>
16
- extends AbstractCreatable<TParams, TEventData> {
17
+ extends AbstractCreatable<TParams, TEventData> implements ServiceInterface {
17
18
  private static singletonInitMutex = new Mutex()
18
19
 
19
20
  static get singletons() {
@@ -32,11 +33,15 @@ export class BaseService<TParams extends BaseServiceParams = BaseServiceParams,
32
33
  }
33
34
 
34
35
  span<T>(name: string, fn: () => T): T {
35
- return span(name, fn, this.tracer)
36
+ return spanRoot(name, fn, this.tracer)
36
37
  }
37
38
 
38
39
  async spanAsync<T>(name: string, fn: () => Promise<T>): Promise<T> {
39
- return await spanAsync(name, fn, this.tracer)
40
+ return await spanRootAsync(name, fn, this.tracer)
41
+ }
42
+
43
+ sync(_head: Hash): Promise<void> {
44
+ throw new Error('Method not implemented.')
40
45
  }
41
46
  }
42
47
 
@@ -46,7 +51,7 @@ export abstract class BaseAccountableService<
46
51
  // Base class for services that have an account
47
52
  }
48
53
 
49
- export interface CreatableService<T extends BaseService = BaseService> extends Service {
54
+ export interface CreatableService<T extends BaseService = BaseService> extends ServiceInterface {
50
55
  new(params: T['params']): T
51
56
  create<T extends BaseService>(this: CreatableService<T>, params?: Partial<T['params']>): Promisable<T>
52
57
  }
@@ -15,7 +15,9 @@ import {
15
15
  AccountBalanceServiceV2,
16
16
  AllowedBlockPayload, asBlockBoundWitness, AttoXL1, BlockBoundWitness, BlockNumber, BlockNumberSchema,
17
17
  BlockProducerService, ChainStakeIntent,
18
- HydratedBlock, PendingTransactionsService, StakeIntentService, Transfer,
18
+ defaultRewardRatio,
19
+ HydratedBlock, PendingTransactionsService, SignedHydratedTransaction, StakeIntentService,
20
+ TimePayload, TimeSchema, TimeSyncViewInterface, Transfer,
19
21
  } from '@xyo-network/xl1-protocol'
20
22
 
21
23
  import { BaseService } from '../BaseService.ts'
@@ -43,6 +45,7 @@ export interface BaseBlockProducerServiceParams extends XyoValidatorParams {
43
45
  pendingTransactionsService: PendingTransactionsService
44
46
  rejectedTransactionsArchivist: ArchivistInstance
45
47
  rewardAddress: Address
48
+ time: TimeSyncViewInterface
46
49
  }
47
50
 
48
51
  @creatable()
@@ -116,6 +119,10 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
116
119
  return assertEx(this.params.stakeIntentService, () => 'No StakeIntentService provided')
117
120
  }
118
121
 
122
+ protected get time(): TimeSyncViewInterface {
123
+ return assertEx(this.params.time, () => 'No TimeSyncViewInterface provided')
124
+ }
125
+
119
126
  protected get validateHydratedBlockState() {
120
127
  return assertEx(this.params.validateHydratedBlockState, () => 'validateHydratedBlockState is required')
121
128
  }
@@ -139,7 +146,7 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
139
146
  blockRewardService: this.rewardService,
140
147
  config: {
141
148
  rewardAddress: this.rewardAddress,
142
- rewardPercentageRatio: 0.5,
149
+ rewardPercentageRatio: defaultRewardRatio,
143
150
  schema: FixedPercentageBlockRewardDivinerConfigSchema,
144
151
  },
145
152
  })
@@ -194,32 +201,26 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
194
201
  if (rewardTransferPayload) blockPayloads.push(rewardTransferPayload)
195
202
 
196
203
  const transactionTransfers = await generateTransactionFeeTransfers(this.address, nextBlockTransactions)
204
+ const timePayload = await this.generateTimePayload(nextBlock)
197
205
 
198
- const fundedTransfers: Transfer[] = []
199
- const fundedNextBlockTransactions = (await Promise.all(nextBlockTransactions.map(async (tx) => {
200
- const transfer: Transfer | undefined = transactionTransfers.find(txTransfer => txTransfer.from === tx[0].from)
201
- if (!transfer) return
202
- const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t ?? '00' as Hex), 0n)
203
- if (validateBalances) {
204
- const balance = (await this.balanceService.balances(head._hash, [transfer.from]))[transfer.from] ?? AttoXL1(0n)
205
- if (balance >= totalTransferCost) {
206
- fundedTransfers.push(transfer)
207
- return tx
208
- }
209
- } else {
210
- fundedTransfers.push(transfer)
211
- return tx
212
- }
213
- }))).filter(exists)
214
- blockPayloads.push(...fundedTransfers)
206
+ const [fundedNextBlockTransactions, fundedTransfers] = await this.filterByFunded(head, nextBlockTransactions, transactionTransfers, validateBalances)
207
+
208
+ blockPayloads.push(...fundedTransfers, timePayload)
215
209
 
216
210
  // Build the block
217
- this.logger?.info(`buildNextBlock: Building block ${head.block + 1} (${new Date().toISOString()})`)
211
+ this.logger?.info(`Building block ${head.block + 1}`)
212
+ const startBuild = Date.now()
218
213
  const block = await buildNextBlock(head, fundedNextBlockTransactions, blockPayloads, [this.account])
219
- this.logger?.info(`buildNextBlock: Built block ${block[0].block} with ${block[1].length} payloads (${new Date().toISOString()})`)
220
- this.logger?.info(`validateHydratedBlockState: Validating block ${block[0].block} with ${block[1].length} payloads (${new Date().toISOString()})`)
214
+
215
+ this.logger?.info(
216
+ `Built block ${block[0].block} in ${Date.now() - startBuild}ms with ${block[1].length} payloads`,
217
+ )
218
+
219
+ this.logger?.info(`Validating block ${block[0].block} with ${block[1].length} payloads`)
220
+ const startValidate = Date.now()
221
221
  const errors = await this.validateHydratedBlockState(block, this.chainId, { accountBalance: this.balanceService })
222
- this.logger?.info(`validateHydratedBlockState: Validated block ${block[0].block} with ${block[1].length} payloads (${new Date().toISOString()})`)
222
+ this.logger?.info(`Validated block ${block[0].block} in ${Date.now() - startValidate}ms with ${block[1].length} payloads`)
223
+
223
224
  if (errors.length > 0) {
224
225
  this.logger?.warn(`Validation of produced block failed: ${errors.at(0)?.message}`)
225
226
  const rejectedTransactions = block[1]
@@ -229,4 +230,43 @@ export class BaseBlockProducerService extends BaseService<BaseBlockProducerServi
229
230
  }
230
231
  })
231
232
  }
233
+
234
+ // remove unfunded transactions and block transfers
235
+ private async filterByFunded(
236
+ head: WithStorageMeta<BlockBoundWitness>,
237
+ txs: SignedHydratedTransaction[],
238
+ transfers: Transfer[],
239
+ validateBalances = false,
240
+ ): Promise<[SignedHydratedTransaction[], Transfer[]]> {
241
+ const start = Date.now()
242
+ const fundedTransfers: Transfer[] = []
243
+ const fundedTransactions = (await Promise.all(txs.map(async (tx) => {
244
+ const transfer: Transfer | undefined = transfers.find(transfer => transfer.from === tx[0].from)
245
+ if (!transfer) return
246
+ const totalTransferCost = Object.values(transfer?.transfers).reduce((acc, t) => acc + hexToBigInt(t ?? '00' as Hex), 0n)
247
+ if (validateBalances) {
248
+ const balance = (await this.balanceService.balances(head._hash, [transfer.from]))[transfer.from] ?? AttoXL1(0n)
249
+ if (balance >= totalTransferCost) {
250
+ fundedTransfers.push(transfer)
251
+ return tx
252
+ }
253
+ } else {
254
+ fundedTransfers.push(transfer)
255
+ return tx
256
+ }
257
+ }))).filter(exists)
258
+ this.logger?.info(`Filtered ${txs.length} transactions to ${fundedTransactions.length} funded transactions in ${Date.now() - start}ms`)
259
+ return [fundedTransactions, fundedTransfers]
260
+ }
261
+
262
+ private async generateTimePayload(nextBlock: number) {
263
+ const timePayload: TimePayload = {
264
+ schema: TimeSchema,
265
+ xl1: nextBlock,
266
+ // TODO: Change to entire tuple for time in ETH
267
+ ethereum: (await this.time.currentTime('ethereum'))[1],
268
+ epoch: Date.now(),
269
+ }
270
+ return timePayload
271
+ }
232
272
  }
@@ -23,6 +23,7 @@ import type {
23
23
  HydratedBlock,
24
24
  HydratedBlockStateValidationFunctionV2,
25
25
  StakeIntentService,
26
+ TimeSyncViewInterface,
26
27
  } from '@xyo-network/xl1-protocol'
27
28
  import {
28
29
  asBlockBoundWitness,
@@ -60,6 +61,7 @@ describe('XyoBlockProducer', () => {
60
61
  let rewardAddress = '1111111111111111111111111111111111111111' as Address
61
62
  let rewardService: BlockRewardService
62
63
  let stakeIntentService: ReturnType<typeof mock<StakeIntentService>>
64
+ let time: TimeSyncViewInterface
63
65
  let transactionAccount: AccountInstance
64
66
  const validPendingTransactions = Math.ceil(BaseBlockProducerService.DefaultBlockSize)
65
67
  let config: Config
@@ -93,6 +95,7 @@ describe('XyoBlockProducer', () => {
93
95
 
94
96
  stakeIntentService = mock<StakeIntentService>()
95
97
  stakeIntentService.getDeclaredCandidateRanges.mockResolvedValue([])
98
+ time = mock<TimeSyncViewInterface>()
96
99
  rewardService = await MemoryBlockRewardService.create()
97
100
  const balanceService = await accountBalanceServiceFromArchivist(chainArchivist)
98
101
  const params: BaseBlockProducerServiceParams = {
@@ -109,6 +112,7 @@ describe('XyoBlockProducer', () => {
109
112
  rewardAddress,
110
113
  rewardService,
111
114
  stakeIntentService,
115
+ time,
112
116
  validateHydratedBlockState,
113
117
  }
114
118
  blockProducer = await BaseBlockProducerService.create(params)
@@ -194,6 +198,7 @@ describe('XyoBlockProducer', () => {
194
198
  rewardAddress,
195
199
  rewardService,
196
200
  stakeIntentService,
201
+ time,
197
202
  validateHydratedBlockState,
198
203
  }
199
204
  blockProducer = await BaseBlockProducerService.create(params)
@@ -0,0 +1,64 @@
1
+ import '@xylabs/vitest-extended'
2
+
3
+ import { toFixedPoint } from '@xylabs/decimal-precision'
4
+ import {
5
+ beforeAll, describe, expect, it,
6
+ } from 'vitest'
7
+
8
+ import { MemoryBlockRewardService } from '../index.ts'
9
+
10
+ describe('MemoryBlockRewardService', () => {
11
+ let sut: MemoryBlockRewardService
12
+ // const genesisReward = toFixedPoint(18_000_000_000n)
13
+ // const initialReward = toFixedPoint(500n)
14
+ // const minRewardPerBlock = toFixedPoint(10n)
15
+ const genesisReward = 18_000_000_000_000_000_000_000_000_000n
16
+ const initialReward = 500_000_000_000_000_000_000n
17
+ const minRewardPerBlock = 10_000_000_000_000_000_000n
18
+ const stepFactorDenominator = 100n
19
+ const stepFactorNumerator = 95n
20
+ const stepSize = 1_000_000n
21
+ beforeAll(async () => {
22
+ sut = await MemoryBlockRewardService.create({
23
+ stepFactorNumerator,
24
+ stepFactorDenominator,
25
+ stepSize,
26
+ initialStepReward: initialReward,
27
+ minRewardPerBlock,
28
+ creatorReward: genesisReward,
29
+ })
30
+ })
31
+
32
+ describe('rewards', () => {
33
+ it('for block 0', async () => {
34
+ const reward = await sut.getRewardForBlock(0n)
35
+ expect(reward).toEqual(18_000_000_000_000_000_000_000_000_000n)
36
+ expect(reward).toEqual(toFixedPoint(18_000_000_000n))
37
+ })
38
+ it('for block 1', async () => {
39
+ const reward = await sut.getRewardForBlock(1n)
40
+ expect(reward).toEqual(500_000_000_000_000_000_000n)
41
+ expect(reward).toEqual(toFixedPoint(500n))
42
+ })
43
+ it('for block 2', async () => {
44
+ const reward = await sut.getRewardForBlock(2n)
45
+ expect(reward).toEqual(500_000_000_000_000_000_000n)
46
+ expect(reward).toEqual(toFixedPoint(500n))
47
+ })
48
+ it('for block 3', async () => {
49
+ const reward = await sut.getRewardForBlock(3n)
50
+ expect(reward).toEqual(500_000_000_000_000_000_000n)
51
+ expect(reward).toEqual(toFixedPoint(500n))
52
+ })
53
+ it('for block 4', async () => {
54
+ const reward = await sut.getRewardForBlock(4n)
55
+ expect(reward).toEqual(500_000_000_000_000_000_000n)
56
+ expect(reward).toEqual(toFixedPoint(500n))
57
+ })
58
+ it('for block 1000000', async () => {
59
+ const reward = await sut.getRewardForBlock(1_000_000n)
60
+ expect(reward).toEqual(475_000_000_000_000_000_000n)
61
+ expect(reward).toEqual(toFixedPoint(475n))
62
+ })
63
+ })
64
+ })
@@ -0,0 +1,35 @@
1
+ import { creatable } from '@xylabs/creatable'
2
+ import { Promisable } from '@xylabs/promise'
3
+ import { ReadArchivist } from '@xyo-network/archivist-model'
4
+ import {
5
+ BridgeBack,
6
+ BridgeComplete,
7
+ BridgeRequest,
8
+ BridgeService,
9
+ } from '@xyo-network/xl1-protocol'
10
+
11
+ import { BaseService } from '../BaseService.ts'
12
+ import { BaseServiceParams } from '../model/index.ts'
13
+
14
+ export interface BaseBridgeServiceParams extends BaseServiceParams {
15
+ chainArchivist: ReadArchivist
16
+ }
17
+
18
+ @creatable()
19
+ export class BaseBridgeService extends BaseService<BaseBridgeServiceParams> implements BridgeService {
20
+ completedBridgeBack(): Promisable<BridgeBack[]> {
21
+ throw new Error('Method not implemented.')
22
+ }
23
+
24
+ completedBridgeRequests(): Promisable<[BridgeRequest, BridgeComplete][]> {
25
+ throw new Error('Method not implemented.')
26
+ }
27
+
28
+ pendingBridgeBack(): Promisable<BridgeBack[]> {
29
+ throw new Error('Method not implemented.')
30
+ }
31
+
32
+ pendingBridgeRequests(): Promisable<BridgeRequest[]> {
33
+ throw new Error('Method not implemented.')
34
+ }
35
+ }
@@ -0,0 +1 @@
1
+ export * from './BaseBridgeService.ts'
@@ -0,0 +1,26 @@
1
+ import { creatable } from '@xylabs/creatable'
2
+ import { Address } from '@xylabs/hex'
3
+ import { Promisable } from '@xylabs/promise'
4
+ import { ReadArchivist } from '@xyo-network/archivist-model'
5
+ import {
6
+ CompletedStep,
7
+ StepStakeService,
8
+ } from '@xyo-network/xl1-protocol'
9
+
10
+ import { BaseService } from '../BaseService.ts'
11
+ import { BaseServiceParams } from '../model/index.ts'
12
+
13
+ export interface BaseStepStakeServiceParams extends BaseServiceParams {
14
+ chainArchivist: ReadArchivist
15
+ }
16
+
17
+ @creatable()
18
+ export class BaseStepStakeService extends BaseService<BaseStepStakeServiceParams> implements StepStakeService {
19
+ stepStake(_step: CompletedStep): Promisable<Record<Address, bigint>> {
20
+ throw new Error('Method not implemented.')
21
+ }
22
+
23
+ stepStakeForAddress(_address: Address, _step: CompletedStep): Promisable<bigint> {
24
+ throw new Error('Method not implemented.')
25
+ }
26
+ }
@@ -0,0 +1 @@
1
+ export * from './BaseStepStakeService.ts'
@@ -0,0 +1,79 @@
1
+ import { assertEx } from '@xylabs/assert'
2
+ import { creatable } from '@xylabs/creatable'
3
+ import { ReadArchivist } from '@xyo-network/archivist-model'
4
+ import {
5
+ asTimePayload,
6
+ EventingChainBlockNumberIteratorService, TimeDomain, TimeSchema, TimeSyncService,
7
+ } from '@xyo-network/xl1-protocol'
8
+ import { Provider } from 'ethers'
9
+
10
+ import { BaseService } from '../BaseService.ts'
11
+ import { BaseServiceParams } from '../model/index.ts'
12
+
13
+ export interface BaseTimeServiceParams extends BaseServiceParams {
14
+ chainArchivist: ReadArchivist
15
+ chainIterator: EventingChainBlockNumberIteratorService
16
+ ethProvider?: Provider
17
+ }
18
+
19
+ @creatable()
20
+ export class BaseTimeSyncService extends BaseService<BaseTimeServiceParams> implements TimeSyncService {
21
+ get chainArchivist() {
22
+ return this.params.chainArchivist
23
+ }
24
+
25
+ get chainIterator() {
26
+ return this.params.chainIterator
27
+ }
28
+
29
+ get ethProvider() {
30
+ return this.params.ethProvider
31
+ }
32
+
33
+ async convertTime(fromDomain: TimeDomain, toDomain: TimeDomain, from: number): Promise<number> {
34
+ switch (fromDomain) {
35
+ case 'xl1': {
36
+ const block = assertEx(await this.chainIterator.get(from), () => 'Block not found')
37
+ const timeSchemaIndex = block.payload_schemas.indexOf(TimeSchema)
38
+ const hash = timeSchemaIndex === -1 ? undefined : block.payload_hashes[timeSchemaIndex]
39
+ const [payload] = hash === undefined ? [] : await this.chainArchivist.get([hash])
40
+ const timePayload = asTimePayload(payload)
41
+ if (timePayload === undefined) return 0
42
+ switch (toDomain) {
43
+ case 'xl1': {
44
+ return timePayload.xl1 ?? 0
45
+ }
46
+ case 'epoch': {
47
+ return timePayload.epoch ?? 0
48
+ }
49
+ case 'ethereum': {
50
+ return timePayload.ethereum ?? 0
51
+ }
52
+ default: {
53
+ throw new Error(`Unsupported to toDomain: ${toDomain}`)
54
+ }
55
+ }
56
+ }
57
+ default: {
58
+ throw new Error(`Unsupported from fromDomain: ${fromDomain}`)
59
+ }
60
+ }
61
+ }
62
+
63
+ async currentTime(domain: TimeDomain): Promise<[string, number]> {
64
+ switch (domain) {
65
+ case 'xl1': {
66
+ return ['xl1', (await this.chainIterator.head()).block]
67
+ }
68
+ case 'epoch': {
69
+ return ['epoch', Date.now()]
70
+ }
71
+ case 'ethereum': {
72
+ return ['ethereum', (await this.ethProvider?.getBlockNumber()) ?? 0]
73
+ }
74
+ default: {
75
+ throw new Error(`Unknown time domain: ${domain}`)
76
+ }
77
+ }
78
+ }
79
+ }
@@ -0,0 +1 @@
1
+ export * from './BaseTimeSyncService.ts'
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from './AccountBalance/index.ts'
2
2
  export * from './BaseService.ts'
3
3
  export * from './BlockProducer/index.ts'
4
4
  export * from './BlockReward/index.ts'
5
+ export * from './Bridge/index.ts'
5
6
  export * from './ChainBlockNumberIteration/index.ts'
6
7
  export * from './ChainService/index.ts'
7
8
  export * from './ChainValidator/index.ts'
@@ -9,3 +10,5 @@ export * from './Election/index.ts'
9
10
  export * from './model/index.ts'
10
11
  export * from './PendingTransactions/index.ts'
11
12
  export * from './StakeIntent/index.ts'
13
+ export * from './StepStake/index.ts'
14
+ export * from './Time/index.ts'