@xyo-network/service-kit-xl1 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,510 @@
1
+ // src/createFleetAuthority.ts
2
+ import {
3
+ foldFleetControls,
4
+ resolveFleetPayload,
5
+ verifyFleetPayload
6
+ } from "@xyo-network/service-kit-protocol";
7
+ import {
8
+ AddressZod,
9
+ FleetControlSchema,
10
+ FleetMemberSchema,
11
+ FleetPublicationScopeSchema,
12
+ FleetPublicationScopeZod,
13
+ FleetSchema,
14
+ FleetZod,
15
+ HashZod
16
+ } from "@xyo-network/service-kit-schemas";
17
+ import {
18
+ createXl1FinalizedPublicationEvidence
19
+ } from "@xyo-network/xl1-sdk/protocol-sdk/finalized-publication";
20
+
21
+ // src/fleetControl.ts
22
+ var abortedDescriptor = Object.getOwnPropertyDescriptor(AbortSignal.prototype, "aborted");
23
+ var abortedGetter = Reflect.get(abortedDescriptor ?? {}, "get");
24
+ var nativeEvents = EventTarget.prototype;
25
+ var addListener = nativeEvents.addEventListener;
26
+ var removeListener = nativeEvents.removeEventListener;
27
+ var apply = Reflect.apply;
28
+ var now = performance.now.bind(performance);
29
+ function captureSignal(value) {
30
+ if (value === void 0) return;
31
+ if (typeof abortedGetter !== "function") throw new TypeError("Native AbortSignal is required");
32
+ apply(abortedGetter, value, []);
33
+ return value;
34
+ }
35
+ function aborted(signal) {
36
+ if (typeof abortedGetter !== "function") throw new TypeError("Native AbortSignal is required");
37
+ return apply(abortedGetter, signal, []);
38
+ }
39
+ function listenAbort(signal, listener) {
40
+ if (signal === void 0) return () => {
41
+ };
42
+ apply(addListener, signal, ["abort", listener, { once: true }]);
43
+ return () => {
44
+ apply(removeListener, signal, ["abort", listener]);
45
+ };
46
+ }
47
+ var FleetAuthorityError = class extends Error {
48
+ code;
49
+ status;
50
+ constructor(status, code) {
51
+ super(code);
52
+ this.name = "FleetAuthorityError";
53
+ this.status = status;
54
+ this.code = code;
55
+ }
56
+ };
57
+ function operationControl(signal, timeoutMs, startedAt) {
58
+ const controller = new AbortController();
59
+ const deadline = startedAt + timeoutMs;
60
+ let terminal;
61
+ const stop = (status) => {
62
+ terminal ??= new FleetAuthorityError(status, status);
63
+ controller.abort();
64
+ };
65
+ const unlisten = listenAbort(signal, () => stop("cancelled"));
66
+ if (signal !== void 0 && aborted(signal)) stop("cancelled");
67
+ const timer = setTimeout(() => stop("deadline"), Math.max(1, Math.ceil(deadline - now())));
68
+ return {
69
+ signal: controller.signal,
70
+ assertActive() {
71
+ if (now() >= deadline) stop("deadline");
72
+ if (terminal !== void 0) throw terminal;
73
+ },
74
+ remainingMs: () => Math.max(1, Math.ceil(deadline - now())),
75
+ dispose() {
76
+ clearTimeout(timer);
77
+ unlisten();
78
+ controller.abort();
79
+ }
80
+ };
81
+ }
82
+ var fleetNow = now;
83
+
84
+ // src/fleetProjection.ts
85
+ function nextPublisherProjection(result) {
86
+ const { publicationBlock: projectionBlock, ...original } = result;
87
+ const context2 = {
88
+ ...original,
89
+ projection: "pending-N+1",
90
+ projectionBlock
91
+ };
92
+ if (result.status === "authorized" || result.status === "absent") {
93
+ return Object.freeze({
94
+ ...context2,
95
+ status: result.status === "authorized" ? "projected-granted" : "projected-absent",
96
+ coveredRange: Object.freeze({ fromBlockNumber: 0, toBlockNumber: result.anchor.blockNumber })
97
+ });
98
+ }
99
+ return Object.freeze(context2);
100
+ }
101
+
102
+ // src/createFleetAuthority.ts
103
+ var b4Families = Object.freeze([FleetSchema, FleetMemberSchema, FleetPublicationScopeSchema, FleetControlSchema]);
104
+ function ownRecord(input, required, optional = []) {
105
+ if (input === null || typeof input !== "object" || Object.getPrototypeOf(input) !== Object.prototype) throw new TypeError("Use a strict own-data profile/request");
106
+ const keys = Reflect.ownKeys(input);
107
+ if (keys.some((key) => typeof key !== "string" || ![...required, ...optional].includes(key)) || required.some((key) => !keys.includes(key))) throw new TypeError("Unexpected or missing profile/request fields");
108
+ return Object.fromEntries(keys.map((key) => {
109
+ const descriptor = Object.getOwnPropertyDescriptor(input, key);
110
+ if (descriptor?.enumerable !== true || !("value" in descriptor)) throw new TypeError("Profile/request accessors are unsupported");
111
+ return [key, descriptor.value];
112
+ }));
113
+ }
114
+ function finiteProfile(input, keys) {
115
+ const values = ownRecord(input, keys);
116
+ if (Object.values(values).some((value) => typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0 || value > 2147483647)) throw new RangeError("Every finite positive bound is required");
117
+ return Object.freeze(values);
118
+ }
119
+ function pinProfile(input) {
120
+ const profile = ownRecord(input, ["evidence", "foldLimits", "limits", "resolutionLimits", "seeds"]);
121
+ const evidence = ownRecord(profile.evidence, ["assurance", "chainId", "genesisRoot", "limits", "network", "source"]);
122
+ const source = ownRecord(evidence.source, ["bodyBaseUrl", "finalizedBaseUrl", "headUrl"], ["fetch"]);
123
+ const evidenceLimits = finiteProfile(evidence.limits, [
124
+ "maxAggregateBytes",
125
+ "maxBlocks",
126
+ "maxBodies",
127
+ "maxConcurrentReads",
128
+ "maxDecodedDepth",
129
+ "maxDecodedNodes",
130
+ "maxLineageBlocks",
131
+ "maxResponseBytes",
132
+ "maxRoots",
133
+ "maxSourceUrlBytes",
134
+ "perCallTimeoutMs",
135
+ "totalTimeoutMs"
136
+ ]);
137
+ const fixedEvidence = Object.freeze({
138
+ ...evidence,
139
+ limits: evidenceLimits,
140
+ source: Object.freeze(source)
141
+ });
142
+ const limits = finiteProfile(profile.limits, [
143
+ "maxBlocks",
144
+ "maxConcurrentCalls",
145
+ "maxConcurrentReads",
146
+ "maxFleets",
147
+ "maxOccurrences",
148
+ "maxPages",
149
+ "maxRootReads",
150
+ "totalTimeoutMs"
151
+ ]);
152
+ const foldLimits = finiteProfile(profile.foldLimits, ["maxBodyBytes", "maxControls", "maxDeclarations", "maxDepth", "maxGrants", "maxMembers", "maxNodes"]);
153
+ const resolutionLimits = finiteProfile(profile.resolutionLimits, [
154
+ "attemptTimeoutMs",
155
+ "maxBodyBytes",
156
+ "maxCandidatesPerSeed",
157
+ "maxDepth",
158
+ "maxNodes",
159
+ "maxSeeds",
160
+ "totalTimeoutMs"
161
+ ]);
162
+ return {
163
+ evidence: fixedEvidence,
164
+ limits,
165
+ foldLimits,
166
+ resolutionLimits,
167
+ seeds: profile.seeds
168
+ };
169
+ }
170
+ function pinRequest(input, next = false) {
171
+ const values = ownRecord(input, ["anchor", "owner", "publicationBlock"], ["fleetRoot", "signal"]);
172
+ const anchor = ownRecord(values.anchor, ["blockNumber", "blockRoot"]);
173
+ HashZod.parse(anchor.blockRoot);
174
+ AddressZod.parse(values.owner);
175
+ if (values.fleetRoot !== void 0) HashZod.parse(values.fleetRoot);
176
+ if (!Number.isSafeInteger(anchor.blockNumber) || anchor.blockNumber < 0 || anchor.blockNumber >= Number.MAX_SAFE_INTEGER || typeof values.publicationBlock !== "number" || !Number.isSafeInteger(values.publicationBlock) || values.publicationBlock < 0 || (next ? values.publicationBlock !== anchor.blockNumber + 1 : values.publicationBlock > anchor.blockNumber)) throw new RangeError("Select an exact publication height within the anchor");
177
+ return Object.freeze({
178
+ ...values,
179
+ anchor: Object.freeze(anchor),
180
+ signal: captureSignal(values.signal)
181
+ });
182
+ }
183
+ function pinReaders(seeds, profile) {
184
+ if (!Array.isArray(seeds) || seeds.length === 0 || seeds.length > profile.resolutionLimits.maxSeeds) throw new RangeError("Explicit bounded root readers required");
185
+ const ids = /* @__PURE__ */ new Set();
186
+ return Object.freeze(Array.from({ length: seeds.length }, (_, index) => {
187
+ const slot = Object.getOwnPropertyDescriptor(seeds, String(index));
188
+ if (slot?.enumerable !== true || !("value" in slot)) throw new TypeError("Readers require dense own data slots");
189
+ const seed = ownRecord(slot.value, ["id", "reader"]);
190
+ if (typeof seed.id !== "string" || seed.id.length === 0 || seed.id.length > 128 || seed.id.trim() !== seed.id || ids.has(seed.id)) throw new TypeError("Readers require unique bounded IDs");
191
+ ids.add(seed.id);
192
+ const reader = ownRecord(seed.reader, ["get"]);
193
+ if (typeof reader.get !== "function") throw new TypeError("Readers require an own get method");
194
+ const get = reader.get.bind(seed.reader);
195
+ return Object.freeze({ id: seed.id, reader: Object.freeze({ get }) });
196
+ }));
197
+ }
198
+ function capacityReaders(seeds, state, maximum, capacity) {
199
+ return Object.freeze(seeds.map((seed) => Object.freeze({
200
+ id: seed.id,
201
+ reader: Object.freeze({
202
+ get: async (...args) => {
203
+ if (state.active >= maximum) {
204
+ capacity.limited = true;
205
+ throw new FleetAuthorityError("resource-limit", "reader-capacity");
206
+ }
207
+ state.active++;
208
+ try {
209
+ return await seed.reader.get(...args);
210
+ } finally {
211
+ state.active--;
212
+ }
213
+ }
214
+ })
215
+ })));
216
+ }
217
+ function context(profile, request) {
218
+ return Object.freeze({
219
+ assurance: "source-trusted-finalized-replay",
220
+ historyScope: "verified-native-owner-and-B4-families",
221
+ network: profile.evidence.network,
222
+ chainId: profile.evidence.chainId,
223
+ genesisRoot: profile.evidence.genesisRoot,
224
+ anchor: request.anchor,
225
+ owner: request.owner,
226
+ publicationBlock: request.publicationBlock
227
+ });
228
+ }
229
+ function positionAfter(left, right) {
230
+ return left.blockNumber > right.blockNumber || left.blockNumber === right.blockNumber && (left.transactionIndex > right.transactionIndex || left.transactionIndex === right.transactionIndex && left.payloadOrdinal > right.payloadOrdinal);
231
+ }
232
+ function nativeFailure(page) {
233
+ const statuses = ["cancelled", "deadline", "conflict", "unsupported", "resource-limit"];
234
+ const status = statuses.includes(page.status) ? page.status : "incomplete";
235
+ return new FleetAuthorityError(status, `native-${page.issues[0]?.code ?? page.status}`);
236
+ }
237
+ function validatePage(page, profile, request, from, to) {
238
+ const actual = [
239
+ page.network,
240
+ page.chainId,
241
+ page.genesisRoot,
242
+ page.anchor.blockNumber,
243
+ page.anchor.blockRoot,
244
+ page.assurance,
245
+ page.requestedRange.fromBlockNumber,
246
+ page.requestedRange.toBlockNumber
247
+ ];
248
+ const expected = [
249
+ profile.evidence.network,
250
+ profile.evidence.chainId,
251
+ profile.evidence.genesisRoot,
252
+ request.anchor.blockNumber,
253
+ request.anchor.blockRoot,
254
+ "source-trusted-finalized-replay",
255
+ from,
256
+ to
257
+ ];
258
+ if (actual.some((value, index) => value !== expected[index])) throw new FleetAuthorityError("conflict", "scan-binding");
259
+ if (page.scopeCompleteness !== "verified-native-header-selection" || page.scope.authorizers?.length !== 1 || page.scope.authorizers[0] !== request.owner || page.scope.schemas?.length !== b4Families.length || page.scope.schemas.some((family, index) => family !== b4Families[index])) throw new FleetAuthorityError("conflict", "scan-scope");
260
+ if (page.status !== "complete") throw nativeFailure(page);
261
+ if (page.coveredRange?.fromBlockNumber !== from || page.coveredRange.toBlockNumber !== to || page.continuation !== void 0 || page.issues.length > 0) {
262
+ throw new FleetAuthorityError("incomplete", "scan-coverage");
263
+ }
264
+ }
265
+ function createFleetAuthority(input) {
266
+ const profile = pinProfile(input);
267
+ const evidence = createXl1FinalizedPublicationEvidence(profile.evidence);
268
+ const readState = { active: 0 };
269
+ const seeds = pinReaders(profile.seeds, profile);
270
+ let activeCalls = 0;
271
+ async function resolved(root, family, work) {
272
+ work.control.assertActive();
273
+ const cached = work.roots.get(root);
274
+ if (cached !== void 0) {
275
+ if (cached.schema !== family) throw new FleetAuthorityError("unsupported", "declaration-family");
276
+ return cached;
277
+ }
278
+ if (work.roots.size >= profile.limits.maxRootReads) throw new FleetAuthorityError("resource-limit", "root-reads");
279
+ const result = await resolveFleetPayload(root, family, {
280
+ seeds: work.seeds,
281
+ signal: work.control.signal,
282
+ limits: { ...profile.resolutionLimits, totalTimeoutMs: Math.min(profile.resolutionLimits.totalTimeoutMs, work.control.remainingMs()) }
283
+ });
284
+ work.control.assertActive();
285
+ if (work.capacity.limited) throw new FleetAuthorityError("resource-limit", "reader-capacity");
286
+ if (result.status !== "verified") {
287
+ if (result.status === "aborted") throw new FleetAuthorityError("cancelled", "root-cancelled");
288
+ if (result.reason === "resource-limit") throw new FleetAuthorityError("resource-limit", "root-resource-limit");
289
+ if (result.reason === "deadline") throw new FleetAuthorityError("deadline", "root-deadline");
290
+ if (result.attempts.some((attempt) => attempt.status === "unsupported")) throw new FleetAuthorityError("unsupported", "root-definition");
291
+ throw new FleetAuthorityError("incomplete", "root-unavailable");
292
+ }
293
+ work.roots.set(root, result.payload);
294
+ if (family !== FleetControlSchema) work.declarations.set(root, Object.freeze({ root, payload: result.payload }));
295
+ return result.payload;
296
+ }
297
+ async function scan(request, control) {
298
+ if (request.anchor.blockNumber + 1 > profile.limits.maxBlocks) throw new FleetAuthorityError("resource-limit", "history-blocks");
299
+ const occurrences = [];
300
+ let pages = 0;
301
+ for (let from = 0; from <= request.anchor.blockNumber; ) {
302
+ control.assertActive();
303
+ if (++pages > profile.limits.maxPages) throw new FleetAuthorityError("resource-limit", "scan-pages");
304
+ const to = Math.min(request.anchor.blockNumber, from + profile.evidence.limits.maxBlocks - 1);
305
+ const page = await evidence.scanScoped({
306
+ anchor: request.anchor,
307
+ fromBlockNumber: from,
308
+ toBlockNumber: to,
309
+ signal: control.signal,
310
+ scope: { authorizers: [request.owner], schemas: b4Families }
311
+ });
312
+ control.assertActive();
313
+ validatePage(page, profile, request, from, to);
314
+ for (const fact of page.occurrences) {
315
+ const previous = occurrences.at(-1);
316
+ if (fact.network !== profile.evidence.network || fact.chainId !== profile.evidence.chainId || fact.genesisRoot !== profile.evidence.genesisRoot || fact.signer !== request.owner || !b4Families.includes(fact.schema) || fact.blockNumber < from || fact.blockNumber > to || previous !== void 0 && !positionAfter(fact, previous)) throw new FleetAuthorityError("conflict", "occurrence-binding-order");
317
+ if (occurrences.length >= profile.limits.maxOccurrences) throw new FleetAuthorityError("resource-limit", "occurrences");
318
+ occurrences.push(fact);
319
+ }
320
+ from = to + 1;
321
+ }
322
+ return occurrences;
323
+ }
324
+ async function original(fact, family, control) {
325
+ const checked = await verifyFleetPayload(fact.payloadRoot, family, fact.body, profile.foldLimits);
326
+ control.assertActive();
327
+ if (checked.status !== "verified") throw new FleetAuthorityError(checked.status === "unsupported" ? "unsupported" : "incomplete", "owner-definition");
328
+ return checked.payload;
329
+ }
330
+ async function discoverFleet(fact, request, work, roots) {
331
+ if (fact.schema !== FleetSchema || request.fleetRoot !== void 0) return;
332
+ const checked = await verifyFleetPayload(fact.payloadRoot, FleetSchema, fact.body, profile.foldLimits);
333
+ work.control.assertActive();
334
+ if (checked.status !== "verified") {
335
+ if (fact.signer === request.owner) throw new FleetAuthorityError(checked.status === "unsupported" ? "unsupported" : "incomplete", "owner-declaration");
336
+ return;
337
+ }
338
+ if (FleetZod.parse(checked.payload).owner === request.owner) roots.add(fact.payloadRoot);
339
+ }
340
+ async function collect(request, work, occurrences) {
341
+ const roots = new Set(request.fleetRoot === void 0 ? [] : [request.fleetRoot]);
342
+ const controls = [];
343
+ for (const fact of occurrences) {
344
+ work.control.assertActive();
345
+ if (fact.blockNumber > request.publicationBlock) continue;
346
+ await discoverFleet(fact, request, work, roots);
347
+ if (fact.schema !== FleetControlSchema || fact.signer !== request.owner || fact.blockNumber === request.publicationBlock) continue;
348
+ const payload = await original(fact, FleetControlSchema, work.control);
349
+ if (request.fleetRoot !== void 0 && payload.fleetRoot !== request.fleetRoot) continue;
350
+ const fleet = FleetZod.parse(await resolved(payload.fleetRoot, FleetSchema, work));
351
+ if (fleet.owner !== request.owner) continue;
352
+ roots.add(payload.fleetRoot);
353
+ await resolved(fact.payloadRoot, FleetControlSchema, work);
354
+ controls.push(Object.freeze({
355
+ root: fact.payloadRoot,
356
+ payload,
357
+ authorizer: fact.signer,
358
+ block: fact.blockNumber,
359
+ chainId: fact.chainId,
360
+ transactionIndex: fact.transactionIndex,
361
+ payloadIndex: fact.payloadOrdinal
362
+ }));
363
+ if ("memberRoot" in payload) await resolved(payload.memberRoot, FleetMemberSchema, work);
364
+ if ("scopeRoot" in payload) await resolved(payload.scopeRoot, FleetPublicationScopeSchema, work);
365
+ if (roots.size > profile.limits.maxFleets) throw new FleetAuthorityError("resource-limit", "fleets");
366
+ }
367
+ if (roots.size > profile.limits.maxFleets) throw new FleetAuthorityError("resource-limit", "fleets");
368
+ return { roots, controls };
369
+ }
370
+ async function enumerateWork(request, work) {
371
+ const occurrences = await scan(request, work.control);
372
+ const { roots, controls } = await collect(request, work, occurrences);
373
+ const views = [];
374
+ for (const root of roots) {
375
+ await resolved(root, FleetSchema, work);
376
+ const selected = controls.filter((fact) => fact.payload.fleetRoot === root);
377
+ const needed = /* @__PURE__ */ new Set([root]);
378
+ for (const fact of selected) {
379
+ if ("memberRoot" in fact.payload) needed.add(fact.payload.memberRoot);
380
+ if ("scopeRoot" in fact.payload) needed.add(fact.payload.scopeRoot);
381
+ }
382
+ const folded = foldFleetControls({
383
+ owner: request.owner,
384
+ fleetRoot: root,
385
+ chainId: profile.evidence.chainId,
386
+ genesisRoot: profile.evidence.genesisRoot,
387
+ publicationBlock: request.publicationBlock,
388
+ controls: selected,
389
+ declarations: [...needed].map((key) => {
390
+ const declaration = work.declarations.get(key);
391
+ if (declaration === void 0) throw new FleetAuthorityError("incomplete", "missing-declaration");
392
+ return declaration;
393
+ }),
394
+ limits: profile.foldLimits,
395
+ signal: work.control.signal
396
+ });
397
+ work.control.assertActive();
398
+ if (folded.status !== "folded") {
399
+ const status = folded.status === "aborted" ? "cancelled" : folded.reason === "resource-limit" ? "resource-limit" : folded.status;
400
+ throw new FleetAuthorityError(status, `fold-${folded.reason}`);
401
+ }
402
+ views.push(Object.freeze({
403
+ ...folded,
404
+ status: "complete",
405
+ assurance: "source-trusted-finalized-replay"
406
+ }));
407
+ }
408
+ return Object.freeze({
409
+ ...context(profile, request),
410
+ status: "complete",
411
+ correspondence: "native-sdk-verified",
412
+ history: "complete-genesis-to-anchor",
413
+ coveredRange: Object.freeze({ fromBlockNumber: 0, toBlockNumber: request.anchor.blockNumber }),
414
+ views: Object.freeze(views)
415
+ });
416
+ }
417
+ async function execute(request, startedAt, operation) {
418
+ const control = operationControl(request.signal, profile.limits.totalTimeoutMs, startedAt);
419
+ let admitted = false;
420
+ try {
421
+ control.assertActive();
422
+ if (activeCalls >= profile.limits.maxConcurrentCalls) throw new FleetAuthorityError("resource-limit", "composition-capacity");
423
+ activeCalls++;
424
+ admitted = true;
425
+ const capacity = { limited: false };
426
+ return await operation({
427
+ control,
428
+ roots: /* @__PURE__ */ new Map(),
429
+ declarations: /* @__PURE__ */ new Map(),
430
+ capacity,
431
+ seeds: capacityReaders(seeds, readState, profile.limits.maxConcurrentReads, capacity)
432
+ });
433
+ } catch (error) {
434
+ const failure = error instanceof FleetAuthorityError ? error : new FleetAuthorityError("incomplete", "composition-source");
435
+ return Object.freeze({
436
+ ...context(profile, request),
437
+ status: failure.status,
438
+ code: failure.code
439
+ });
440
+ } finally {
441
+ if (admitted) activeCalls--;
442
+ control.dispose();
443
+ }
444
+ }
445
+ async function publisherWork(request, scopeRoot, publisherAddress, work) {
446
+ const scope = FleetPublicationScopeZod.parse(await resolved(scopeRoot, FleetPublicationScopeSchema, work));
447
+ const result = await enumerateWork({ ...request, fleetRoot: scope.fleetRoot }, work);
448
+ const view = result.views[0];
449
+ const matches = view?.fleetActive ? view.grants.filter((grant2) => grant2.scopeRoot === scopeRoot && grant2.publisherAddress === publisherAddress) : [];
450
+ if (matches.length > 1) throw new FleetAuthorityError("conflict", "publisher-ambiguity");
451
+ const grant = matches[0];
452
+ return grant === void 0 ? Object.freeze({
453
+ ...context(profile, request),
454
+ status: "absent",
455
+ correspondence: "native-sdk-verified",
456
+ history: "complete-genesis-to-anchor",
457
+ scopeRoot,
458
+ publisherAddress
459
+ }) : Object.freeze({
460
+ ...context(profile, request),
461
+ status: "authorized",
462
+ correspondence: "native-sdk-verified",
463
+ history: "complete-genesis-to-anchor",
464
+ fleetRoot: scope.fleetRoot,
465
+ memberRoot: grant.memberRoot,
466
+ controlRoot: grant.controlRoot,
467
+ scopeRoot,
468
+ publisherAddress
469
+ });
470
+ }
471
+ return Object.freeze({
472
+ async enumerate(inputRequest) {
473
+ const startedAt = fleetNow();
474
+ const request = pinRequest(inputRequest);
475
+ return await execute(request, startedAt, (work) => enumerateWork(request, work));
476
+ },
477
+ async resolvePublisher(inputRequest) {
478
+ const startedAt = fleetNow();
479
+ const values = ownRecord(inputRequest, ["anchor", "owner", "publicationBlock", "publisherAddress", "scopeRoot"], ["signal"]);
480
+ const publisherAddress = AddressZod.parse(values.publisherAddress);
481
+ const scopeRoot = HashZod.parse(values.scopeRoot);
482
+ const request = pinRequest({
483
+ anchor: values.anchor,
484
+ owner: values.owner,
485
+ publicationBlock: values.publicationBlock,
486
+ ...values.signal !== void 0 && { signal: values.signal }
487
+ });
488
+ return await execute(request, startedAt, (work) => publisherWork(request, scopeRoot, publisherAddress, work));
489
+ },
490
+ async projectNextPublisher(inputRequest) {
491
+ const startedAt = fleetNow();
492
+ const values = ownRecord(inputRequest, ["anchor", "owner", "publisherAddress", "scopeRoot"], ["signal"]);
493
+ const anchor = ownRecord(values.anchor, ["blockNumber", "blockRoot"]);
494
+ const publisherAddress = AddressZod.parse(values.publisherAddress);
495
+ const scopeRoot = HashZod.parse(values.scopeRoot);
496
+ const request = pinRequest({
497
+ anchor,
498
+ owner: values.owner,
499
+ publicationBlock: anchor.blockNumber + 1,
500
+ ...values.signal !== void 0 && { signal: values.signal }
501
+ }, true);
502
+ const result = await execute(request, startedAt, (work) => publisherWork(request, scopeRoot, publisherAddress, work));
503
+ return nextPublisherProjection(result);
504
+ }
505
+ });
506
+ }
507
+
1
508
  // src/createXl1DataLakeSeed.ts
2
509
  import { createRestDataLakeViewer } from "@xyo-network/xl1-sdk/providers";
3
510
 
@@ -134,6 +641,7 @@ async function createXl1DataLakeSeed(options) {
134
641
  });
135
642
  }
136
643
  export {
644
+ createFleetAuthority,
137
645
  createXl1DataLakeSeed
138
646
  };
139
647
  //# sourceMappingURL=index.mjs.map