@ensnode/ensnode-sdk 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,11 +4,12 @@ var ROOT_NODE = namehash("");
4
4
  var ETH_NODE = namehash("eth");
5
5
  var BASENAMES_NODE = namehash("base.eth");
6
6
  var LINEANAMES_NODE = namehash("linea.eth");
7
- var REVERSE_ROOT_NODES = /* @__PURE__ */ new Set([namehash("addr.reverse")]);
7
+ var ADDR_REVERSE_NODE = namehash("addr.reverse");
8
8
 
9
9
  // src/ens/subname-helpers.ts
10
- import { concat, isAddress, isHash, keccak256, toHex } from "viem";
11
- import { labelhash } from "viem/ens";
10
+ import { concat, keccak256, toHex } from "viem";
11
+ var makeSubdomainNode = (labelHash, node) => keccak256(concat([node, labelHash]));
12
+ var uint256ToHex32 = (num) => toHex(num, { size: 32 });
12
13
 
13
14
  // src/ens/coin-type.ts
14
15
  import {
@@ -33,8 +34,43 @@ var bigintToCoinType = (value) => {
33
34
  return Number(value);
34
35
  };
35
36
 
37
+ // src/ens/names.ts
38
+ import { ens_beautify } from "@adraffy/ens-normalize";
39
+
40
+ // src/ens/is-normalized.ts
41
+ import { normalize } from "viem/ens";
42
+ function isNormalizedName(name) {
43
+ try {
44
+ return name === normalize(name);
45
+ } catch {
46
+ return false;
47
+ }
48
+ }
49
+ function isNormalizedLabel(label) {
50
+ if (label === "") return false;
51
+ if (label.includes(".")) return false;
52
+ try {
53
+ return label === normalize(label);
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ // src/ens/names.ts
60
+ var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
61
+ var beautifyName = (name) => {
62
+ const beautifiedLabels = name.split(".").map((label) => {
63
+ if (isNormalizedLabel(label)) {
64
+ return ens_beautify(label);
65
+ } else {
66
+ return label;
67
+ }
68
+ });
69
+ return beautifiedLabels.join(".");
70
+ };
71
+
36
72
  // src/ens/reverse-name.ts
37
- var addrReverseLabel = (address) => address.slice(2).toLowerCase();
73
+ var addrReverseLabel = (address) => address.slice(2);
38
74
  var coinTypeReverseLabel = (coinType) => coinType.toString(16);
39
75
  function reverseName(address, coinType) {
40
76
  const label = addrReverseLabel(address);
@@ -51,84 +87,16 @@ function reverseName(address, coinType) {
51
87
  return `${label}.${middle}.reverse`;
52
88
  }
53
89
 
54
- // src/ens/subname-helpers.ts
55
- var makeSubdomainNode = (labelHash, node) => keccak256(concat([node, labelHash]));
56
- var maybeHealLabelByReverseAddress = ({
57
- maybeReverseAddress,
58
- labelHash
59
- }) => {
60
- if (!isAddress(maybeReverseAddress)) {
61
- throw new Error(
62
- `Invalid reverse address: '${maybeReverseAddress}'. Must be a valid EVM Address.`
63
- );
64
- }
65
- if (!isHash(labelHash)) {
66
- throw new Error(
67
- `Invalid labelHash: '${labelHash}'. Must start with '0x' and represent 32 bytes.`
68
- );
69
- }
70
- const assumedLabel = addrReverseLabel(maybeReverseAddress);
71
- if (labelhash(assumedLabel) === labelHash) return assumedLabel;
72
- return null;
73
- };
74
- var uint256ToHex32 = (num) => toHex(num, { size: 32 });
75
- var UNINDEXABLE_LABEL_CHARACTERS = [
76
- "\0",
77
- // null byte: PostgreSQL does not allow storing this character in text fields.
78
- ".",
79
- // conflicts with ENS label separator logic.
80
- "[",
81
- // conflicts with "unknown label" representations.
82
- "]"
83
- // conflicts with "unknown label" representations.
84
- ];
85
- var UNINDEXABLE_LABEL_CHARACTER_CODES = new Set(
86
- UNINDEXABLE_LABEL_CHARACTERS.map((char) => char.charCodeAt(0))
87
- );
88
- var isLabelIndexable = (label) => {
89
- if (!label) return false;
90
- for (let i = 0; i < label.length; i++) {
91
- if (UNINDEXABLE_LABEL_CHARACTER_CODES.has(label.charCodeAt(i))) return false;
92
- }
93
- return true;
94
- };
95
-
96
- // src/ens/names.ts
97
- var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
98
-
99
90
  // src/ens/types.ts
100
91
  import { ENSNamespaceIds } from "@ensnode/datasources";
101
92
 
102
93
  // src/ens/parse-reverse-name.ts
103
- import { getAddress, hexToBigInt } from "viem";
104
- var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
105
- var parseAddressLabel = (addressLabel) => getAddress(`0x${addressLabel}`);
106
- var parseCoinTypeLabel = (coinTypeLabel) => {
107
- if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
108
- if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
109
- return bigintToCoinType(hexToBigInt(`0x${coinTypeLabel}`));
110
- };
111
- function parseReverseName(name) {
112
- const match = name.match(REVERSE_NAME_REGEX);
113
- if (!match) return null;
114
- try {
115
- const [, addressLabel, coinTypeLabel] = match;
116
- if (!addressLabel) return null;
117
- if (!coinTypeLabel) return null;
118
- return {
119
- address: parseAddressLabel(addressLabel),
120
- coinType: parseCoinTypeLabel(coinTypeLabel)
121
- };
122
- } catch {
123
- return null;
124
- }
125
- }
126
-
127
- // src/ensindexer/config/deserialize.ts
128
- import { prettifyError as prettifyError2 } from "zod/v4";
94
+ import { hexToBigInt, isAddress as isAddress2 } from "viem";
129
95
 
130
- // src/ensindexer/config/zod-schemas.ts
131
- import z2 from "zod/v4";
96
+ // src/shared/address.ts
97
+ function asLowerCaseAddress(address) {
98
+ return address.toLowerCase();
99
+ }
132
100
 
133
101
  // src/shared/cache.ts
134
102
  var LruCache = class {
@@ -197,6 +165,7 @@ function serializeUrl(url) {
197
165
  import { prettifyError } from "zod/v4";
198
166
 
199
167
  // src/shared/zod-schemas.ts
168
+ import { isAddress } from "viem";
200
169
  import z from "zod/v4";
201
170
  var makeIntegerSchema = (valueLabel = "Value") => z.int({
202
171
  error: `${valueLabel} must be an integer.`
@@ -210,7 +179,7 @@ var makeNonNegativeIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(v
210
179
  var makeDurationSchema = (valueLabel = "Value") => z.coerce.number({
211
180
  error: `${valueLabel} must be a number.`
212
181
  }).pipe(makeNonNegativeIntegerSchema(valueLabel));
213
- var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel);
182
+ var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel).transform((val) => val);
214
183
  var makeChainIdStringSchema = (valueLabel = "Chain ID String") => z.string({ error: `${valueLabel} must be a string representing a chain ID.` }).pipe(z.coerce.number({ error: `${valueLabel} must represent a positive integer (>0).` })).pipe(makeChainIdSchema(`The numeric value represented by ${valueLabel}`));
215
184
  var makeDatetimeSchema = (valueLabel = "Datetime string") => z.iso.datetime({ error: `${valueLabel} must be a string in ISO 8601 format.` }).transform((v) => new Date(v));
216
185
  var makeUnixTimestampSchema = (valueLabel = "Timestamp") => makeIntegerSchema(valueLabel);
@@ -271,6 +240,16 @@ ${prettifyError(parsed.error)}
271
240
  }
272
241
  return parsed.data;
273
242
  }
243
+ function deserializeUnixTimestamp(maybeTimestamp, valueLabel) {
244
+ const schema = makeUnixTimestampSchema(valueLabel);
245
+ const parsed = schema.safeParse(maybeTimestamp);
246
+ if (parsed.error) {
247
+ throw new Error(`Cannot deserialize Unix Timestamp:
248
+ ${prettifyError(parsed.error)}
249
+ `);
250
+ }
251
+ return parsed.data;
252
+ }
274
253
  function deserializeUrl(maybeUrl, valueLabel) {
275
254
  const schema = makeUrlSchema(valueLabel);
276
255
  const parsed = schema.safeParse(maybeUrl);
@@ -322,29 +301,121 @@ ${prettifyError(parsed.error)}
322
301
  return parsed.data;
323
302
  }
324
303
 
325
- // src/shared/is-normalized.ts
326
- import { normalize } from "viem/ens";
327
- function isNormalized(name) {
328
- try {
329
- return name === normalize(name);
330
- } catch {
331
- return false;
332
- }
333
- }
334
-
335
304
  // src/shared/account-id.ts
336
305
  import { isAddressEqual } from "viem";
337
306
  var accountIdEqual = (a, b) => {
338
307
  return a.chainId === b.chainId && isAddressEqual(a.address, b.address);
339
308
  };
340
309
 
310
+ // src/shared/labelhash.ts
311
+ import { keccak256 as keccak2562, stringToBytes } from "viem";
312
+ var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
313
+
314
+ // src/shared/interpretation.ts
315
+ function literalLabelToInterpretedLabel(label) {
316
+ if (isNormalizedLabel(label)) return label;
317
+ return encodeLabelHash(labelhashLiteralLabel(label));
318
+ }
319
+ function literalLabelsToInterpretedName(labels) {
320
+ return labels.map(literalLabelToInterpretedLabel).join(".");
321
+ }
322
+ function interpretedLabelsToInterpretedName(labels) {
323
+ return labels.join(".");
324
+ }
325
+ function literalLabelsToLiteralName(labels) {
326
+ return labels.join(".");
327
+ }
328
+
329
+ // src/shared/url.ts
330
+ function isHttpProtocol(url) {
331
+ return ["http:", "https:"].includes(url.protocol);
332
+ }
333
+ function isWebSocketProtocol(url) {
334
+ return ["ws:", "wss:"].includes(url.protocol);
335
+ }
336
+
337
+ // src/ens/parse-reverse-name.ts
338
+ var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
339
+ var parseAddressLabel = (addressLabel) => {
340
+ const maybeAddress = `0x${addressLabel}`;
341
+ if (!isAddress2(maybeAddress)) {
342
+ throw new Error(`Invalid EVM address "${maybeAddress}"`);
343
+ }
344
+ return asLowerCaseAddress(maybeAddress);
345
+ };
346
+ var parseCoinTypeLabel = (coinTypeLabel) => {
347
+ if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
348
+ if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
349
+ return bigintToCoinType(hexToBigInt(`0x${coinTypeLabel}`));
350
+ };
351
+ function parseReverseName(name) {
352
+ const match = name.match(REVERSE_NAME_REGEX);
353
+ if (!match) return null;
354
+ try {
355
+ const [, addressLabel, coinTypeLabel] = match;
356
+ if (!addressLabel) return null;
357
+ if (!coinTypeLabel) return null;
358
+ return {
359
+ address: parseAddressLabel(addressLabel),
360
+ coinType: parseCoinTypeLabel(coinTypeLabel)
361
+ };
362
+ } catch {
363
+ return null;
364
+ }
365
+ }
366
+
367
+ // src/ens/encode-labelhash.ts
368
+ var encodeLabelHash = (labelHash) => `[${labelHash.slice(2)}]`;
369
+
370
+ // src/ens/dns-encoded-name.ts
371
+ import { bytesToString, hexToBytes } from "viem";
372
+ function decodeDNSEncodedLiteralName(packet) {
373
+ return decodeDNSEncodedName(packet);
374
+ }
375
+ function decodeDNSEncodedName(packet) {
376
+ const segments = [];
377
+ const bytes = hexToBytes(packet);
378
+ if (bytes.length === 0) throw new Error(`Packet is empty.`);
379
+ let offset = 0;
380
+ while (offset < bytes.length) {
381
+ const len = bytes[offset];
382
+ if (len === void 0) {
383
+ throw new Error(`Invariant: bytes[offset] is undefined after offset < bytes.length check.`);
384
+ }
385
+ if (len < 0 || len > 255) {
386
+ throw new Error(
387
+ `Invariant: this should be literally impossible, but an unsigned byte was less than zero or greater than 255. The value in question is ${len}`
388
+ );
389
+ }
390
+ if (len === 0) break;
391
+ const segment = bytesToString(bytes.subarray(offset + 1, offset + len + 1));
392
+ segments.push(segment);
393
+ offset += len + 1;
394
+ }
395
+ if (offset >= bytes.length) throw new Error(`Overflow, offset >= bytes.length`);
396
+ if (offset !== bytes.length - 1) throw new Error(`Junk at end of name`);
397
+ return segments;
398
+ }
399
+
400
+ // src/ens/index.ts
401
+ import { getENSRootChainId } from "@ensnode/datasources";
402
+
403
+ // src/ensindexer/config/deserialize.ts
404
+ import { prettifyError as prettifyError2 } from "zod/v4";
405
+
406
+ // src/ensindexer/config/zod-schemas.ts
407
+ import z2 from "zod/v4";
408
+
409
+ // src/ensindexer/config/helpers.ts
410
+ import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
411
+
341
412
  // src/ensindexer/config/types.ts
342
413
  var PluginName = /* @__PURE__ */ ((PluginName2) => {
343
414
  PluginName2["Subgraph"] = "subgraph";
344
415
  PluginName2["Basenames"] = "basenames";
345
416
  PluginName2["Lineanames"] = "lineanames";
346
417
  PluginName2["ThreeDNS"] = "threedns";
347
- PluginName2["ReverseResolvers"] = "reverse-resolvers";
418
+ PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
348
419
  PluginName2["Referrals"] = "referrals";
349
420
  PluginName2["TokenScope"] = "tokenscope";
350
421
  return PluginName2;
@@ -353,25 +424,32 @@ var PluginName = /* @__PURE__ */ ((PluginName2) => {
353
424
  // src/ensindexer/config/helpers.ts
354
425
  function isSubgraphCompatible(config) {
355
426
  const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
356
- const indexingBehaviorIsSubgraphCompatible = !config.healReverseAddresses && !config.indexAdditionalResolverRecords;
357
- const labelSetIsSubgraphCompatible = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
358
- return onlySubgraphPluginActivated && indexingBehaviorIsSubgraphCompatible && labelSetIsSubgraphCompatible;
427
+ const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
428
+ const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
429
+ const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
430
+ return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
431
+ }
432
+
433
+ // src/ensindexer/config/validations.ts
434
+ function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
435
+ const versionInfo = ctx.value;
436
+ if (versionInfo.ensDb !== versionInfo.ensIndexer) {
437
+ ctx.issues.push({
438
+ code: "custom",
439
+ input: versionInfo,
440
+ message: "`ensDb` version must be same as `ensIndexer` version"
441
+ });
442
+ }
359
443
  }
360
444
 
361
445
  // src/ensindexer/config/zod-schemas.ts
362
446
  var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
363
447
  error: `${valueLabel} must be an array.`
364
448
  }).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
365
- var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(
366
- z2.enum(PluginName, {
367
- error: `${valueLabel} must be a list with at least one valid plugin name. Valid plugins are: ${Object.values(
368
- PluginName
369
- ).join(", ")}`
370
- })
371
- ).min(1, {
372
- error: `${valueLabel} must be a list with at least one valid plugin name. Valid plugins are: ${Object.values(
373
- PluginName
374
- ).join(", ")}`
449
+ var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(z2.string(), {
450
+ error: `${valueLabel} must be a list of strings.`
451
+ }).min(1, {
452
+ error: `${valueLabel} must be a list of strings with at least one string value`
375
453
  }).refine((arr) => arr.length === uniq(arr).length, {
376
454
  error: `${valueLabel} cannot contain duplicate values.`
377
455
  });
@@ -402,54 +480,39 @@ var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
402
480
  });
403
481
  };
404
482
  var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
405
- var makeDependencyInfoSchema = (valueLabel = "Value") => z2.strictObject(
483
+ var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z2.strictObject(
406
484
  {
407
485
  nodejs: makeNonEmptyStringSchema(),
408
486
  ponder: makeNonEmptyStringSchema(),
487
+ ensDb: makeNonEmptyStringSchema(),
488
+ ensIndexer: makeNonEmptyStringSchema(),
489
+ ensNormalize: makeNonEmptyStringSchema(),
409
490
  ensRainbow: makeNonEmptyStringSchema(),
410
491
  ensRainbowSchema: makePositiveIntegerSchema()
411
492
  },
412
493
  {
413
- error: `${valueLabel} must be a valid DependencyInfo object.`
494
+ error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
414
495
  }
415
- );
416
- function invariant_reverseResolversPluginNeedsResolverRecords(ctx) {
417
- const { value: config } = ctx;
418
- const reverseResolversPluginActive = config.plugins.includes("reverse-resolvers" /* ReverseResolvers */);
419
- if (reverseResolversPluginActive && !config.indexAdditionalResolverRecords) {
420
- ctx.issues.push({
421
- code: "custom",
422
- input: config,
423
- message: `The '${"reverse-resolvers" /* ReverseResolvers */}' plugin requires 'indexAdditionalResolverRecords' to be 'true'.`
424
- });
425
- }
426
- }
496
+ ).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
427
497
  function invariant_isSubgraphCompatibleRequirements(ctx) {
428
498
  const { value: config } = ctx;
429
- if (config.isSubgraphCompatible !== isSubgraphCompatible(config)) {
430
- const message = config.isSubgraphCompatible ? `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active, both 'indexAdditionalResolverRecords' and 'healReverseAddresses' must be set to 'false', and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}` : `Both 'indexAdditionalResolverRecords' and 'healReverseAddresses' were set to 'false', the only active plugin was the '${"subgraph" /* Subgraph */}' plugin, and labelSet was {labelSetId: "subgraph", labelSetVersion: 0}. The 'isSubgraphCompatible' must be set to 'true'`;
499
+ if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
431
500
  ctx.issues.push({
432
501
  code: "custom",
433
502
  input: config,
434
- message
503
+ message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
435
504
  });
436
505
  }
437
506
  }
438
507
  var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
439
- ensAdminUrl: makeUrlSchema(`${valueLabel}.ensAdminUrl`),
440
- ensNodePublicUrl: makeUrlSchema(`${valueLabel}.ensNodePublicUrl`),
441
508
  labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
442
- healReverseAddresses: z2.boolean({ error: `${valueLabel}.healReverseAddresses` }),
443
- indexAdditionalResolverRecords: z2.boolean({
444
- error: `${valueLabel}.indexAdditionalResolverRecords`
445
- }),
446
509
  indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
447
510
  isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
448
511
  namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
449
512
  plugins: makePluginsListSchema(`${valueLabel}.plugins`),
450
513
  databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
451
- dependencyInfo: makeDependencyInfoSchema(`${valueLabel}.dependencyInfo`)
452
- }).check(invariant_reverseResolversPluginNeedsResolverRecords).check(invariant_isSubgraphCompatibleRequirements);
514
+ versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
515
+ }).check(invariant_isSubgraphCompatibleRequirements);
453
516
 
454
517
  // src/ensindexer/config/deserialize.ts
455
518
  function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
@@ -469,30 +532,22 @@ function serializeIndexedChainIds(indexedChainIds) {
469
532
  }
470
533
  function serializeENSIndexerPublicConfig(config) {
471
534
  const {
472
- ensAdminUrl,
473
- ensNodePublicUrl,
474
535
  labelSet,
475
536
  indexedChainIds,
476
537
  databaseSchemaName,
477
- healReverseAddresses,
478
- indexAdditionalResolverRecords,
479
538
  isSubgraphCompatible: isSubgraphCompatible2,
480
539
  namespace,
481
540
  plugins,
482
- dependencyInfo
541
+ versionInfo
483
542
  } = config;
484
543
  return {
485
- ensAdminUrl: serializeUrl(ensAdminUrl),
486
- ensNodePublicUrl: serializeUrl(ensNodePublicUrl),
487
544
  labelSet,
488
545
  indexedChainIds: serializeIndexedChainIds(indexedChainIds),
489
546
  databaseSchemaName,
490
- healReverseAddresses,
491
- indexAdditionalResolverRecords,
492
547
  isSubgraphCompatible: isSubgraphCompatible2,
493
548
  namespace,
494
549
  plugins,
495
- dependencyInfo
550
+ versionInfo
496
551
  };
497
552
  }
498
553
 
@@ -526,7 +581,7 @@ function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
526
581
  }
527
582
 
528
583
  // src/ensindexer/config/label-utils.ts
529
- import { hexToBytes } from "viem";
584
+ import { hexToBytes as hexToBytes2 } from "viem";
530
585
  function labelHashToBytes(labelHash) {
531
586
  try {
532
587
  if (labelHash.length !== 66) {
@@ -538,7 +593,7 @@ function labelHashToBytes(labelHash) {
538
593
  if (!labelHash.startsWith("0x")) {
539
594
  throw new Error("Labelhash must be 0x-prefixed");
540
595
  }
541
- const bytes = hexToBytes(labelHash);
596
+ const bytes = hexToBytes2(labelHash);
542
597
  if (bytes.length !== 32) {
543
598
  throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
544
599
  }
@@ -582,6 +637,92 @@ import { prettifyError as prettifyError3 } from "zod/v4";
582
637
  // src/ensindexer/indexing-status/zod-schemas.ts
583
638
  import z3 from "zod/v4";
584
639
 
640
+ // src/ensindexer/indexing-status/types.ts
641
+ var ChainIndexingConfigTypeIds = {
642
+ /**
643
+ * Represents that indexing of the chain should be performed for an indefinite range.
644
+ */
645
+ Indefinite: "indefinite",
646
+ /**
647
+ * Represents that indexing of the chain should be performed for a definite range.
648
+ */
649
+ Definite: "definite"
650
+ };
651
+ var ChainIndexingStatusIds = {
652
+ /**
653
+ * Represents that indexing of the chain is not ready to begin yet because:
654
+ * - ENSIndexer is in its initialization phase and the data to build a
655
+ * "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
656
+ * - ENSIndexer is using an omnichain indexing strategy and the
657
+ * `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
658
+ * {@link ChainIndexingSnapshot}.
659
+ */
660
+ Queued: "chain-queued",
661
+ /**
662
+ * Represents that indexing of the chain is in progress and under a special
663
+ * "backfill" phase that optimizes for accelerated indexing until reaching the
664
+ * "fixed target" `backfillEndBlock`.
665
+ */
666
+ Backfill: "chain-backfill",
667
+ /**
668
+ * Represents that the "backfill" phase of indexing the chain is completed
669
+ * and that the chain is configured to be indexed for an indefinite range.
670
+ * Therefore, indexing of the chain remains indefinitely in progress where
671
+ * ENSIndexer will continuously work to discover and index new blocks as they
672
+ * are added to the chain across time.
673
+ */
674
+ Following: "chain-following",
675
+ /**
676
+ * Represents that indexing of the chain is completed as the chain is configured
677
+ * to be indexed for a definite range and the indexing of all blocks through
678
+ * that definite range is completed.
679
+ */
680
+ Completed: "chain-completed"
681
+ };
682
+ var OmnichainIndexingStatusIds = {
683
+ /**
684
+ * Represents that omnichain indexing is not ready to begin yet because
685
+ * ENSIndexer is in its initialization phase and the data to build a "true"
686
+ * {@link OmnichainIndexingStatusSnapshot} is still being loaded.
687
+ */
688
+ Unstarted: "omnichain-unstarted",
689
+ /**
690
+ * Represents that omnichain indexing is in an overall "backfill" status because
691
+ * - At least one indexed chain has a `chainStatus` of
692
+ * {@link ChainIndexingStatusIds.Backfill}; and
693
+ * - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
694
+ */
695
+ Backfill: "omnichain-backfill",
696
+ /**
697
+ * Represents that omnichain indexing is in an overall "following" status because
698
+ * at least one indexed chain has a `chainStatus` of
699
+ * {@link ChainIndexingStatusIds.Following}.
700
+ */
701
+ Following: "omnichain-following",
702
+ /**
703
+ * Represents that omnichain indexing has completed because all indexed chains have
704
+ * a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
705
+ */
706
+ Completed: "omnichain-completed"
707
+ };
708
+ var CrossChainIndexingStrategyIds = {
709
+ /**
710
+ * Represents that the indexing of events across all indexed chains will
711
+ * proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
712
+ * and block number.
713
+ *
714
+ * This strategy is "deterministic" in that the order of processing cross-chain indexed
715
+ * events and each resulting indexed data state transition recorded in ENSDb is always
716
+ * the same for each ENSIndexer instance operating with an equivalent
717
+ * `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
718
+ * - increased indexing latency that must wait for the slowest indexed chain to
719
+ * add new blocks or to discover new blocks through the configured RPCs.
720
+ * - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
721
+ * will be affected.
722
+ */
723
+ Omnichain: "omnichain"
724
+ };
725
+
585
726
  // src/shared/block-ref.ts
586
727
  function isBefore(blockA, blockB) {
587
728
  return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
@@ -593,49 +734,21 @@ function isBeforeOrEqualTo(blockA, blockB) {
593
734
  return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
594
735
  }
595
736
 
596
- // src/ensindexer/indexing-status/types.ts
597
- var ChainIndexingStatusIds = {
598
- Unstarted: "unstarted",
599
- Backfill: "backfill",
600
- Following: "following",
601
- Completed: "completed"
602
- };
603
- var OverallIndexingStatusIds = {
604
- Unstarted: "unstarted",
605
- Backfill: "backfill",
606
- Following: "following",
607
- Completed: "completed",
608
- IndexerError: "indexer-error"
609
- };
610
- var ChainIndexingStrategyIds = {
611
- Indefinite: "indefinite",
612
- Definite: "definite"
613
- };
614
-
615
737
  // src/ensindexer/indexing-status/helpers.ts
616
- function getOverallIndexingStatus(chains) {
617
- const chainStatuses = chains.map((chain) => chain.status);
618
- let overallStatus;
619
- if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Following)) {
620
- overallStatus = OverallIndexingStatusIds.Following;
621
- } else if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Backfill)) {
622
- overallStatus = OverallIndexingStatusIds.Backfill;
623
- } else if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Unstarted)) {
624
- overallStatus = OverallIndexingStatusIds.Unstarted;
625
- } else {
626
- overallStatus = OverallIndexingStatusIds.Completed;
738
+ function getOmnichainIndexingStatus(chains) {
739
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
740
+ return OmnichainIndexingStatusIds.Following;
627
741
  }
628
- return overallStatus;
629
- }
630
- function getOverallApproxRealtimeDistance(chains) {
631
- const chainApproxRealtimeDistances = chains.filter((chain) => chain.status === ChainIndexingStatusIds.Following).map((chain) => chain.approxRealtimeDistance);
632
- if (chainApproxRealtimeDistances.length === 0) {
633
- throw new Error(
634
- `The overall approximate realtime distance value is undefined if no indexed chain is in the '${OverallIndexingStatusIds.Following}' status`
635
- );
742
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
743
+ return OmnichainIndexingStatusIds.Backfill;
744
+ }
745
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
746
+ return OmnichainIndexingStatusIds.Unstarted;
636
747
  }
637
- const approxRealtimeDistance = Math.max(...chainApproxRealtimeDistances);
638
- return approxRealtimeDistance;
748
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
749
+ return OmnichainIndexingStatusIds.Completed;
750
+ }
751
+ throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
639
752
  }
640
753
  function getTimestampForLowestOmnichainStartBlock(chains) {
641
754
  const earliestKnownBlockTimestamps = chains.map(
@@ -646,8 +759,8 @@ function getTimestampForLowestOmnichainStartBlock(chains) {
646
759
  function getTimestampForHighestOmnichainKnownBlock(chains) {
647
760
  const latestKnownBlockTimestamps = [];
648
761
  for (const chain of chains) {
649
- switch (chain.status) {
650
- case ChainIndexingStatusIds.Unstarted:
762
+ switch (chain.chainStatus) {
763
+ case ChainIndexingStatusIds.Queued:
651
764
  if (chain.config.endBlock) {
652
765
  latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
653
766
  }
@@ -666,159 +779,349 @@ function getTimestampForHighestOmnichainKnownBlock(chains) {
666
779
  return Math.max(...latestKnownBlockTimestamps);
667
780
  }
668
781
  function getOmnichainIndexingCursor(chains) {
669
- return Math.min(...chains.map((chain) => chain.latestIndexedBlock.timestamp));
670
- }
671
- function getActiveChains(chains) {
672
- return chains.filter(
673
- (chain) => chain.status === ChainIndexingStatusIds.Backfill || chain.status === ChainIndexingStatusIds.Following
674
- );
675
- }
676
- function getStandbyChains(chains) {
677
- return chains.filter(
678
- (chain) => chain.status === ChainIndexingStatusIds.Unstarted || chain.status === ChainIndexingStatusIds.Completed
679
- );
782
+ if (chains.length === 0) {
783
+ throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
784
+ }
785
+ if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
786
+ const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
787
+ return Math.min(...earliestStartBlockTimestamps) - 1;
788
+ }
789
+ const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
790
+ if (latestIndexedBlockTimestamps.length < 1) {
791
+ throw new Error("latestIndexedBlockTimestamps array must include at least one element");
792
+ }
793
+ return Math.max(...latestIndexedBlockTimestamps);
680
794
  }
681
795
  function createIndexingConfig(startBlock, endBlock) {
682
796
  if (endBlock) {
683
797
  return {
684
- strategy: ChainIndexingStrategyIds.Definite,
798
+ configType: ChainIndexingConfigTypeIds.Definite,
685
799
  startBlock,
686
800
  endBlock
687
801
  };
688
802
  }
689
803
  return {
690
- strategy: ChainIndexingStrategyIds.Indefinite,
691
- startBlock,
692
- endBlock: null
804
+ configType: ChainIndexingConfigTypeIds.Indefinite,
805
+ startBlock
693
806
  };
694
807
  }
695
- function checkChainIndexingStatusesForUnstartedOverallStatus(chains) {
696
- return chains.every((chain) => chain.status === ChainIndexingStatusIds.Unstarted);
808
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
809
+ return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
697
810
  }
698
- function checkChainIndexingStatusesForBackfillOverallStatus(chains) {
811
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
699
812
  const atLeastOneChainInTargetStatus = chains.some(
700
- (chain) => chain.status === ChainIndexingStatusIds.Backfill
813
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
701
814
  );
702
815
  const otherChainsHaveValidStatuses = chains.every(
703
- (chain) => chain.status === ChainIndexingStatusIds.Unstarted || chain.status === ChainIndexingStatusIds.Backfill || chain.status === ChainIndexingStatusIds.Completed
816
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
704
817
  );
705
818
  return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
706
819
  }
707
- function checkChainIndexingStatusesForCompletedOverallStatus(chains) {
820
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
708
821
  const allChainsHaveValidStatuses = chains.every(
709
- (chain) => chain.status === ChainIndexingStatusIds.Completed
822
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
710
823
  );
711
824
  return allChainsHaveValidStatuses;
712
825
  }
713
- function checkChainIndexingStatusesForFollowingOverallStatus(chains) {
826
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
714
827
  const allChainsHaveValidStatuses = chains.some(
715
- (chain) => chain.status === ChainIndexingStatusIds.Following
828
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Following
716
829
  );
717
830
  return allChainsHaveValidStatuses;
718
831
  }
719
- function sortAscChainStatusesByStartBlock(chains) {
832
+ function sortChainStatusesByStartBlockAsc(chains) {
720
833
  chains.sort(
721
834
  ([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
722
835
  );
723
836
  return chains;
724
837
  }
725
838
 
839
+ // src/ensindexer/indexing-status/validations.ts
840
+ function invariant_chainSnapshotQueuedBlocks(ctx) {
841
+ const { config } = ctx.value;
842
+ if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
843
+ ctx.issues.push({
844
+ code: "custom",
845
+ input: ctx.value,
846
+ message: "`config.startBlock` must be before or same as `config.endBlock`."
847
+ });
848
+ }
849
+ }
850
+ function invariant_chainSnapshotBackfillBlocks(ctx) {
851
+ const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
852
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
853
+ ctx.issues.push({
854
+ code: "custom",
855
+ input: ctx.value,
856
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
857
+ });
858
+ }
859
+ if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
860
+ ctx.issues.push({
861
+ code: "custom",
862
+ input: ctx.value,
863
+ message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
864
+ });
865
+ }
866
+ if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
867
+ ctx.issues.push({
868
+ code: "custom",
869
+ input: ctx.value,
870
+ message: "`backfillEndBlock` must be the same as `config.endBlock`."
871
+ });
872
+ }
873
+ }
874
+ function invariant_chainSnapshotCompletedBlocks(ctx) {
875
+ const { config, latestIndexedBlock } = ctx.value;
876
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
877
+ ctx.issues.push({
878
+ code: "custom",
879
+ input: ctx.value,
880
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
881
+ });
882
+ }
883
+ if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
884
+ ctx.issues.push({
885
+ code: "custom",
886
+ input: ctx.value,
887
+ message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
888
+ });
889
+ }
890
+ }
891
+ function invariant_chainSnapshotFollowingBlocks(ctx) {
892
+ const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
893
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
894
+ ctx.issues.push({
895
+ code: "custom",
896
+ input: ctx.value,
897
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
898
+ });
899
+ }
900
+ if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
901
+ ctx.issues.push({
902
+ code: "custom",
903
+ input: ctx.value,
904
+ message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
905
+ });
906
+ }
907
+ }
908
+ function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
909
+ const snapshot = ctx.value;
910
+ const chains = Array.from(snapshot.chains.values());
911
+ const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
912
+ const actualOmnichainStatus = snapshot.omnichainStatus;
913
+ if (expectedOmnichainStatus !== actualOmnichainStatus) {
914
+ ctx.issues.push({
915
+ code: "custom",
916
+ input: snapshot,
917
+ message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
918
+ });
919
+ }
920
+ }
921
+ function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
922
+ const snapshot = ctx.value;
923
+ const queuedChains = Array.from(snapshot.chains.values()).filter(
924
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
925
+ );
926
+ if (queuedChains.length === 0) {
927
+ return;
928
+ }
929
+ const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
930
+ const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
931
+ if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
932
+ ctx.issues.push({
933
+ code: "custom",
934
+ input: snapshot,
935
+ message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
936
+ });
937
+ }
938
+ }
939
+ function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
940
+ const snapshot = ctx.value;
941
+ const backfillChains = Array.from(snapshot.chains.values()).filter(
942
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
943
+ );
944
+ if (backfillChains.length === 0) {
945
+ return;
946
+ }
947
+ const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
948
+ const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
949
+ if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
950
+ ctx.issues.push({
951
+ code: "custom",
952
+ input: snapshot,
953
+ message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
954
+ });
955
+ }
956
+ }
957
+ function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
958
+ const snapshot = ctx.value;
959
+ const indexedChains = Array.from(snapshot.chains.values()).filter(
960
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
961
+ );
962
+ if (indexedChains.length === 0) {
963
+ return;
964
+ }
965
+ const indexedChainLatestIndexedBlocks = indexedChains.map(
966
+ (chain) => chain.latestIndexedBlock.timestamp
967
+ );
968
+ const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
969
+ if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
970
+ ctx.issues.push({
971
+ code: "custom",
972
+ input: snapshot,
973
+ message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
974
+ });
975
+ }
976
+ }
977
+ function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
978
+ const chains = ctx.value;
979
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
980
+ Array.from(chains.values())
981
+ );
982
+ if (hasValidChains === false) {
983
+ ctx.issues.push({
984
+ code: "custom",
985
+ input: chains,
986
+ message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
987
+ });
988
+ }
989
+ }
990
+ function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
991
+ const chains = ctx.value;
992
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
993
+ Array.from(chains.values())
994
+ );
995
+ if (hasValidChains === false) {
996
+ ctx.issues.push({
997
+ code: "custom",
998
+ input: chains,
999
+ message: `For omnichain status snapshot 'backfill', at least one chain must be in "backfill" status and each chain has to have a status of either "queued", "backfill" or "completed".`
1000
+ });
1001
+ }
1002
+ }
1003
+ function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
1004
+ const chains = ctx.value;
1005
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
1006
+ Array.from(chains.values())
1007
+ );
1008
+ if (hasValidChains === false) {
1009
+ ctx.issues.push({
1010
+ code: "custom",
1011
+ input: chains,
1012
+ message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
1013
+ });
1014
+ }
1015
+ }
1016
+ function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
1017
+ const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
1018
+ const { omnichainIndexingCursor } = omnichainSnapshot;
1019
+ if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
1020
+ console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
1021
+ slowestChainIndexingCursor,
1022
+ omnichainIndexingCursor
1023
+ });
1024
+ ctx.issues.push({
1025
+ code: "custom",
1026
+ input: ctx.value,
1027
+ message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
1028
+ });
1029
+ }
1030
+ }
1031
+ function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
1032
+ const { snapshotTime, omnichainSnapshot } = ctx.value;
1033
+ const chains = Array.from(omnichainSnapshot.chains.values());
1034
+ const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1035
+ const endBlockTimestamps = chains.filter((chain) => chain.config.configType === ChainIndexingConfigTypeIds.Definite).map((chain) => chain.config.endBlock.timestamp);
1036
+ const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
1037
+ const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
1038
+ const highestKnownBlockTimestamp = Math.max(
1039
+ ...startBlockTimestamps,
1040
+ ...endBlockTimestamps,
1041
+ ...backfillEndBlockTimestamps,
1042
+ ...latestKnownBlockTimestamps
1043
+ );
1044
+ if (snapshotTime < highestKnownBlockTimestamp) {
1045
+ ctx.issues.push({
1046
+ code: "custom",
1047
+ input: ctx.value,
1048
+ message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
1049
+ });
1050
+ }
1051
+ }
1052
+ function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
1053
+ const projection = ctx.value;
1054
+ const { snapshot, projectedAt } = projection;
1055
+ if (snapshot.snapshotTime > projectedAt) {
1056
+ ctx.issues.push({
1057
+ code: "custom",
1058
+ input: projection,
1059
+ message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
1060
+ });
1061
+ }
1062
+ }
1063
+ function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
1064
+ const projection = ctx.value;
1065
+ const { projectedAt, snapshot, worstCaseDistance } = projection;
1066
+ const { omnichainSnapshot } = snapshot;
1067
+ const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
1068
+ if (worstCaseDistance !== expectedWorstCaseDistance) {
1069
+ ctx.issues.push({
1070
+ code: "custom",
1071
+ input: projection,
1072
+ message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
1073
+ });
1074
+ }
1075
+ }
1076
+
726
1077
  // src/ensindexer/indexing-status/zod-schemas.ts
727
- var makeChainIndexingConfigSchema = (valueLabel = "Value") => z3.discriminatedUnion("strategy", [
1078
+ var makeChainIndexingConfigSchema = (valueLabel = "Value") => z3.discriminatedUnion("configType", [
728
1079
  z3.strictObject({
729
- strategy: z3.literal(ChainIndexingStrategyIds.Indefinite),
730
- startBlock: makeBlockRefSchema(valueLabel),
731
- endBlock: z3.null()
1080
+ configType: z3.literal(ChainIndexingConfigTypeIds.Indefinite),
1081
+ startBlock: makeBlockRefSchema(valueLabel)
732
1082
  }),
733
1083
  z3.strictObject({
734
- strategy: z3.literal(ChainIndexingStrategyIds.Definite),
1084
+ configType: z3.literal(ChainIndexingConfigTypeIds.Definite),
735
1085
  startBlock: makeBlockRefSchema(valueLabel),
736
1086
  endBlock: makeBlockRefSchema(valueLabel)
737
1087
  })
738
1088
  ]);
739
- var makeChainIndexingUnstartedStatusSchema = (valueLabel = "Value") => z3.strictObject({
740
- status: z3.literal(ChainIndexingStatusIds.Unstarted),
1089
+ var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => z3.strictObject({
1090
+ chainStatus: z3.literal(ChainIndexingStatusIds.Queued),
741
1091
  config: makeChainIndexingConfigSchema(valueLabel)
742
- }).refine(
743
- ({ config }) => config.endBlock === null || isBeforeOrEqualTo(config.startBlock, config.endBlock),
744
- {
745
- error: `config.startBlock must be before or same as config.endBlock.`
746
- }
747
- );
748
- var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictObject({
749
- status: z3.literal(ChainIndexingStatusIds.Backfill),
1092
+ }).check(invariant_chainSnapshotQueuedBlocks);
1093
+ var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => z3.strictObject({
1094
+ chainStatus: z3.literal(ChainIndexingStatusIds.Backfill),
750
1095
  config: makeChainIndexingConfigSchema(valueLabel),
751
1096
  latestIndexedBlock: makeBlockRefSchema(valueLabel),
752
- latestSyncedBlock: makeBlockRefSchema(valueLabel),
753
1097
  backfillEndBlock: makeBlockRefSchema(valueLabel)
754
- }).refine(
755
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
756
- {
757
- error: `config.startBlock must be before or same as latestIndexedBlock.`
758
- }
759
- ).refine(
760
- ({ latestIndexedBlock, latestSyncedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestSyncedBlock),
761
- {
762
- error: `latestIndexedBlock must be before or same as latestSyncedBlock.`
763
- }
764
- ).refine(
765
- ({ latestSyncedBlock, backfillEndBlock }) => isBeforeOrEqualTo(latestSyncedBlock, backfillEndBlock),
766
- {
767
- error: `latestSyncedBlock must be before or same as backfillEndBlock.`
768
- }
769
- ).refine(
770
- ({ config, backfillEndBlock }) => config.endBlock === null || isEqualTo(backfillEndBlock, config.endBlock),
771
- {
772
- error: `backfillEndBlock must be the same as config.endBlock.`
773
- }
774
- );
775
- var makeChainIndexingFollowingStatusSchema = (valueLabel = "Value") => z3.strictObject({
776
- status: z3.literal(ChainIndexingStatusIds.Following),
1098
+ }).check(invariant_chainSnapshotBackfillBlocks);
1099
+ var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => z3.strictObject({
1100
+ chainStatus: z3.literal(ChainIndexingStatusIds.Completed),
777
1101
  config: z3.strictObject({
778
- strategy: z3.literal(ChainIndexingStrategyIds.Indefinite),
779
- startBlock: makeBlockRefSchema(valueLabel)
780
- }),
781
- latestIndexedBlock: makeBlockRefSchema(valueLabel),
782
- latestKnownBlock: makeBlockRefSchema(valueLabel),
783
- approxRealtimeDistance: makeDurationSchema(valueLabel)
784
- }).refine(
785
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
786
- {
787
- error: `config.startBlock must be before or same as latestIndexedBlock.`
788
- }
789
- ).refine(
790
- ({ latestIndexedBlock, latestKnownBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock),
791
- {
792
- error: `latestIndexedBlock must be before or same as latestKnownBlock.`
793
- }
794
- );
795
- var makeChainIndexingCompletedStatusSchema = (valueLabel = "Value") => z3.strictObject({
796
- status: z3.literal(ChainIndexingStatusIds.Completed),
797
- config: z3.strictObject({
798
- strategy: z3.literal(ChainIndexingStrategyIds.Definite),
1102
+ configType: z3.literal(ChainIndexingConfigTypeIds.Definite),
799
1103
  startBlock: makeBlockRefSchema(valueLabel),
800
1104
  endBlock: makeBlockRefSchema(valueLabel)
801
1105
  }),
802
1106
  latestIndexedBlock: makeBlockRefSchema(valueLabel)
803
- }).refine(
804
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
805
- {
806
- error: `config.startBlock must be before or same as latestIndexedBlock.`
807
- }
808
- ).refine(
809
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, config.endBlock),
810
- {
811
- error: `latestIndexedBlock must be before or same as config.endBlock.`
812
- }
813
- );
814
- var makeChainIndexingStatusSchema = (valueLabel = "Value") => z3.discriminatedUnion("status", [
815
- makeChainIndexingUnstartedStatusSchema(valueLabel),
816
- makeChainIndexingBackfillStatusSchema(valueLabel),
817
- makeChainIndexingFollowingStatusSchema(valueLabel),
818
- makeChainIndexingCompletedStatusSchema(valueLabel)
1107
+ }).check(invariant_chainSnapshotCompletedBlocks);
1108
+ var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => z3.strictObject({
1109
+ chainStatus: z3.literal(ChainIndexingStatusIds.Following),
1110
+ config: z3.strictObject({
1111
+ configType: z3.literal(ChainIndexingConfigTypeIds.Indefinite),
1112
+ startBlock: makeBlockRefSchema(valueLabel)
1113
+ }),
1114
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1115
+ latestKnownBlock: makeBlockRefSchema(valueLabel)
1116
+ }).check(invariant_chainSnapshotFollowingBlocks);
1117
+ var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => z3.discriminatedUnion("chainStatus", [
1118
+ makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
1119
+ makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
1120
+ makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
1121
+ makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
819
1122
  ]);
820
- var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z3.record(makeChainIdStringSchema(), makeChainIndexingStatusSchema(valueLabel), {
821
- error: "Chains configuration must be an object mapping valid chain IDs to their configs."
1123
+ var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z3.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
1124
+ error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
822
1125
  }).transform((serializedChainsIndexingStatus) => {
823
1126
  const chainsIndexingStatus = /* @__PURE__ */ new Map();
824
1127
  for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
@@ -826,164 +1129,164 @@ var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z3.record(makeCh
826
1129
  }
827
1130
  return chainsIndexingStatus;
828
1131
  });
829
- var makeUnstartedOverallStatusSchema = (valueLabel) => z3.strictObject({
830
- overallStatus: z3.literal(OverallIndexingStatusIds.Unstarted),
831
- chains: makeChainIndexingStatusesSchema(valueLabel).refine(
832
- (chains) => checkChainIndexingStatusesForUnstartedOverallStatus(Array.from(chains.values())),
833
- {
834
- error: `${valueLabel} at least one chain must be in "unstarted" status and
835
- each chain has to have a status of either "unstarted", or "completed"`
836
- }
837
- ).transform((chains) => chains)
838
- }).refine(
839
- (indexingStatus) => {
840
- const chains = Array.from(indexingStatus.chains.values());
841
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
842
- },
843
- { error: `${valueLabel} is an invalid overallStatus.` }
844
- );
845
- var makeBackfillOverallStatusSchema = (valueLabel) => z3.strictObject({
846
- overallStatus: z3.literal(OverallIndexingStatusIds.Backfill),
847
- chains: makeChainIndexingStatusesSchema(valueLabel).refine(
848
- (chains) => checkChainIndexingStatusesForBackfillOverallStatus(Array.from(chains.values())),
849
- {
850
- error: `${valueLabel} at least one chain must be in "backfill" status and
851
- each chain has to have a status of either "unstarted", "backfill" or "completed"`
852
- }
853
- ).transform((chains) => chains),
1132
+ var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => z3.strictObject({
1133
+ omnichainStatus: z3.literal(OmnichainIndexingStatusIds.Unstarted),
1134
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
854
1135
  omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
855
- }).refine(
856
- (indexingStatus) => {
857
- const chains = Array.from(indexingStatus.chains.values());
858
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
859
- },
860
- { error: `${valueLabel} is an invalid overallStatus.` }
861
- ).refine(
862
- (indexingStatus) => {
863
- const chains = Array.from(indexingStatus.chains.values());
864
- const standbyChainStartBlocks = getStandbyChains(chains).map(
865
- (chain) => chain.config.startBlock.timestamp
866
- );
867
- const standbyChainEarliestStartBlocks = Math.min(...standbyChainStartBlocks);
868
- return indexingStatus.omnichainIndexingCursor <= standbyChainEarliestStartBlocks;
869
- },
870
- {
871
- error: "omnichainIndexingCursor must be lower than or equal to the earliest config.startBlock across all standby chains"
872
- }
873
- );
874
- var makeCompletedOverallStatusSchema = (valueLabel) => z3.strictObject({
875
- overallStatus: z3.literal(OverallIndexingStatusIds.Completed),
876
- chains: makeChainIndexingStatusesSchema(valueLabel).refine(
877
- (chains) => checkChainIndexingStatusesForCompletedOverallStatus(Array.from(chains.values())),
878
- {
879
- error: `${valueLabel} all chains must have "completed" status`
880
- }
881
- ).transform((chains) => chains)
882
- }).refine(
883
- (indexingStatus) => {
884
- const chains = Array.from(indexingStatus.chains.values());
885
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
886
- },
887
- { error: `${valueLabel} is an invalid overallStatus.` }
888
- );
889
- var makeFollowingOverallStatusSchema = (valueLabel) => z3.strictObject({
890
- overallStatus: z3.literal(OverallIndexingStatusIds.Following),
1136
+ });
1137
+ var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => z3.strictObject({
1138
+ omnichainStatus: z3.literal(OmnichainIndexingStatusIds.Backfill),
1139
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
1140
+ (chains) => chains
1141
+ ),
1142
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1143
+ });
1144
+ var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => z3.strictObject({
1145
+ omnichainStatus: z3.literal(OmnichainIndexingStatusIds.Completed),
1146
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
1147
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1148
+ });
1149
+ var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => z3.strictObject({
1150
+ omnichainStatus: z3.literal(OmnichainIndexingStatusIds.Following),
891
1151
  chains: makeChainIndexingStatusesSchema(valueLabel),
892
- overallApproxRealtimeDistance: makeDurationSchema(valueLabel),
893
1152
  omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
894
- }).refine(
895
- (indexingStatus) => {
896
- const chains = Array.from(indexingStatus.chains.values());
897
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
898
- },
899
- { error: `${valueLabel} is an invalid overallStatus.` }
900
- ).refine(
901
- (indexingStatus) => checkChainIndexingStatusesForFollowingOverallStatus(
902
- Array.from(indexingStatus.chains.values())
903
- ),
904
- {
905
- error: `${valueLabel} at least one chain must be in "following" status`
906
- }
907
- ).refine(
908
- (indexingStatus) => {
909
- const chains = Array.from(indexingStatus.chains.values());
910
- return getOverallApproxRealtimeDistance(chains) === indexingStatus.overallApproxRealtimeDistance;
911
- },
912
- { error: `${valueLabel} is an invalid overallApproxRealtimeDistance.` }
913
- ).refine(
914
- (indexingStatus) => {
915
- const chains = Array.from(indexingStatus.chains.values());
916
- const standbyChainStartBlocks = getStandbyChains(chains).map(
917
- (chain) => chain.config.startBlock.timestamp
918
- );
919
- const standbyChainEarliestStartBlocks = Math.min(...standbyChainStartBlocks);
920
- return indexingStatus.omnichainIndexingCursor <= standbyChainEarliestStartBlocks;
921
- },
922
- {
923
- error: "omnichainIndexingCursor must be lower than or equal to the earliest config.startBlock across all standby chains"
924
- }
925
- );
926
- var makeErrorSchemaOverallStatusSchema = (valueLabel) => z3.strictObject({
927
- overallStatus: z3.literal(OverallIndexingStatusIds.IndexerError)
928
1153
  });
929
- var makeENSIndexerIndexingStatusSchema = (valueLabel = "ENSIndexerIndexingStatus") => z3.discriminatedUnion("overallStatus", [
930
- makeUnstartedOverallStatusSchema(valueLabel),
931
- makeBackfillOverallStatusSchema(valueLabel),
932
- makeCompletedOverallStatusSchema(valueLabel),
933
- makeFollowingOverallStatusSchema(valueLabel),
934
- makeErrorSchemaOverallStatusSchema(valueLabel)
1154
+ var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => z3.discriminatedUnion("omnichainStatus", [
1155
+ makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
1156
+ makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
1157
+ makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
1158
+ makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
1159
+ ]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
1160
+ invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
1161
+ ).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
1162
+ var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => z3.strictObject({
1163
+ strategy: z3.literal(CrossChainIndexingStrategyIds.Omnichain),
1164
+ slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
1165
+ snapshotTime: makeUnixTimestampSchema(valueLabel),
1166
+ omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
1167
+ }).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
1168
+ var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => z3.discriminatedUnion("strategy", [
1169
+ makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
935
1170
  ]);
1171
+ var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => z3.strictObject({
1172
+ projectedAt: makeUnixTimestampSchema(valueLabel),
1173
+ worstCaseDistance: makeDurationSchema(valueLabel),
1174
+ snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
1175
+ }).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
936
1176
 
937
1177
  // src/ensindexer/indexing-status/deserialize.ts
938
- function deserializeENSIndexerIndexingStatus(maybeStatus, valueLabel) {
939
- const schema = makeENSIndexerIndexingStatusSchema(valueLabel);
940
- const parsed = schema.safeParse(maybeStatus);
1178
+ function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1179
+ const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
1180
+ const parsed = schema.safeParse(maybeSnapshot);
1181
+ if (parsed.error) {
1182
+ throw new Error(
1183
+ `Cannot deserialize into ChainIndexingStatusSnapshot:
1184
+ ${prettifyError3(parsed.error)}
1185
+ `
1186
+ );
1187
+ }
1188
+ return parsed.data;
1189
+ }
1190
+ function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1191
+ const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
1192
+ const parsed = schema.safeParse(maybeSnapshot);
941
1193
  if (parsed.error) {
942
1194
  throw new Error(
943
- `Cannot deserialize ENSIndexerIndexingStatus:
1195
+ `Cannot deserialize into OmnichainIndexingStatusSnapshot:
944
1196
  ${prettifyError3(parsed.error)}
945
1197
  `
946
1198
  );
947
1199
  }
948
1200
  return parsed.data;
949
1201
  }
1202
+ function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1203
+ const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
1204
+ const parsed = schema.safeParse(maybeSnapshot);
1205
+ if (parsed.error) {
1206
+ throw new Error(
1207
+ `Cannot deserialize into CrossChainIndexingStatusSnapshot:
1208
+ ${prettifyError3(parsed.error)}
1209
+ `
1210
+ );
1211
+ }
1212
+ return parsed.data;
1213
+ }
1214
+ function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
1215
+ const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
1216
+ const parsed = schema.safeParse(maybeProjection);
1217
+ if (parsed.error) {
1218
+ throw new Error(
1219
+ `Cannot deserialize into RealtimeIndexingStatusProjection:
1220
+ ${prettifyError3(parsed.error)}
1221
+ `
1222
+ );
1223
+ }
1224
+ return parsed.data;
1225
+ }
1226
+
1227
+ // src/ensindexer/indexing-status/projection.ts
1228
+ function createRealtimeIndexingStatusProjection(snapshot, now) {
1229
+ const projectedAt = Math.max(now, snapshot.snapshotTime);
1230
+ return {
1231
+ projectedAt,
1232
+ worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
1233
+ snapshot
1234
+ };
1235
+ }
950
1236
 
951
1237
  // src/ensindexer/indexing-status/serialize.ts
952
- function serializeChainIndexingStatuses(chainIndexingStatuses) {
953
- const serializedChainsIndexingStatuses = {};
954
- for (const [chainId, chainIndexingStatus] of chainIndexingStatuses.entries()) {
955
- serializedChainsIndexingStatuses[serializeChainId(chainId)] = chainIndexingStatus;
1238
+ function serializeCrossChainIndexingStatusSnapshotOmnichain({
1239
+ strategy,
1240
+ slowestChainIndexingCursor,
1241
+ snapshotTime,
1242
+ omnichainSnapshot
1243
+ }) {
1244
+ return {
1245
+ strategy,
1246
+ slowestChainIndexingCursor,
1247
+ snapshotTime,
1248
+ omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
1249
+ };
1250
+ }
1251
+ function serializeRealtimeIndexingStatusProjection(indexingProjection) {
1252
+ return {
1253
+ projectedAt: indexingProjection.projectedAt,
1254
+ worstCaseDistance: indexingProjection.worstCaseDistance,
1255
+ snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
1256
+ };
1257
+ }
1258
+ function serializeChainIndexingSnapshots(chains) {
1259
+ const serializedSnapshots = {};
1260
+ for (const [chainId, snapshot] of chains.entries()) {
1261
+ serializedSnapshots[serializeChainId(chainId)] = snapshot;
956
1262
  }
957
- return serializedChainsIndexingStatuses;
1263
+ return serializedSnapshots;
958
1264
  }
959
- function serializeENSIndexerIndexingStatus(indexingStatus) {
960
- switch (indexingStatus.overallStatus) {
961
- case OverallIndexingStatusIds.IndexerError:
1265
+ function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
1266
+ switch (indexingStatus.omnichainStatus) {
1267
+ case OmnichainIndexingStatusIds.Unstarted:
962
1268
  return {
963
- overallStatus: OverallIndexingStatusIds.IndexerError
964
- };
965
- case OverallIndexingStatusIds.Unstarted:
966
- return {
967
- overallStatus: OverallIndexingStatusIds.Unstarted,
968
- chains: serializeChainIndexingStatuses(indexingStatus.chains)
1269
+ omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
1270
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1271
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
969
1272
  };
970
- case OverallIndexingStatusIds.Backfill:
1273
+ case OmnichainIndexingStatusIds.Backfill:
971
1274
  return {
972
- overallStatus: OverallIndexingStatusIds.Backfill,
973
- chains: serializeChainIndexingStatuses(indexingStatus.chains),
1275
+ omnichainStatus: OmnichainIndexingStatusIds.Backfill,
1276
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
974
1277
  omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
975
1278
  };
976
- case OverallIndexingStatusIds.Completed: {
1279
+ case OmnichainIndexingStatusIds.Completed: {
977
1280
  return {
978
- overallStatus: OverallIndexingStatusIds.Completed,
979
- chains: serializeChainIndexingStatuses(indexingStatus.chains)
1281
+ omnichainStatus: OmnichainIndexingStatusIds.Completed,
1282
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1283
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
980
1284
  };
981
1285
  }
982
- case OverallIndexingStatusIds.Following:
1286
+ case OmnichainIndexingStatusIds.Following:
983
1287
  return {
984
- overallStatus: OverallIndexingStatusIds.Following,
985
- chains: serializeChainIndexingStatuses(indexingStatus.chains),
986
- overallApproxRealtimeDistance: indexingStatus.overallApproxRealtimeDistance,
1288
+ omnichainStatus: OmnichainIndexingStatusIds.Following,
1289
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
987
1290
  omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
988
1291
  };
989
1292
  }
@@ -1019,17 +1322,42 @@ var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
1019
1322
  var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
1020
1323
  var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
1021
1324
 
1022
- // src/api/helpers.ts
1325
+ // src/api/deserialize.ts
1023
1326
  import { prettifyError as prettifyError4 } from "zod/v4";
1024
1327
 
1025
1328
  // src/api/zod-schemas.ts
1026
1329
  import z4 from "zod/v4";
1330
+
1331
+ // src/api/types.ts
1332
+ var IndexingStatusResponseCodes = {
1333
+ /**
1334
+ * Represents that the indexing status is available.
1335
+ */
1336
+ Ok: "ok",
1337
+ /**
1338
+ * Represents that the indexing status is unavailable.
1339
+ */
1340
+ Error: "error"
1341
+ };
1342
+
1343
+ // src/api/zod-schemas.ts
1027
1344
  var ErrorResponseSchema = z4.object({
1028
1345
  message: z4.string(),
1029
1346
  details: z4.optional(z4.unknown())
1030
1347
  });
1348
+ var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z4.strictObject({
1349
+ responseCode: z4.literal(IndexingStatusResponseCodes.Ok),
1350
+ realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
1351
+ });
1352
+ var makeIndexingStatusResponseErrorSchema = (valueLabel = "Indexing Status Response Error") => z4.strictObject({
1353
+ responseCode: z4.literal(IndexingStatusResponseCodes.Error)
1354
+ });
1355
+ var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z4.discriminatedUnion("responseCode", [
1356
+ makeIndexingStatusResponseOkSchema(valueLabel),
1357
+ makeIndexingStatusResponseErrorSchema(valueLabel)
1358
+ ]);
1031
1359
 
1032
- // src/api/helpers.ts
1360
+ // src/api/deserialize.ts
1033
1361
  function deserializeErrorResponse(maybeErrorResponse) {
1034
1362
  const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
1035
1363
  if (parsed.error) {
@@ -1039,12 +1367,28 @@ ${prettifyError4(parsed.error)}
1039
1367
  }
1040
1368
  return parsed.data;
1041
1369
  }
1370
+ function deserializeIndexingStatusResponse(maybeResponse) {
1371
+ const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
1372
+ if (parsed.error) {
1373
+ throw new Error(`Cannot deserialize IndexingStatusResponse:
1374
+ ${prettifyError4(parsed.error)}
1375
+ `);
1376
+ }
1377
+ return parsed.data;
1378
+ }
1042
1379
 
1043
- // src/api/types.ts
1044
- var IndexingStatusResponseCodes = {
1045
- IndexerError: 512,
1046
- RequestedDistanceNotAchievedError: 513
1047
- };
1380
+ // src/api/serialize.ts
1381
+ function serializeIndexingStatusResponse(response) {
1382
+ switch (response.responseCode) {
1383
+ case IndexingStatusResponseCodes.Ok:
1384
+ return {
1385
+ responseCode: response.responseCode,
1386
+ realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
1387
+ };
1388
+ case IndexingStatusResponseCodes.Error:
1389
+ return response;
1390
+ }
1391
+ }
1048
1392
 
1049
1393
  // src/client-error.ts
1050
1394
  var ClientError = class _ClientError extends Error {
@@ -1082,6 +1426,9 @@ var ENSNodeClient = class _ENSNodeClient {
1082
1426
  /**
1083
1427
  * Resolves records for an ENS name (Forward Resolution).
1084
1428
  *
1429
+ * The returned `name` field, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
1430
+ * If the name record returned by the resolver is not normalized, `null` is returned as if no name record was set.
1431
+ *
1085
1432
  * @param name The ENS Name whose records to resolve
1086
1433
  * @param selection selection of Resolver records
1087
1434
  * @param options additional options
@@ -1133,9 +1480,13 @@ var ENSNodeClient = class _ENSNodeClient {
1133
1480
  /**
1134
1481
  * Resolves the primary name of a specified address (Reverse Resolution) on a specific chain.
1135
1482
  *
1136
- * If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
1137
- * the Default Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to
1138
- * determine the `address`'s Default Name directly.
1483
+ * If the chainId-specific Primary Name is not defined, but the `address` specifies a valid
1484
+ * [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default
1485
+ * Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to determine the
1486
+ * `address`'s Default Name directly.
1487
+ *
1488
+ * The returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
1489
+ * If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.
1139
1490
  *
1140
1491
  * @param address The Address whose Primary Name to resolve
1141
1492
  * @param chainId The chain id within which to query the address' ENSIP-19 Multichain Primary Name
@@ -1175,10 +1526,14 @@ var ENSNodeClient = class _ENSNodeClient {
1175
1526
  /**
1176
1527
  * Resolves the primary names of a specified address across multiple chains.
1177
1528
  *
1178
- * If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
1179
- * the Default Name will be returned for all chainIds for which there is not a chain-specific
1180
- * Primary Name. To avoid misuse, you _may not_ query the Default EVM Chain Id (`0`) directly, and
1181
- * should rely on the aforementioned per-chain defaulting behavior.
1529
+ * For each Primary Name, if the chainId-specific Primary Name is not defined, but the `address`
1530
+ * specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
1531
+ * the Default Name will be returned. You _may not_ query the Default EVM Chain Id (`0`) directly,
1532
+ * and should rely on the aforementioned per-chain defaulting behavior.
1533
+ *
1534
+ * Each returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
1535
+ * If the primary name set for the address on any chain is not normalized, `null` is returned for
1536
+ * that chain as if no primary name was set.
1182
1537
  *
1183
1538
  * @param address The Address whose Primary Names to resolve
1184
1539
  * @param options additional options
@@ -1196,12 +1551,12 @@ var ENSNodeClient = class _ENSNodeClient {
1196
1551
  *
1197
1552
  * console.log(names);
1198
1553
  * // {
1199
- * // "1": "gregskril.eth",
1200
- * // "10": "gregskril.eth",
1201
- * // "8453": "greg.base.eth", // base-specific Primary Name!
1202
- * // "42161": "gregskril.eth",
1203
- * // "59144": "gregskril.eth",
1204
- * // "534352": "gregskril.eth"
1554
+ * // "1": "gregskril.eth", // Default Primary Name
1555
+ * // "10": "gregskril.eth", // Default Primary Name
1556
+ * // "8453": "greg.base.eth", // Base-specific Primary Name!
1557
+ * // "42161": "gregskril.eth", // Default Primary Name
1558
+ * // "59144": "gregskril.eth", // Default Primary Name
1559
+ * // "534352": "gregskril.eth" // Default Primary Name
1205
1560
  * // }
1206
1561
  *
1207
1562
  * // Resolve the address' Primary Names on specific chain Ids
@@ -1256,28 +1611,14 @@ var ENSNodeClient = class _ENSNodeClient {
1256
1611
  /**
1257
1612
  * Fetch ENSNode Indexing Status
1258
1613
  *
1259
- * Fetch the ENSNode's multichain indexing status.
1260
- *
1261
- * @param options additional options
1262
- * @param options.maxRealtimeDistance the max allowed distance between the
1263
- * latest indexed block of each chain and the "tip" of all indexed chains.
1264
- * Setting this parameter influences the HTTP response code as follows:
1265
- * - Success (200 OK): The latest indexed block of each chain is within the
1266
- * requested distance from realtime.
1267
- * - Service Unavailable (503): The latest indexed block of each chain is NOT
1268
- * within the requested distance from realtime.
1269
- *
1270
1614
  * @returns {IndexingStatusResponse}
1271
1615
  *
1272
1616
  * @throws if the ENSNode request fails
1273
1617
  * @throws if the ENSNode API returns an error response
1274
1618
  * @throws if the ENSNode response breaks required invariants
1275
1619
  */
1276
- async indexingStatus(options) {
1620
+ async indexingStatus() {
1277
1621
  const url = new URL(`/api/indexing-status`, this.options.url);
1278
- if (typeof options?.maxRealtimeDistance !== "undefined") {
1279
- url.searchParams.set("maxRealtimeDistance", `${options.maxRealtimeDistance}`);
1280
- }
1281
1622
  const response = await fetch(url);
1282
1623
  let responseData;
1283
1624
  try {
@@ -1286,40 +1627,48 @@ var ENSNodeClient = class _ENSNodeClient {
1286
1627
  throw new Error("Malformed response data: invalid JSON");
1287
1628
  }
1288
1629
  if (!response.ok) {
1289
- switch (response.status) {
1290
- case IndexingStatusResponseCodes.IndexerError: {
1291
- console.error("Indexing Status API: indexer error");
1292
- return deserializeENSIndexerIndexingStatus(
1293
- responseData
1294
- );
1295
- }
1296
- case IndexingStatusResponseCodes.RequestedDistanceNotAchievedError: {
1297
- console.error(
1298
- "Indexing Status API: Requested realtime indexing distance not achieved error"
1299
- );
1300
- return deserializeENSIndexerIndexingStatus(
1301
- responseData
1302
- );
1303
- }
1304
- default: {
1305
- const errorResponse = deserializeErrorResponse(responseData);
1306
- throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
1307
- }
1630
+ let errorResponse;
1631
+ try {
1632
+ errorResponse = deserializeErrorResponse(responseData);
1633
+ } catch {
1634
+ console.log("Indexing Status API: handling a known indexing status server error.");
1635
+ }
1636
+ if (typeof errorResponse !== "undefined") {
1637
+ throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
1308
1638
  }
1309
1639
  }
1310
- return deserializeENSIndexerIndexingStatus(
1311
- responseData
1312
- );
1640
+ return deserializeIndexingStatusResponse(responseData);
1313
1641
  }
1314
1642
  };
1315
1643
 
1316
1644
  // src/resolution/resolver-records-selection.ts
1317
1645
  var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
1318
1646
 
1647
+ // src/resolution/types.ts
1648
+ var ResolutionStatusIds = {
1649
+ /**
1650
+ * Represents that the `Identity` is not resolved yet.
1651
+ */
1652
+ Unresolved: "unresolved",
1653
+ /**
1654
+ * Represents that resolution of the `Identity` resulted in a named identity.
1655
+ */
1656
+ Named: "named",
1657
+ /**
1658
+ * Represents that resolution of the `Identity` resulted in an unnamed identity.
1659
+ */
1660
+ Unnamed: "unnamed",
1661
+ /**
1662
+ * Represents that attempted resolution of the `Identity` resulted in an error
1663
+ * and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
1664
+ */
1665
+ Unknown: "unknown"
1666
+ };
1667
+
1319
1668
  // src/resolution/default-records-selection.ts
1320
1669
  import {
1321
1670
  DatasourceNames,
1322
- ENSNamespaceIds as ENSNamespaceIds2,
1671
+ ENSNamespaceIds as ENSNamespaceIds3,
1323
1672
  maybeGetDatasource
1324
1673
  } from "@ensnode/datasources";
1325
1674
  var getENSIP19SupportedCoinTypes = (namespace) => uniq(
@@ -1331,6 +1680,9 @@ var getENSIP19SupportedCoinTypes = (namespace) => uniq(
1331
1680
  maybeGetDatasource(namespace, DatasourceNames.ReverseResolverScroll)
1332
1681
  ].filter((ds) => ds !== void 0).map((ds) => ds.chain.id)
1333
1682
  ).map(evmChainIdToCoinType);
1683
+ var getCommonCoinTypes = (namespace) => {
1684
+ return [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(namespace)];
1685
+ };
1334
1686
  var TEXTS = [
1335
1687
  "url",
1336
1688
  "avatar",
@@ -1342,31 +1694,57 @@ var TEXTS = [
1342
1694
  "com.github"
1343
1695
  ];
1344
1696
  var DefaultRecordsSelection = {
1345
- [ENSNamespaceIds2.Mainnet]: {
1346
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Mainnet)],
1697
+ [ENSNamespaceIds3.Mainnet]: {
1698
+ addresses: getCommonCoinTypes(ENSNamespaceIds3.Mainnet),
1347
1699
  texts: TEXTS
1348
1700
  },
1349
- [ENSNamespaceIds2.Sepolia]: {
1350
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Sepolia)],
1701
+ [ENSNamespaceIds3.Sepolia]: {
1702
+ addresses: getCommonCoinTypes(ENSNamespaceIds3.Sepolia),
1351
1703
  texts: TEXTS
1352
1704
  },
1353
- [ENSNamespaceIds2.Holesky]: {
1354
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Holesky)],
1705
+ [ENSNamespaceIds3.Holesky]: {
1706
+ addresses: getCommonCoinTypes(ENSNamespaceIds3.Holesky),
1355
1707
  texts: TEXTS
1356
1708
  },
1357
- [ENSNamespaceIds2.EnsTestEnv]: {
1358
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.EnsTestEnv)],
1709
+ [ENSNamespaceIds3.EnsTestEnv]: {
1710
+ addresses: getCommonCoinTypes(ENSNamespaceIds3.EnsTestEnv),
1359
1711
  texts: TEXTS
1360
1712
  }
1361
1713
  };
1714
+
1715
+ // src/resolution/ensip19-chainid.ts
1716
+ import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
1717
+ import { mainnet } from "viem/chains";
1718
+ var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
1719
+ const ensRootChainId = getENSRootChainId2(namespaceId);
1720
+ return chainId === ensRootChainId ? mainnet.id : chainId;
1721
+ };
1722
+ var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
1723
+ return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId2(namespaceId) : chainId;
1724
+ };
1725
+
1726
+ // src/resolution/identity.ts
1727
+ import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
1728
+ function buildUnresolvedIdentity(address, namespaceId, chainId) {
1729
+ return {
1730
+ resolutionStatus: ResolutionStatusIds.Unresolved,
1731
+ chainId: chainId ?? getENSRootChainId3(namespaceId),
1732
+ address
1733
+ };
1734
+ }
1735
+ function isResolvedIdentity(identity) {
1736
+ return identity.resolutionStatus !== ResolutionStatusIds.Unresolved;
1737
+ }
1362
1738
  export {
1739
+ ADDR_REVERSE_NODE,
1363
1740
  ATTR_PROTOCOL_NAME,
1364
1741
  ATTR_PROTOCOL_STEP,
1365
1742
  ATTR_PROTOCOL_STEP_RESULT,
1366
1743
  BASENAMES_NODE,
1744
+ ChainIndexingConfigTypeIds,
1367
1745
  ChainIndexingStatusIds,
1368
- ChainIndexingStrategyIds,
1369
1746
  ClientError,
1747
+ CrossChainIndexingStrategyIds,
1370
1748
  DEFAULT_ENSNODE_API_URL,
1371
1749
  DEFAULT_EVM_CHAIN_ID,
1372
1750
  DEFAULT_EVM_COIN_TYPE,
@@ -1379,73 +1757,86 @@ export {
1379
1757
  IndexingStatusResponseCodes,
1380
1758
  LINEANAMES_NODE,
1381
1759
  LruCache,
1382
- OverallIndexingStatusIds,
1760
+ OmnichainIndexingStatusIds,
1383
1761
  PROTOCOL_ATTRIBUTE_PREFIX,
1384
1762
  PluginName,
1385
- REVERSE_ROOT_NODES,
1386
1763
  ROOT_NODE,
1764
+ ResolutionStatusIds,
1387
1765
  ReverseResolutionProtocolStep,
1388
1766
  TraceableENSProtocol,
1389
1767
  accountIdEqual,
1390
1768
  addrReverseLabel,
1769
+ asLowerCaseAddress,
1770
+ beautifyName,
1391
1771
  bigintToCoinType,
1392
1772
  buildEnsRainbowClientLabelSet,
1393
1773
  buildLabelSetId,
1394
1774
  buildLabelSetVersion,
1395
- checkChainIndexingStatusesForBackfillOverallStatus,
1396
- checkChainIndexingStatusesForCompletedOverallStatus,
1397
- checkChainIndexingStatusesForFollowingOverallStatus,
1398
- checkChainIndexingStatusesForUnstartedOverallStatus,
1775
+ buildUnresolvedIdentity,
1776
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
1777
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
1778
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing,
1779
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted,
1399
1780
  coinTypeReverseLabel,
1400
1781
  coinTypeToEvmChainId,
1401
1782
  createIndexingConfig,
1783
+ createRealtimeIndexingStatusProjection,
1784
+ decodeDNSEncodedLiteralName,
1785
+ decodeDNSEncodedName,
1402
1786
  deserializeBlockNumber,
1403
1787
  deserializeBlockRef,
1404
1788
  deserializeBlockrange,
1405
1789
  deserializeChainId,
1790
+ deserializeChainIndexingStatusSnapshot,
1791
+ deserializeCrossChainIndexingStatusSnapshot,
1406
1792
  deserializeDatetime,
1407
1793
  deserializeDuration,
1408
- deserializeENSIndexerIndexingStatus,
1409
1794
  deserializeENSIndexerPublicConfig,
1410
1795
  deserializeErrorResponse,
1796
+ deserializeIndexingStatusResponse,
1797
+ deserializeOmnichainIndexingStatusSnapshot,
1798
+ deserializeRealtimeIndexingStatusProjection,
1799
+ deserializeUnixTimestamp,
1411
1800
  deserializeUrl,
1801
+ encodeLabelHash,
1412
1802
  evmChainIdToCoinType,
1413
- getActiveChains,
1803
+ getCommonCoinTypes,
1804
+ getENSRootChainId,
1414
1805
  getNameHierarchy,
1415
1806
  getOmnichainIndexingCursor,
1416
- getOverallApproxRealtimeDistance,
1417
- getOverallIndexingStatus,
1418
- getStandbyChains,
1807
+ getOmnichainIndexingStatus,
1808
+ getResolvePrimaryNameChainIdParam,
1419
1809
  getTimestampForHighestOmnichainKnownBlock,
1420
1810
  getTimestampForLowestOmnichainStartBlock,
1421
- invariant_isSubgraphCompatibleRequirements,
1422
- invariant_reverseResolversPluginNeedsResolverRecords,
1423
- isLabelIndexable,
1424
- isNormalized,
1811
+ interpretedLabelsToInterpretedName,
1812
+ isHttpProtocol,
1813
+ isNormalizedLabel,
1814
+ isNormalizedName,
1815
+ isResolvedIdentity,
1425
1816
  isSelectionEmpty,
1426
1817
  isSubgraphCompatible,
1818
+ isWebSocketProtocol,
1427
1819
  labelHashToBytes,
1428
- makeDatabaseSchemaNameSchema,
1429
- makeDependencyInfoSchema,
1430
- makeENSIndexerPublicConfigSchema,
1431
- makeFullyPinnedLabelSetSchema,
1432
- makeIndexedChainIdsSchema,
1433
- makeLabelSetIdSchema,
1434
- makeLabelSetVersionSchema,
1435
- makePluginsListSchema,
1820
+ labelhashLiteralLabel,
1821
+ literalLabelToInterpretedLabel,
1822
+ literalLabelsToInterpretedName,
1823
+ literalLabelsToLiteralName,
1436
1824
  makeSubdomainNode,
1437
- maybeHealLabelByReverseAddress,
1438
1825
  parseNonNegativeInteger,
1439
1826
  parseReverseName,
1440
1827
  reverseName,
1441
1828
  serializeChainId,
1442
- serializeChainIndexingStatuses,
1829
+ serializeChainIndexingSnapshots,
1830
+ serializeCrossChainIndexingStatusSnapshotOmnichain,
1443
1831
  serializeDatetime,
1444
- serializeENSIndexerIndexingStatus,
1445
1832
  serializeENSIndexerPublicConfig,
1446
1833
  serializeIndexedChainIds,
1834
+ serializeIndexingStatusResponse,
1835
+ serializeOmnichainIndexingStatusSnapshot,
1836
+ serializeRealtimeIndexingStatusProjection,
1447
1837
  serializeUrl,
1448
- sortAscChainStatusesByStartBlock,
1838
+ sortChainStatusesByStartBlockAsc,
1839
+ translateDefaultableChainIdToChainId,
1449
1840
  uint256ToHex32,
1450
1841
  uniq,
1451
1842
  validateSupportedLabelSetAndVersion