@xyo-network/xl1-protocol-sdk 1.26.28 → 1.26.29

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.
@@ -0,0 +1,1995 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __decorateClass = (decorators, target, key, kind) => {
5
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
6
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
7
+ if (decorator = decorators[i])
8
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
9
+ if (kind && result) __defProp(target, key, result);
10
+ return result;
11
+ };
12
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
+
14
+ // src/test/buildRandomTransaction.ts
15
+ import { Account } from "@xyo-network/sdk-js";
16
+ import { asXL1BlockNumber, isAllowedBlockPayload } from "@xyo-network/xl1-protocol-lib";
17
+
18
+ // src/createTransferPayload.ts
19
+ import { toHex } from "@xylabs/sdk-js";
20
+ import { PayloadBuilder } from "@xyo-network/sdk-js";
21
+ import { TransferSchema } from "@xyo-network/xl1-protocol-lib";
22
+ function createTransferPayload(from, transfers, context) {
23
+ return new PayloadBuilder({ schema: TransferSchema }).fields({
24
+ epoch: Date.now(),
25
+ from,
26
+ transfers: Object.fromEntries(Object.entries(transfers).map(([k, v]) => [k, toHex(v)])),
27
+ context
28
+ }).build();
29
+ }
30
+
31
+ // src/transaction/buildTransaction.ts
32
+ import { assertEx, toHex as toHex2 } from "@xylabs/sdk-js";
33
+ import {
34
+ asAnyPayload,
35
+ BoundWitnessBuilder,
36
+ PayloadBuilder as PayloadBuilder2
37
+ } from "@xyo-network/sdk-js";
38
+ import { defaultTransactionFees } from "@xyo-network/xl1-protocol-lib";
39
+ async function buildTransaction(chain, onChainPayloads, offChainPayloads, signer, nbf, exp, from, fees = defaultTransactionFees) {
40
+ if (from === void 0 && Array.isArray(signer)) {
41
+ throw new Error("from is required when signer is an array");
42
+ }
43
+ const txBoundWitnessFields = {
44
+ chain,
45
+ fees: {
46
+ base: toHex2(fees.base),
47
+ gasLimit: toHex2(fees.gasLimit),
48
+ gasPrice: toHex2(fees.gasPrice),
49
+ priority: toHex2(fees.priority)
50
+ },
51
+ nbf,
52
+ exp
53
+ };
54
+ const elevatedHashes = await PayloadBuilder2.hashes(onChainPayloads);
55
+ const script = [];
56
+ for (const elevatedHash of elevatedHashes) {
57
+ script.push(`elevate|${elevatedHash}`);
58
+ }
59
+ const fields = {
60
+ ...txBoundWitnessFields,
61
+ from: from ?? (Array.isArray(signer) ? assertEx(signer.at(0)?.address) : signer.address)
62
+ };
63
+ if (script.length > 0) {
64
+ fields.script = script;
65
+ }
66
+ const [tx, txPayloads] = await new BoundWitnessBuilder().fields(fields).meta({ $signatures: [] }).payloads([...onChainPayloads, ...offChainPayloads]).signers(Array.isArray(signer) ? signer : [signer]).build();
67
+ return [await PayloadBuilder2.addHashMeta(tx), await PayloadBuilder2.addHashMeta(txPayloads.map((p) => asAnyPayload(p, true)))];
68
+ }
69
+
70
+ // src/test/buildRandomTransaction.ts
71
+ var buildRandomTransaction = async (chain, payloads, account, nbf = asXL1BlockNumber(0, true), exp = asXL1BlockNumber(nbf + 1e3, true), privatePayloadSchemas = [], receiverAddress) => {
72
+ const elevatedPayloads = (payloads ?? []).filter(isAllowedBlockPayload);
73
+ const additionalPayloads = (payloads ?? []).filter((payload) => !isAllowedBlockPayload(payload));
74
+ const sender = account ?? await Account.random();
75
+ if (elevatedPayloads.length === 0) {
76
+ const receiver = receiverAddress ?? (await Account.random()).address;
77
+ const transferPayload = createTransferPayload(sender.address, { [receiver]: 1n });
78
+ elevatedPayloads.push(transferPayload);
79
+ }
80
+ const hydratedTransaction = await buildTransaction(chain, elevatedPayloads, additionalPayloads, sender, nbf, exp);
81
+ return [hydratedTransaction[0], hydratedTransaction[1].filter((payload) => !privatePayloadSchemas.includes(payload.schema))];
82
+ };
83
+
84
+ // src/test/getSimpleBlockViewerLocator.ts
85
+ import { XYO_ZERO_ADDRESS as XYO_ZERO_ADDRESS3 } from "@xyo-network/xl1-protocol-lib";
86
+
87
+ // src/CreatableProvider/AbstractCreatableProvider.ts
88
+ import {
89
+ AbstractCreatable,
90
+ assertEx as assertEx3,
91
+ IdLogger
92
+ } from "@xylabs/sdk-js";
93
+
94
+ // src/CreatableProvider/ProviderFactory.ts
95
+ import { assertEx as assertEx2 } from "@xylabs/sdk-js";
96
+ function providerFactoryDescription(factory, labels) {
97
+ return `${factory.providerName}:${factory.defaultMoniker}:${JSON.stringify(labels ?? factory.labels ?? {})}`;
98
+ }
99
+ var ProviderFactory = class _ProviderFactory {
100
+ creatableProvider;
101
+ defaultMoniker;
102
+ defaultParams;
103
+ dependencies;
104
+ labels;
105
+ monikers;
106
+ providerName;
107
+ scope;
108
+ _uniqueId;
109
+ constructor(creatableProvider2, dependencies, params, labels = {}, scope = "context") {
110
+ this.creatableProvider = creatableProvider2;
111
+ this.defaultParams = params;
112
+ this.defaultMoniker = creatableProvider2.defaultMoniker;
113
+ this.dependencies = dependencies;
114
+ this.monikers = creatableProvider2.monikers;
115
+ this.scope = scope;
116
+ assertEx2(this.monikers.includes(this.defaultMoniker), () => "defaultMoniker must be in monikers");
117
+ this.labels = Object.assign({}, creatableProvider2.labels ?? {}, labels ?? {});
118
+ this.providerName = creatableProvider2.name;
119
+ this._uniqueId = Symbol(providerFactoryDescription(this));
120
+ }
121
+ get resolvedMoniker() {
122
+ const labels = this.labels ?? {};
123
+ const labelString = Object.entries(labels).map(([key, value]) => `${key}=${value}`).join(",");
124
+ return labelString.length === 0 ? `${this.defaultMoniker}` : `${this.defaultMoniker}|${labelString}`;
125
+ }
126
+ get uniqueId() {
127
+ return this._uniqueId;
128
+ }
129
+ static withParams(creatableProvider2, dependencies, params, labels = {}) {
130
+ return new _ProviderFactory(creatableProvider2, dependencies, params, labels);
131
+ }
132
+ factory(dependencies, params, labels = {}) {
133
+ return new _ProviderFactory(this.creatableProvider, dependencies, params, labels);
134
+ }
135
+ async getInstance(params, { start = true }) {
136
+ let scopeObject;
137
+ switch (this.scope) {
138
+ case "global": {
139
+ globalThis.xyoServiceSingletons ??= {};
140
+ scopeObject = globalThis.xyoServiceSingletons;
141
+ break;
142
+ }
143
+ case "context": {
144
+ const context = assertEx2(
145
+ params?.context,
146
+ () => "Context is required for context-scoped providers"
147
+ );
148
+ context.singletons ??= {};
149
+ scopeObject = context.singletons;
150
+ break;
151
+ }
152
+ default: {
153
+ scopeObject = {};
154
+ break;
155
+ }
156
+ }
157
+ const mergedParams = {
158
+ ...this.defaultParams,
159
+ ...params
160
+ };
161
+ const resultPromise = scopeObject[this.resolvedMoniker] ?? this.creatableProvider.create(mergedParams);
162
+ scopeObject[this.resolvedMoniker] = resultPromise;
163
+ const result = await resultPromise;
164
+ if (start) {
165
+ assertEx2(await result.start(), () => `Failed to start provider instance [${this.resolvedMoniker}]`);
166
+ }
167
+ return result;
168
+ }
169
+ async tryGetInstance(params, options) {
170
+ try {
171
+ return await this.getInstance(params, options);
172
+ } catch {
173
+ return;
174
+ }
175
+ }
176
+ };
177
+
178
+ // src/CreatableProvider/AbstractCreatableProvider.ts
179
+ var AbstractCreatableProvider = class extends AbstractCreatable {
180
+ dependencies = {};
181
+ _contextCache;
182
+ _logger;
183
+ get logger() {
184
+ if (this._logger === void 0) {
185
+ const providedLogger = this.params.logger ?? this.context.logger;
186
+ this._logger = providedLogger ? new IdLogger(providedLogger, () => `${this.moniker} [${this.constructor.name}]`) : null;
187
+ }
188
+ return this._logger ?? void 0;
189
+ }
190
+ get meter() {
191
+ return this.context.meterProvider?.getMeter(this.name) ?? super.meter;
192
+ }
193
+ get tracer() {
194
+ return this.context.traceProvider?.getTracer(this.name) ?? super.tracer;
195
+ }
196
+ get config() {
197
+ return this.context.config;
198
+ }
199
+ get context() {
200
+ return this.params.context;
201
+ }
202
+ get locator() {
203
+ return this.context.locator;
204
+ }
205
+ static factory(dependencies, params) {
206
+ const factory = ProviderFactory.withParams(this, dependencies, params);
207
+ return factory;
208
+ }
209
+ static async paramsHandler(params = {}) {
210
+ const context = assertEx3(params.context, () => new Error("Context is required"));
211
+ const config = assertEx3(context.config, () => new Error("Context config is required"));
212
+ const locator = assertEx3(context.locator, () => new Error("Context locator is required"));
213
+ return await super.paramsHandler({
214
+ ...params,
215
+ statusReporter: params.statusReporter ?? context.statusReporter,
216
+ context: {
217
+ ...context,
218
+ config,
219
+ locator
220
+ },
221
+ name: params.name ?? this.defaultMoniker,
222
+ logger: params.logger ?? context.logger
223
+ });
224
+ }
225
+ async createHandler() {
226
+ await super.createHandler();
227
+ if (this.tracer === void 0) {
228
+ this.logger?.warn("No tracer available in context");
229
+ }
230
+ if (this.meter === void 0) {
231
+ this.logger?.warn("No meter available in context");
232
+ }
233
+ }
234
+ async locateAndCreate(moniker) {
235
+ return await this.locator.getInstance(moniker);
236
+ }
237
+ async tryLocateAndCreate(moniker) {
238
+ return await this.locator.tryGetInstance(moniker);
239
+ }
240
+ };
241
+
242
+ // src/CreatableProvider/CreatableProvider.ts
243
+ function creatableProvider() {
244
+ return (constructor) => {
245
+ constructor;
246
+ };
247
+ }
248
+
249
+ // src/CreatableProvider/CreatableProviderRegistry.ts
250
+ import { isTruthy } from "@xylabs/sdk-js";
251
+ var buildProviderFactory = (provider, defaultParams, labels) => {
252
+ const factory = {
253
+ monikers: provider.monikers,
254
+ uniqueId: Symbol(providerFactoryDescription(provider, labels)),
255
+ // Merge module & supplied labels
256
+ labels: { ...provider.labels, ...labels },
257
+ creatableProvider: provider.creatableProvider,
258
+ dependencies: provider.dependencies,
259
+ resolvedMoniker: provider.resolvedMoniker,
260
+ providerName: provider.providerName,
261
+ scope: provider.scope,
262
+ defaultParams,
263
+ getInstance: provider.getInstance.bind(provider),
264
+ tryGetInstance: provider.tryGetInstance?.bind(provider),
265
+ defaultMoniker: provider.defaultMoniker,
266
+ factory: provider.factory.bind(provider)
267
+ };
268
+ return factory;
269
+ };
270
+ var registerCreatableProviderFactory = (registry, factory, labels, primary = false) => {
271
+ const primaryMonikers = primary !== true && isTruthy(primary) ? Array.isArray(primary) ? primary : [primary] : [];
272
+ for (const primaryMoniker of primaryMonikers) {
273
+ if (!factory.monikers.includes(primaryMoniker)) {
274
+ console.warn(`Primary moniker ${String(primary)} not found in factory monikers`);
275
+ }
276
+ }
277
+ const isPrimaryForMoniker = (moniker) => {
278
+ switch (typeof primary) {
279
+ case "boolean": {
280
+ return primary;
281
+ }
282
+ case "string": {
283
+ return moniker === primary;
284
+ }
285
+ case "object": {
286
+ if (Array.isArray(primary)) {
287
+ return primary.includes(moniker);
288
+ }
289
+ }
290
+ }
291
+ throw new Error(`Invalid primary value: ${String(primary)}`);
292
+ };
293
+ const factoryClone = buildProviderFactory(factory, factory.defaultParams, labels);
294
+ registry[factoryClone.defaultMoniker] = [factoryClone, ...registry[factoryClone.defaultMoniker] ?? []];
295
+ for (const moniker of factoryClone.monikers) {
296
+ registry[moniker] = isPrimaryForMoniker(moniker) ? [factoryClone, ...registry[moniker] ?? []] : [...registry[moniker] ?? [], factoryClone];
297
+ }
298
+ };
299
+
300
+ // src/CreatableProvider/LabeledCreatableProviderFactory.ts
301
+ var hasLabels = (factory) => {
302
+ return factory.labels !== void 0;
303
+ };
304
+
305
+ // src/CreatableProvider/ProviderFactoryLocator.ts
306
+ import { hasAllLabels } from "@xylabs/sdk-js";
307
+ import { assertEx as assertEx4 } from "@xylabs/sdk-js";
308
+ var ProviderFactoryLocator = class _ProviderFactoryLocator {
309
+ _context;
310
+ _registry;
311
+ _frozen = false;
312
+ _parent;
313
+ _validateDepsOnRegister;
314
+ constructor(context, registry = {}, validateDepsOnRegister = false) {
315
+ this._registry = registry;
316
+ this._context = { ...context, locator: this };
317
+ this._parent = context.locator;
318
+ this._validateDepsOnRegister = validateDepsOnRegister;
319
+ }
320
+ get context() {
321
+ return this._context;
322
+ }
323
+ get logger() {
324
+ return this.context.logger;
325
+ }
326
+ /**
327
+ * The current registry for the module factory
328
+ */
329
+ get registry() {
330
+ return this._registry;
331
+ }
332
+ get validateDepsOnRegister() {
333
+ return this._validateDepsOnRegister;
334
+ }
335
+ freeze() {
336
+ this._frozen = true;
337
+ }
338
+ async getInstance(moniker, { start = true, labels } = {}) {
339
+ return assertEx4(
340
+ await this.tryGetInstance(moniker, { start, labels }),
341
+ () => `No provider instance for the supplied config moniker [${moniker}]${labels ? ` & labels [${JSON.stringify(labels)}]` : ""} could be created`
342
+ );
343
+ }
344
+ has(moniker) {
345
+ return !!this._registry[moniker];
346
+ }
347
+ /**
348
+ * Locates a provider factory that matches the supplied moniker and labels
349
+ * @param moniker The config moniker for the provider
350
+ * @param labels The labels for the provider factory
351
+ * @returns A provider factory that matches the supplied moniker and labels or throws if one is not found
352
+ */
353
+ locate(moniker, labels) {
354
+ return assertEx4(
355
+ this.tryLocate(moniker, labels),
356
+ () => `No module factory for the supplied config moniker [${moniker}]${labels ? ` & labels [${JSON.stringify(labels)}]` : ""} registered`
357
+ );
358
+ }
359
+ merge(locator) {
360
+ const registry = { ...this.registry };
361
+ for (const moniker in locator.registry) {
362
+ if (registry[moniker]) {
363
+ registry[moniker].push(...locator.registry[moniker] ?? []);
364
+ } else {
365
+ registry[moniker] = locator.registry[moniker];
366
+ }
367
+ }
368
+ return new _ProviderFactoryLocator(this.context, registry);
369
+ }
370
+ /**
371
+ * Registers a single module factory (with optional tags) with the locator
372
+ * @param factory The factory to register
373
+ * @param labels The labels for the module factory
374
+ */
375
+ register(factory, labels, primary = false) {
376
+ assertEx4(!this._frozen, () => "Cannot register a module factory after the locator has been frozen");
377
+ if (this.validateDepsOnRegister) {
378
+ const missingDeps = factory.dependencies.filter((dep) => !this.registered(dep));
379
+ assertEx4(missingDeps.length === 0, () => `Cannot register module factory [${factory.uniqueId.description}] due to missing dependencies: ${missingDeps.join(", ")}`);
380
+ }
381
+ registerCreatableProviderFactory(this._registry, factory, labels, primary);
382
+ return this;
383
+ }
384
+ /**
385
+ * Registers multiple module factories with the locator
386
+ * @param factories The factories to register
387
+ */
388
+ registerMany(factories) {
389
+ for (const factory of factories) {
390
+ this.register(factory);
391
+ }
392
+ return this;
393
+ }
394
+ registered(moniker) {
395
+ return !!this.registry[moniker] || (this._parent?.registered(moniker) ?? false);
396
+ }
397
+ async tryGetInstance(moniker, { start = true, labels } = {}) {
398
+ const resolvedParams = { context: this.context };
399
+ const factory = this.tryLocate(moniker, labels);
400
+ if (factory) {
401
+ if (this.context.singletons[factory.uniqueId]) {
402
+ return this.context.singletons[factory.uniqueId];
403
+ }
404
+ this.logger?.info(`Creating provider instance for moniker [${moniker}]${labels ? ` with labels [${JSON.stringify(labels)}]` : ""} using factory [${factory.uniqueId.description}]`);
405
+ const result = await factory.getInstance(resolvedParams, { start });
406
+ this.context.singletons[factory.uniqueId] = result;
407
+ return result;
408
+ }
409
+ }
410
+ /**
411
+ * Tries to locate a module factory that matches the supplied moniker and labels
412
+ * @param moniker The config moniker for the module
413
+ * @param labels The labels for the module factory
414
+ * @returns A module factory that matches the supplied moniker and labels or undefined
415
+ */
416
+ tryLocate(moniker, labels) {
417
+ const result = (labels ? this._registry[moniker]?.filter(hasLabels).find((factory) => hasAllLabels(factory?.labels, labels)) ?? this._registry[moniker]?.[0] : this._registry[moniker]?.[0]) ?? this._parent?.tryLocate(moniker, labels);
418
+ return result;
419
+ }
420
+ validateDependencies(recursive = false) {
421
+ if (recursive) {
422
+ this._parent?.validateDependencies();
423
+ }
424
+ for (const moniker in this.registry) {
425
+ for (const factory of this.registry[moniker] ?? []) {
426
+ const missingDeps = factory.dependencies.filter((dep) => !this.registered(dep));
427
+ assertEx4(missingDeps.length === 0, () => `Module factory [${factory.uniqueId.description}] is missing dependencies: ${missingDeps.join(", ")}`);
428
+ }
429
+ }
430
+ }
431
+ };
432
+
433
+ // src/_internal/context/getTestProviderContext.ts
434
+ function getTestProviderContext(config) {
435
+ const singletons = {};
436
+ const caches = {};
437
+ const locator = new ProviderFactoryLocator({
438
+ config,
439
+ singletons,
440
+ caches,
441
+ logger: console
442
+ });
443
+ return locator.context;
444
+ }
445
+
446
+ // src/config/Actor.ts
447
+ import {
448
+ zodAsFactory as zodAsFactory2,
449
+ zodIsFactory as zodIsFactory2,
450
+ zodToFactory as zodToFactory2
451
+ } from "@xylabs/sdk-js";
452
+ import { globalRegistry as globalRegistry12, z as z17 } from "zod";
453
+
454
+ // src/validation/schema/Mnemonic.ts
455
+ import { z } from "zod";
456
+ var MnemonicStringZod = z.string().transform((s) => s.trim().replaceAll(/\s+/g, " ")).refine(
457
+ (s) => [12, 15, 18, 21, 24].includes(s.split(" ").length),
458
+ { message: "Mnemonic must contain 12, 15, 18, 21, or 24 words." }
459
+ ).describe("BIP-39 mnemonic string");
460
+
461
+ // src/config/Base.ts
462
+ import { z as z16 } from "zod";
463
+
464
+ // src/config/Chain.ts
465
+ import { AddressZod, HexZod } from "@xylabs/sdk-js";
466
+ import { globalRegistry, z as z2 } from "zod";
467
+ var ChainConfigZod = z2.object({
468
+ id: HexZod.optional().register(globalRegistry, {
469
+ description: "The unique identifier for the chain. Should be the staking contract address for contract-backed chains.",
470
+ title: "chain.id",
471
+ type: "string"
472
+ }),
473
+ genesisRewardAddress: AddressZod.optional().register(globalRegistry, {
474
+ description: "Address to send the initial genesis rewards to, if a new chain is being created.",
475
+ title: "chain.genesisRewardAddress",
476
+ type: "Address"
477
+ })
478
+ });
479
+
480
+ // src/config/DataLake/DataLake.ts
481
+ import { z as z6 } from "zod";
482
+
483
+ // src/config/DataLake/RestDataLakeConfig.ts
484
+ import { globalRegistry as globalRegistry3, z as z4 } from "zod";
485
+
486
+ // src/config/DataLake/DataLakeRemoteConfig.ts
487
+ import { globalRegistry as globalRegistry2, z as z3 } from "zod";
488
+ var DataLakeDriverConfigBaseZod = z3.object({
489
+ driver: z3.string().register(globalRegistry2, {
490
+ description: "Driver for the data lake",
491
+ type: "string"
492
+ })
493
+ }).describe("Base configuration for a data lake driver");
494
+
495
+ // src/config/DataLake/RestDataLakeConfig.ts
496
+ var RestDataLakeConfigZod = DataLakeDriverConfigBaseZod.extend({
497
+ driver: z4.literal("rest").register(globalRegistry3, {
498
+ description: "Driver for the REST data lake",
499
+ type: "string"
500
+ }),
501
+ url: z4.string().register(globalRegistry3, {
502
+ description: "URL for the REST data lake",
503
+ type: "string"
504
+ })
505
+ }).describe("Configuration for the REST data lake driver");
506
+
507
+ // src/config/DataLake/RouterDataLakeConfig.ts
508
+ import { globalRegistry as globalRegistry4, z as z5 } from "zod";
509
+ var RouterDataLakeConfigZod = z5.object({
510
+ driver: z5.literal("router").register(globalRegistry4, {
511
+ description: "Driver for the router data lake",
512
+ type: "string"
513
+ }),
514
+ children: z5.array(z5.lazy(() => DataLakeConfigZod)).register(globalRegistry4, {
515
+ description: "Child data lake drivers",
516
+ type: "array"
517
+ })
518
+ }).describe("Configuration for the router data lake driver");
519
+
520
+ // src/config/DataLake/DataLake.ts
521
+ var DataLakeConfigZod = z6.lazy(() => z6.union([RestDataLakeConfigZod, RouterDataLakeConfigZod])).describe("Configuration for a data lake");
522
+
523
+ // src/config/Evm.ts
524
+ import { globalRegistry as globalRegistry5, z as z7 } from "zod";
525
+ var EvmInfuraConfigZod = z7.object({
526
+ projectId: z7.string().optional().register(globalRegistry5, {
527
+ description: "Infura project ID",
528
+ title: "evm.infura.projectId",
529
+ type: "string"
530
+ }),
531
+ projectSecret: z7.string().optional().register(globalRegistry5, {
532
+ description: "Infura project secret",
533
+ title: "evm.infura.projectSecret",
534
+ type: "string"
535
+ })
536
+ });
537
+ var EvmJsonRpcConfigZod = z7.object({
538
+ url: z7.url().optional().register(globalRegistry5, {
539
+ description: "JSON-RPC URL",
540
+ title: "evm.jsonRpc.url",
541
+ type: "string"
542
+ })
543
+ });
544
+ var EvmConfigZod = z7.object({
545
+ chainId: z7.string().optional().register(globalRegistry5, {
546
+ description: "EVM chain ID",
547
+ title: "evm.chainId",
548
+ type: "string"
549
+ }),
550
+ infura: EvmInfuraConfigZod.optional().describe("Infura Provider configuration"),
551
+ jsonRpc: EvmJsonRpcConfigZod.optional().describe("JSON-RPC Provider configuration")
552
+ });
553
+
554
+ // src/config/Log.ts
555
+ import { LogLevel } from "@xylabs/sdk-js";
556
+ import { globalRegistry as globalRegistry6, z as z8 } from "zod";
557
+ var LogLevelNames = Object.keys(LogLevel);
558
+ var LogConfigZod = z8.object({
559
+ logLevel: z8.enum(LogLevelNames).default("info").register(globalRegistry6, {
560
+ choices: LogLevelNames,
561
+ default: "info",
562
+ description: "Desired process verbosity",
563
+ title: "logLevel",
564
+ type: "string"
565
+ }),
566
+ silent: z8.boolean().default(false).register(globalRegistry6, {
567
+ default: false,
568
+ description: "Whether to run in silent mode",
569
+ title: "silent",
570
+ type: "boolean"
571
+ })
572
+ });
573
+
574
+ // src/config/Providers.ts
575
+ import z10 from "zod";
576
+
577
+ // src/config/Provider.ts
578
+ import {
579
+ zodAsFactory,
580
+ zodIsFactory,
581
+ zodToFactory
582
+ } from "@xylabs/sdk-js";
583
+ import { z as z9 } from "zod";
584
+ var ProviderConfigZod = z9.object({
585
+ moniker: z9.string(),
586
+ labels: z9.array(z9.string()).optional()
587
+ }).describe("Configuration for a Provider");
588
+ var isProviderConfig = zodIsFactory(ProviderConfigZod);
589
+ var asProviderConfig = zodAsFactory(ProviderConfigZod, "asProviderConfig");
590
+ var toProviderConfig = zodToFactory(ProviderConfigZod, "toProviderConfig");
591
+
592
+ // src/config/Providers.ts
593
+ var ProvidersConfigZod = z10.array(ProviderConfigZod.loose()).describe("Configuration for providers").default([]);
594
+
595
+ // src/config/Remote.ts
596
+ import { globalRegistry as globalRegistry7, z as z11 } from "zod";
597
+ var RpcRemoteConfigBaseZod = z11.object({
598
+ protocol: z11.string("http").register(globalRegistry7, {
599
+ description: "Protocol for the RPC connection",
600
+ type: "string"
601
+ })
602
+ }).describe("Base configuration for the remote RPC");
603
+ var HttpRpcRemoteConfigZod = RpcRemoteConfigBaseZod.extend({
604
+ protocol: z11.string("http").register(globalRegistry7, {
605
+ description: "Protocol for the RPC connection",
606
+ type: "string"
607
+ }).default("http"),
608
+ url: z11.string().register(globalRegistry7, {
609
+ description: "URL for the Chain RPC API",
610
+ type: "string"
611
+ })
612
+ }).describe("Configuration for the remote RPC using Http");
613
+ var PostMessageRpcRemoteConfigZod = RpcRemoteConfigBaseZod.extend({
614
+ protocol: z11.string().register(globalRegistry7, {
615
+ description: "Protocol for the RPC connection",
616
+ type: "string"
617
+ }).default("postMessage"),
618
+ networkId: z11.string().register(globalRegistry7, {
619
+ description: "Network ID to use for the postMessage RPC connection",
620
+ type: "string"
621
+ }),
622
+ sessionId: z11.string().register(globalRegistry7, {
623
+ description: "Session ID to use for the postMessage RPC connection",
624
+ type: "string"
625
+ })
626
+ }).describe("Configuration for the remote RPC using postMessage");
627
+ var RpcRemoteConfigZod = z11.union([HttpRpcRemoteConfigZod, PostMessageRpcRemoteConfigZod]).describe("Configuration for a remote RPC connection, either Http or postMessage");
628
+ var RemoteConfigZod = z11.object({ rpc: RpcRemoteConfigZod.optional() }).describe("Configuration for remote connections, including RPC");
629
+
630
+ // src/config/storage/driver/Mongo.ts
631
+ import { isDefined, isUndefined } from "@xylabs/sdk-js";
632
+ import { globalRegistry as globalRegistry8, z as z12 } from "zod";
633
+ var MongoConfigZod = z12.object({
634
+ // TODO: Create from other arguments
635
+ connectionString: z12.string().nonempty().optional().register(globalRegistry8, {
636
+ description: "MongoDB connection string",
637
+ title: "storage.mongo.connectionString",
638
+ type: "string"
639
+ }),
640
+ database: z12.string().nonempty().optional().register(globalRegistry8, {
641
+ description: "MongoDB database name",
642
+ title: "storage.mongo.database",
643
+ type: "string"
644
+ }),
645
+ domain: z12.string().nonempty().optional().register(globalRegistry8, {
646
+ description: "MongoDB domain",
647
+ title: "storage.mongo.domain",
648
+ type: "string"
649
+ }),
650
+ password: z12.string().nonempty().optional().register(globalRegistry8, {
651
+ description: "MongoDB password",
652
+ title: "storage.mongo.password",
653
+ type: "string"
654
+ }),
655
+ username: z12.string().nonempty().optional().register(globalRegistry8, {
656
+ description: "MongoDB username",
657
+ title: "storage.mongo.username",
658
+ type: "string"
659
+ })
660
+ });
661
+
662
+ // src/config/storage/Storage.ts
663
+ import { globalRegistry as globalRegistry9, z as z13 } from "zod";
664
+ var StorageConfigZod = z13.object({
665
+ mongo: MongoConfigZod.optional().describe("Configuration for the MongoD storage driver"),
666
+ root: z13.string().optional().register(globalRegistry9, {
667
+ description: "Root directory for local storage",
668
+ title: "storage.root",
669
+ type: "string"
670
+ })
671
+ }).describe("Storage configuration options");
672
+
673
+ // src/config/Telemetry.ts
674
+ import { globalRegistry as globalRegistry10, z as z14 } from "zod";
675
+ var MetricsScrapeConfigZod = z14.object({
676
+ path: z14.string().default("/metrics").register(globalRegistry10, {
677
+ default: "/metrics",
678
+ description: "Path for the metrics scrape endpoint",
679
+ title: "telemetry.metrics.scrape.path",
680
+ type: "string"
681
+ }),
682
+ port: z14.coerce.number().int().positive().optional().register(globalRegistry10, {
683
+ description: "Port for the metrics scrape endpoint",
684
+ title: "telemetry.metrics.scrape.port",
685
+ type: "number"
686
+ })
687
+ }).describe("Metrics scrape configuration");
688
+ var MetricsConfigZod = z14.object({ scrape: MetricsScrapeConfigZod }).describe("Metrics configuration options");
689
+ var OpenTelemetryConfigZod = z14.object({
690
+ // OpenTelemetry options
691
+ otlpEndpoint: z14.url().optional().register(globalRegistry10, {
692
+ description: "OTLP endpoint for exporting telemetry data",
693
+ title: "telemetry.otel.otlpEndpoint",
694
+ type: "string"
695
+ })
696
+ });
697
+ var TelemetryConfigZod = z14.object({
698
+ // Metrics configuration
699
+ metrics: MetricsConfigZod.optional().describe("Metrics configuration"),
700
+ // OpenTelemetry configuration
701
+ otel: OpenTelemetryConfigZod.optional().describe("OpenTelemetry configuration")
702
+ }).describe("Telemetry configuration options");
703
+
704
+ // src/config/Validation.ts
705
+ import { AddressZod as AddressZod2, asAddress } from "@xylabs/sdk-js";
706
+ import { globalRegistry as globalRegistry11, z as z15 } from "zod";
707
+
708
+ // src/primitives/block/rate/blockRate.ts
709
+ import { isDefined as isDefined3, isFalsy } from "@xylabs/sdk-js";
710
+ import { asXL1BlockRange } from "@xyo-network/xl1-protocol-lib";
711
+
712
+ // src/primitives/block/rate/timeHelpers.ts
713
+ import { assertEx as assertEx5, isDefined as isDefined2 } from "@xylabs/sdk-js";
714
+ var rateMultipliers = {
715
+ millis: 1,
716
+ seconds: 1e3,
717
+ minutes: 1e3 * 60,
718
+ hours: 1e3 * 60 * 60,
719
+ days: 1e3 * 60 * 60 * 24,
720
+ weeks: 1e3 * 60 * 60 * 24 * 7
721
+ };
722
+ var timeDurations = (timeInMs) => ({
723
+ millis: timeInMs,
724
+ seconds: timeInMs / 1e3,
725
+ minutes: timeInMs / (1e3 * 60),
726
+ hours: timeInMs / (1e3 * 60 * 60),
727
+ days: timeInMs / (1e3 * 60 * 60 * 24),
728
+ weeks: timeInMs / (1e3 * 60 * 60 * 24 * 7)
729
+ });
730
+ var getTimeConfigInMilliseconds = (timeConfig) => {
731
+ const assertedTimeConfig = assertEx5(isDefined2(timeConfig) ? timeConfig : void 0, () => "Time configuration must be provided");
732
+ let totalMilliseconds = 0;
733
+ if ("years" in assertedTimeConfig) {
734
+ totalMilliseconds += assertedTimeConfig.years * 31536e6;
735
+ return totalMilliseconds;
736
+ }
737
+ if ("months" in assertedTimeConfig) {
738
+ totalMilliseconds += assertedTimeConfig.months * 2592e6;
739
+ return totalMilliseconds;
740
+ }
741
+ if ("weeks" in assertedTimeConfig) {
742
+ totalMilliseconds += assertedTimeConfig.weeks * 6048e5;
743
+ return totalMilliseconds;
744
+ }
745
+ if ("days" in assertedTimeConfig) {
746
+ totalMilliseconds += assertedTimeConfig.days * 864e5;
747
+ return totalMilliseconds;
748
+ }
749
+ if ("hours" in assertedTimeConfig) {
750
+ totalMilliseconds += assertedTimeConfig.hours * 36e5;
751
+ return totalMilliseconds;
752
+ }
753
+ if ("minutes" in assertedTimeConfig) {
754
+ totalMilliseconds += assertedTimeConfig.minutes * 6e4;
755
+ return totalMilliseconds;
756
+ }
757
+ return totalMilliseconds;
758
+ };
759
+
760
+ // src/primitives/block/rate/blockRate.ts
761
+ var blockRate = (startBlock, endBlock, timeUnit) => {
762
+ const startingBlock = startBlock[0];
763
+ const endingBlock = endBlock[0];
764
+ const heightDifference = endingBlock.block - startingBlock.block;
765
+ const timeDifference = endingBlock.$epoch - startingBlock.$epoch;
766
+ if (timeDifference === 0) {
767
+ throw new Error("Time difference must be greater than 0");
768
+ }
769
+ const rate = heightDifference / timeDifference;
770
+ const timeUnitValue = isDefined3(timeUnit) ? timeUnit : "millis";
771
+ const returnedTimeDifference = isDefined3(timeUnit) ? timeDurations(timeDifference)[timeUnit] : timeDifference;
772
+ const timePerBlock = returnedTimeDifference / heightDifference;
773
+ return {
774
+ range: asXL1BlockRange([startingBlock.block, endingBlock.block], true),
775
+ span: heightDifference,
776
+ rate: isDefined3(timeUnit) ? rate * rateMultipliers[timeUnit] : rate,
777
+ timeUnit: timeUnitValue,
778
+ timeDifference: returnedTimeDifference,
779
+ timePerBlock
780
+ };
781
+ };
782
+ var getBlockRateBlocks = async (viewer, startBlockHeight, endBlockHeight) => {
783
+ if (endBlockHeight <= startBlockHeight) {
784
+ console.error("startBlockHeight", startBlockHeight);
785
+ console.error("endBlockHeight", endBlockHeight);
786
+ throw new Error("End block height must be greater than start block height");
787
+ }
788
+ const startingBlock = await viewer.blockByNumber(startBlockHeight);
789
+ const endingBlock = await viewer.blockByNumber(endBlockHeight);
790
+ if (isFalsy(startingBlock) || isFalsy(endingBlock)) {
791
+ throw new Error("Could not retrieve blocks for speed calculation");
792
+ }
793
+ return { startingBlock, endingBlock };
794
+ };
795
+ var calculateBlockRate = async (viewer, range, timeUnit) => {
796
+ const [startBlockHeight, endBlockHeight] = range;
797
+ const { startingBlock, endingBlock } = await getBlockRateBlocks(
798
+ viewer,
799
+ startBlockHeight,
800
+ endBlockHeight
801
+ );
802
+ return blockRate(startingBlock, endingBlock, timeUnit);
803
+ };
804
+
805
+ // src/primitives/block/rate/stepRate.ts
806
+ import { assertEx as assertEx6 } from "@xylabs/sdk-js";
807
+ import {
808
+ asXL1BlockRange as asXL1BlockRange2,
809
+ isValidStep,
810
+ StepSizes
811
+ } from "@xyo-network/xl1-protocol-lib";
812
+ var stepRate = async (viewer, start, step, count = 1, timeUnit) => {
813
+ const end = start + step * count;
814
+ const range = asXL1BlockRange2([start, end], true);
815
+ return await calculateBlockRate(viewer, range, timeUnit);
816
+ };
817
+ var calculateStepSizeRate = async (viewer, start, stepIndex, count = 1, timeUnit) => {
818
+ assertEx6(isValidStep(stepIndex), () => `Invalid step index: ${stepIndex}`);
819
+ const step = StepSizes[stepIndex];
820
+ return await stepRate(viewer, start, step, count, timeUnit);
821
+ };
822
+
823
+ // src/primitives/block/rate/timeRate.ts
824
+ import {
825
+ assertEx as assertEx7,
826
+ isDefined as isDefined4,
827
+ isDefinedNotNull
828
+ } from "@xylabs/sdk-js";
829
+ import { asXL1BlockNumber as asXL1BlockNumber2, asXL1BlockRange as asXL1BlockRange3 } from "@xyo-network/xl1-protocol-lib";
830
+ var DEFAULT_TOLERANCE_MS = 3e4;
831
+ var DEFAULT_MAX_ATTEMPTS = 10;
832
+ var calculateTimeRate = async (viewer, timeConfig, startBlockNumber, timeUnit, toleranceMs = DEFAULT_TOLERANCE_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
833
+ assertEx7(Object.keys(timeConfig ?? {}).length === 1, () => "Only one time unit should be specified in timeConfig");
834
+ const startBlock = isDefinedNotNull(startBlockNumber) ? await viewer.blockByNumber(startBlockNumber) : null;
835
+ const resolvedStartBlock = isDefinedNotNull(startBlock) ? startBlock[0] : (await viewer.currentBlock())[0];
836
+ const timeInMilliseconds = getTimeConfigInMilliseconds(timeConfig);
837
+ assertEx7(timeInMilliseconds > 0, () => "Time duration must be greater than zero");
838
+ const blocksPerMillisecondRate = 1 / (12 * 1e3);
839
+ const initialBlocksInDuration = Math.floor(blocksPerMillisecondRate * timeInMilliseconds);
840
+ const endBlockNumber = await findEndBlockRecursive(
841
+ viewer,
842
+ resolvedStartBlock,
843
+ timeInMilliseconds,
844
+ initialBlocksInDuration,
845
+ toleranceMs,
846
+ maxAttempts
847
+ );
848
+ return await calculateBlockRate(
849
+ viewer,
850
+ asXL1BlockRange3([endBlockNumber, resolvedStartBlock.block], true),
851
+ timeUnit
852
+ );
853
+ };
854
+ var findEndBlockRecursive = async (viewer, startBlock, targetTimeMs, estimatedBlocksBack, toleranceMs, attemptsRemaining) => {
855
+ console.log(`Attempts remaining: ${attemptsRemaining}, Estimated blocks back: ${estimatedBlocksBack}`);
856
+ assertEx7(attemptsRemaining >= 0, () => "Maximum attempts reached while searching for end block");
857
+ const startBlockEpoch = startBlock.$epoch;
858
+ const estimatedEndBlockNumber = asXL1BlockNumber2(startBlock.block - estimatedBlocksBack, true);
859
+ if (estimatedEndBlockNumber < 0) {
860
+ throw new Error("Estimated end block number is less than zero");
861
+ }
862
+ const endBlock = await viewer.blockByNumber(estimatedEndBlockNumber);
863
+ const resolvedEndBlock = assertEx7(
864
+ isDefined4(endBlock?.[0]) ? endBlock[0] : void 0,
865
+ () => `Could not retrieve block ${estimatedEndBlockNumber} for time rate calculation`
866
+ );
867
+ const endBlockEpoch = resolvedEndBlock.$epoch;
868
+ if (!Number.isFinite(startBlockEpoch) || !Number.isFinite(endBlockEpoch)) {
869
+ throw new TypeError("Block has missing or invalid $epoch");
870
+ }
871
+ const actualTimeDifference = startBlockEpoch - endBlockEpoch;
872
+ if (actualTimeDifference === 0) {
873
+ throw new Error("Start and end blocks have identical timestamps");
874
+ }
875
+ const timeDelta = Math.abs(actualTimeDifference - targetTimeMs);
876
+ if (timeDelta <= toleranceMs) {
877
+ return resolvedEndBlock.block;
878
+ }
879
+ let adjustedBlocksBack;
880
+ if (actualTimeDifference < targetTimeMs) {
881
+ const adjustmentFactor = targetTimeMs / actualTimeDifference;
882
+ adjustedBlocksBack = Math.floor(estimatedBlocksBack * adjustmentFactor);
883
+ } else {
884
+ const adjustmentFactor = actualTimeDifference / targetTimeMs;
885
+ adjustedBlocksBack = Math.floor(estimatedBlocksBack / adjustmentFactor);
886
+ }
887
+ adjustedBlocksBack = Number.isFinite(adjustedBlocksBack) && adjustedBlocksBack >= 1 ? adjustedBlocksBack : 1;
888
+ return await findEndBlockRecursive(
889
+ viewer,
890
+ startBlock,
891
+ targetTimeMs,
892
+ adjustedBlocksBack,
893
+ toleranceMs,
894
+ attemptsRemaining - 1
895
+ );
896
+ };
897
+
898
+ // src/ChainContextHelpers.ts
899
+ import {
900
+ isDefined as isDefined6,
901
+ isObject,
902
+ isUndefined as isUndefined2,
903
+ timeBudget
904
+ } from "@xylabs/sdk-js";
905
+
906
+ // src/driver/cache/LruCacheMap.ts
907
+ import { LRUCache } from "lru-cache";
908
+ var LruCacheMap = class {
909
+ lruCache;
910
+ constructor(options) {
911
+ this.lruCache = new LRUCache(options ?? { max: 5e3 });
912
+ }
913
+ clear() {
914
+ this.lruCache.clear();
915
+ }
916
+ delete(id) {
917
+ return this.lruCache.delete(id);
918
+ }
919
+ get(id) {
920
+ return this.lruCache.get(id);
921
+ }
922
+ getMany(id) {
923
+ const results = [];
924
+ for (const key of id) {
925
+ const value = this.lruCache.get(key);
926
+ if (value !== void 0) {
927
+ results.push(value);
928
+ }
929
+ }
930
+ return results;
931
+ }
932
+ has(id) {
933
+ return this.lruCache.has(id);
934
+ }
935
+ set(id, data) {
936
+ this.lruCache.set(id, data);
937
+ }
938
+ setMany(entries) {
939
+ for (const [key, value] of entries) {
940
+ this.lruCache.set(key, value);
941
+ }
942
+ }
943
+ };
944
+
945
+ // src/driver/memory/MemoryMap.ts
946
+ import { isDefined as isDefined5 } from "@xylabs/sdk-js";
947
+ var MemoryMap = class {
948
+ map;
949
+ constructor() {
950
+ this.map = /* @__PURE__ */ new Map();
951
+ }
952
+ clear() {
953
+ this.map.clear();
954
+ }
955
+ delete(id) {
956
+ return this.map.delete(id);
957
+ }
958
+ get(id) {
959
+ return this.map.get(id);
960
+ }
961
+ getMany(ids) {
962
+ const results = [];
963
+ for (const id of ids) {
964
+ const data = this.map.get(id);
965
+ if (isDefined5(data)) {
966
+ results.push(data);
967
+ }
968
+ }
969
+ return results;
970
+ }
971
+ has(id) {
972
+ return this.map.has(id);
973
+ }
974
+ set(id, data) {
975
+ this.map.set(id, data);
976
+ }
977
+ setMany(entries) {
978
+ for (const [key, value] of entries) {
979
+ this.map.set(key, value);
980
+ }
981
+ }
982
+ };
983
+
984
+ // src/ChainContextHelpers.ts
985
+ function contextCache(context, name, create) {
986
+ if (!isObject(context.caches)) {
987
+ throw new Error("Context does not have an appropriate caches property");
988
+ }
989
+ if (isUndefined2(context.caches[name])) {
990
+ context.caches[name] = create?.() ?? new MemoryMap();
991
+ }
992
+ return context.caches[name];
993
+ }
994
+ async function withContextCacheResponse(context, name, key, func, { max = 1e4 } = {}) {
995
+ const cache = contextCache(
996
+ context,
997
+ name,
998
+ () => new LruCacheMap({ max })
999
+ );
1000
+ const { timeBudgetLimit = 0 } = context;
1001
+ const cacheResult = await cache.get(key);
1002
+ if (isDefined6(cacheResult)) {
1003
+ return cacheResult;
1004
+ }
1005
+ const result = timeBudgetLimit > 0 ? timeBudget(name, context.logger, func, timeBudgetLimit) : func();
1006
+ await cache.set(key, result);
1007
+ return result;
1008
+ }
1009
+
1010
+ // src/block/hydrate/allHashesPresent.ts
1011
+ function allHashesPresent(hashes, payloads) {
1012
+ const payloadHashes = new Set(payloads.map((p) => p._hash));
1013
+ return hashes.every((hash) => payloadHashes.has(hash));
1014
+ }
1015
+
1016
+ // src/block/hydrate/flattenHydratedBlock.ts
1017
+ import { toHydratedBlock } from "@xyo-network/xl1-protocol-lib";
1018
+ var flattenHydratedBlock = (hydratedBlock) => {
1019
+ const [blk, blkPayloads] = hydratedBlock;
1020
+ return [...blkPayloads, blk];
1021
+ };
1022
+
1023
+ // src/block/hydrate/flattenHydratedBlocks.ts
1024
+ var flattenHydratedBlocks = (hydratedBlocks) => hydratedBlocks.flatMap((blk) => flattenHydratedBlock(blk));
1025
+
1026
+ // src/block/hydrate/hydrateBlock.ts
1027
+ import { assertEx as assertEx8 } from "@xylabs/sdk-js";
1028
+ import { asAnyPayload as asAnyPayload2 } from "@xyo-network/sdk-js";
1029
+ import { asBlockBoundWitnessWithStorageMeta, isTransactionBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
1030
+ var hydrateBlock = async (context, hash, maxDepth = 1, minDepth = maxDepth) => {
1031
+ assertEx8(maxDepth >= 0, () => "maxDepth must be greater than or equal to 0");
1032
+ assertEx8(minDepth >= 0, () => "minDepth must be greater than or equal to 0");
1033
+ assertEx8(maxDepth >= minDepth, () => "maxDepth must be greater than or equal to minDepth");
1034
+ const { chainMap } = context;
1035
+ const [block] = await chainMap.get([hash]);
1036
+ const bw = assertEx8(asBlockBoundWitnessWithStorageMeta(
1037
+ assertEx8(block, () => `block ${hash} not found`)
1038
+ ), () => `hash ${hash} is not a BlockBoundWitness`);
1039
+ if (maxDepth === 0) return [bw, []];
1040
+ const blkPayloads = (await chainMap.get(bw.payload_hashes)).map((p) => asAnyPayload2(p, true));
1041
+ if (minDepth === 1) assertEx8(allHashesPresent(bw.payload_hashes, blkPayloads), () => `Unable to find all payloads for block ${hash}`);
1042
+ if (maxDepth === 1) return [bw, blkPayloads];
1043
+ const transactions = blkPayloads.filter(isTransactionBoundWitnessWithStorageMeta);
1044
+ const transactionsPayloadHashes = transactions.flatMap((tx) => tx.payload_hashes);
1045
+ const transactionsPayloads = (await chainMap.get(transactionsPayloadHashes)).map((p) => asAnyPayload2(p, true));
1046
+ assertEx8(allHashesPresent(transactionsPayloadHashes, transactionsPayloads), () => `Unable to find all payloads for transactions in block ${hash}`);
1047
+ const allPayloadsHashes = new Set([...blkPayloads, ...transactionsPayloads].flatMap((p) => p._hash));
1048
+ const allPayloads = (await chainMap.get([...allPayloadsHashes])).map((p) => asAnyPayload2(p, true));
1049
+ const allPayloadsFiltered = allPayloads.filter((p) => allPayloadsHashes.has(p._hash));
1050
+ if (maxDepth === 2) assertEx8(allHashesPresent(
1051
+ [...allPayloadsHashes],
1052
+ allPayloadsFiltered
1053
+ ), () => `Unable to find all payloads for transactions in block ${hash}`);
1054
+ return [bw, allPayloadsFiltered];
1055
+ };
1056
+
1057
+ // src/block/primitives/blockFromBlockNumber.ts
1058
+ import {
1059
+ asHash,
1060
+ isDefined as isDefined7,
1061
+ spanAsync
1062
+ } from "@xylabs/sdk-js";
1063
+ import { toSafeJsonString } from "@xylabs/sdk-js";
1064
+ import {
1065
+ asSignedBlockBoundWitnessWithStorageMeta,
1066
+ SignedBlockBoundWitnessWithHashMetaZod,
1067
+ StepSizes as StepSizes2
1068
+ } from "@xyo-network/xl1-protocol-lib";
1069
+ async function blockFromBlockNumber(context, blockNumber) {
1070
+ return await spanAsync("blockFromBlockNumber", async () => {
1071
+ const cacheKey = `${blockNumber}`;
1072
+ const { chainMap, head } = context;
1073
+ return await withContextCacheResponse(context, "blockFromBlockNumber", cacheKey, async () => {
1074
+ const [result] = await chainMap.get([head._hash]);
1075
+ if (!isDefined7(result)) {
1076
+ throw new Error(`Head block not found for hash: ${head._hash}`);
1077
+ }
1078
+ let currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
1079
+ result,
1080
+ () => `Found Payload is not a Signed<BlockBoundWitness>: ${JSON.stringify(result, null, 2)}`
1081
+ );
1082
+ if (currentBlock.block < blockNumber) {
1083
+ throw new Error(`Block number ${blockNumber} is greater than head ${currentBlock.block}.`);
1084
+ }
1085
+ while (currentBlock.block > blockNumber) {
1086
+ let jumpHash = currentBlock.previous;
1087
+ let jumpBlockNumber = currentBlock.block - 1;
1088
+ for (const [step, stepSize] of StepSizes2.entries()) {
1089
+ const possibleJumpBlockNumber = currentBlock.block - currentBlock.block % stepSize - 1;
1090
+ if (possibleJumpBlockNumber >= blockNumber && possibleJumpBlockNumber <= jumpBlockNumber) {
1091
+ jumpBlockNumber = possibleJumpBlockNumber;
1092
+ jumpHash = asHash(currentBlock.step_hashes?.at(step), () => `Step hash not found for step ${step} in block ${currentBlock.block}`);
1093
+ }
1094
+ }
1095
+ const [newBlock] = await chainMap.get([
1096
+ asHash(jumpHash, () => `Jump hash not found for block number [${blockNumber}]: ${jumpBlockNumber} ${toSafeJsonString(currentBlock, 10)}`)
1097
+ ]);
1098
+ if (!isDefined7(newBlock)) {
1099
+ throw new Error(`Block not found for jump hash: ${jumpHash}`);
1100
+ }
1101
+ currentBlock = asSignedBlockBoundWitnessWithStorageMeta(
1102
+ newBlock,
1103
+ () => {
1104
+ const result2 = SignedBlockBoundWitnessWithHashMetaZod.safeParse(newBlock);
1105
+ return `Found Payload [jump hash] is not a Signed<BlockBoundWitness>: ${result2.error}`;
1106
+ }
1107
+ );
1108
+ if (currentBlock.block === blockNumber) {
1109
+ break;
1110
+ }
1111
+ if (currentBlock.block < blockNumber) {
1112
+ throw new Error(`Block number ${blockNumber} is not a valid step block number for block ${head._hash}.`);
1113
+ }
1114
+ }
1115
+ return currentBlock;
1116
+ });
1117
+ }, { ...context, timeBudgetLimit: 500 });
1118
+ }
1119
+
1120
+ // src/block/primitives/validateTransactionOpcodes.ts
1121
+ import {
1122
+ assertEx as assertEx9,
1123
+ isHash,
1124
+ toSafeJsonString as toSafeJsonString2
1125
+ } from "@xylabs/sdk-js";
1126
+ import {
1127
+ PayloadBuilder as PayloadBuilder3
1128
+ } from "@xyo-network/sdk-js";
1129
+ import { isExecutable } from "@xyo-network/xl1-protocol-lib";
1130
+ async function validateTransactionsOpcodes(txs) {
1131
+ const txElevatedPayloads = [];
1132
+ for (const [txBw, txPayloads] of txs) {
1133
+ if (isExecutable(txBw)) {
1134
+ const operations = txBw.script.map((op) => op.split("|"));
1135
+ for (const [opCode, ...args] of operations) {
1136
+ switch (opCode) {
1137
+ case "elevate": {
1138
+ const [hash, ...rest] = args;
1139
+ const txPayloadsWithStorageMeta = await PayloadBuilder3.addStorageMeta(txPayloads);
1140
+ assertEx9(rest.length === 0, () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Too many Arguments`);
1141
+ if (isHash(hash)) {
1142
+ assertEx9(
1143
+ txBw.payload_hashes.includes(hash),
1144
+ () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Hash not in payload hashes => ${toSafeJsonString2(txBw, 20)}`
1145
+ );
1146
+ const txPayload = assertEx9(
1147
+ txPayloadsWithStorageMeta.find((p) => p._hash === hash),
1148
+ () => `Invalid elevate operation ${opCode} ${args.join(", ")} - Payload not found`
1149
+ );
1150
+ txElevatedPayloads.push(txPayload);
1151
+ } else {
1152
+ throw new Error(`Invalid elevate operation ${opCode} ${args.join(", ")} - Invalid hash`);
1153
+ }
1154
+ break;
1155
+ }
1156
+ default: {
1157
+ throw new Error(`Invalid opCode ${opCode}`);
1158
+ }
1159
+ }
1160
+ }
1161
+ }
1162
+ }
1163
+ return txElevatedPayloads;
1164
+ }
1165
+
1166
+ // src/primitives/datalake/addDataLakePayloadsToPayloads.ts
1167
+ import { isUndefined as isUndefined3 } from "@xylabs/sdk-js";
1168
+ import { isAnyPayload, PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
1169
+ async function addDataLakePayloadsToPayloads(hashes, payloads, dataLakeViewer) {
1170
+ if (isUndefined3(dataLakeViewer)) return [payloads, []];
1171
+ const missingPayloadHashes = hashes.filter((hash) => !payloads.some((p) => p._hash === hash));
1172
+ const payloadsFromDataLake = await PayloadBuilder4.addHashMeta(
1173
+ await PayloadBuilder4.addHashMeta((await dataLakeViewer.get(missingPayloadHashes)).filter(isAnyPayload))
1174
+ );
1175
+ return [[...payloads, ...payloadsFromDataLake], payloadsFromDataLake.map((p) => p._hash)];
1176
+ }
1177
+
1178
+ // src/primitives/datalake/addDataLakePayloads.ts
1179
+ async function addDataLakePayloads([boundWitness, payloads], dataLakeViewer) {
1180
+ const [updatedPayloads, foundHashes] = await addDataLakePayloadsToPayloads(boundWitness.payload_hashes, payloads, dataLakeViewer);
1181
+ return [
1182
+ [
1183
+ boundWitness,
1184
+ updatedPayloads
1185
+ ],
1186
+ foundHashes
1187
+ ];
1188
+ }
1189
+
1190
+ // src/primitives/state/findMostRecentBlock.ts
1191
+ import { isSignedBlockBoundWitnessWithStorageMeta } from "@xyo-network/xl1-protocol-lib";
1192
+ var DEFAULT_NEXT_OPTIONS = { limit: 50 };
1193
+ var findMostRecentBlock = async (chainArchivist, nextOptions = DEFAULT_NEXT_OPTIONS, maxIterations = Number.POSITIVE_INFINITY) => {
1194
+ let mostRecentBlock;
1195
+ let cursor;
1196
+ let batch;
1197
+ let iterations = 0;
1198
+ do {
1199
+ batch = await chainArchivist.next({
1200
+ ...nextOptions,
1201
+ order: "desc",
1202
+ cursor
1203
+ });
1204
+ const blocks = batch.filter(isSignedBlockBoundWitnessWithStorageMeta);
1205
+ const last = blocks?.at(0);
1206
+ if (last) {
1207
+ mostRecentBlock = last;
1208
+ break;
1209
+ } else {
1210
+ cursor = batch.at(-1)?._sequence;
1211
+ }
1212
+ iterations = iterations + 1;
1213
+ } while (batch.length > 0 && iterations < maxIterations);
1214
+ return mostRecentBlock;
1215
+ };
1216
+
1217
+ // src/primitives/state/hydratedBlockByNumber.ts
1218
+ import { assertEx as assertEx10, spanAsync as spanAsync2 } from "@xylabs/sdk-js";
1219
+ async function hydratedBlockByNumber(context, blockNumber) {
1220
+ return await spanAsync2("hydratedBlockByNumber", async () => {
1221
+ if (blockNumber < 0) throw new Error(`Block number ${blockNumber} is less than 0`);
1222
+ if (blockNumber > Number.MAX_SAFE_INTEGER) throw new Error(`Block number ${blockNumber} is greater than the maximum safe integer`);
1223
+ if (blockNumber % 1 !== 0) throw new Error(`Block number ${blockNumber} is not an integer`);
1224
+ const cacheKey = `${blockNumber}`;
1225
+ return await withContextCacheResponse(context, "hydratedBlockByNumber", cacheKey, async () => {
1226
+ const block = assertEx10(
1227
+ await blockFromBlockNumber(context, blockNumber),
1228
+ () => `Could not find block for block number ${blockNumber}`
1229
+ );
1230
+ return await hydrateBlock(context, block._hash);
1231
+ }, { max: 2e4 });
1232
+ }, { ...context, timeBudgetLimit: 500 });
1233
+ }
1234
+
1235
+ // src/primitives/uncle/findBestUncle.ts
1236
+ var DEFAULT_MIN_CANDIDATES = 2;
1237
+ var DEFAULT_BACKOFF_MS = 12e4;
1238
+
1239
+ // src/config/Validation.ts
1240
+ var ValidationConfigZod = z15.object({
1241
+ allowedRewardRedeemers: z15.preprocess((val) => {
1242
+ if (typeof val === "string") {
1243
+ return val.split(",").map((s) => asAddress(s.trim()));
1244
+ }
1245
+ return val;
1246
+ }, z15.array(AddressZod2).optional().register(globalRegistry11, {
1247
+ description: "List of allowed reward redeemer addresses, if undefined anyone can participate",
1248
+ title: "allowedRewardRedeemers",
1249
+ type: "array"
1250
+ })),
1251
+ allowedRewardEscrowAccountSigners: z15.preprocess((val) => {
1252
+ if (typeof val === "string") {
1253
+ return val.split(",").map((s) => asAddress(s.trim()));
1254
+ }
1255
+ return val;
1256
+ }, z15.array(AddressZod2).optional().register(globalRegistry11, {
1257
+ description: "List of allowed reward escrow account signer addresses, if undefined anyone can participate",
1258
+ title: "allowedRewardEscrowAccountSigners",
1259
+ type: "array"
1260
+ })),
1261
+ minCandidates: z15.coerce.number().default(DEFAULT_MIN_CANDIDATES).register(globalRegistry11, {
1262
+ default: DEFAULT_MIN_CANDIDATES,
1263
+ description: "Minimum number of uncle candidates before selecting the best uncle",
1264
+ title: "validation.minCandidates",
1265
+ type: "number"
1266
+ }),
1267
+ backoffMs: z15.coerce.number().default(DEFAULT_BACKOFF_MS).register(globalRegistry11, {
1268
+ default: DEFAULT_BACKOFF_MS,
1269
+ description: "Back-off timeout in ms. If head age exceeds this, minCandidates is ignored",
1270
+ title: "validation.backoffMs",
1271
+ type: "number"
1272
+ })
1273
+ });
1274
+
1275
+ // src/config/Base.ts
1276
+ var BaseConfigZod = z16.object({
1277
+ chain: ChainConfigZod.default(ChainConfigZod.parse({})).describe("Configuration for the chain"),
1278
+ dataLake: DataLakeConfigZod.optional().describe("Configuration for data lakes"),
1279
+ evm: EvmConfigZod.default(EvmConfigZod.parse({})).describe("Configuration for EVM-backed services"),
1280
+ log: LogConfigZod.default(LogConfigZod.parse({})).describe("Configuration for logging"),
1281
+ providers: ProvidersConfigZod.default(ProvidersConfigZod.parse([])).describe("Configuration for providers"),
1282
+ remote: RemoteConfigZod.default(RemoteConfigZod.parse({})).describe("Configuration for remote services"),
1283
+ storage: StorageConfigZod.default(StorageConfigZod.parse({})).describe("Configuration for the storage"),
1284
+ telemetry: TelemetryConfigZod.default(TelemetryConfigZod.parse({})).describe("Configuration for telemetry"),
1285
+ validation: ValidationConfigZod.default(ValidationConfigZod.parse({})).describe("Configuration for validation")
1286
+ });
1287
+
1288
+ // src/config/Actor.ts
1289
+ var ActorConfigZod = BaseConfigZod.extend({
1290
+ name: z17.string(),
1291
+ mnemonic: MnemonicStringZod.optional().register(globalRegistry12, {
1292
+ description: "Mnemonic for the Actor wallet",
1293
+ title: "mnemonic",
1294
+ type: "string"
1295
+ }),
1296
+ healthCheckPort: z17.coerce.number().optional().register(globalRegistry12, {
1297
+ description: "Port for the Producer health checks",
1298
+ title: "producer.healthCheckPort",
1299
+ type: "number"
1300
+ })
1301
+ });
1302
+ var isActorConfig = zodIsFactory2(ActorConfigZod);
1303
+ var asActorConfig = zodAsFactory2(ActorConfigZod, "asActorConfig");
1304
+ var toActorConfig = zodToFactory2(ActorConfigZod, "toActorConfig");
1305
+
1306
+ // src/config/Actors.ts
1307
+ import z18 from "zod";
1308
+ var ActorsConfigZod = z18.array(ActorConfigZod.loose()).describe("Actor-specific configurations that override the base configuration when the actor is running").default([]);
1309
+
1310
+ // src/config/Config.ts
1311
+ var ConfigZod = BaseConfigZod.extend({ actors: ActorsConfigZod }).describe("The complete configuration for the protocol, including global settings and actor-specific overrides");
1312
+
1313
+ // src/simple/block/SimpleBlockViewer.ts
1314
+ import {
1315
+ assertEx as assertEx11,
1316
+ exists,
1317
+ isUndefined as isUndefined4
1318
+ } from "@xylabs/sdk-js";
1319
+ import {
1320
+ asSignedHydratedBlockWithHashMeta,
1321
+ asSignedHydratedBlockWithStorageMeta,
1322
+ asXL1BlockNumber as asXL1BlockNumber3,
1323
+ BlockViewerMoniker,
1324
+ DataLakeViewerMoniker,
1325
+ FinalizationViewerMoniker
1326
+ } from "@xyo-network/xl1-protocol-lib";
1327
+
1328
+ // src/utils/HydratedCache.ts
1329
+ import { LRUCache as LRUCache2 } from "lru-cache";
1330
+ var HydratedCache = class {
1331
+ cache;
1332
+ context;
1333
+ hydrateFunction;
1334
+ constructor(context, hydrateFunction, maxCount = 2e3, ttl = Number.MAX_SAFE_INTEGER) {
1335
+ this.context = context;
1336
+ this.hydrateFunction = hydrateFunction;
1337
+ this.cache = new LRUCache2({ max: maxCount, ttl });
1338
+ }
1339
+ async get(hash) {
1340
+ const existing = this.cache.get(hash);
1341
+ if (existing !== void 0) return existing;
1342
+ const block = await this.hydrateFunction(this.context, hash) ?? null;
1343
+ if (block !== null) this.cache.set(hash, block);
1344
+ return block;
1345
+ }
1346
+ has(hash) {
1347
+ return this.cache.has(hash);
1348
+ }
1349
+ };
1350
+
1351
+ // src/simple/block/SimpleBlockViewer.ts
1352
+ var SimpleBlockViewer = class extends AbstractCreatableProvider {
1353
+ moniker = SimpleBlockViewer.defaultMoniker;
1354
+ _store;
1355
+ dataLakeViewer;
1356
+ finalizationViewer;
1357
+ payloadCache = new LruCacheMap({ max: 1e4 });
1358
+ signedHydratedBlockWithDataLakePayloadsCache = new LruCacheMap({ max: 2e3, ttl: 1e3 * 60 * 60 });
1359
+ _signedHydratedBlockCache;
1360
+ get finalizedArchivist() {
1361
+ return this.params.finalizedArchivist;
1362
+ }
1363
+ get hydratedBlockCache() {
1364
+ if (this._signedHydratedBlockCache) return this._signedHydratedBlockCache;
1365
+ const context = this.getBlockContextRead();
1366
+ this._signedHydratedBlockCache = new HydratedCache(context, async (context2, hash, maxDepth, minDepth) => {
1367
+ const result = await hydrateBlock(context2, hash, maxDepth, minDepth);
1368
+ return asSignedHydratedBlockWithStorageMeta(result, true);
1369
+ }, 2e4);
1370
+ return this._signedHydratedBlockCache;
1371
+ }
1372
+ get store() {
1373
+ return this._store;
1374
+ }
1375
+ static async paramsHandler(params) {
1376
+ return {
1377
+ ...await super.paramsHandler(params),
1378
+ finalizedArchivist: assertEx11(params.finalizedArchivist, () => "finalizedArchivist is required")
1379
+ };
1380
+ }
1381
+ async blockByHash(hash) {
1382
+ return await this.spanAsync("blockByHash", async () => {
1383
+ const cachedBlock = this.signedHydratedBlockWithDataLakePayloadsCache.get(hash);
1384
+ if (cachedBlock) {
1385
+ return cachedBlock;
1386
+ }
1387
+ const cache = this.hydratedBlockCache;
1388
+ const block = await cache.get(hash);
1389
+ const [result] = block ? await addDataLakePayloads(block, this.dataLakeViewer) : [null, []];
1390
+ if (result) {
1391
+ this.signedHydratedBlockWithDataLakePayloadsCache.set(hash, result);
1392
+ }
1393
+ return result;
1394
+ }, { ...this.context, timeBudgetLimit: 100 });
1395
+ }
1396
+ async blockByNumber(blockNumber) {
1397
+ return await this.spanAsync("blockByNumber", async () => {
1398
+ const chainContext = await this.getChainContextRead();
1399
+ if (isUndefined4(chainContext.head)) {
1400
+ return null;
1401
+ }
1402
+ return await this.blockByNumberWithContext(chainContext, blockNumber);
1403
+ }, { ...this.context, timeBudgetLimit: 100 });
1404
+ }
1405
+ async blocksByHash(hash, limit = 50) {
1406
+ return await this.spanAsync("blocksByHash", async () => {
1407
+ assertEx11(limit > 0, () => "limit must be greater than 0");
1408
+ assertEx11(limit <= 100, () => "limit must be less than 100");
1409
+ const blocks = [];
1410
+ let current = await this.blockByHash(hash);
1411
+ while (current && blocks.length < limit) {
1412
+ blocks.push(current);
1413
+ const previousHash = current[0].previous;
1414
+ if (previousHash === null) break;
1415
+ current = await this.blockByHash(previousHash);
1416
+ }
1417
+ return blocks.map((b) => asSignedHydratedBlockWithHashMeta(b, true));
1418
+ }, { ...this.context, timeBudgetLimit: 300 });
1419
+ }
1420
+ async blocksByNumber(blockNumber, limit = 50) {
1421
+ return await this.spanAsync("blocksByNumber", async () => {
1422
+ assertEx11(limit > 0, () => "limit must be greater than 0");
1423
+ assertEx11(limit <= 100, () => "limit must be less than 100");
1424
+ const chainContext = await this.getChainContextRead();
1425
+ if (isUndefined4(chainContext.head)) {
1426
+ return [];
1427
+ }
1428
+ const blocks = [];
1429
+ let current = await this.blockByNumberWithContext(chainContext, blockNumber);
1430
+ while (current && blocks.length < limit) {
1431
+ blocks.push(current);
1432
+ if (current[0].block === 0) break;
1433
+ const previousNumber = asXL1BlockNumber3(current[0].block - 1, true);
1434
+ current = await this.blockByNumberWithContext(chainContext, previousNumber);
1435
+ }
1436
+ return blocks.map((b) => asSignedHydratedBlockWithHashMeta(b, true));
1437
+ }, this.context);
1438
+ }
1439
+ async chainId(blockNumber = "latest") {
1440
+ return await this.spanAsync("chainId", async () => {
1441
+ return blockNumber === "latest" ? (await this.finalizationViewer.headBlock()).chain : assertEx11(await this.blockByNumber(blockNumber), () => `Block not found [${blockNumber}]`)[0].chain;
1442
+ }, this.context);
1443
+ }
1444
+ async createHandler() {
1445
+ await super.createHandler();
1446
+ this.dataLakeViewer = await this.locator.tryGetInstance(DataLakeViewerMoniker);
1447
+ this.finalizationViewer = await this.locator.getInstance(FinalizationViewerMoniker);
1448
+ this._store = { chainMap: this.params.finalizedArchivist };
1449
+ }
1450
+ async currentBlock() {
1451
+ const [result] = await addDataLakePayloads(await this.finalizationViewer.head(), this.dataLakeViewer);
1452
+ return result;
1453
+ }
1454
+ async currentBlockHash() {
1455
+ return await this.finalizationViewer.headHash();
1456
+ }
1457
+ async currentBlockNumber() {
1458
+ return await this.finalizationViewer.headNumber();
1459
+ }
1460
+ async payloadByHash(hash) {
1461
+ const [payload] = await this.payloadsByHash([hash]);
1462
+ return payload ?? null;
1463
+ }
1464
+ async payloadsByHash(hashes) {
1465
+ let remainingHashes = [...hashes];
1466
+ const cachedPayloads = this.payloadCache.getMany(remainingHashes);
1467
+ const cachedHashes = new Set(cachedPayloads.map((p) => p._hash));
1468
+ remainingHashes = remainingHashes.filter((h) => !cachedHashes.has(h));
1469
+ const finalizedPayloads = remainingHashes.length > 0 ? await this.finalizedArchivist.get(remainingHashes) : [];
1470
+ const [resultPayloads] = await addDataLakePayloadsToPayloads(hashes, [...cachedPayloads, ...finalizedPayloads.filter(exists)], this.dataLakeViewer);
1471
+ resultPayloads.map((payload) => {
1472
+ this.payloadCache.set(payload._hash, payload);
1473
+ });
1474
+ return resultPayloads;
1475
+ }
1476
+ async rate(range, timeUnit) {
1477
+ return await calculateBlockRate(this, range, timeUnit);
1478
+ }
1479
+ async stepSizeRate(start, stepIndex, count = 1, timeUnit) {
1480
+ return await calculateStepSizeRate(this, start, stepIndex, count, timeUnit);
1481
+ }
1482
+ async timeDurationRate(timeConfig, startBlockNumber, timeUnit, toleranceMs, maxAttempts) {
1483
+ return await calculateTimeRate(this, timeConfig, startBlockNumber, timeUnit, toleranceMs, maxAttempts);
1484
+ }
1485
+ getBlockContextRead() {
1486
+ return {
1487
+ ...this.context,
1488
+ chainMap: this.store.chainMap
1489
+ };
1490
+ }
1491
+ async getChainContextRead() {
1492
+ return {
1493
+ ...this.getBlockContextRead(),
1494
+ head: (await this.finalizationViewer.head())[0]
1495
+ };
1496
+ }
1497
+ async blockByNumberWithContext(chainContext, blockNumber) {
1498
+ const block = asSignedHydratedBlockWithHashMeta(await hydratedBlockByNumber(chainContext, blockNumber)) ?? null;
1499
+ const [result] = block ? await addDataLakePayloads(block, this.dataLakeViewer) : [null, []];
1500
+ return result;
1501
+ }
1502
+ };
1503
+ __publicField(SimpleBlockViewer, "defaultMoniker", BlockViewerMoniker);
1504
+ __publicField(SimpleBlockViewer, "dependencies", [FinalizationViewerMoniker]);
1505
+ __publicField(SimpleBlockViewer, "monikers", [BlockViewerMoniker]);
1506
+ SimpleBlockViewer = __decorateClass([
1507
+ creatableProvider()
1508
+ ], SimpleBlockViewer);
1509
+
1510
+ // src/simple/chainContractViewer/SimpleChainContractViewer.ts
1511
+ import {
1512
+ assertEx as assertEx12
1513
+ } from "@xylabs/sdk-js";
1514
+ import {
1515
+ ChainContractViewerMoniker,
1516
+ FinalizationViewerMoniker as FinalizationViewerMoniker2
1517
+ } from "@xyo-network/xl1-protocol-lib";
1518
+ var SimpleChainContractViewer = class extends AbstractCreatableProvider {
1519
+ moniker = SimpleChainContractViewer.defaultMoniker;
1520
+ _finalizationViewer;
1521
+ get finalizationViewer() {
1522
+ return this._finalizationViewer;
1523
+ }
1524
+ chainId() {
1525
+ return this.finalizationViewer.chainId();
1526
+ }
1527
+ async chainIdAtBlockNumber(blockNumber) {
1528
+ return await withContextCacheResponse(this.context, "chainIdAtBlockNumber", `${blockNumber}`, async () => {
1529
+ let chainId = this.chainId();
1530
+ let contractViewer = this;
1531
+ let forkedAtBlockNumber = await contractViewer.forkedAtBlockNumber();
1532
+ while (forkedAtBlockNumber !== null && blockNumber <= forkedAtBlockNumber) {
1533
+ contractViewer = assertEx12(await contractViewer.forkedChainContractViewer());
1534
+ forkedAtBlockNumber = await contractViewer.forkedAtBlockNumber();
1535
+ chainId = await contractViewer.chainId();
1536
+ }
1537
+ return chainId;
1538
+ });
1539
+ }
1540
+ async createHandler() {
1541
+ this._finalizationViewer = await this.locator.getInstance(FinalizationViewerMoniker2);
1542
+ return await super.createHandler();
1543
+ }
1544
+ forkedAtBlockNumber() {
1545
+ return this.params.forkedAtBlockNumber ?? null;
1546
+ }
1547
+ forkedAtHash() {
1548
+ return this.params.forkedAtHash ?? null;
1549
+ }
1550
+ forkedChainContractViewer() {
1551
+ return this.params.forkedChainContractViewer ?? null;
1552
+ }
1553
+ forkedChainId() {
1554
+ return this.params.forkedChainId ?? null;
1555
+ }
1556
+ minWithdrawalBlocks() {
1557
+ return this.params.minWithdrawalBlocks;
1558
+ }
1559
+ rewardsContract() {
1560
+ return this.params.rewardsContract;
1561
+ }
1562
+ stakingTokenAddress() {
1563
+ return this.params.stakingTokenAddress;
1564
+ }
1565
+ };
1566
+ __publicField(SimpleChainContractViewer, "defaultMoniker", ChainContractViewerMoniker);
1567
+ __publicField(SimpleChainContractViewer, "dependencies", [FinalizationViewerMoniker2]);
1568
+ __publicField(SimpleChainContractViewer, "monikers", [ChainContractViewerMoniker]);
1569
+ SimpleChainContractViewer = __decorateClass([
1570
+ creatableProvider()
1571
+ ], SimpleChainContractViewer);
1572
+
1573
+ // src/simple/finalization/SimpleFinalizationViewer.ts
1574
+ import {
1575
+ assertEx as assertEx13
1576
+ } from "@xylabs/sdk-js";
1577
+ import {
1578
+ asSignedHydratedBlockWithStorageMeta as asSignedHydratedBlockWithStorageMeta2,
1579
+ ChainContractViewerMoniker as ChainContractViewerMoniker2,
1580
+ FinalizationViewerMoniker as FinalizationViewerMoniker3
1581
+ } from "@xyo-network/xl1-protocol-lib";
1582
+ var SimpleFinalizationViewer = class extends AbstractCreatableProvider {
1583
+ moniker = SimpleFinalizationViewer.defaultMoniker;
1584
+ _chainId;
1585
+ _store;
1586
+ _signedHydratedBlockCache;
1587
+ get finalizedArchivist() {
1588
+ return this.params.finalizedArchivist;
1589
+ }
1590
+ get hydratedBlockCache() {
1591
+ if (this._signedHydratedBlockCache) return this._signedHydratedBlockCache;
1592
+ const context = this.getBlockContextRead();
1593
+ this._signedHydratedBlockCache = new HydratedCache(context, async (store, hash, maxDepth, minDepth) => {
1594
+ const result = await hydrateBlock(context, hash, maxDepth, minDepth);
1595
+ return asSignedHydratedBlockWithStorageMeta2(result, true);
1596
+ }, 200);
1597
+ return this._signedHydratedBlockCache;
1598
+ }
1599
+ get store() {
1600
+ return this._store;
1601
+ }
1602
+ static async paramsHandler(params) {
1603
+ return {
1604
+ ...await super.paramsHandler(params),
1605
+ finalizedArchivist: assertEx13(params.finalizedArchivist, () => "finalizedArchivist is required")
1606
+ };
1607
+ }
1608
+ chainId() {
1609
+ return this._chainId;
1610
+ }
1611
+ async createHandler() {
1612
+ await super.createHandler();
1613
+ this._chainId = assertEx13(this.config.chain.id ?? (await findMostRecentBlock(this.params.finalizedArchivist))?.chain, () => "chain.id is required if empty archivist");
1614
+ this._store = { chainMap: this.params.finalizedArchivist };
1615
+ }
1616
+ async head() {
1617
+ return await this.spanAsync("head", async () => {
1618
+ const currentHead = assertEx13(await this.getCurrentHead(), () => "Could not find most recent block [currentBlock]");
1619
+ const cache = this.hydratedBlockCache;
1620
+ const block = await cache.get(currentHead._hash);
1621
+ if (!block) {
1622
+ console.log(`Could not find current block with hash ${currentHead._hash}`);
1623
+ }
1624
+ return assertEx13(block, () => "Could not find current block");
1625
+ }, this.context);
1626
+ }
1627
+ async headBlock() {
1628
+ return (await this.head())[0];
1629
+ }
1630
+ async headHash() {
1631
+ return (await this.headBlock())._hash;
1632
+ }
1633
+ async headNumber() {
1634
+ return (await this.headBlock()).block;
1635
+ }
1636
+ getBlockContextRead() {
1637
+ return {
1638
+ ...this.context,
1639
+ chainMap: this.store.chainMap
1640
+ };
1641
+ }
1642
+ async getChainContextRead() {
1643
+ return {
1644
+ ...this.getBlockContextRead(),
1645
+ head: (await this.head())[0]
1646
+ };
1647
+ }
1648
+ async getCurrentHead() {
1649
+ const chainArchivist = this.finalizedArchivist;
1650
+ const result = assertEx13(await findMostRecentBlock(chainArchivist), () => "Could not find most recent block [getCurrentHead]");
1651
+ assertEx13(result?.chain === this._chainId, () => "Chain ID does not match head block chain ID");
1652
+ return result;
1653
+ }
1654
+ };
1655
+ __publicField(SimpleFinalizationViewer, "defaultMoniker", FinalizationViewerMoniker3);
1656
+ __publicField(SimpleFinalizationViewer, "dependencies", [ChainContractViewerMoniker2]);
1657
+ __publicField(SimpleFinalizationViewer, "monikers", [FinalizationViewerMoniker3]);
1658
+ SimpleFinalizationViewer = __decorateClass([
1659
+ creatableProvider()
1660
+ ], SimpleFinalizationViewer);
1661
+
1662
+ // src/test/buildRandomChain.ts
1663
+ import { asAddress as asAddress3, assertEx as assertEx16 } from "@xylabs/sdk-js";
1664
+ import {
1665
+ Account as Account3,
1666
+ asSchema as asSchema2,
1667
+ IdSchema as IdSchema2,
1668
+ MemoryArchivist,
1669
+ PayloadBuilder as PayloadBuilder9
1670
+ } from "@xyo-network/sdk-js";
1671
+ import {
1672
+ asXL1BlockNumber as asXL1BlockNumber7
1673
+ } from "@xyo-network/xl1-protocol-lib";
1674
+
1675
+ // src/test/buildNextBlock.ts
1676
+ import {
1677
+ AttoXL1 as AttoXL12,
1678
+ XYO_STEP_REWARD_ADDRESS as XYO_STEP_REWARD_ADDRESS2
1679
+ } from "@xyo-network/xl1-protocol-lib";
1680
+
1681
+ // src/test/buildBlock.ts
1682
+ import { assertEx as assertEx14, isDefined as isDefined8 } from "@xylabs/sdk-js";
1683
+ import {
1684
+ asAnyPayload as asAnyPayload3,
1685
+ BoundWitnessBuilder as BoundWitnessBuilder2,
1686
+ PayloadBuilder as PayloadBuilder5
1687
+ } from "@xyo-network/sdk-js";
1688
+ import {
1689
+ asXL1BlockNumber as asXL1BlockNumber4,
1690
+ AttoXL1,
1691
+ completedStepRewardAddress,
1692
+ isBlockBoundWitness,
1693
+ StepRewardFractions,
1694
+ StepSizes as StepSizes3,
1695
+ XL1_PROTOCOL_VERSION,
1696
+ XYO_STEP_REWARD_ADDRESS,
1697
+ XYO_ZERO_ADDRESS
1698
+ } from "@xyo-network/xl1-protocol-lib";
1699
+
1700
+ // src/test/BuildBlockOptions.ts
1701
+ import {
1702
+ isAddress,
1703
+ isArray,
1704
+ isHash as isHash2,
1705
+ isNumber,
1706
+ isObject as isObject2
1707
+ } from "@xylabs/sdk-js";
1708
+ var isBaseBuildBlockOptions = (value) => {
1709
+ if (!isObject2(value)) {
1710
+ return false;
1711
+ }
1712
+ const typedValue = value;
1713
+ if (!isArray(typedValue.blockPayloads) || !isAddress(typedValue.chainId) || !isArray(typedValue.signers) || !isArray(typedValue.txs)) {
1714
+ return false;
1715
+ }
1716
+ return true;
1717
+ };
1718
+ var isBuildGenesisBlockOptions = (value) => {
1719
+ if (!isBaseBuildBlockOptions(value)) {
1720
+ return false;
1721
+ }
1722
+ const typedValue = value;
1723
+ if (typedValue.previousBlockHash !== null) {
1724
+ return false;
1725
+ }
1726
+ if (typedValue.previousBlockNumber !== void 0) {
1727
+ return false;
1728
+ }
1729
+ return true;
1730
+ };
1731
+ var isBuildNextBlockOptions = (value) => {
1732
+ if (!isBaseBuildBlockOptions(value)) {
1733
+ return false;
1734
+ }
1735
+ const typedValue = value;
1736
+ if (!isHash2(typedValue.previousBlockHash)) {
1737
+ return false;
1738
+ }
1739
+ if (!isNumber(typedValue.previousBlockNumber)) {
1740
+ return false;
1741
+ }
1742
+ if (!isArray(typedValue.previousStepHashes)) {
1743
+ return false;
1744
+ }
1745
+ return true;
1746
+ };
1747
+
1748
+ // src/test/buildBlock.ts
1749
+ function calculateCompletedStepReward(step, balance) {
1750
+ return AttoXL1(StepRewardFractions[step][0] * balance / StepRewardFractions[step][1]);
1751
+ }
1752
+ async function buildBlock(options) {
1753
+ const previousBlockNumber = isBuildGenesisBlockOptions(options) ? -1 : options.previousBlockNumber;
1754
+ const blockNumber = asXL1BlockNumber4(previousBlockNumber + 1, true);
1755
+ const inStepHashes = isBuildNextBlockOptions(options) ? options.previousStepHashes : [];
1756
+ const previousBlockHash = isBuildNextBlockOptions(options) ? options.previousBlockHash : void 0;
1757
+ const stepRewardPoolBalance = isBuildNextBlockOptions(options) ? options.stepRewardPoolBalance : AttoXL1(0n);
1758
+ const {
1759
+ chainId,
1760
+ txs,
1761
+ chainStepRewardAddress = XYO_STEP_REWARD_ADDRESS,
1762
+ blockPayloads,
1763
+ protocol = XL1_PROTOCOL_VERSION,
1764
+ signers
1765
+ } = options;
1766
+ const step_hashes = [];
1767
+ for (const [tx] of txs) {
1768
+ if (tx.nbf > blockNumber) {
1769
+ throw new Error(`Transaction ${await PayloadBuilder5.hash(tx)} not valid for block ${blockNumber} - NBF is ${tx.nbf}`);
1770
+ }
1771
+ if (tx.exp < blockNumber) {
1772
+ throw new Error(`Transaction ${await PayloadBuilder5.hash(tx)} not valid for block ${blockNumber} - EXP is ${tx.exp}`);
1773
+ }
1774
+ }
1775
+ const completedStepRewardTransfers = [];
1776
+ for (const [i, step] of StepSizes3.entries()) {
1777
+ if (blockNumber < step) {
1778
+ break;
1779
+ }
1780
+ if (blockNumber % step === 0) {
1781
+ if (StepRewardFractions[i][0] > 0 && chainStepRewardAddress !== XYO_ZERO_ADDRESS) {
1782
+ const completedStepRewardHolderAddress = completedStepRewardAddress({ block: blockNumber, step });
1783
+ const completedStepReward = calculateCompletedStepReward(i, stepRewardPoolBalance);
1784
+ completedStepRewardTransfers.push(createTransferPayload(chainStepRewardAddress, { [completedStepRewardHolderAddress]: completedStepReward }));
1785
+ }
1786
+ step_hashes.push(assertEx14(previousBlockHash, () => `Previous block hash is required for step ${step} at block ${blockNumber}`));
1787
+ } else {
1788
+ if (isDefined8(inStepHashes.at(i))) {
1789
+ step_hashes.push(inStepHashes[i]);
1790
+ }
1791
+ }
1792
+ }
1793
+ const previous = previousBlockHash ?? null;
1794
+ const block = blockNumber;
1795
+ const txElevatedPayloads = await validateTransactionsOpcodes(txs);
1796
+ const payloads = [
1797
+ ...txs.map(([tx]) => tx),
1798
+ ...blockPayloads,
1799
+ ...txElevatedPayloads,
1800
+ ...completedStepRewardTransfers
1801
+ ];
1802
+ const [bw, txPayloads] = await new BoundWitnessBuilder2().fields({
1803
+ block,
1804
+ chain: chainId,
1805
+ previous,
1806
+ step_hashes,
1807
+ protocol
1808
+ }).meta({ $epoch: Date.now(), $signatures: [] }).signers(signers).payloads(await PayloadBuilder5.addStorageMeta(payloads)).build();
1809
+ assertEx14(isBlockBoundWitness(bw), () => "Build of BlockBoundWitness failed");
1810
+ return [await PayloadBuilder5.addStorageMeta(bw), txPayloads.map((p) => asAnyPayload3(p, true))];
1811
+ }
1812
+
1813
+ // src/test/buildNextBlock.ts
1814
+ async function buildNextBlock(previousBlock, txs, blockPayloads, signers, chainStepRewardAddress = XYO_STEP_REWARD_ADDRESS2, stepRewardPoolBalance = AttoXL12(0n), protocol, chainId) {
1815
+ return await buildBlock({
1816
+ chainId: chainId ?? previousBlock.chain,
1817
+ previousBlockNumber: previousBlock.block,
1818
+ previousStepHashes: previousBlock.step_hashes ?? [],
1819
+ previousBlockHash: previousBlock._hash,
1820
+ txs,
1821
+ blockPayloads,
1822
+ signers,
1823
+ protocol,
1824
+ chainStepRewardAddress,
1825
+ stepRewardPoolBalance
1826
+ });
1827
+ }
1828
+
1829
+ // src/test/buildRandomGenesisBlock.ts
1830
+ import { asAddress as asAddress2, assertEx as assertEx15 } from "@xylabs/sdk-js";
1831
+ import {
1832
+ Account as Account2,
1833
+ asAnyPayload as asAnyPayload4,
1834
+ asSchema,
1835
+ IdSchema,
1836
+ PayloadBuilder as PayloadBuilder6
1837
+ } from "@xyo-network/sdk-js";
1838
+ import {
1839
+ asXL1BlockNumber as asXL1BlockNumber5
1840
+ } from "@xyo-network/xl1-protocol-lib";
1841
+
1842
+ // src/test/buildGenesisBlock.ts
1843
+ import { XYO_ZERO_ADDRESS as XYO_ZERO_ADDRESS2 } from "@xyo-network/xl1-protocol-lib";
1844
+ async function buildGenesisBlock(chainId, txs, blockPayloads, signers, chainStepRewardAddress = XYO_ZERO_ADDRESS2, protocol) {
1845
+ return await buildBlock({
1846
+ previousBlockHash: null,
1847
+ chainId,
1848
+ txs,
1849
+ blockPayloads,
1850
+ signers,
1851
+ chainStepRewardAddress,
1852
+ protocol
1853
+ });
1854
+ }
1855
+
1856
+ // src/test/buildRandomGenesisBlock.ts
1857
+ var TestChainId = assertEx15(asAddress2("c5fe2e6F6841Cbab12d8C0618Be2DF8C6156cC44"));
1858
+
1859
+ // src/test/createGenesisBlock.ts
1860
+ import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
1861
+ import {
1862
+ BlockBoundWitnessSchemaPayload,
1863
+ BlockBoundWitnessWithStorageMetaSchemaPayload,
1864
+ ChainStakeIntentPayloadJsonSchemaPayload,
1865
+ HashPayloadJsonSchemaPayload,
1866
+ TransactionBoundWitnessSchemaPayload,
1867
+ TransactionBoundWitnessWithStorageMetaSchemaPayload,
1868
+ TransferPayloadJsonSchemaPayload
1869
+ } from "@xyo-network/xl1-schema";
1870
+
1871
+ // src/test/createProducerChainStakeIntentTransaction.ts
1872
+ import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/sdk-js";
1873
+ import {
1874
+ asXL1BlockNumber as asXL1BlockNumber6,
1875
+ ChainStakeIntentSchema,
1876
+ defaultTransactionFees as defaultTransactionFees2
1877
+ } from "@xyo-network/xl1-protocol-lib";
1878
+ async function createProducerChainStakeIntent(from, exp, nbf = 0) {
1879
+ return await PayloadBuilder7.addHashMeta(new PayloadBuilder7({ schema: ChainStakeIntentSchema }).fields({
1880
+ from,
1881
+ exp,
1882
+ nbf,
1883
+ intent: "producer"
1884
+ }).build());
1885
+ }
1886
+
1887
+ // src/test/createGenesisBlock.ts
1888
+ var createGenesisBlock = async (initialBlockProducer, nextContractAddress, genesisBlockRewardAmount, genesisBlockRewardAddress) => {
1889
+ const blockPayloads = await PayloadBuilder8.addHashMeta([
1890
+ TransferPayloadJsonSchemaPayload,
1891
+ BlockBoundWitnessSchemaPayload,
1892
+ BlockBoundWitnessWithStorageMetaSchemaPayload,
1893
+ TransactionBoundWitnessSchemaPayload,
1894
+ TransactionBoundWitnessWithStorageMetaSchemaPayload,
1895
+ ChainStakeIntentPayloadJsonSchemaPayload,
1896
+ HashPayloadJsonSchemaPayload
1897
+ ]);
1898
+ const intentPayload = await createProducerChainStakeIntent(initialBlockProducer.address, 1, 0);
1899
+ blockPayloads.push(intentPayload);
1900
+ if (genesisBlockRewardAmount > 0n) {
1901
+ blockPayloads.push(await PayloadBuilder8.addHashMeta(createTransferPayload(
1902
+ nextContractAddress,
1903
+ { [genesisBlockRewardAddress]: genesisBlockRewardAmount }
1904
+ )));
1905
+ }
1906
+ return await buildGenesisBlock(nextContractAddress, [], blockPayloads, [initialBlockProducer]);
1907
+ };
1908
+
1909
+ // src/test/buildRandomChain.ts
1910
+ var TestGenesisBlockRewardAddress = assertEx16(asAddress3("fa7f0bb865a4bfff3d5e2c726d3e063297014da9"));
1911
+ var buildRandomChain = async (blockProducer, count = 10, previousBlock, chainId, transactionAccount, receiverAddresses) => {
1912
+ const chainIdToUse = chainId ?? TestChainId;
1913
+ const blocks = [];
1914
+ let remaining = count;
1915
+ let lastBlock = previousBlock;
1916
+ const transactionAccountToUse = transactionAccount ?? await Account3.random();
1917
+ if (!lastBlock) {
1918
+ const block = await createGenesisBlock(
1919
+ blockProducer,
1920
+ chainIdToUse,
1921
+ 1000000000n * 10n ** 18n,
1922
+ transactionAccountToUse.address
1923
+ );
1924
+ blocks.push(block);
1925
+ remaining = remaining - 1;
1926
+ lastBlock = block;
1927
+ }
1928
+ const resolvedReceiverAddresses = receiverAddresses ?? [(await Account3.random()).address];
1929
+ let saltCounter = 0;
1930
+ while (remaining > 0) {
1931
+ saltCounter += 1;
1932
+ const payloads = [new PayloadBuilder9({ schema: IdSchema2 }).fields({ salt: `${Date.now()}-${saltCounter}` }).build()];
1933
+ saltCounter += 1;
1934
+ const additionalPrivatePayloads = remaining % 2 === 0 ? [new PayloadBuilder9({ schema: asSchema2("network.xyo.private", true) }).fields({ salt: `${Date.now()}-${saltCounter}` }).build()] : [];
1935
+ const txs = [];
1936
+ for (const receiverAddress of resolvedReceiverAddresses) {
1937
+ txs.push(await buildRandomTransaction(
1938
+ chainIdToUse,
1939
+ [...payloads, ...additionalPrivatePayloads],
1940
+ transactionAccountToUse,
1941
+ asXL1BlockNumber7(Math.max(count - remaining - 1e3, 0), true),
1942
+ asXL1BlockNumber7(count - remaining + 1e3, true),
1943
+ [asSchema2("network.xyo.private", true)],
1944
+ receiverAddress
1945
+ ));
1946
+ }
1947
+ const previousBlock2 = assertEx16(lastBlock?.[0], () => new Error("No last block"));
1948
+ const block = await buildNextBlock(previousBlock2, txs, [], [blockProducer], transactionAccountToUse.address);
1949
+ blocks.push(block);
1950
+ remaining = remaining - 1;
1951
+ lastBlock = block;
1952
+ }
1953
+ return blocks;
1954
+ };
1955
+ async function buildRandomChainArchivist(count = 20) {
1956
+ const producerAccount = await Account3.random();
1957
+ const blocks = await buildRandomChain(producerAccount, count);
1958
+ const archivist = await MemoryArchivist.create();
1959
+ const payloads = flattenHydratedBlocks(blocks);
1960
+ await archivist.insert(payloads);
1961
+ return archivist;
1962
+ }
1963
+
1964
+ // src/test/getSimpleBlockViewerLocator.ts
1965
+ async function getTestSimpleBlockViewerLocator({
1966
+ minWithdrawalBlocks = 10,
1967
+ config = ConfigZod.parse({}),
1968
+ finalizedArchivist: finalizedArchivistIn,
1969
+ rewardsContract = XYO_ZERO_ADDRESS3,
1970
+ stakingTokenAddress = XYO_ZERO_ADDRESS3
1971
+ }) {
1972
+ const finalizedArchivist = finalizedArchivistIn ?? await buildRandomChainArchivist();
1973
+ const context = getTestProviderContext(config);
1974
+ context.locator.registerMany([
1975
+ SimpleChainContractViewer.factory(SimpleChainContractViewer.dependencies, {
1976
+ minWithdrawalBlocks,
1977
+ rewardsContract,
1978
+ stakingTokenAddress
1979
+ }),
1980
+ SimpleFinalizationViewer.factory(SimpleFinalizationViewer.dependencies, { finalizedArchivist }),
1981
+ SimpleBlockViewer.factory(SimpleBlockViewer.dependencies, { finalizedArchivist })
1982
+ ]);
1983
+ return context.locator;
1984
+ }
1985
+
1986
+ // src/test/getTestProviderContext.ts
1987
+ function getTestProviderContext2(config) {
1988
+ return getTestProviderContext(config);
1989
+ }
1990
+ export {
1991
+ buildRandomTransaction,
1992
+ getTestProviderContext2 as getTestProviderContext,
1993
+ getTestSimpleBlockViewerLocator
1994
+ };
1995
+ //# sourceMappingURL=index.mjs.map