@ensnode/ensnode-sdk 0.35.0 → 1.0.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
@@ -1,14 +1,56 @@
1
- // src/ens/constants.ts
2
- import { namehash } from "viem";
3
- var ROOT_NODE = namehash("");
4
- var ETH_NODE = namehash("eth");
5
- var BASENAMES_NODE = namehash("base.eth");
6
- var LINEANAMES_NODE = namehash("linea.eth");
7
- var REVERSE_ROOT_NODES = /* @__PURE__ */ new Set([namehash("addr.reverse")]);
1
+ // src/api/deserialize.ts
2
+ import { prettifyError as prettifyError2 } from "zod/v4";
8
3
 
9
- // src/ens/subname-helpers.ts
10
- import { concat, isAddress, isHash, keccak256, toHex } from "viem";
11
- import { labelhash } from "viem/ens";
4
+ // src/api/zod-schemas.ts
5
+ import { namehash as namehash2 } from "viem";
6
+ import z7 from "zod/v4";
7
+
8
+ // src/ensindexer/indexing-status/zod-schemas.ts
9
+ import z2 from "zod/v4";
10
+
11
+ // src/ens/is-normalized.ts
12
+ import { normalize } from "viem/ens";
13
+ function isNormalizedName(name) {
14
+ try {
15
+ return name === normalize(name);
16
+ } catch {
17
+ return false;
18
+ }
19
+ }
20
+ function isNormalizedLabel(label) {
21
+ if (label === "") return false;
22
+ if (label.includes(".")) return false;
23
+ try {
24
+ return label === normalize(label);
25
+ } catch {
26
+ return false;
27
+ }
28
+ }
29
+
30
+ // src/shared/account-id.ts
31
+ import { isAddressEqual } from "viem";
32
+ var accountIdEqual = (a, b) => {
33
+ return a.chainId === b.chainId && isAddressEqual(a.address, b.address);
34
+ };
35
+
36
+ // src/shared/address.ts
37
+ function asLowerCaseAddress(address) {
38
+ return address.toLowerCase();
39
+ }
40
+
41
+ // src/shared/cache.ts
42
+ import { getUnixTime } from "date-fns";
43
+
44
+ // src/shared/deserialize.ts
45
+ import { prettifyError } from "zod/v4";
46
+
47
+ // src/shared/zod-schemas.ts
48
+ import { AccountId as CaipAccountId } from "caip";
49
+ import { isAddress as isAddress2, isHex as isHex2, size } from "viem";
50
+ import z from "zod/v4";
51
+
52
+ // src/ens/index.ts
53
+ import { getENSRootChainId } from "@ensnode/datasources";
12
54
 
13
55
  // src/ens/coin-type.ts
14
56
  import {
@@ -33,76 +75,85 @@ var bigintToCoinType = (value) => {
33
75
  return Number(value);
34
76
  };
35
77
 
36
- // src/ens/reverse-name.ts
37
- var addrReverseLabel = (address) => address.slice(2).toLowerCase();
38
- var coinTypeReverseLabel = (coinType) => coinType.toString(16);
39
- function reverseName(address, coinType) {
40
- const label = addrReverseLabel(address);
41
- const middle = (() => {
42
- switch (coinType) {
43
- case ETH_COIN_TYPE:
44
- return "addr";
45
- case DEFAULT_EVM_COIN_TYPE:
46
- return "default";
47
- default:
48
- return coinTypeReverseLabel(coinType);
78
+ // src/ens/constants.ts
79
+ import { namehash } from "viem";
80
+ var ROOT_NODE = namehash("");
81
+ var ETH_NODE = namehash("eth");
82
+ var BASENAMES_NODE = namehash("base.eth");
83
+ var LINEANAMES_NODE = namehash("linea.eth");
84
+ var ADDR_REVERSE_NODE = namehash("addr.reverse");
85
+
86
+ // src/ens/dns-encoded-name.ts
87
+ import { bytesToString, hexToBytes } from "viem";
88
+ function decodeDNSEncodedLiteralName(packet) {
89
+ return decodeDNSEncodedName(packet);
90
+ }
91
+ function decodeDNSEncodedName(packet) {
92
+ const segments = [];
93
+ const bytes = hexToBytes(packet);
94
+ if (bytes.length === 0) throw new Error(`Packet is empty.`);
95
+ let offset = 0;
96
+ while (offset < bytes.length) {
97
+ const len = bytes[offset];
98
+ if (len === void 0) {
99
+ throw new Error(`Invariant: bytes[offset] is undefined after offset < bytes.length check.`);
49
100
  }
50
- })();
51
- return `${label}.${middle}.reverse`;
101
+ if (len < 0 || len > 255) {
102
+ throw new Error(
103
+ `Invariant: this should be literally impossible, but an unsigned byte was less than zero or greater than 255. The value in question is ${len}`
104
+ );
105
+ }
106
+ if (len === 0) break;
107
+ const segment = bytesToString(bytes.subarray(offset + 1, offset + len + 1));
108
+ segments.push(segment);
109
+ offset += len + 1;
110
+ }
111
+ if (offset >= bytes.length) throw new Error(`Overflow, offset >= bytes.length`);
112
+ if (offset !== bytes.length - 1) throw new Error(`Junk at end of name`);
113
+ return segments;
52
114
  }
53
115
 
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
- };
116
+ // src/ens/labelhash.ts
117
+ import { isHex } from "viem";
118
+ function isLabelHash(maybeLabelHash) {
119
+ const expectedLength = maybeLabelHash.length === 66;
120
+ const expectedEncoding = isHex(maybeLabelHash);
121
+ const expectedCasing = maybeLabelHash === maybeLabelHash.toLowerCase();
122
+ return expectedLength && expectedEncoding && expectedCasing;
123
+ }
124
+
125
+ // src/ens/encode-labelhash.ts
126
+ var encodeLabelHash = (labelHash) => `[${labelHash.slice(2)}]`;
127
+ function isEncodedLabelHash(maybeEncodedLabelHash) {
128
+ const expectedFormatting = maybeEncodedLabelHash.startsWith("[") && maybeEncodedLabelHash.endsWith("]");
129
+ const includesLabelHash = isLabelHash(`0x${maybeEncodedLabelHash.slice(1, -1)}`);
130
+ return expectedFormatting && includesLabelHash;
131
+ }
95
132
 
96
133
  // src/ens/names.ts
134
+ import { ens_beautify } from "@adraffy/ens-normalize";
97
135
  var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
98
-
99
- // src/ens/types.ts
100
- import { ENSNamespaceIds } from "@ensnode/datasources";
136
+ var beautifyName = (name) => {
137
+ const beautifiedLabels = name.split(".").map((label) => {
138
+ if (isNormalizedLabel(label)) {
139
+ return ens_beautify(label);
140
+ } else {
141
+ return label;
142
+ }
143
+ });
144
+ return beautifiedLabels.join(".");
145
+ };
101
146
 
102
147
  // src/ens/parse-reverse-name.ts
103
- import { getAddress, hexToBigInt } from "viem";
148
+ import { hexToBigInt, isAddress } from "viem";
104
149
  var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
105
- var parseAddressLabel = (addressLabel) => getAddress(`0x${addressLabel}`);
150
+ var parseAddressLabel = (addressLabel) => {
151
+ const maybeAddress = `0x${addressLabel}`;
152
+ if (!isAddress(maybeAddress)) {
153
+ throw new Error(`Invalid EVM address "${maybeAddress}"`);
154
+ }
155
+ return asLowerCaseAddress(maybeAddress);
156
+ };
106
157
  var parseCoinTypeLabel = (coinTypeLabel) => {
107
158
  if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
108
159
  if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
@@ -124,102 +175,122 @@ function parseReverseName(name) {
124
175
  }
125
176
  }
126
177
 
127
- // src/ens/is-normalized.ts
128
- import { normalize } from "viem/ens";
129
- function isNormalizedName(name) {
130
- try {
131
- return name === normalize(name);
132
- } catch {
133
- return false;
134
- }
135
- }
136
- function isNormalizedLabel(label) {
137
- if (label === "") return false;
138
- if (label.includes(".")) return false;
139
- try {
140
- return label === normalize(label);
141
- } catch {
142
- return false;
143
- }
178
+ // src/ens/reverse-name.ts
179
+ var addrReverseLabel = (address) => address.slice(2);
180
+ var coinTypeReverseLabel = (coinType) => coinType.toString(16);
181
+ function reverseName(address, coinType) {
182
+ const label = addrReverseLabel(address);
183
+ const middle = (() => {
184
+ switch (coinType) {
185
+ case ETH_COIN_TYPE:
186
+ return "addr";
187
+ case DEFAULT_EVM_COIN_TYPE:
188
+ return "default";
189
+ default:
190
+ return coinTypeReverseLabel(coinType);
191
+ }
192
+ })();
193
+ return `${label}.${middle}.reverse`;
144
194
  }
145
195
 
146
- // src/ens/encode-labelhash.ts
147
- var encodeLabelHash = (labelHash) => `[${labelHash.slice(2)}]`;
148
-
149
- // src/ensindexer/config/deserialize.ts
150
- import { prettifyError as prettifyError2 } from "zod/v4";
196
+ // src/ens/subname-helpers.ts
197
+ import { concat, keccak256, toHex } from "viem";
198
+ var makeSubdomainNode = (labelHash, node) => keccak256(concat([node, labelHash]));
199
+ var uint256ToHex32 = (num) => toHex(num, { size: 32 });
151
200
 
152
- // src/ensindexer/config/zod-schemas.ts
153
- import z2 from "zod/v4";
201
+ // src/ens/types.ts
202
+ import { ENSNamespaceIds } from "@ensnode/datasources";
154
203
 
155
- // src/shared/cache.ts
156
- var LruCache = class {
157
- _cache = /* @__PURE__ */ new Map();
158
- _capacity;
159
- /**
160
- * Create a new LRU cache with the given capacity.
161
- *
162
- * @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
163
- * @throws Error if capacity is not a non-negative integer.
164
- */
165
- constructor(capacity) {
166
- if (!Number.isInteger(capacity)) {
167
- throw new Error(
168
- `LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
169
- );
170
- }
171
- if (capacity < 0) {
172
- throw new Error(
173
- `LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
174
- );
175
- }
176
- this._capacity = capacity;
177
- }
178
- set(key, value) {
179
- this._cache.set(key, value);
180
- if (this._cache.size > this._capacity) {
181
- const oldestKey = this._cache.keys().next().value;
182
- this._cache.delete(oldestKey);
183
- }
184
- }
185
- get(key) {
186
- const value = this._cache.get(key);
187
- if (value) {
188
- this._cache.delete(key);
189
- this._cache.set(key, value);
190
- }
191
- return value;
192
- }
193
- clear() {
194
- this._cache.clear();
195
- }
196
- get size() {
197
- return this._cache.size;
198
- }
199
- get capacity() {
200
- return this._capacity;
204
+ // src/shared/currencies.ts
205
+ var CurrencyIds = {
206
+ ETH: "ETH",
207
+ USDC: "USDC",
208
+ DAI: "DAI"
209
+ };
210
+ var currencyInfo = {
211
+ [CurrencyIds.ETH]: {
212
+ id: CurrencyIds.ETH,
213
+ name: "ETH",
214
+ decimals: 18
215
+ },
216
+ [CurrencyIds.USDC]: {
217
+ id: CurrencyIds.USDC,
218
+ name: "USDC",
219
+ decimals: 6
220
+ },
221
+ [CurrencyIds.DAI]: {
222
+ id: CurrencyIds.DAI,
223
+ name: "Dai Stablecoin",
224
+ decimals: 18
201
225
  }
202
226
  };
203
-
204
- // src/shared/collections.ts
205
- var uniq = (arr) => [...new Set(arr)];
206
-
207
- // src/shared/serialize.ts
208
- function serializeChainId(chainId) {
209
- return chainId.toString();
227
+ function getCurrencyInfo(currencyId) {
228
+ return currencyInfo[currencyId];
210
229
  }
211
- function serializeDatetime(datetime) {
212
- return datetime.toISOString();
230
+ function priceEth(amount) {
231
+ return {
232
+ amount,
233
+ currency: CurrencyIds.ETH
234
+ };
213
235
  }
214
- function serializeUrl(url) {
215
- return url.toString();
236
+ function priceUsdc(amount) {
237
+ return {
238
+ amount,
239
+ currency: CurrencyIds.USDC
240
+ };
241
+ }
242
+ function priceDai(amount) {
243
+ return {
244
+ amount,
245
+ currency: CurrencyIds.DAI
246
+ };
247
+ }
248
+ function isPriceCurrencyEqual(priceA, priceB) {
249
+ return priceA.currency === priceB.currency;
250
+ }
251
+ function isPriceEqual(priceA, priceB) {
252
+ return isPriceCurrencyEqual(priceA, priceB) && priceA.amount === priceB.amount;
253
+ }
254
+ function addPrices(...prices) {
255
+ const firstPrice = prices[0];
256
+ const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
257
+ if (allPricesInSameCurrency === false) {
258
+ throw new Error("All prices must have the same currency to be added together.");
259
+ }
260
+ const { currency } = firstPrice;
261
+ return prices.reduce(
262
+ (acc, price) => ({
263
+ amount: acc.amount + price.amount,
264
+ currency
265
+ }),
266
+ {
267
+ amount: 0n,
268
+ currency: firstPrice.currency
269
+ }
270
+ );
216
271
  }
217
272
 
218
- // src/shared/deserialize.ts
219
- import { prettifyError } from "zod/v4";
273
+ // src/shared/reinterpretation.ts
274
+ import { labelhash as labelToLabelHash } from "viem";
275
+ function reinterpretLabel(label) {
276
+ if (label === "") {
277
+ throw new Error(
278
+ `Cannot reinterpret an empty label that violates the invariants of an InterpretedLabel.`
279
+ );
280
+ }
281
+ if (isEncodedLabelHash(label)) return label;
282
+ if (isNormalizedLabel(label)) return label;
283
+ return encodeLabelHash(labelToLabelHash(label));
284
+ }
285
+ function reinterpretName(name) {
286
+ if (name === "") return name;
287
+ const interpretedLabels = name.split(".");
288
+ const reinterpretedLabels = interpretedLabels.map(reinterpretLabel);
289
+ const reinterpretedName = reinterpretedLabels.join(".");
290
+ return reinterpretedName;
291
+ }
220
292
 
221
293
  // src/shared/zod-schemas.ts
222
- import z from "zod/v4";
223
294
  var makeIntegerSchema = (valueLabel = "Value") => z.int({
224
295
  error: `${valueLabel} must be an integer.`
225
296
  });
@@ -232,12 +303,22 @@ var makeNonNegativeIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(v
232
303
  var makeDurationSchema = (valueLabel = "Value") => z.coerce.number({
233
304
  error: `${valueLabel} must be a number.`
234
305
  }).pipe(makeNonNegativeIntegerSchema(valueLabel));
235
- var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel);
306
+ var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel).transform((val) => val);
236
307
  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}`));
308
+ var makeLowercaseAddressSchema = (valueLabel = "EVM address") => z.string().check((ctx) => {
309
+ if (!isAddress2(ctx.value)) {
310
+ ctx.issues.push({
311
+ code: "custom",
312
+ message: `${valueLabel} must be a valid EVM address`,
313
+ input: ctx.value
314
+ });
315
+ }
316
+ }).transform((val) => asLowerCaseAddress(val));
237
317
  var makeDatetimeSchema = (valueLabel = "Datetime string") => z.iso.datetime({ error: `${valueLabel} must be a string in ISO 8601 format.` }).transform((v) => new Date(v));
238
318
  var makeUnixTimestampSchema = (valueLabel = "Timestamp") => makeIntegerSchema(valueLabel);
239
319
  var makeUrlSchema = (valueLabel = "Value") => z.url({
240
- error: `${valueLabel} must be a valid URL string (e.g., http://localhost:8080 or https://example.com).`
320
+ error: `${valueLabel} must be a valid URL string (e.g., http://localhost:8080 or https://example.com).`,
321
+ abort: true
241
322
  }).transform((v) => new URL(v));
242
323
  var makeBlockNumberSchema = (valueLabel = "Block number") => makeNonNegativeIntegerSchema(valueLabel);
243
324
  var makeBlockrangeSchema = (valueLabel = "Value") => z.strictObject(
@@ -271,6 +352,62 @@ var makeENSNamespaceIdSchema = (valueLabel = "ENSNamespaceId") => z.enum(ENSName
271
352
  return `Invalid ${valueLabel}. Supported ENS namespace IDs are: ${Object.keys(ENSNamespaceIds).join(", ")}`;
272
353
  }
273
354
  });
355
+ var makePriceAmountSchema = (valueLabel = "Amount") => z.coerce.bigint({
356
+ error: `${valueLabel} must represent a bigint.`
357
+ }).nonnegative({
358
+ error: `${valueLabel} must not be negative.`
359
+ });
360
+ var makePriceCurrencySchema = (currency, valueLabel = "Price Currency") => z.strictObject({
361
+ amount: makePriceAmountSchema(`${valueLabel} amount`),
362
+ currency: z.literal(currency, {
363
+ error: `${valueLabel} currency must be set to '${currency}'.`
364
+ })
365
+ });
366
+ var makePriceEthSchema = (valueLabel = "Price ETH") => makePriceCurrencySchema(CurrencyIds.ETH, valueLabel).transform((v) => v);
367
+ var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
368
+ chainId: makeChainIdStringSchema(`${valueLabel} chain ID`),
369
+ address: makeLowercaseAddressSchema(`${valueLabel} address`)
370
+ });
371
+ var makeSerializedAccountIdSchema = (valueLabel = "Account ID") => z.coerce.string().transform((v) => {
372
+ const result = new CaipAccountId(v);
373
+ return {
374
+ chainId: result.chainId.reference,
375
+ address: result.address
376
+ };
377
+ }).pipe(makeAccountIdSchema(valueLabel));
378
+ var makeHexStringSchema = (options, valueLabel = "String representation of bytes array") => z.string().check(function invariant_isHexEncoded(ctx) {
379
+ if (!isHex2(ctx.value)) {
380
+ ctx.issues.push({
381
+ code: "custom",
382
+ input: ctx.value,
383
+ message: `${valueLabel} must start with '0x'.`
384
+ });
385
+ }
386
+ }).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
387
+ const expectedBytesCount = options.bytesCount;
388
+ const actualBytesCount = size(ctx.value);
389
+ if (actualBytesCount !== expectedBytesCount) {
390
+ ctx.issues.push({
391
+ code: "custom",
392
+ input: ctx.value,
393
+ message: `${valueLabel} must represent exactly ${expectedBytesCount} bytes. Currently represented bytes count: ${actualBytesCount}.`
394
+ });
395
+ }
396
+ });
397
+ var makeNodeSchema = (valueLabel = "Node") => makeHexStringSchema({ bytesCount: 32 }, valueLabel);
398
+ var makeTransactionHashSchema = (valueLabel = "Transaction hash") => makeHexStringSchema({ bytesCount: 32 }, valueLabel);
399
+ var makeReinterpretedNameSchema = (valueLabel = "Reinterpreted Name") => z.string().transform((v) => v).check((ctx) => {
400
+ try {
401
+ reinterpretName(ctx.value);
402
+ } catch (error) {
403
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
404
+ ctx.issues.push({
405
+ code: "custom",
406
+ input: ctx.value,
407
+ message: `${valueLabel} cannot be reinterpreted: ${errorMessage}`
408
+ });
409
+ }
410
+ }).transform(reinterpretName);
274
411
 
275
412
  // src/shared/deserialize.ts
276
413
  function deserializeChainId(maybeChainId, valueLabel) {
@@ -293,6 +430,16 @@ ${prettifyError(parsed.error)}
293
430
  }
294
431
  return parsed.data;
295
432
  }
433
+ function deserializeUnixTimestamp(maybeTimestamp, valueLabel) {
434
+ const schema = makeUnixTimestampSchema(valueLabel);
435
+ const parsed = schema.safeParse(maybeTimestamp);
436
+ if (parsed.error) {
437
+ throw new Error(`Cannot deserialize Unix Timestamp:
438
+ ${prettifyError(parsed.error)}
439
+ `);
440
+ }
441
+ return parsed.data;
442
+ }
296
443
  function deserializeUrl(maybeUrl, valueLabel) {
297
444
  const schema = makeUrlSchema(valueLabel);
298
445
  const parsed = schema.safeParse(maybeUrl);
@@ -343,216 +490,1305 @@ ${prettifyError(parsed.error)}
343
490
  }
344
491
  return parsed.data;
345
492
  }
493
+ function deserializeAccountId(maybeAccountId, valueLabel) {
494
+ const schema = makeSerializedAccountIdSchema(valueLabel);
495
+ const parsed = schema.safeParse(maybeAccountId);
496
+ if (parsed.error) {
497
+ throw new RangeError(`Cannot deserialize AccountId:
498
+ ${prettifyError(parsed.error)}
499
+ `);
500
+ }
501
+ return parsed.data;
502
+ }
346
503
 
347
- // src/shared/account-id.ts
348
- import { isAddressEqual } from "viem";
349
- var accountIdEqual = (a, b) => {
350
- return a.chainId === b.chainId && isAddressEqual(a.address, b.address);
504
+ // src/shared/datetime.ts
505
+ function durationBetween(start, end) {
506
+ return deserializeDuration(end - start, "Duration");
507
+ }
508
+ function addDuration(timestamp, duration) {
509
+ return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
510
+ }
511
+
512
+ // src/shared/cache.ts
513
+ var LruCache = class {
514
+ _cache = /* @__PURE__ */ new Map();
515
+ _capacity;
516
+ /**
517
+ * Create a new LRU cache with the given capacity.
518
+ *
519
+ * @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
520
+ * @throws Error if capacity is not a non-negative integer.
521
+ */
522
+ constructor(capacity) {
523
+ if (!Number.isInteger(capacity)) {
524
+ throw new Error(
525
+ `LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
526
+ );
527
+ }
528
+ if (capacity < 0) {
529
+ throw new Error(
530
+ `LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
531
+ );
532
+ }
533
+ this._capacity = capacity;
534
+ }
535
+ set(key, value) {
536
+ this._cache.set(key, value);
537
+ if (this._cache.size > this._capacity) {
538
+ const oldestKey = this._cache.keys().next().value;
539
+ this._cache.delete(oldestKey);
540
+ }
541
+ }
542
+ get(key) {
543
+ const value = this._cache.get(key);
544
+ if (value) {
545
+ this._cache.delete(key);
546
+ this._cache.set(key, value);
547
+ }
548
+ return value;
549
+ }
550
+ clear() {
551
+ this._cache.clear();
552
+ }
553
+ get size() {
554
+ return this._cache.size;
555
+ }
556
+ get capacity() {
557
+ return this._capacity;
558
+ }
351
559
  };
560
+ var TtlCache = class {
561
+ _cache = /* @__PURE__ */ new Map();
562
+ _ttl;
563
+ /**
564
+ * Create a new TTL cache with the given TTL.
565
+ *
566
+ * @param ttl Time-to-live duration in seconds. Items expire after this duration.
567
+ */
568
+ constructor(ttl) {
569
+ this._ttl = ttl;
570
+ }
571
+ _cleanup() {
572
+ const now = getUnixTime(/* @__PURE__ */ new Date());
573
+ for (const [key, entry] of this._cache.entries()) {
574
+ if (entry.expiresAt <= now) {
575
+ this._cache.delete(key);
576
+ }
577
+ }
578
+ }
579
+ set(key, value) {
580
+ this._cleanup();
581
+ const expiresAt = addDuration(getUnixTime(/* @__PURE__ */ new Date()), this._ttl);
582
+ this._cache.set(key, { value, expiresAt });
583
+ }
584
+ get(key) {
585
+ this._cleanup();
586
+ const entry = this._cache.get(key);
587
+ if (!entry) {
588
+ return void 0;
589
+ }
590
+ if (entry.expiresAt <= getUnixTime(/* @__PURE__ */ new Date())) {
591
+ this._cache.delete(key);
592
+ return void 0;
593
+ }
594
+ return entry.value;
595
+ }
596
+ clear() {
597
+ this._cache.clear();
598
+ }
599
+ get size() {
600
+ this._cleanup();
601
+ return this._cache.size;
602
+ }
603
+ get capacity() {
604
+ return Number.MAX_SAFE_INTEGER;
605
+ }
606
+ has(key) {
607
+ this._cleanup();
608
+ const entry = this._cache.get(key);
609
+ if (!entry) {
610
+ return false;
611
+ }
612
+ if (entry.expiresAt <= getUnixTime(/* @__PURE__ */ new Date())) {
613
+ this._cache.delete(key);
614
+ return false;
615
+ }
616
+ return true;
617
+ }
618
+ delete(key) {
619
+ return this._cache.delete(key);
620
+ }
621
+ };
622
+ function staleWhileRevalidate(options) {
623
+ const { fn, ttl } = options;
624
+ let cache = null;
625
+ let cacheInitializer = null;
626
+ return async () => {
627
+ if (!cache) {
628
+ if (cacheInitializer) {
629
+ return cacheInitializer;
630
+ }
631
+ cacheInitializer = fn().then((value) => {
632
+ cache = { value, updatedAt: getUnixTime(/* @__PURE__ */ new Date()) };
633
+ cacheInitializer = null;
634
+ return value;
635
+ }).catch(() => {
636
+ cacheInitializer = null;
637
+ return null;
638
+ });
639
+ return cacheInitializer;
640
+ }
641
+ const isStale = durationBetween(cache.updatedAt, getUnixTime(/* @__PURE__ */ new Date())) > ttl;
642
+ if (!isStale) return cache.value;
643
+ if (cache.inProgressRevalidation) return cache.value;
644
+ const revalidationPromise = fn().then((value) => {
645
+ cache = { value, updatedAt: getUnixTime(/* @__PURE__ */ new Date()) };
646
+ }).catch(() => {
647
+ if (cache) {
648
+ cache.inProgressRevalidation = void 0;
649
+ }
650
+ });
651
+ cache.inProgressRevalidation = revalidationPromise;
652
+ return cache.value;
653
+ };
654
+ }
655
+
656
+ // src/shared/collections.ts
657
+ var uniq = (arr) => [...new Set(arr)];
658
+
659
+ // src/shared/labelhash.ts
660
+ import { keccak256 as keccak2562, stringToBytes } from "viem";
661
+ var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
352
662
 
353
663
  // src/shared/interpretation.ts
354
- import { labelhash as labelhash2 } from "viem";
355
- function interpretLiteralLabel(label) {
664
+ function literalLabelToInterpretedLabel(label) {
356
665
  if (isNormalizedLabel(label)) return label;
357
- return encodeLabelHash(labelhash2(label));
666
+ return encodeLabelHash(labelhashLiteralLabel(label));
667
+ }
668
+ function literalLabelsToInterpretedName(labels) {
669
+ return labels.map(literalLabelToInterpretedLabel).join(".");
670
+ }
671
+ function interpretedLabelsToInterpretedName(labels) {
672
+ return labels.join(".");
673
+ }
674
+ function literalLabelsToLiteralName(labels) {
675
+ return labels.join(".");
676
+ }
677
+
678
+ // src/shared/null-bytes.ts
679
+ var hasNullByte = (value) => value.indexOf("\0") !== -1;
680
+ var stripNullBytes = (value) => value.replaceAll("\0", "");
681
+
682
+ // src/shared/numbers.ts
683
+ function bigIntToNumber(n) {
684
+ if (n < Number.MIN_SAFE_INTEGER) {
685
+ throw new Error(
686
+ `The bigint '${n.toString()}' value is too low to be to converted into a number.'`
687
+ );
688
+ }
689
+ if (n > Number.MAX_SAFE_INTEGER) {
690
+ throw new Error(
691
+ `The bigint '${n.toString()}' value is too high to be to converted into a number.'`
692
+ );
693
+ }
694
+ return Number(n);
695
+ }
696
+
697
+ // src/shared/serialize.ts
698
+ import { AccountId as CaipAccountId2 } from "caip";
699
+ function serializeChainId(chainId) {
700
+ return chainId.toString();
701
+ }
702
+ function serializeDatetime(datetime) {
703
+ return datetime.toISOString();
704
+ }
705
+ function serializeUrl(url) {
706
+ return url.toString();
707
+ }
708
+ function serializePrice(price) {
709
+ return {
710
+ currency: price.currency,
711
+ amount: price.amount.toString()
712
+ };
713
+ }
714
+ function serializePriceEth(price) {
715
+ return serializePrice(price);
716
+ }
717
+ function serializeAccountId(accountId) {
718
+ return CaipAccountId2.format({
719
+ chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
720
+ address: accountId.address
721
+ }).toLowerCase();
722
+ }
723
+
724
+ // src/shared/url.ts
725
+ function isHttpProtocol(url) {
726
+ return ["http:", "https:"].includes(url.protocol);
727
+ }
728
+ function isWebSocketProtocol(url) {
729
+ return ["ws:", "wss:"].includes(url.protocol);
730
+ }
731
+
732
+ // src/ensindexer/indexing-status/types.ts
733
+ var ChainIndexingConfigTypeIds = {
734
+ /**
735
+ * Represents that indexing of the chain should be performed for an indefinite range.
736
+ */
737
+ Indefinite: "indefinite",
738
+ /**
739
+ * Represents that indexing of the chain should be performed for a definite range.
740
+ */
741
+ Definite: "definite"
742
+ };
743
+ var ChainIndexingStatusIds = {
744
+ /**
745
+ * Represents that indexing of the chain is not ready to begin yet because:
746
+ * - ENSIndexer is in its initialization phase and the data to build a
747
+ * "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
748
+ * - ENSIndexer is using an omnichain indexing strategy and the
749
+ * `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
750
+ * {@link ChainIndexingSnapshot}.
751
+ */
752
+ Queued: "chain-queued",
753
+ /**
754
+ * Represents that indexing of the chain is in progress and under a special
755
+ * "backfill" phase that optimizes for accelerated indexing until reaching the
756
+ * "fixed target" `backfillEndBlock`.
757
+ */
758
+ Backfill: "chain-backfill",
759
+ /**
760
+ * Represents that the "backfill" phase of indexing the chain is completed
761
+ * and that the chain is configured to be indexed for an indefinite range.
762
+ * Therefore, indexing of the chain remains indefinitely in progress where
763
+ * ENSIndexer will continuously work to discover and index new blocks as they
764
+ * are added to the chain across time.
765
+ */
766
+ Following: "chain-following",
767
+ /**
768
+ * Represents that indexing of the chain is completed as the chain is configured
769
+ * to be indexed for a definite range and the indexing of all blocks through
770
+ * that definite range is completed.
771
+ */
772
+ Completed: "chain-completed"
773
+ };
774
+ var OmnichainIndexingStatusIds = {
775
+ /**
776
+ * Represents that omnichain indexing is not ready to begin yet because
777
+ * ENSIndexer is in its initialization phase and the data to build a "true"
778
+ * {@link OmnichainIndexingStatusSnapshot} is still being loaded.
779
+ */
780
+ Unstarted: "omnichain-unstarted",
781
+ /**
782
+ * Represents that omnichain indexing is in an overall "backfill" status because
783
+ * - At least one indexed chain has a `chainStatus` of
784
+ * {@link ChainIndexingStatusIds.Backfill}; and
785
+ * - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
786
+ */
787
+ Backfill: "omnichain-backfill",
788
+ /**
789
+ * Represents that omnichain indexing is in an overall "following" status because
790
+ * at least one indexed chain has a `chainStatus` of
791
+ * {@link ChainIndexingStatusIds.Following}.
792
+ */
793
+ Following: "omnichain-following",
794
+ /**
795
+ * Represents that omnichain indexing has completed because all indexed chains have
796
+ * a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
797
+ */
798
+ Completed: "omnichain-completed"
799
+ };
800
+ var CrossChainIndexingStrategyIds = {
801
+ /**
802
+ * Represents that the indexing of events across all indexed chains will
803
+ * proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
804
+ * and block number.
805
+ *
806
+ * This strategy is "deterministic" in that the order of processing cross-chain indexed
807
+ * events and each resulting indexed data state transition recorded in ENSDb is always
808
+ * the same for each ENSIndexer instance operating with an equivalent
809
+ * `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
810
+ * - increased indexing latency that must wait for the slowest indexed chain to
811
+ * add new blocks or to discover new blocks through the configured RPCs.
812
+ * - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
813
+ * will be affected.
814
+ */
815
+ Omnichain: "omnichain"
816
+ };
817
+
818
+ // src/shared/block-ref.ts
819
+ function isBefore(blockA, blockB) {
820
+ return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
821
+ }
822
+ function isEqualTo(blockA, blockB) {
823
+ return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
824
+ }
825
+ function isBeforeOrEqualTo(blockA, blockB) {
826
+ return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
827
+ }
828
+
829
+ // src/ensindexer/indexing-status/helpers.ts
830
+ function getOmnichainIndexingStatus(chains) {
831
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
832
+ return OmnichainIndexingStatusIds.Following;
833
+ }
834
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
835
+ return OmnichainIndexingStatusIds.Backfill;
836
+ }
837
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
838
+ return OmnichainIndexingStatusIds.Unstarted;
839
+ }
840
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
841
+ return OmnichainIndexingStatusIds.Completed;
842
+ }
843
+ throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
844
+ }
845
+ function getTimestampForLowestOmnichainStartBlock(chains) {
846
+ const earliestKnownBlockTimestamps = chains.map(
847
+ (chain) => chain.config.startBlock.timestamp
848
+ );
849
+ return Math.min(...earliestKnownBlockTimestamps);
850
+ }
851
+ function getTimestampForHighestOmnichainKnownBlock(chains) {
852
+ const latestKnownBlockTimestamps = [];
853
+ for (const chain of chains) {
854
+ switch (chain.chainStatus) {
855
+ case ChainIndexingStatusIds.Queued:
856
+ if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
857
+ latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
858
+ }
859
+ break;
860
+ case ChainIndexingStatusIds.Backfill:
861
+ latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
862
+ break;
863
+ case ChainIndexingStatusIds.Completed:
864
+ latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
865
+ break;
866
+ case ChainIndexingStatusIds.Following:
867
+ latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
868
+ break;
869
+ }
870
+ }
871
+ return Math.max(...latestKnownBlockTimestamps);
872
+ }
873
+ function getOmnichainIndexingCursor(chains) {
874
+ if (chains.length === 0) {
875
+ throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
876
+ }
877
+ if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
878
+ const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
879
+ return Math.min(...earliestStartBlockTimestamps) - 1;
880
+ }
881
+ const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
882
+ if (latestIndexedBlockTimestamps.length < 1) {
883
+ throw new Error("latestIndexedBlockTimestamps array must include at least one element");
884
+ }
885
+ return Math.max(...latestIndexedBlockTimestamps);
886
+ }
887
+ function createIndexingConfig(startBlock, endBlock) {
888
+ if (endBlock) {
889
+ return {
890
+ configType: ChainIndexingConfigTypeIds.Definite,
891
+ startBlock,
892
+ endBlock
893
+ };
894
+ }
895
+ return {
896
+ configType: ChainIndexingConfigTypeIds.Indefinite,
897
+ startBlock
898
+ };
899
+ }
900
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
901
+ return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
902
+ }
903
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
904
+ const atLeastOneChainInTargetStatus = chains.some(
905
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
906
+ );
907
+ const otherChainsHaveValidStatuses = chains.every(
908
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
909
+ );
910
+ return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
911
+ }
912
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
913
+ const allChainsHaveValidStatuses = chains.every(
914
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
915
+ );
916
+ return allChainsHaveValidStatuses;
917
+ }
918
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
919
+ const allChainsHaveValidStatuses = chains.some(
920
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Following
921
+ );
922
+ return allChainsHaveValidStatuses;
923
+ }
924
+ function sortChainStatusesByStartBlockAsc(chains) {
925
+ chains.sort(
926
+ ([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
927
+ );
928
+ return chains;
929
+ }
930
+
931
+ // src/ensindexer/indexing-status/validations.ts
932
+ function invariant_chainSnapshotQueuedBlocks(ctx) {
933
+ const { config } = ctx.value;
934
+ if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
935
+ return;
936
+ }
937
+ if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
938
+ ctx.issues.push({
939
+ code: "custom",
940
+ input: ctx.value,
941
+ message: "`config.startBlock` must be before or same as `config.endBlock`."
942
+ });
943
+ }
944
+ }
945
+ function invariant_chainSnapshotBackfillBlocks(ctx) {
946
+ const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
947
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
948
+ ctx.issues.push({
949
+ code: "custom",
950
+ input: ctx.value,
951
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
952
+ });
953
+ }
954
+ if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
955
+ ctx.issues.push({
956
+ code: "custom",
957
+ input: ctx.value,
958
+ message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
959
+ });
960
+ }
961
+ if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
962
+ return;
963
+ }
964
+ if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
965
+ ctx.issues.push({
966
+ code: "custom",
967
+ input: ctx.value,
968
+ message: "`backfillEndBlock` must be the same as `config.endBlock`."
969
+ });
970
+ }
971
+ }
972
+ function invariant_chainSnapshotCompletedBlocks(ctx) {
973
+ const { config, latestIndexedBlock } = ctx.value;
974
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
975
+ ctx.issues.push({
976
+ code: "custom",
977
+ input: ctx.value,
978
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
979
+ });
980
+ }
981
+ if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
982
+ ctx.issues.push({
983
+ code: "custom",
984
+ input: ctx.value,
985
+ message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
986
+ });
987
+ }
988
+ }
989
+ function invariant_chainSnapshotFollowingBlocks(ctx) {
990
+ const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
991
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
992
+ ctx.issues.push({
993
+ code: "custom",
994
+ input: ctx.value,
995
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
996
+ });
997
+ }
998
+ if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
999
+ ctx.issues.push({
1000
+ code: "custom",
1001
+ input: ctx.value,
1002
+ message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
1003
+ });
1004
+ }
1005
+ }
1006
+ function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
1007
+ const snapshot = ctx.value;
1008
+ const chains = Array.from(snapshot.chains.values());
1009
+ const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
1010
+ const actualOmnichainStatus = snapshot.omnichainStatus;
1011
+ if (expectedOmnichainStatus !== actualOmnichainStatus) {
1012
+ ctx.issues.push({
1013
+ code: "custom",
1014
+ input: snapshot,
1015
+ message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
1016
+ });
1017
+ }
1018
+ }
1019
+ function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
1020
+ const snapshot = ctx.value;
1021
+ const queuedChains = Array.from(snapshot.chains.values()).filter(
1022
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
1023
+ );
1024
+ if (queuedChains.length === 0) {
1025
+ return;
1026
+ }
1027
+ const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
1028
+ const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
1029
+ if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
1030
+ ctx.issues.push({
1031
+ code: "custom",
1032
+ input: snapshot,
1033
+ message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
1034
+ });
1035
+ }
1036
+ }
1037
+ function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
1038
+ const snapshot = ctx.value;
1039
+ const backfillChains = Array.from(snapshot.chains.values()).filter(
1040
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1041
+ );
1042
+ if (backfillChains.length === 0) {
1043
+ return;
1044
+ }
1045
+ const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
1046
+ const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
1047
+ if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
1048
+ ctx.issues.push({
1049
+ code: "custom",
1050
+ input: snapshot,
1051
+ message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
1052
+ });
1053
+ }
1054
+ }
1055
+ function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
1056
+ const snapshot = ctx.value;
1057
+ const indexedChains = Array.from(snapshot.chains.values()).filter(
1058
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
1059
+ );
1060
+ if (indexedChains.length === 0) {
1061
+ return;
1062
+ }
1063
+ const indexedChainLatestIndexedBlocks = indexedChains.map(
1064
+ (chain) => chain.latestIndexedBlock.timestamp
1065
+ );
1066
+ const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
1067
+ if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
1068
+ ctx.issues.push({
1069
+ code: "custom",
1070
+ input: snapshot,
1071
+ message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
1072
+ });
1073
+ }
1074
+ }
1075
+ function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
1076
+ const chains = ctx.value;
1077
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
1078
+ Array.from(chains.values())
1079
+ );
1080
+ if (hasValidChains === false) {
1081
+ ctx.issues.push({
1082
+ code: "custom",
1083
+ input: chains,
1084
+ message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
1085
+ });
1086
+ }
1087
+ }
1088
+ function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
1089
+ const chains = ctx.value;
1090
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
1091
+ Array.from(chains.values())
1092
+ );
1093
+ if (hasValidChains === false) {
1094
+ ctx.issues.push({
1095
+ code: "custom",
1096
+ input: chains,
1097
+ 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".`
1098
+ });
1099
+ }
1100
+ }
1101
+ function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
1102
+ const chains = ctx.value;
1103
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
1104
+ Array.from(chains.values())
1105
+ );
1106
+ if (hasValidChains === false) {
1107
+ ctx.issues.push({
1108
+ code: "custom",
1109
+ input: chains,
1110
+ message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
1111
+ });
1112
+ }
1113
+ }
1114
+ function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
1115
+ const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
1116
+ const { omnichainIndexingCursor } = omnichainSnapshot;
1117
+ if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
1118
+ console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
1119
+ slowestChainIndexingCursor,
1120
+ omnichainIndexingCursor
1121
+ });
1122
+ ctx.issues.push({
1123
+ code: "custom",
1124
+ input: ctx.value,
1125
+ message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
1126
+ });
1127
+ }
1128
+ }
1129
+ function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
1130
+ const { snapshotTime, omnichainSnapshot } = ctx.value;
1131
+ const chains = Array.from(omnichainSnapshot.chains.values());
1132
+ const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1133
+ const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
1134
+ const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
1135
+ const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
1136
+ const highestKnownBlockTimestamp = Math.max(
1137
+ ...startBlockTimestamps,
1138
+ ...endBlockTimestamps,
1139
+ ...backfillEndBlockTimestamps,
1140
+ ...latestKnownBlockTimestamps
1141
+ );
1142
+ if (snapshotTime < highestKnownBlockTimestamp) {
1143
+ ctx.issues.push({
1144
+ code: "custom",
1145
+ input: ctx.value,
1146
+ message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
1147
+ });
1148
+ }
1149
+ }
1150
+ function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
1151
+ const projection = ctx.value;
1152
+ const { snapshot, projectedAt } = projection;
1153
+ if (snapshot.snapshotTime > projectedAt) {
1154
+ ctx.issues.push({
1155
+ code: "custom",
1156
+ input: projection,
1157
+ message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
1158
+ });
1159
+ }
358
1160
  }
359
- function interpretLiteralName(name) {
360
- if (isNormalizedName(name)) return name;
361
- return name.split(".").map(interpretLiteralLabel).join(".");
1161
+ function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
1162
+ const projection = ctx.value;
1163
+ const { projectedAt, snapshot, worstCaseDistance } = projection;
1164
+ const { omnichainSnapshot } = snapshot;
1165
+ const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
1166
+ if (worstCaseDistance !== expectedWorstCaseDistance) {
1167
+ ctx.issues.push({
1168
+ code: "custom",
1169
+ input: projection,
1170
+ message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
1171
+ });
1172
+ }
362
1173
  }
363
1174
 
1175
+ // src/ensindexer/indexing-status/zod-schemas.ts
1176
+ var makeChainIndexingConfigSchema = (valueLabel = "Value") => z2.discriminatedUnion("configType", [
1177
+ z2.strictObject({
1178
+ configType: z2.literal(ChainIndexingConfigTypeIds.Indefinite),
1179
+ startBlock: makeBlockRefSchema(valueLabel)
1180
+ }),
1181
+ z2.strictObject({
1182
+ configType: z2.literal(ChainIndexingConfigTypeIds.Definite),
1183
+ startBlock: makeBlockRefSchema(valueLabel),
1184
+ endBlock: makeBlockRefSchema(valueLabel)
1185
+ })
1186
+ ]);
1187
+ var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => z2.strictObject({
1188
+ chainStatus: z2.literal(ChainIndexingStatusIds.Queued),
1189
+ config: makeChainIndexingConfigSchema(valueLabel)
1190
+ }).check(invariant_chainSnapshotQueuedBlocks);
1191
+ var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => z2.strictObject({
1192
+ chainStatus: z2.literal(ChainIndexingStatusIds.Backfill),
1193
+ config: makeChainIndexingConfigSchema(valueLabel),
1194
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1195
+ backfillEndBlock: makeBlockRefSchema(valueLabel)
1196
+ }).check(invariant_chainSnapshotBackfillBlocks);
1197
+ var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => z2.strictObject({
1198
+ chainStatus: z2.literal(ChainIndexingStatusIds.Completed),
1199
+ config: z2.strictObject({
1200
+ configType: z2.literal(ChainIndexingConfigTypeIds.Definite),
1201
+ startBlock: makeBlockRefSchema(valueLabel),
1202
+ endBlock: makeBlockRefSchema(valueLabel)
1203
+ }),
1204
+ latestIndexedBlock: makeBlockRefSchema(valueLabel)
1205
+ }).check(invariant_chainSnapshotCompletedBlocks);
1206
+ var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => z2.strictObject({
1207
+ chainStatus: z2.literal(ChainIndexingStatusIds.Following),
1208
+ config: z2.strictObject({
1209
+ configType: z2.literal(ChainIndexingConfigTypeIds.Indefinite),
1210
+ startBlock: makeBlockRefSchema(valueLabel)
1211
+ }),
1212
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1213
+ latestKnownBlock: makeBlockRefSchema(valueLabel)
1214
+ }).check(invariant_chainSnapshotFollowingBlocks);
1215
+ var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => z2.discriminatedUnion("chainStatus", [
1216
+ makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
1217
+ makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
1218
+ makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
1219
+ makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
1220
+ ]);
1221
+ var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z2.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
1222
+ error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
1223
+ }).transform((serializedChainsIndexingStatus) => {
1224
+ const chainsIndexingStatus = /* @__PURE__ */ new Map();
1225
+ for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
1226
+ chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
1227
+ }
1228
+ return chainsIndexingStatus;
1229
+ });
1230
+ var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => z2.strictObject({
1231
+ omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Unstarted),
1232
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
1233
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1234
+ });
1235
+ var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => z2.strictObject({
1236
+ omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Backfill),
1237
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
1238
+ (chains) => chains
1239
+ ),
1240
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1241
+ });
1242
+ var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => z2.strictObject({
1243
+ omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Completed),
1244
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
1245
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1246
+ });
1247
+ var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => z2.strictObject({
1248
+ omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Following),
1249
+ chains: makeChainIndexingStatusesSchema(valueLabel),
1250
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1251
+ });
1252
+ var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => z2.discriminatedUnion("omnichainStatus", [
1253
+ makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
1254
+ makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
1255
+ makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
1256
+ makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
1257
+ ]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
1258
+ invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
1259
+ ).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
1260
+ var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => z2.strictObject({
1261
+ strategy: z2.literal(CrossChainIndexingStrategyIds.Omnichain),
1262
+ slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
1263
+ snapshotTime: makeUnixTimestampSchema(valueLabel),
1264
+ omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
1265
+ }).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
1266
+ var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => z2.discriminatedUnion("strategy", [
1267
+ makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
1268
+ ]);
1269
+ var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => z2.strictObject({
1270
+ projectedAt: makeUnixTimestampSchema(valueLabel),
1271
+ worstCaseDistance: makeDurationSchema(valueLabel),
1272
+ snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
1273
+ }).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
1274
+
1275
+ // src/ensindexer/config/zod-schemas.ts
1276
+ import z3 from "zod/v4";
1277
+
1278
+ // src/ensindexer/config/is-subgraph-compatible.ts
1279
+ import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
1280
+
364
1281
  // src/ensindexer/config/types.ts
365
1282
  var PluginName = /* @__PURE__ */ ((PluginName2) => {
366
1283
  PluginName2["Subgraph"] = "subgraph";
367
1284
  PluginName2["Basenames"] = "basenames";
368
1285
  PluginName2["Lineanames"] = "lineanames";
369
1286
  PluginName2["ThreeDNS"] = "threedns";
370
- PluginName2["ReverseResolvers"] = "reverse-resolvers";
371
- PluginName2["Referrals"] = "referrals";
1287
+ PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
1288
+ PluginName2["Registrars"] = "registrars";
372
1289
  PluginName2["TokenScope"] = "tokenscope";
373
1290
  return PluginName2;
374
1291
  })(PluginName || {});
375
1292
 
376
- // src/ensindexer/config/helpers.ts
1293
+ // src/ensindexer/config/is-subgraph-compatible.ts
377
1294
  function isSubgraphCompatible(config) {
378
1295
  const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
379
- const indexingBehaviorIsSubgraphCompatible = !config.healReverseAddresses && !config.indexAdditionalResolverRecords && !config.replaceUnnormalized;
380
- const labelSetIsSubgraphCompatible = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
381
- return onlySubgraphPluginActivated && indexingBehaviorIsSubgraphCompatible && labelSetIsSubgraphCompatible;
1296
+ const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
1297
+ const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
1298
+ const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
1299
+ return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
1300
+ }
1301
+
1302
+ // src/ensindexer/config/validations.ts
1303
+ function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
1304
+ const versionInfo = ctx.value;
1305
+ if (versionInfo.ensDb !== versionInfo.ensIndexer) {
1306
+ ctx.issues.push({
1307
+ code: "custom",
1308
+ input: versionInfo,
1309
+ message: "`ensDb` version must be same as `ensIndexer` version"
1310
+ });
1311
+ }
382
1312
  }
383
1313
 
384
1314
  // src/ensindexer/config/zod-schemas.ts
385
- var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
1315
+ var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z3.array(makeChainIdSchema(valueLabel), {
386
1316
  error: `${valueLabel} must be an array.`
387
1317
  }).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
388
- var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(
389
- z2.enum(PluginName, {
390
- error: `${valueLabel} must be a list with at least one valid plugin name. Valid plugins are: ${Object.values(
391
- PluginName
392
- ).join(", ")}`
393
- })
394
- ).min(1, {
395
- error: `${valueLabel} must be a list with at least one valid plugin name. Valid plugins are: ${Object.values(
396
- PluginName
397
- ).join(", ")}`
1318
+ var makePluginsListSchema = (valueLabel = "Plugins") => z3.array(z3.string(), {
1319
+ error: `${valueLabel} must be a list of strings.`
1320
+ }).min(1, {
1321
+ error: `${valueLabel} must be a list of strings with at least one string value`
398
1322
  }).refine((arr) => arr.length === uniq(arr).length, {
399
1323
  error: `${valueLabel} cannot contain duplicate values.`
400
1324
  });
401
- var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
1325
+ var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z3.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
402
1326
  error: `${valueLabel} is required and must be a non-empty string.`
403
1327
  });
404
1328
  var makeLabelSetIdSchema = (valueLabel) => {
405
- return z2.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
1329
+ return z3.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
406
1330
  error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
407
1331
  });
408
1332
  };
409
1333
  var makeLabelSetVersionSchema = (valueLabel) => {
410
- return z2.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
1334
+ return z3.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
411
1335
  };
412
1336
  var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
413
1337
  let valueLabelLabelSetId = valueLabel;
414
1338
  let valueLabelLabelSetVersion = valueLabel;
415
- if (valueLabel == "LABEL_SET") {
1339
+ if (valueLabel === "LABEL_SET") {
416
1340
  valueLabelLabelSetId = "LABEL_SET_ID";
417
1341
  valueLabelLabelSetVersion = "LABEL_SET_VERSION";
418
1342
  } else {
419
- valueLabelLabelSetId = valueLabel + ".labelSetId";
420
- valueLabelLabelSetVersion = valueLabel + ".labelSetVersion";
1343
+ valueLabelLabelSetId = `${valueLabel}.labelSetId`;
1344
+ valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
421
1345
  }
422
- return z2.object({
1346
+ return z3.object({
423
1347
  labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
424
1348
  labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
425
1349
  });
426
1350
  };
427
- var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
428
- var makeDependencyInfoSchema = (valueLabel = "Value") => z2.strictObject(
1351
+ var makeNonEmptyStringSchema = (valueLabel = "Value") => z3.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
1352
+ var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z3.strictObject(
429
1353
  {
430
1354
  nodejs: makeNonEmptyStringSchema(),
431
1355
  ponder: makeNonEmptyStringSchema(),
1356
+ ensDb: makeNonEmptyStringSchema(),
1357
+ ensIndexer: makeNonEmptyStringSchema(),
1358
+ ensNormalize: makeNonEmptyStringSchema(),
432
1359
  ensRainbow: makeNonEmptyStringSchema(),
433
1360
  ensRainbowSchema: makePositiveIntegerSchema()
434
1361
  },
435
1362
  {
436
- error: `${valueLabel} must be a valid DependencyInfo object.`
437
- }
438
- );
439
- function invariant_reverseResolversPluginNeedsResolverRecords(ctx) {
440
- const { value: config } = ctx;
441
- const reverseResolversPluginActive = config.plugins.includes("reverse-resolvers" /* ReverseResolvers */);
442
- if (reverseResolversPluginActive && !config.indexAdditionalResolverRecords) {
443
- ctx.issues.push({
444
- code: "custom",
445
- input: config,
446
- message: `The '${"reverse-resolvers" /* ReverseResolvers */}' plugin requires 'indexAdditionalResolverRecords' to be 'true'.`
447
- });
1363
+ error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
448
1364
  }
449
- }
1365
+ ).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
450
1366
  function invariant_isSubgraphCompatibleRequirements(ctx) {
451
1367
  const { value: config } = ctx;
452
- if (config.isSubgraphCompatible !== isSubgraphCompatible(config)) {
453
- const message = config.isSubgraphCompatible ? `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active, 'indexAdditionalResolverRecords', 'healReverseAddresses', and 'replaceUnnormalized' must be set to 'false', and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}` : `'indexAdditionalResolverRecords', 'healReverseAddresses', and 'replaceUnnormalized' 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'`;
1368
+ if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
454
1369
  ctx.issues.push({
455
1370
  code: "custom",
456
1371
  input: config,
457
- message
1372
+ message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
458
1373
  });
459
1374
  }
460
1375
  }
461
- var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
462
- ensAdminUrl: makeUrlSchema(`${valueLabel}.ensAdminUrl`),
463
- ensNodePublicUrl: makeUrlSchema(`${valueLabel}.ensNodePublicUrl`),
1376
+ var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z3.object({
464
1377
  labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
465
- healReverseAddresses: z2.boolean({ error: `${valueLabel}.healReverseAddresses` }),
466
- indexAdditionalResolverRecords: z2.boolean({
467
- error: `${valueLabel}.indexAdditionalResolverRecords`
468
- }),
469
- replaceUnnormalized: z2.boolean({ error: `${valueLabel}.replaceUnnormalized` }),
470
1378
  indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
471
- isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
1379
+ isSubgraphCompatible: z3.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
472
1380
  namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
473
1381
  plugins: makePluginsListSchema(`${valueLabel}.plugins`),
474
1382
  databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
475
- dependencyInfo: makeDependencyInfoSchema(`${valueLabel}.dependencyInfo`)
476
- }).check(invariant_reverseResolversPluginNeedsResolverRecords).check(invariant_isSubgraphCompatibleRequirements);
1383
+ versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
1384
+ }).check(invariant_isSubgraphCompatibleRequirements);
477
1385
 
478
- // src/ensindexer/config/deserialize.ts
479
- function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
480
- const schema = makeENSIndexerPublicConfigSchema(valueLabel);
481
- const parsed = schema.safeParse(maybeConfig);
482
- if (parsed.error) {
483
- throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
484
- ${prettifyError2(parsed.error)}
485
- `);
1386
+ // src/shared/config/build-rpc-urls.ts
1387
+ import {
1388
+ arbitrum,
1389
+ arbitrumSepolia,
1390
+ base,
1391
+ baseSepolia,
1392
+ holesky,
1393
+ linea,
1394
+ lineaSepolia,
1395
+ mainnet,
1396
+ optimism,
1397
+ optimismSepolia,
1398
+ scroll,
1399
+ scrollSepolia,
1400
+ sepolia
1401
+ } from "viem/chains";
1402
+
1403
+ // src/shared/config/rpc-configs-from-env.ts
1404
+ import { getENSNamespace } from "@ensnode/datasources";
1405
+
1406
+ // src/shared/config/validatons.ts
1407
+ import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
1408
+ function invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL(ctx) {
1409
+ const endpoints = ctx.value;
1410
+ const httpEndpoints = endpoints.filter(isHttpProtocol);
1411
+ if (httpEndpoints.length < 1) {
1412
+ ctx.issues.push({
1413
+ code: "custom",
1414
+ input: endpoints,
1415
+ message: `RPC endpoint configuration for a chain must include at least one http/https protocol URL.`
1416
+ });
1417
+ }
1418
+ }
1419
+ function invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL(ctx) {
1420
+ const endpoints = ctx.value;
1421
+ const wsEndpoints = endpoints.filter(isWebSocketProtocol);
1422
+ if (wsEndpoints.length > 1) {
1423
+ ctx.issues.push({
1424
+ code: "custom",
1425
+ input: endpoints,
1426
+ message: `RPC endpoint configuration for a chain must include at most one websocket (ws/wss) protocol URL.`
1427
+ });
486
1428
  }
487
- return parsed.data;
488
1429
  }
489
1430
 
490
- // src/ensindexer/config/serialize.ts
491
- function serializeIndexedChainIds(indexedChainIds) {
492
- return Array.from(indexedChainIds);
1431
+ // src/shared/config/zod-schemas.ts
1432
+ import { z as z4 } from "zod/v4";
1433
+ import { ENSNamespaceIds as ENSNamespaceIds3 } from "@ensnode/datasources";
1434
+ var DatabaseSchemaNameSchema = z4.string({
1435
+ error: "DATABASE_SCHEMA is required."
1436
+ }).trim().min(1, {
1437
+ error: "DATABASE_SCHEMA is required and cannot be an empty string."
1438
+ });
1439
+ var RpcConfigSchema = z4.string().transform((val) => val.split(",")).pipe(z4.array(makeUrlSchema("RPC URL"))).check(invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL).check(invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL);
1440
+ var RpcConfigsSchema = z4.record(makeChainIdStringSchema("RPC URL"), RpcConfigSchema, {
1441
+ error: "Chains configuration must be an object mapping valid chain IDs to their configs."
1442
+ }).transform((records) => {
1443
+ const rpcConfigs = /* @__PURE__ */ new Map();
1444
+ for (const [chainIdString, rpcConfig] of Object.entries(records)) {
1445
+ const httpRPCs = rpcConfig.filter(isHttpProtocol);
1446
+ const websocketRPC = rpcConfig.find(isWebSocketProtocol);
1447
+ rpcConfigs.set(deserializeChainId(chainIdString), {
1448
+ httpRPCs,
1449
+ websocketRPC
1450
+ });
1451
+ }
1452
+ return rpcConfigs;
1453
+ });
1454
+ var EnsIndexerUrlSchema = makeUrlSchema("ENSINDEXER_URL");
1455
+ var ENSNamespaceSchema = z4.enum(ENSNamespaceIds3, {
1456
+ error: ({ input }) => `Invalid NAMESPACE. Got '${input}', but supported ENS namespaces are: ${Object.keys(ENSNamespaceIds3).join(", ")}`
1457
+ });
1458
+ var PortSchema = z4.coerce.number({ error: "PORT must be a number." }).min(1, { error: "PORT must be greater than 1." }).max(65535, { error: "PORT must be less than 65535" }).optional();
1459
+ var TheGraphApiKeySchema = z4.string().optional();
1460
+
1461
+ // src/shared/datasources-with-resolvers.ts
1462
+ import {
1463
+ DatasourceNames,
1464
+ maybeGetDatasource
1465
+ } from "@ensnode/datasources";
1466
+ var DATASOURCE_NAMES_WITH_RESOLVERS = [
1467
+ DatasourceNames.ENSRoot,
1468
+ DatasourceNames.Basenames,
1469
+ DatasourceNames.Lineanames,
1470
+ DatasourceNames.ThreeDNSOptimism,
1471
+ DatasourceNames.ThreeDNSBase
1472
+ ];
1473
+
1474
+ // src/shared/log-level.ts
1475
+ import { z as z5 } from "zod/v4";
1476
+ var LogLevelSchema = z5.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]);
1477
+
1478
+ // src/shared/protocol-acceleration/interpret-record-values.ts
1479
+ import { isAddress as isAddress3, isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
1480
+
1481
+ // src/registrars/zod-schemas.ts
1482
+ import { decodeEncodedReferrer as decodeEncodedReferrer2, ENCODED_REFERRER_BYTE_LENGTH } from "@namehash/ens-referrals";
1483
+ import z6 from "zod/v4";
1484
+
1485
+ // src/registrars/registrar-action.ts
1486
+ import { decodeEncodedReferrer, zeroEncodedReferrer } from "@namehash/ens-referrals";
1487
+
1488
+ // src/registrars/subregistry.ts
1489
+ function serializeSubregistry(subregistry) {
1490
+ return {
1491
+ subregistryId: serializeAccountId(subregistry.subregistryId),
1492
+ node: subregistry.node
1493
+ };
493
1494
  }
494
- function serializeENSIndexerPublicConfig(config) {
495
- const {
496
- ensAdminUrl,
497
- ensNodePublicUrl,
498
- labelSet,
499
- indexedChainIds,
500
- databaseSchemaName,
501
- healReverseAddresses,
502
- indexAdditionalResolverRecords,
503
- replaceUnnormalized,
504
- isSubgraphCompatible: isSubgraphCompatible2,
505
- namespace,
506
- plugins,
507
- dependencyInfo
508
- } = config;
1495
+
1496
+ // src/registrars/registration-lifecycle.ts
1497
+ function serializeRegistrationLifecycle(registrationLifecycle) {
509
1498
  return {
510
- ensAdminUrl: serializeUrl(ensAdminUrl),
511
- ensNodePublicUrl: serializeUrl(ensNodePublicUrl),
512
- labelSet,
513
- indexedChainIds: serializeIndexedChainIds(indexedChainIds),
514
- databaseSchemaName,
515
- healReverseAddresses,
516
- indexAdditionalResolverRecords,
517
- replaceUnnormalized,
518
- isSubgraphCompatible: isSubgraphCompatible2,
519
- namespace,
520
- plugins,
521
- dependencyInfo
1499
+ subregistry: serializeSubregistry(registrationLifecycle.subregistry),
1500
+ node: registrationLifecycle.node,
1501
+ expiresAt: registrationLifecycle.expiresAt
522
1502
  };
523
1503
  }
524
1504
 
525
- // src/ensindexer/config/labelset-utils.ts
526
- function buildLabelSetId(maybeLabelSetId) {
527
- return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
1505
+ // src/registrars/registrar-action.ts
1506
+ var RegistrarActionTypes = {
1507
+ Registration: "registration",
1508
+ Renewal: "renewal"
1509
+ };
1510
+ function isRegistrarActionPricingAvailable(registrarActionPricing) {
1511
+ const { baseCost, premium, total } = registrarActionPricing;
1512
+ return baseCost !== null && premium !== null && total !== null;
528
1513
  }
529
- function buildLabelSetVersion(maybeLabelSetVersion) {
530
- return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
1514
+ function isRegistrarActionReferralAvailable(registrarActionReferral) {
1515
+ const { encodedReferrer, decodedReferrer } = registrarActionReferral;
1516
+ return encodedReferrer !== null && decodedReferrer !== null;
531
1517
  }
532
- function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
533
- if (labelSetVersion !== void 0 && labelSetId === void 0) {
534
- throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
1518
+ function serializeRegistrarActionPricing(pricing) {
1519
+ if (isRegistrarActionPricingAvailable(pricing)) {
1520
+ return {
1521
+ baseCost: serializePriceEth(pricing.baseCost),
1522
+ premium: serializePriceEth(pricing.premium),
1523
+ total: serializePriceEth(pricing.total)
1524
+ };
535
1525
  }
536
- return { labelSetId, labelSetVersion };
1526
+ return pricing;
537
1527
  }
538
- function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
539
- if (clientSet.labelSetId === void 0) {
540
- return;
1528
+ function serializeRegistrarAction(registrarAction) {
1529
+ return {
1530
+ id: registrarAction.id,
1531
+ type: registrarAction.type,
1532
+ incrementalDuration: registrarAction.incrementalDuration,
1533
+ registrant: registrarAction.registrant,
1534
+ registrationLifecycle: serializeRegistrationLifecycle(registrarAction.registrationLifecycle),
1535
+ pricing: serializeRegistrarActionPricing(registrarAction.pricing),
1536
+ referral: registrarAction.referral,
1537
+ block: registrarAction.block,
1538
+ transactionHash: registrarAction.transactionHash,
1539
+ eventIds: registrarAction.eventIds
1540
+ };
1541
+ }
1542
+
1543
+ // src/registrars/zod-schemas.ts
1544
+ var makeSubregistrySchema = (valueLabel = "Subregistry") => z6.object({
1545
+ subregistryId: makeSerializedAccountIdSchema(`${valueLabel} Subregistry ID`),
1546
+ node: makeNodeSchema(`${valueLabel} Node`)
1547
+ });
1548
+ var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => z6.object({
1549
+ subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
1550
+ node: makeNodeSchema(`${valueLabel} Node`),
1551
+ expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
1552
+ });
1553
+ function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
1554
+ const { baseCost, premium, total } = ctx.value;
1555
+ const actualTotal = addPrices(baseCost, premium);
1556
+ if (!isPriceEqual(actualTotal, total)) {
1557
+ ctx.issues.push({
1558
+ code: "custom",
1559
+ input: ctx.value,
1560
+ message: `'total' must be equal to the sum of 'baseCost' and 'premium'`
1561
+ });
541
1562
  }
542
- if (serverSet.labelSetId !== clientSet.labelSetId) {
543
- throw new Error(
544
- `Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
545
- );
1563
+ }
1564
+ var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => z6.union([
1565
+ // pricing available
1566
+ z6.object({
1567
+ baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
1568
+ premium: makePriceEthSchema(`${valueLabel} Premium`),
1569
+ total: makePriceEthSchema(`${valueLabel} Total`)
1570
+ }).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
1571
+ // pricing unknown
1572
+ z6.object({
1573
+ baseCost: z6.null(),
1574
+ premium: z6.null(),
1575
+ total: z6.null()
1576
+ }).transform((v) => v)
1577
+ ]);
1578
+ function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
1579
+ const { encodedReferrer, decodedReferrer } = ctx.value;
1580
+ try {
1581
+ const expectedDecodedReferrer = decodeEncodedReferrer2(encodedReferrer).toLowerCase();
1582
+ if (decodedReferrer !== expectedDecodedReferrer) {
1583
+ ctx.issues.push({
1584
+ code: "custom",
1585
+ input: ctx.value,
1586
+ message: `'decodedReferrer' must be based on 'encodedReferrer'`
1587
+ });
1588
+ }
1589
+ } catch (error) {
1590
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
1591
+ ctx.issues.push({
1592
+ code: "custom",
1593
+ input: ctx.value,
1594
+ message: errorMessage
1595
+ });
546
1596
  }
547
- if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
1597
+ }
1598
+ var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => z6.union([
1599
+ // referral available
1600
+ z6.object({
1601
+ encodedReferrer: makeHexStringSchema(
1602
+ { bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
1603
+ `${valueLabel} Encoded Referrer`
1604
+ ),
1605
+ decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
1606
+ }).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
1607
+ // referral not applicable
1608
+ z6.object({
1609
+ encodedReferrer: z6.null(),
1610
+ decodedReferrer: z6.null()
1611
+ })
1612
+ ]);
1613
+ function invariant_eventIdsInitialElementIsTheActionId(ctx) {
1614
+ const { id, eventIds } = ctx.value;
1615
+ if (eventIds[0] !== id) {
1616
+ ctx.issues.push({
1617
+ code: "custom",
1618
+ input: ctx.value,
1619
+ message: "The initial element of `eventIds` must be the `id` value"
1620
+ });
1621
+ }
1622
+ }
1623
+ var EventIdSchema = z6.string().nonempty();
1624
+ var EventIdsSchema = z6.array(EventIdSchema).min(1).transform((v) => v);
1625
+ var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z6.object({
1626
+ id: EventIdSchema,
1627
+ incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
1628
+ registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
1629
+ registrationLifecycle: makeRegistrationLifecycleSchema(
1630
+ `${valueLabel} Registration Lifecycle`
1631
+ ),
1632
+ pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
1633
+ referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
1634
+ block: makeBlockRefSchema(`${valueLabel} Block`),
1635
+ transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
1636
+ eventIds: EventIdsSchema
1637
+ }).check(invariant_eventIdsInitialElementIsTheActionId);
1638
+ var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
1639
+ type: z6.literal(RegistrarActionTypes.Registration)
1640
+ });
1641
+ var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
1642
+ type: z6.literal(RegistrarActionTypes.Renewal)
1643
+ });
1644
+ var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => z6.discriminatedUnion("type", [
1645
+ makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
1646
+ makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
1647
+ ]);
1648
+
1649
+ // src/api/types.ts
1650
+ var IndexingStatusResponseCodes = {
1651
+ /**
1652
+ * Represents that the indexing status is available.
1653
+ */
1654
+ Ok: "ok",
1655
+ /**
1656
+ * Represents that the indexing status is unavailable.
1657
+ */
1658
+ Error: "error"
1659
+ };
1660
+ var RegistrarActionsFilterTypes = {
1661
+ BySubregistryNode: "bySubregistryNode",
1662
+ WithEncodedReferral: "withEncodedReferral"
1663
+ };
1664
+ var RegistrarActionsOrders = {
1665
+ LatestRegistrarActions: "orderBy[timestamp]=desc"
1666
+ };
1667
+ var RegistrarActionsResponseCodes = {
1668
+ /**
1669
+ * Represents that Registrar Actions are available.
1670
+ */
1671
+ Ok: "ok",
1672
+ /**
1673
+ * Represents that Registrar Actions are unavailable.
1674
+ */
1675
+ Error: "error"
1676
+ };
1677
+
1678
+ // src/api/zod-schemas.ts
1679
+ var ErrorResponseSchema = z7.object({
1680
+ message: z7.string(),
1681
+ details: z7.optional(z7.unknown())
1682
+ });
1683
+ var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z7.strictObject({
1684
+ responseCode: z7.literal(IndexingStatusResponseCodes.Ok),
1685
+ realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
1686
+ });
1687
+ var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => z7.strictObject({
1688
+ responseCode: z7.literal(IndexingStatusResponseCodes.Error)
1689
+ });
1690
+ var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z7.discriminatedUnion("responseCode", [
1691
+ makeIndexingStatusResponseOkSchema(valueLabel),
1692
+ makeIndexingStatusResponseErrorSchema(valueLabel)
1693
+ ]);
1694
+ function invariant_registrationLifecycleNodeMatchesName(ctx) {
1695
+ const { name, action } = ctx.value;
1696
+ const expectedNode = action.registrationLifecycle.node;
1697
+ const actualNode = namehash2(name);
1698
+ if (actualNode !== expectedNode) {
1699
+ ctx.issues.push({
1700
+ code: "custom",
1701
+ input: ctx.value,
1702
+ message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
1703
+ });
1704
+ }
1705
+ }
1706
+ var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z7.object({
1707
+ action: makeRegistrarActionSchema(valueLabel),
1708
+ name: makeReinterpretedNameSchema(valueLabel)
1709
+ }).check(invariant_registrationLifecycleNodeMatchesName);
1710
+ var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z7.strictObject({
1711
+ responseCode: z7.literal(RegistrarActionsResponseCodes.Ok),
1712
+ registrarActions: z7.array(makeNamedRegistrarActionSchema(valueLabel))
1713
+ });
1714
+ var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => z7.strictObject({
1715
+ responseCode: z7.literal(RegistrarActionsResponseCodes.Error),
1716
+ error: ErrorResponseSchema
1717
+ });
1718
+ var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => z7.discriminatedUnion("responseCode", [
1719
+ makeRegistrarActionsResponseOkSchema(valueLabel),
1720
+ makeRegistrarActionsResponseErrorSchema(valueLabel)
1721
+ ]);
1722
+
1723
+ // src/api/deserialize.ts
1724
+ function deserializeErrorResponse(maybeErrorResponse) {
1725
+ const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
1726
+ if (parsed.error) {
1727
+ throw new Error(`Cannot deserialize ErrorResponse:
1728
+ ${prettifyError2(parsed.error)}
1729
+ `);
1730
+ }
1731
+ return parsed.data;
1732
+ }
1733
+ function deserializeIndexingStatusResponse(maybeResponse) {
1734
+ const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
1735
+ if (parsed.error) {
1736
+ throw new Error(`Cannot deserialize IndexingStatusResponse:
1737
+ ${prettifyError2(parsed.error)}
1738
+ `);
1739
+ }
1740
+ return parsed.data;
1741
+ }
1742
+ function deserializeRegistrarActionsResponse(maybeResponse) {
1743
+ const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
1744
+ if (parsed.error) {
548
1745
  throw new Error(
549
- `Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
1746
+ `Cannot deserialize RegistrarActionsResponse:
1747
+ ${prettifyError2(parsed.error)}
1748
+ `
550
1749
  );
551
1750
  }
1751
+ return parsed.data;
1752
+ }
1753
+
1754
+ // src/api/registrar-actions/filters.ts
1755
+ function byParentNode(parentNode) {
1756
+ if (typeof parentNode === "undefined") {
1757
+ return void 0;
1758
+ }
1759
+ return {
1760
+ filterType: RegistrarActionsFilterTypes.BySubregistryNode,
1761
+ value: parentNode
1762
+ };
1763
+ }
1764
+ function withReferral(withReferral2) {
1765
+ if (!withReferral2) {
1766
+ return void 0;
1767
+ }
1768
+ return {
1769
+ filterType: RegistrarActionsFilterTypes.WithEncodedReferral
1770
+ };
1771
+ }
1772
+ var registrarActionsFilter = {
1773
+ byParentNode,
1774
+ withReferral
1775
+ };
1776
+
1777
+ // src/ensindexer/config/deserialize.ts
1778
+ import { prettifyError as prettifyError3 } from "zod/v4";
1779
+ function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
1780
+ const schema = makeENSIndexerPublicConfigSchema(valueLabel);
1781
+ const parsed = schema.safeParse(maybeConfig);
1782
+ if (parsed.error) {
1783
+ throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
1784
+ ${prettifyError3(parsed.error)}
1785
+ `);
1786
+ }
1787
+ return parsed.data;
552
1788
  }
553
1789
 
554
1790
  // src/ensindexer/config/label-utils.ts
555
- import { hexToBytes } from "viem";
1791
+ import { hexToBytes as hexToBytes2 } from "viem";
556
1792
  function labelHashToBytes(labelHash) {
557
1793
  try {
558
1794
  if (labelHash.length !== 66) {
@@ -564,7 +1800,7 @@ function labelHashToBytes(labelHash) {
564
1800
  if (!labelHash.startsWith("0x")) {
565
1801
  throw new Error("Labelhash must be 0x-prefixed");
566
1802
  }
567
- const bytes = hexToBytes(labelHash);
1803
+ const bytes = hexToBytes2(labelHash);
568
1804
  if (bytes.length !== 32) {
569
1805
  throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
570
1806
  }
@@ -577,6 +1813,35 @@ function labelHashToBytes(labelHash) {
577
1813
  }
578
1814
  }
579
1815
 
1816
+ // src/ensindexer/config/labelset-utils.ts
1817
+ function buildLabelSetId(maybeLabelSetId) {
1818
+ return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
1819
+ }
1820
+ function buildLabelSetVersion(maybeLabelSetVersion) {
1821
+ return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
1822
+ }
1823
+ function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
1824
+ if (labelSetVersion !== void 0 && labelSetId === void 0) {
1825
+ throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
1826
+ }
1827
+ return { labelSetId, labelSetVersion };
1828
+ }
1829
+ function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
1830
+ if (clientSet.labelSetId === void 0) {
1831
+ return;
1832
+ }
1833
+ if (serverSet.labelSetId !== clientSet.labelSetId) {
1834
+ throw new Error(
1835
+ `Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
1836
+ );
1837
+ }
1838
+ if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
1839
+ throw new Error(
1840
+ `Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
1841
+ );
1842
+ }
1843
+ }
1844
+
580
1845
  // src/ensindexer/config/parsing.ts
581
1846
  function parseNonNegativeInteger(maybeNumber) {
582
1847
  const trimmed = maybeNumber.trim();
@@ -602,488 +1867,417 @@ function parseNonNegativeInteger(maybeNumber) {
602
1867
  return num;
603
1868
  }
604
1869
 
605
- // src/ensindexer/indexing-status/deserialize.ts
606
- import { prettifyError as prettifyError3 } from "zod/v4";
607
-
608
- // src/ensindexer/indexing-status/zod-schemas.ts
609
- import z3 from "zod/v4";
610
-
611
- // src/shared/block-ref.ts
612
- function isBefore(blockA, blockB) {
613
- return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
614
- }
615
- function isEqualTo(blockA, blockB) {
616
- return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
1870
+ // src/ensindexer/config/serialize.ts
1871
+ function serializeIndexedChainIds(indexedChainIds) {
1872
+ return Array.from(indexedChainIds);
617
1873
  }
618
- function isBeforeOrEqualTo(blockA, blockB) {
619
- return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
1874
+ function serializeENSIndexerPublicConfig(config) {
1875
+ const {
1876
+ labelSet,
1877
+ indexedChainIds,
1878
+ databaseSchemaName,
1879
+ isSubgraphCompatible: isSubgraphCompatible2,
1880
+ namespace,
1881
+ plugins,
1882
+ versionInfo
1883
+ } = config;
1884
+ return {
1885
+ labelSet,
1886
+ indexedChainIds: serializeIndexedChainIds(indexedChainIds),
1887
+ databaseSchemaName,
1888
+ isSubgraphCompatible: isSubgraphCompatible2,
1889
+ namespace,
1890
+ plugins,
1891
+ versionInfo
1892
+ };
620
1893
  }
621
1894
 
622
- // src/ensindexer/indexing-status/types.ts
623
- var ChainIndexingStatusIds = {
624
- Unstarted: "unstarted",
625
- Backfill: "backfill",
626
- Following: "following",
627
- Completed: "completed"
628
- };
629
- var OverallIndexingStatusIds = {
630
- Unstarted: "unstarted",
631
- Backfill: "backfill",
632
- Following: "following",
633
- Completed: "completed",
634
- IndexerError: "indexer-error"
635
- };
636
- var ChainIndexingStrategyIds = {
637
- Indefinite: "indefinite",
638
- Definite: "definite"
639
- };
640
-
641
- // src/ensindexer/indexing-status/helpers.ts
642
- function getOverallIndexingStatus(chains) {
643
- const chainStatuses = chains.map((chain) => chain.status);
644
- let overallStatus;
645
- if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Following)) {
646
- overallStatus = OverallIndexingStatusIds.Following;
647
- } else if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Backfill)) {
648
- overallStatus = OverallIndexingStatusIds.Backfill;
649
- } else if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Unstarted)) {
650
- overallStatus = OverallIndexingStatusIds.Unstarted;
651
- } else {
652
- overallStatus = OverallIndexingStatusIds.Completed;
1895
+ // src/ensindexer/indexing-status/deserialize.ts
1896
+ import { prettifyError as prettifyError4 } from "zod/v4";
1897
+ function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1898
+ const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
1899
+ const parsed = schema.safeParse(maybeSnapshot);
1900
+ if (parsed.error) {
1901
+ throw new Error(
1902
+ `Cannot deserialize into ChainIndexingStatusSnapshot:
1903
+ ${prettifyError4(parsed.error)}
1904
+ `
1905
+ );
653
1906
  }
654
- return overallStatus;
1907
+ return parsed.data;
655
1908
  }
656
- function getOverallApproxRealtimeDistance(chains) {
657
- const chainApproxRealtimeDistances = chains.filter((chain) => chain.status === ChainIndexingStatusIds.Following).map((chain) => chain.approxRealtimeDistance);
658
- if (chainApproxRealtimeDistances.length === 0) {
1909
+ function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1910
+ const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
1911
+ const parsed = schema.safeParse(maybeSnapshot);
1912
+ if (parsed.error) {
659
1913
  throw new Error(
660
- `The overall approximate realtime distance value is undefined if no indexed chain is in the '${OverallIndexingStatusIds.Following}' status`
1914
+ `Cannot deserialize into OmnichainIndexingStatusSnapshot:
1915
+ ${prettifyError4(parsed.error)}
1916
+ `
661
1917
  );
662
1918
  }
663
- const approxRealtimeDistance = Math.max(...chainApproxRealtimeDistances);
664
- return approxRealtimeDistance;
665
- }
666
- function getTimestampForLowestOmnichainStartBlock(chains) {
667
- const earliestKnownBlockTimestamps = chains.map(
668
- (chain) => chain.config.startBlock.timestamp
669
- );
670
- return Math.min(...earliestKnownBlockTimestamps);
1919
+ return parsed.data;
671
1920
  }
672
- function getTimestampForHighestOmnichainKnownBlock(chains) {
673
- const latestKnownBlockTimestamps = [];
674
- for (const chain of chains) {
675
- switch (chain.status) {
676
- case ChainIndexingStatusIds.Unstarted:
677
- if (chain.config.endBlock) {
678
- latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
679
- }
680
- break;
681
- case ChainIndexingStatusIds.Backfill:
682
- latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
683
- break;
684
- case ChainIndexingStatusIds.Completed:
685
- latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
686
- break;
687
- case ChainIndexingStatusIds.Following:
688
- latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
689
- break;
690
- }
1921
+ function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1922
+ const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
1923
+ const parsed = schema.safeParse(maybeSnapshot);
1924
+ if (parsed.error) {
1925
+ throw new Error(
1926
+ `Cannot deserialize into CrossChainIndexingStatusSnapshot:
1927
+ ${prettifyError4(parsed.error)}
1928
+ `
1929
+ );
691
1930
  }
692
- return Math.max(...latestKnownBlockTimestamps);
693
- }
694
- function getOmnichainIndexingCursor(chains) {
695
- return Math.min(...chains.map((chain) => chain.latestIndexedBlock.timestamp));
696
- }
697
- function getActiveChains(chains) {
698
- return chains.filter(
699
- (chain) => chain.status === ChainIndexingStatusIds.Backfill || chain.status === ChainIndexingStatusIds.Following
700
- );
701
- }
702
- function getStandbyChains(chains) {
703
- return chains.filter(
704
- (chain) => chain.status === ChainIndexingStatusIds.Unstarted || chain.status === ChainIndexingStatusIds.Completed
705
- );
1931
+ return parsed.data;
706
1932
  }
707
- function createIndexingConfig(startBlock, endBlock) {
708
- if (endBlock) {
709
- return {
710
- strategy: ChainIndexingStrategyIds.Definite,
711
- startBlock,
712
- endBlock
713
- };
1933
+ function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
1934
+ const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
1935
+ const parsed = schema.safeParse(maybeProjection);
1936
+ if (parsed.error) {
1937
+ throw new Error(
1938
+ `Cannot deserialize into RealtimeIndexingStatusProjection:
1939
+ ${prettifyError4(parsed.error)}
1940
+ `
1941
+ );
714
1942
  }
1943
+ return parsed.data;
1944
+ }
1945
+
1946
+ // src/ensindexer/indexing-status/projection.ts
1947
+ function createRealtimeIndexingStatusProjection(snapshot, now) {
1948
+ const projectedAt = Math.max(now, snapshot.snapshotTime);
715
1949
  return {
716
- strategy: ChainIndexingStrategyIds.Indefinite,
717
- startBlock,
718
- endBlock: null
1950
+ projectedAt,
1951
+ worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
1952
+ snapshot
719
1953
  };
720
1954
  }
721
- function checkChainIndexingStatusesForUnstartedOverallStatus(chains) {
722
- return chains.every((chain) => chain.status === ChainIndexingStatusIds.Unstarted);
723
- }
724
- function checkChainIndexingStatusesForBackfillOverallStatus(chains) {
725
- const atLeastOneChainInTargetStatus = chains.some(
726
- (chain) => chain.status === ChainIndexingStatusIds.Backfill
727
- );
728
- const otherChainsHaveValidStatuses = chains.every(
729
- (chain) => chain.status === ChainIndexingStatusIds.Unstarted || chain.status === ChainIndexingStatusIds.Backfill || chain.status === ChainIndexingStatusIds.Completed
730
- );
731
- return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
1955
+
1956
+ // src/ensindexer/indexing-status/serialize.ts
1957
+ function serializeCrossChainIndexingStatusSnapshotOmnichain({
1958
+ strategy,
1959
+ slowestChainIndexingCursor,
1960
+ snapshotTime,
1961
+ omnichainSnapshot
1962
+ }) {
1963
+ return {
1964
+ strategy,
1965
+ slowestChainIndexingCursor,
1966
+ snapshotTime,
1967
+ omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
1968
+ };
732
1969
  }
733
- function checkChainIndexingStatusesForCompletedOverallStatus(chains) {
734
- const allChainsHaveValidStatuses = chains.every(
735
- (chain) => chain.status === ChainIndexingStatusIds.Completed
736
- );
737
- return allChainsHaveValidStatuses;
1970
+ function serializeRealtimeIndexingStatusProjection(indexingProjection) {
1971
+ return {
1972
+ projectedAt: indexingProjection.projectedAt,
1973
+ worstCaseDistance: indexingProjection.worstCaseDistance,
1974
+ snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
1975
+ };
738
1976
  }
739
- function checkChainIndexingStatusesForFollowingOverallStatus(chains) {
740
- const allChainsHaveValidStatuses = chains.some(
741
- (chain) => chain.status === ChainIndexingStatusIds.Following
742
- );
743
- return allChainsHaveValidStatuses;
1977
+ function serializeChainIndexingSnapshots(chains) {
1978
+ const serializedSnapshots = {};
1979
+ for (const [chainId, snapshot] of chains.entries()) {
1980
+ serializedSnapshots[serializeChainId(chainId)] = snapshot;
1981
+ }
1982
+ return serializedSnapshots;
744
1983
  }
745
- function sortAscChainStatusesByStartBlock(chains) {
746
- chains.sort(
747
- ([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
748
- );
749
- return chains;
1984
+ function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
1985
+ switch (indexingStatus.omnichainStatus) {
1986
+ case OmnichainIndexingStatusIds.Unstarted:
1987
+ return {
1988
+ omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
1989
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1990
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1991
+ };
1992
+ case OmnichainIndexingStatusIds.Backfill:
1993
+ return {
1994
+ omnichainStatus: OmnichainIndexingStatusIds.Backfill,
1995
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1996
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1997
+ };
1998
+ case OmnichainIndexingStatusIds.Completed: {
1999
+ return {
2000
+ omnichainStatus: OmnichainIndexingStatusIds.Completed,
2001
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
2002
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
2003
+ };
2004
+ }
2005
+ case OmnichainIndexingStatusIds.Following:
2006
+ return {
2007
+ omnichainStatus: OmnichainIndexingStatusIds.Following,
2008
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
2009
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
2010
+ };
2011
+ }
750
2012
  }
751
2013
 
752
- // src/ensindexer/indexing-status/zod-schemas.ts
753
- var makeChainIndexingConfigSchema = (valueLabel = "Value") => z3.discriminatedUnion("strategy", [
754
- z3.strictObject({
755
- strategy: z3.literal(ChainIndexingStrategyIds.Indefinite),
756
- startBlock: makeBlockRefSchema(valueLabel),
757
- endBlock: z3.null()
758
- }),
759
- z3.strictObject({
760
- strategy: z3.literal(ChainIndexingStrategyIds.Definite),
761
- startBlock: makeBlockRefSchema(valueLabel),
762
- endBlock: makeBlockRefSchema(valueLabel)
763
- })
764
- ]);
765
- var makeChainIndexingUnstartedStatusSchema = (valueLabel = "Value") => z3.strictObject({
766
- status: z3.literal(ChainIndexingStatusIds.Unstarted),
767
- config: makeChainIndexingConfigSchema(valueLabel)
768
- }).refine(
769
- ({ config }) => config.endBlock === null || isBeforeOrEqualTo(config.startBlock, config.endBlock),
770
- {
771
- error: `config.startBlock must be before or same as config.endBlock.`
772
- }
773
- );
774
- var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictObject({
775
- status: z3.literal(ChainIndexingStatusIds.Backfill),
776
- config: makeChainIndexingConfigSchema(valueLabel),
777
- latestIndexedBlock: makeBlockRefSchema(valueLabel),
778
- latestSyncedBlock: makeBlockRefSchema(valueLabel),
779
- backfillEndBlock: makeBlockRefSchema(valueLabel)
780
- }).refine(
781
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
782
- {
783
- error: `config.startBlock must be before or same as latestIndexedBlock.`
784
- }
785
- ).refine(
786
- ({ latestIndexedBlock, latestSyncedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestSyncedBlock),
787
- {
788
- error: `latestIndexedBlock must be before or same as latestSyncedBlock.`
789
- }
790
- ).refine(
791
- ({ latestSyncedBlock, backfillEndBlock }) => isBeforeOrEqualTo(latestSyncedBlock, backfillEndBlock),
792
- {
793
- error: `latestSyncedBlock must be before or same as backfillEndBlock.`
794
- }
795
- ).refine(
796
- ({ config, backfillEndBlock }) => config.endBlock === null || isEqualTo(backfillEndBlock, config.endBlock),
797
- {
798
- error: `backfillEndBlock must be the same as config.endBlock.`
799
- }
800
- );
801
- var makeChainIndexingFollowingStatusSchema = (valueLabel = "Value") => z3.strictObject({
802
- status: z3.literal(ChainIndexingStatusIds.Following),
803
- config: z3.strictObject({
804
- strategy: z3.literal(ChainIndexingStrategyIds.Indefinite),
805
- startBlock: makeBlockRefSchema(valueLabel)
806
- }),
807
- latestIndexedBlock: makeBlockRefSchema(valueLabel),
808
- latestKnownBlock: makeBlockRefSchema(valueLabel),
809
- approxRealtimeDistance: makeDurationSchema(valueLabel)
810
- }).refine(
811
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
812
- {
813
- error: `config.startBlock must be before or same as latestIndexedBlock.`
2014
+ // src/api/registrar-actions/prerequisites.ts
2015
+ var registrarActionsPrerequisites = Object.freeze({
2016
+ /**
2017
+ * Required plugins to enable Registrar Actions API routes.
2018
+ *
2019
+ * 1. `registrars` plugin is required so that data in the `registrarActions`
2020
+ * table is populated.
2021
+ * 2. `subgraph`, `basenames`, and `lineanames` are required to get the data
2022
+ * for the name associated with each registrar action.
2023
+ * 3. In theory not all of `subgraph`, `basenames`, and `lineanames` plugins
2024
+ * might be required. Ex: At least one, but the current logic in
2025
+ * the `registrars` plugin always indexes registrar actions across
2026
+ * Ethnames (subgraph), Basenames, and Lineanames and therefore we need to
2027
+ * ensure each value in the registrar actions table has
2028
+ * an associated record in the domains table.
2029
+ */
2030
+ requiredPlugins: [
2031
+ "subgraph" /* Subgraph */,
2032
+ "basenames" /* Basenames */,
2033
+ "lineanames" /* Lineanames */,
2034
+ "registrars" /* Registrars */
2035
+ ],
2036
+ /**
2037
+ * Check if provided ENSApiPublicConfig supports the Registrar Actions API.
2038
+ */
2039
+ hasEnsIndexerConfigSupport(config) {
2040
+ return registrarActionsPrerequisites.requiredPlugins.every(
2041
+ (plugin) => config.plugins.includes(plugin)
2042
+ );
2043
+ },
2044
+ /**
2045
+ * Required Indexing Status IDs
2046
+ *
2047
+ * Database indexes are created by the time the omnichain indexing status
2048
+ * is either `completed` or `following`.
2049
+ */
2050
+ supportedIndexingStatusIds: [
2051
+ OmnichainIndexingStatusIds.Completed,
2052
+ OmnichainIndexingStatusIds.Following
2053
+ ],
2054
+ /**
2055
+ * Check if provided indexing status supports the Registrar Actions API.
2056
+ */
2057
+ hasIndexingStatusSupport(omnichainIndexingStatusId) {
2058
+ return registrarActionsPrerequisites.supportedIndexingStatusIds.some(
2059
+ (supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
2060
+ );
814
2061
  }
815
- ).refine(
816
- ({ latestIndexedBlock, latestKnownBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock),
817
- {
818
- error: `latestIndexedBlock must be before or same as latestKnownBlock.`
2062
+ });
2063
+
2064
+ // src/registrars/ethnames-subregistry.ts
2065
+ import { DatasourceNames as DatasourceNames2, maybeGetDatasource as maybeGetDatasource2 } from "@ensnode/datasources";
2066
+ function getEthnamesSubregistryId(namespace) {
2067
+ const datasource = maybeGetDatasource2(namespace, DatasourceNames2.ENSRoot);
2068
+ if (!datasource) {
2069
+ throw new Error(`Datasource not found for ${namespace} ${DatasourceNames2.ENSRoot}`);
819
2070
  }
820
- );
821
- var makeChainIndexingCompletedStatusSchema = (valueLabel = "Value") => z3.strictObject({
822
- status: z3.literal(ChainIndexingStatusIds.Completed),
823
- config: z3.strictObject({
824
- strategy: z3.literal(ChainIndexingStrategyIds.Definite),
825
- startBlock: makeBlockRefSchema(valueLabel),
826
- endBlock: makeBlockRefSchema(valueLabel)
827
- }),
828
- latestIndexedBlock: makeBlockRefSchema(valueLabel)
829
- }).refine(
830
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
831
- {
832
- error: `config.startBlock must be before or same as latestIndexedBlock.`
2071
+ const address = datasource.contracts.BaseRegistrar?.address;
2072
+ if (address === void 0 || Array.isArray(address)) {
2073
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
833
2074
  }
834
- ).refine(
835
- ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, config.endBlock),
836
- {
837
- error: `latestIndexedBlock must be before or same as config.endBlock.`
2075
+ return {
2076
+ chainId: datasource.chain.id,
2077
+ address
2078
+ };
2079
+ }
2080
+
2081
+ // src/api/serialize.ts
2082
+ function serializeIndexingStatusResponse(response) {
2083
+ switch (response.responseCode) {
2084
+ case IndexingStatusResponseCodes.Ok:
2085
+ return {
2086
+ responseCode: response.responseCode,
2087
+ realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
2088
+ };
2089
+ case IndexingStatusResponseCodes.Error:
2090
+ return response;
838
2091
  }
839
- );
840
- var makeChainIndexingStatusSchema = (valueLabel = "Value") => z3.discriminatedUnion("status", [
841
- makeChainIndexingUnstartedStatusSchema(valueLabel),
842
- makeChainIndexingBackfillStatusSchema(valueLabel),
843
- makeChainIndexingFollowingStatusSchema(valueLabel),
844
- makeChainIndexingCompletedStatusSchema(valueLabel)
845
- ]);
846
- var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z3.record(makeChainIdStringSchema(), makeChainIndexingStatusSchema(valueLabel), {
847
- error: "Chains configuration must be an object mapping valid chain IDs to their configs."
848
- }).transform((serializedChainsIndexingStatus) => {
849
- const chainsIndexingStatus = /* @__PURE__ */ new Map();
850
- for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
851
- chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
2092
+ }
2093
+ function serializeNamedRegistrarAction({
2094
+ action,
2095
+ name
2096
+ }) {
2097
+ return {
2098
+ action: serializeRegistrarAction(action),
2099
+ name
2100
+ };
2101
+ }
2102
+ function serializeRegistrarActionsResponse(response) {
2103
+ switch (response.responseCode) {
2104
+ case RegistrarActionsResponseCodes.Ok:
2105
+ return {
2106
+ responseCode: response.responseCode,
2107
+ registrarActions: response.registrarActions.map(serializeNamedRegistrarAction)
2108
+ };
2109
+ case RegistrarActionsResponseCodes.Error:
2110
+ return response;
852
2111
  }
853
- return chainsIndexingStatus;
854
- });
855
- var makeUnstartedOverallStatusSchema = (valueLabel) => z3.strictObject({
856
- overallStatus: z3.literal(OverallIndexingStatusIds.Unstarted),
857
- chains: makeChainIndexingStatusesSchema(valueLabel).refine(
858
- (chains) => checkChainIndexingStatusesForUnstartedOverallStatus(Array.from(chains.values())),
859
- {
860
- error: `${valueLabel} at least one chain must be in "unstarted" status and
861
- each chain has to have a status of either "unstarted", or "completed"`
862
- }
863
- ).transform((chains) => chains)
864
- }).refine(
865
- (indexingStatus) => {
866
- const chains = Array.from(indexingStatus.chains.values());
867
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
868
- },
869
- { error: `${valueLabel} is an invalid overallStatus.` }
870
- );
871
- var makeBackfillOverallStatusSchema = (valueLabel) => z3.strictObject({
872
- overallStatus: z3.literal(OverallIndexingStatusIds.Backfill),
873
- chains: makeChainIndexingStatusesSchema(valueLabel).refine(
874
- (chains) => checkChainIndexingStatusesForBackfillOverallStatus(Array.from(chains.values())),
875
- {
876
- error: `${valueLabel} at least one chain must be in "backfill" status and
877
- each chain has to have a status of either "unstarted", "backfill" or "completed"`
878
- }
879
- ).transform((chains) => chains),
880
- omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
881
- }).refine(
882
- (indexingStatus) => {
883
- const chains = Array.from(indexingStatus.chains.values());
884
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
885
- },
886
- { error: `${valueLabel} is an invalid overallStatus.` }
887
- ).refine(
888
- (indexingStatus) => {
889
- const chains = Array.from(indexingStatus.chains.values());
890
- const standbyChainStartBlocks = getStandbyChains(chains).map(
891
- (chain) => chain.config.startBlock.timestamp
892
- );
893
- const standbyChainEarliestStartBlocks = Math.min(...standbyChainStartBlocks);
894
- return indexingStatus.omnichainIndexingCursor <= standbyChainEarliestStartBlocks;
895
- },
896
- {
897
- error: "omnichainIndexingCursor must be lower than or equal to the earliest config.startBlock across all standby chains"
2112
+ }
2113
+
2114
+ // src/client-error.ts
2115
+ var ClientError = class _ClientError extends Error {
2116
+ details;
2117
+ constructor(message, details) {
2118
+ super(message);
2119
+ this.name = "ClientError";
2120
+ this.details = details;
898
2121
  }
899
- );
900
- var makeCompletedOverallStatusSchema = (valueLabel) => z3.strictObject({
901
- overallStatus: z3.literal(OverallIndexingStatusIds.Completed),
902
- chains: makeChainIndexingStatusesSchema(valueLabel).refine(
903
- (chains) => checkChainIndexingStatusesForCompletedOverallStatus(Array.from(chains.values())),
904
- {
905
- error: `${valueLabel} all chains must have "completed" status`
906
- }
907
- ).transform((chains) => chains)
908
- }).refine(
909
- (indexingStatus) => {
910
- const chains = Array.from(indexingStatus.chains.values());
911
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
912
- },
913
- { error: `${valueLabel} is an invalid overallStatus.` }
914
- );
915
- var makeFollowingOverallStatusSchema = (valueLabel) => z3.strictObject({
916
- overallStatus: z3.literal(OverallIndexingStatusIds.Following),
917
- chains: makeChainIndexingStatusesSchema(valueLabel),
918
- overallApproxRealtimeDistance: makeDurationSchema(valueLabel),
919
- omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
920
- }).refine(
921
- (indexingStatus) => {
922
- const chains = Array.from(indexingStatus.chains.values());
923
- return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
924
- },
925
- { error: `${valueLabel} is an invalid overallStatus.` }
926
- ).refine(
927
- (indexingStatus) => checkChainIndexingStatusesForFollowingOverallStatus(
928
- Array.from(indexingStatus.chains.values())
2122
+ static fromErrorResponse({ message, details }) {
2123
+ return new _ClientError(message, details);
2124
+ }
2125
+ };
2126
+
2127
+ // src/ensanalytics/deserialize.ts
2128
+ import { prettifyError as prettifyError5 } from "zod/v4";
2129
+
2130
+ // src/ensanalytics/zod-schemas.ts
2131
+ import z8 from "zod/v4";
2132
+
2133
+ // src/ensanalytics/types.ts
2134
+ var ITEMS_PER_PAGE_DEFAULT = 25;
2135
+ var ITEMS_PER_PAGE_MAX = 100;
2136
+ var PaginatedAggregatedReferrersResponseCodes = {
2137
+ /**
2138
+ * Represents that the aggregated referrers data is available.
2139
+ * @note The response may contain an empty array for the first page if there are no qualified referrers.
2140
+ * When the array is empty, total will be 0, page will be 1, and both hasNext and hasPrev will be false.
2141
+ */
2142
+ Ok: "ok",
2143
+ /**
2144
+ * Represents that the aggregated referrers data is not available.
2145
+ */
2146
+ Error: "error"
2147
+ };
2148
+
2149
+ // src/ensanalytics/zod-schemas.ts
2150
+ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => z8.object({
2151
+ referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
2152
+ totalReferrals: makePositiveIntegerSchema(`${valueLabel}.totalReferrals`),
2153
+ totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`)
2154
+ });
2155
+ var makeAggregatedReferrerMetricsContributionSchema = (valueLabel = "AggregatedReferrerMetricsContribution") => makeAggregatedReferrerMetricsSchema(valueLabel).extend({
2156
+ totalReferralsContribution: z8.number({
2157
+ error: `${valueLabel}.totalReferralsContribution must be a number`
2158
+ }).min(0, `${valueLabel}.totalReferralsContribution must be >= 0`).max(1, `${valueLabel}.totalReferralsContribution must be <= 1`),
2159
+ totalIncrementalDurationContribution: z8.number({
2160
+ error: `${valueLabel}.totalIncrementalDurationContribution must be a number`
2161
+ }).min(0, `${valueLabel}.totalIncrementalDurationContribution must be >= 0`).max(1, `${valueLabel}.totalIncrementalDurationContribution must be <= 1`)
2162
+ });
2163
+ var makePaginationParamsSchema = (valueLabel = "PaginationParams") => z8.object({
2164
+ page: makePositiveIntegerSchema(`${valueLabel}.page`).default(1),
2165
+ itemsPerPage: makePositiveIntegerSchema(`${valueLabel}.itemsPerPage`).max(ITEMS_PER_PAGE_MAX, `${valueLabel}.itemsPerPage must not exceed ${ITEMS_PER_PAGE_MAX}`).default(ITEMS_PER_PAGE_DEFAULT)
2166
+ });
2167
+ var makePaginatedAggregatedReferrersSchema = (valueLabel = "PaginatedAggregatedReferrers") => z8.object({
2168
+ referrers: z8.array(
2169
+ makeAggregatedReferrerMetricsContributionSchema(`${valueLabel}.referrers[item]`)
929
2170
  ),
930
- {
931
- error: `${valueLabel} at least one chain must be in "following" status`
2171
+ total: makeNonNegativeIntegerSchema(`${valueLabel}.total`),
2172
+ paginationParams: makePaginationParamsSchema(`${valueLabel}.paginationParams`),
2173
+ hasNext: z8.boolean(),
2174
+ hasPrev: z8.boolean(),
2175
+ updatedAt: makeUnixTimestampSchema(`${valueLabel}.updatedAt`)
2176
+ }).check((ctx) => {
2177
+ const { paginationParams, hasNext, hasPrev, total } = ctx.value;
2178
+ const expectedHasPrev = paginationParams.page > 1;
2179
+ if (hasPrev !== expectedHasPrev) {
2180
+ ctx.issues.push({
2181
+ code: "custom",
2182
+ message: `${valueLabel}.hasPrev must be ${expectedHasPrev} when page is ${paginationParams.page}`,
2183
+ input: ctx.value
2184
+ });
932
2185
  }
933
- ).refine(
934
- (indexingStatus) => {
935
- const chains = Array.from(indexingStatus.chains.values());
936
- return getOverallApproxRealtimeDistance(chains) === indexingStatus.overallApproxRealtimeDistance;
937
- },
938
- { error: `${valueLabel} is an invalid overallApproxRealtimeDistance.` }
939
- ).refine(
940
- (indexingStatus) => {
941
- const chains = Array.from(indexingStatus.chains.values());
942
- const standbyChainStartBlocks = getStandbyChains(chains).map(
943
- (chain) => chain.config.startBlock.timestamp
944
- );
945
- const standbyChainEarliestStartBlocks = Math.min(...standbyChainStartBlocks);
946
- return indexingStatus.omnichainIndexingCursor <= standbyChainEarliestStartBlocks;
947
- },
948
- {
949
- error: "omnichainIndexingCursor must be lower than or equal to the earliest config.startBlock across all standby chains"
2186
+ const endIndex = paginationParams.page * paginationParams.itemsPerPage;
2187
+ const expectedHasNext = endIndex < total;
2188
+ if (hasNext !== expectedHasNext) {
2189
+ ctx.issues.push({
2190
+ code: "custom",
2191
+ message: `${valueLabel}.hasNext must be ${expectedHasNext} when page=${paginationParams.page}, itemsPerPage=${paginationParams.itemsPerPage}, total=${total}`,
2192
+ input: ctx.value
2193
+ });
950
2194
  }
951
- );
952
- var makeErrorSchemaOverallStatusSchema = (valueLabel) => z3.strictObject({
953
- overallStatus: z3.literal(OverallIndexingStatusIds.IndexerError)
954
2195
  });
955
- var makeENSIndexerIndexingStatusSchema = (valueLabel = "ENSIndexerIndexingStatus") => z3.discriminatedUnion("overallStatus", [
956
- makeUnstartedOverallStatusSchema(valueLabel),
957
- makeBackfillOverallStatusSchema(valueLabel),
958
- makeCompletedOverallStatusSchema(valueLabel),
959
- makeFollowingOverallStatusSchema(valueLabel),
960
- makeErrorSchemaOverallStatusSchema(valueLabel)
2196
+ var makePaginatedAggregatedReferrersResponseOkSchema = (valueLabel = "PaginatedAggregatedReferrersResponse") => z8.object({
2197
+ responseCode: z8.literal(PaginatedAggregatedReferrersResponseCodes.Ok),
2198
+ data: makePaginatedAggregatedReferrersSchema(`${valueLabel}.data`)
2199
+ });
2200
+ var makePaginatedAggregatedReferrersResponseErrorSchema = (_valueLabel = "PaginatedAggregatedReferrersResponse") => z8.object({
2201
+ responseCode: z8.literal(PaginatedAggregatedReferrersResponseCodes.Error),
2202
+ error: z8.string(),
2203
+ errorMessage: z8.string()
2204
+ });
2205
+ var makePaginatedAggregatedReferrersResponseSchema = (valueLabel = "PaginatedAggregatedReferrersResponse") => z8.union([
2206
+ makePaginatedAggregatedReferrersResponseOkSchema(valueLabel),
2207
+ makePaginatedAggregatedReferrersResponseErrorSchema(valueLabel)
961
2208
  ]);
962
2209
 
963
- // src/ensindexer/indexing-status/deserialize.ts
964
- function deserializeENSIndexerIndexingStatus(maybeStatus, valueLabel) {
965
- const schema = makeENSIndexerIndexingStatusSchema(valueLabel);
966
- const parsed = schema.safeParse(maybeStatus);
2210
+ // src/ensanalytics/deserialize.ts
2211
+ function deserializePaginatedAggregatedReferrersResponse(maybeResponse, valueLabel) {
2212
+ const schema = makePaginatedAggregatedReferrersResponseSchema(valueLabel);
2213
+ const parsed = schema.safeParse(maybeResponse);
967
2214
  if (parsed.error) {
968
2215
  throw new Error(
969
- `Cannot deserialize ENSIndexerIndexingStatus:
970
- ${prettifyError3(parsed.error)}
2216
+ `Cannot deserialize PaginatedAggregatedReferrersResponse:
2217
+ ${prettifyError5(parsed.error)}
971
2218
  `
972
2219
  );
973
2220
  }
974
2221
  return parsed.data;
975
2222
  }
976
2223
 
977
- // src/ensindexer/indexing-status/serialize.ts
978
- function serializeChainIndexingStatuses(chainIndexingStatuses) {
979
- const serializedChainsIndexingStatuses = {};
980
- for (const [chainId, chainIndexingStatus] of chainIndexingStatuses.entries()) {
981
- serializedChainsIndexingStatuses[serializeChainId(chainId)] = chainIndexingStatus;
982
- }
983
- return serializedChainsIndexingStatuses;
984
- }
985
- function serializeENSIndexerIndexingStatus(indexingStatus) {
986
- switch (indexingStatus.overallStatus) {
987
- case OverallIndexingStatusIds.IndexerError:
988
- return {
989
- overallStatus: OverallIndexingStatusIds.IndexerError
990
- };
991
- case OverallIndexingStatusIds.Unstarted:
992
- return {
993
- overallStatus: OverallIndexingStatusIds.Unstarted,
994
- chains: serializeChainIndexingStatuses(indexingStatus.chains)
995
- };
996
- case OverallIndexingStatusIds.Backfill:
997
- return {
998
- overallStatus: OverallIndexingStatusIds.Backfill,
999
- chains: serializeChainIndexingStatuses(indexingStatus.chains),
1000
- omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1001
- };
1002
- case OverallIndexingStatusIds.Completed: {
1003
- return {
1004
- overallStatus: OverallIndexingStatusIds.Completed,
1005
- chains: serializeChainIndexingStatuses(indexingStatus.chains)
1006
- };
1007
- }
1008
- case OverallIndexingStatusIds.Following:
1009
- return {
1010
- overallStatus: OverallIndexingStatusIds.Following,
1011
- chains: serializeChainIndexingStatuses(indexingStatus.chains),
1012
- overallApproxRealtimeDistance: indexingStatus.overallApproxRealtimeDistance,
1013
- omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1014
- };
2224
+ // src/ensanalytics/serialize.ts
2225
+ function serializePaginatedAggregatedReferrersResponse(response) {
2226
+ switch (response.responseCode) {
2227
+ case PaginatedAggregatedReferrersResponseCodes.Ok:
2228
+ return response;
2229
+ case PaginatedAggregatedReferrersResponseCodes.Error:
2230
+ return response;
1015
2231
  }
1016
2232
  }
1017
2233
 
1018
- // src/tracing/index.ts
1019
- var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
1020
- TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
1021
- TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
1022
- return TraceableENSProtocol2;
1023
- })(TraceableENSProtocol || {});
1024
- var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
1025
- ForwardResolutionProtocolStep2["Operation"] = "forward-resolution";
1026
- ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
1027
- ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
1028
- ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
1029
- ForwardResolutionProtocolStep2["AccelerateKnownOffchainLookupResolver"] = "accelerate-known-offchain-lookup-resolver";
1030
- ForwardResolutionProtocolStep2["AccelerateKnownOnchainStaticResolver"] = "accelerate-known-onchain-static-resolver";
1031
- ForwardResolutionProtocolStep2["RequireResolver"] = "require-resolver";
1032
- ForwardResolutionProtocolStep2["ExecuteResolveCalls"] = "execute-resolve-calls";
1033
- return ForwardResolutionProtocolStep2;
1034
- })(ForwardResolutionProtocolStep || {});
1035
- var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
1036
- ReverseResolutionProtocolStep2["Operation"] = "reverse-resolution";
1037
- ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
1038
- ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
1039
- ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
1040
- ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
1041
- return ReverseResolutionProtocolStep2;
1042
- })(ReverseResolutionProtocolStep || {});
1043
- var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
1044
- var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
1045
- var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
1046
- var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
1047
-
1048
- // src/api/helpers.ts
1049
- import { prettifyError as prettifyError4 } from "zod/v4";
2234
+ // src/ensapi/config/deserialize.ts
2235
+ import { prettifyError as prettifyError6, ZodError } from "zod/v4";
1050
2236
 
1051
- // src/api/zod-schemas.ts
1052
- import z4 from "zod/v4";
1053
- var ErrorResponseSchema = z4.object({
1054
- message: z4.string(),
1055
- details: z4.optional(z4.unknown())
2237
+ // src/ensapi/config/zod-schemas.ts
2238
+ import { z as z9 } from "zod/v4";
2239
+ var TheGraphCannotFallbackReasonSchema = z9.enum({
2240
+ NotSubgraphCompatible: "not-subgraph-compatible",
2241
+ NoApiKey: "no-api-key",
2242
+ NoSubgraphUrl: "no-subgraph-url"
1056
2243
  });
2244
+ var TheGraphFallbackSchema = z9.strictObject({
2245
+ canFallback: z9.boolean(),
2246
+ reason: TheGraphCannotFallbackReasonSchema.nullable()
2247
+ });
2248
+ function makeENSApiPublicConfigSchema(valueLabel) {
2249
+ const label = valueLabel ?? "ENSApiPublicConfig";
2250
+ return z9.strictObject({
2251
+ version: z9.string().min(1, `${label}.version must be a non-empty string`),
2252
+ theGraphFallback: TheGraphFallbackSchema,
2253
+ ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
2254
+ });
2255
+ }
1057
2256
 
1058
- // src/api/helpers.ts
1059
- function deserializeErrorResponse(maybeErrorResponse) {
1060
- const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
1061
- if (parsed.error) {
1062
- throw new Error(`Cannot deserialize ErrorResponse:
1063
- ${prettifyError4(parsed.error)}
2257
+ // src/ensapi/config/deserialize.ts
2258
+ function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
2259
+ const schema = makeENSApiPublicConfigSchema(valueLabel);
2260
+ try {
2261
+ return schema.parse(maybeConfig);
2262
+ } catch (error) {
2263
+ if (error instanceof ZodError) {
2264
+ throw new Error(`Cannot deserialize ENSApiPublicConfig:
2265
+ ${prettifyError6(error)}
1064
2266
  `);
2267
+ }
2268
+ throw error;
1065
2269
  }
1066
- return parsed.data;
1067
2270
  }
1068
2271
 
1069
- // src/api/types.ts
1070
- var IndexingStatusResponseCodes = {
1071
- IndexerError: 512,
1072
- RequestedDistanceNotAchievedError: 513
1073
- };
1074
-
1075
- // src/client-error.ts
1076
- var ClientError = class _ClientError extends Error {
1077
- details;
1078
- constructor(message, details) {
1079
- super(message);
1080
- this.name = "ClientError";
1081
- this.details = details;
1082
- }
1083
- static fromErrorResponse({ message, details }) {
1084
- return new _ClientError(message, details);
1085
- }
1086
- };
2272
+ // src/ensapi/config/serialize.ts
2273
+ function serializeENSApiPublicConfig(config) {
2274
+ const { version, theGraphFallback, ensIndexerPublicConfig } = config;
2275
+ return {
2276
+ version,
2277
+ theGraphFallback,
2278
+ ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
2279
+ };
2280
+ }
1087
2281
 
1088
2282
  // src/client.ts
1089
2283
  var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
@@ -1162,9 +2356,10 @@ var ENSNodeClient = class _ENSNodeClient {
1162
2356
  /**
1163
2357
  * Resolves the primary name of a specified address (Reverse Resolution) on a specific chain.
1164
2358
  *
1165
- * If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
1166
- * the Default Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to
1167
- * determine the `address`'s Default Name directly.
2359
+ * If the chainId-specific Primary Name is not defined, but the `address` specifies a valid
2360
+ * [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default
2361
+ * Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to determine the
2362
+ * `address`'s Default Name directly.
1168
2363
  *
1169
2364
  * The returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
1170
2365
  * If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.
@@ -1207,13 +2402,14 @@ var ENSNodeClient = class _ENSNodeClient {
1207
2402
  /**
1208
2403
  * Resolves the primary names of a specified address across multiple chains.
1209
2404
  *
1210
- * If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
1211
- * the Default Name will be returned for all chainIds for which there is not a chain-specific
1212
- * Primary Name. To avoid misuse, you _may not_ query the Default EVM Chain Id (`0`) directly, and
1213
- * should rely on the aforementioned per-chain defaulting behavior.
2405
+ * For each Primary Name, if the chainId-specific Primary Name is not defined, but the `address`
2406
+ * specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
2407
+ * the Default Name will be returned. You _may not_ query the Default EVM Chain Id (`0`) directly,
2408
+ * and should rely on the aforementioned per-chain defaulting behavior.
1214
2409
  *
1215
2410
  * Each returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
1216
- * If the primary name set for the address on any chain is not normalized, `null` is returned for that chain as if no primary name was set.
2411
+ * If the primary name set for the address on any chain is not normalized, `null` is returned for
2412
+ * that chain as if no primary name was set.
1217
2413
  *
1218
2414
  * @param address The Address whose Primary Names to resolve
1219
2415
  * @param options additional options
@@ -1231,12 +2427,12 @@ var ENSNodeClient = class _ENSNodeClient {
1231
2427
  *
1232
2428
  * console.log(names);
1233
2429
  * // {
1234
- * // "1": "gregskril.eth",
1235
- * // "10": "gregskril.eth",
1236
- * // "8453": "greg.base.eth", // base-specific Primary Name!
1237
- * // "42161": "gregskril.eth",
1238
- * // "59144": "gregskril.eth",
1239
- * // "534352": "gregskril.eth"
2430
+ * // "1": "gregskril.eth", // Default Primary Name
2431
+ * // "10": "gregskril.eth", // Default Primary Name
2432
+ * // "8453": "greg.base.eth", // Base-specific Primary Name!
2433
+ * // "42161": "gregskril.eth", // Default Primary Name
2434
+ * // "59144": "gregskril.eth", // Default Primary Name
2435
+ * // "534352": "gregskril.eth" // Default Primary Name
1240
2436
  * // }
1241
2437
  *
1242
2438
  * // Resolve the address' Primary Names on specific chain Ids
@@ -1286,33 +2482,19 @@ var ENSNodeClient = class _ENSNodeClient {
1286
2482
  const errorResponse = deserializeErrorResponse(responseData);
1287
2483
  throw new Error(`Fetching ENSNode Config Failed: ${errorResponse.message}`);
1288
2484
  }
1289
- return deserializeENSIndexerPublicConfig(responseData);
2485
+ return deserializeENSApiPublicConfig(responseData);
1290
2486
  }
1291
2487
  /**
1292
2488
  * Fetch ENSNode Indexing Status
1293
2489
  *
1294
- * Fetch the ENSNode's multichain indexing status.
1295
- *
1296
- * @param options additional options
1297
- * @param options.maxRealtimeDistance the max allowed distance between the
1298
- * latest indexed block of each chain and the "tip" of all indexed chains.
1299
- * Setting this parameter influences the HTTP response code as follows:
1300
- * - Success (200 OK): The latest indexed block of each chain is within the
1301
- * requested distance from realtime.
1302
- * - Service Unavailable (503): The latest indexed block of each chain is NOT
1303
- * within the requested distance from realtime.
1304
- *
1305
2490
  * @returns {IndexingStatusResponse}
1306
2491
  *
1307
2492
  * @throws if the ENSNode request fails
1308
2493
  * @throws if the ENSNode API returns an error response
1309
2494
  * @throws if the ENSNode response breaks required invariants
1310
2495
  */
1311
- async indexingStatus(options) {
2496
+ async indexingStatus() {
1312
2497
  const url = new URL(`/api/indexing-status`, this.options.url);
1313
- if (typeof options?.maxRealtimeDistance !== "undefined") {
1314
- url.searchParams.set("maxRealtimeDistance", `${options.maxRealtimeDistance}`);
1315
- }
1316
2498
  const response = await fetch(url);
1317
2499
  let responseData;
1318
2500
  try {
@@ -1321,172 +2503,407 @@ var ENSNodeClient = class _ENSNodeClient {
1321
2503
  throw new Error("Malformed response data: invalid JSON");
1322
2504
  }
1323
2505
  if (!response.ok) {
1324
- switch (response.status) {
1325
- case IndexingStatusResponseCodes.IndexerError: {
1326
- console.error("Indexing Status API: indexer error");
1327
- return deserializeENSIndexerIndexingStatus(
1328
- responseData
1329
- );
1330
- }
1331
- case IndexingStatusResponseCodes.RequestedDistanceNotAchievedError: {
1332
- console.error(
1333
- "Indexing Status API: Requested realtime indexing distance not achieved error"
1334
- );
1335
- return deserializeENSIndexerIndexingStatus(
1336
- responseData
1337
- );
1338
- }
1339
- default: {
1340
- const errorResponse = deserializeErrorResponse(responseData);
1341
- throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
1342
- }
2506
+ let errorResponse;
2507
+ try {
2508
+ errorResponse = deserializeErrorResponse(responseData);
2509
+ } catch {
2510
+ console.log("Indexing Status API: handling a known indexing status server error.");
2511
+ }
2512
+ if (typeof errorResponse !== "undefined") {
2513
+ throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
1343
2514
  }
1344
2515
  }
1345
- return deserializeENSIndexerIndexingStatus(
2516
+ return deserializeIndexingStatusResponse(responseData);
2517
+ }
2518
+ /**
2519
+ * Fetch Paginated Aggregated Referrers
2520
+ *
2521
+ * Retrieves a paginated list of aggregated referrer metrics with contribution percentages.
2522
+ * Each referrer's contribution is calculated as a percentage of the grand totals across all referrers.
2523
+ *
2524
+ * @param request - Pagination parameters
2525
+ * @param request.page - The page number to retrieve (1-indexed, default: 1)
2526
+ * @param request.itemsPerPage - Number of items per page (default: 25, max: 100)
2527
+ * @returns {PaginatedAggregatedReferrersResponse}
2528
+ *
2529
+ * @throws if the ENSNode request fails
2530
+ * @throws if the ENSNode API returns an error response
2531
+ * @throws if the ENSNode response breaks required invariants
2532
+ *
2533
+ * @example
2534
+ * ```typescript
2535
+ * // Get first page with default page size (25 items)
2536
+ * const response = await client.getAggregatedReferrers();
2537
+ * if (response.responseCode === 'ok') {
2538
+ * console.log(response.data.referrers);
2539
+ * console.log(`Page ${response.data.paginationParams.page} of ${Math.ceil(response.data.total / response.data.paginationParams.itemsPerPage)}`);
2540
+ * }
2541
+ * ```
2542
+ *
2543
+ * @example
2544
+ * ```typescript
2545
+ * // Get second page with 50 items per page
2546
+ * const response = await client.getAggregatedReferrers({ page: 2, itemsPerPage: 50 });
2547
+ * ```
2548
+ */
2549
+ async getAggregatedReferrers(request) {
2550
+ const url = new URL(`/ensanalytics/aggregated-referrers`, this.options.url);
2551
+ if (request?.page) url.searchParams.set("page", request.page.toString());
2552
+ if (request?.itemsPerPage)
2553
+ url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
2554
+ const response = await fetch(url);
2555
+ let responseData;
2556
+ try {
2557
+ responseData = await response.json();
2558
+ } catch {
2559
+ throw new Error("Malformed response data: invalid JSON");
2560
+ }
2561
+ return deserializePaginatedAggregatedReferrersResponse(
1346
2562
  responseData
1347
2563
  );
1348
2564
  }
2565
+ /**
2566
+ * Fetch ENSNode Registrar Actions
2567
+ *
2568
+ * @param {RegistrarActionsRequestFilter} request.filter is
2569
+ * an optional request filter configuration.
2570
+ * @param {number} request.limit sets the maximum count of results in the response.
2571
+ * @param {RegistrarActionsRequestOrder} request.order sets the order of
2572
+ * results in the response by field and direction.
2573
+ * @returns {RegistrarActionsResponse}
2574
+ *
2575
+ * @throws if the ENSNode request fails
2576
+ * @throws if the ENSNode API returns an error response
2577
+ * @throws if the ENSNode response breaks required invariants
2578
+ *
2579
+ * @example
2580
+ * ```ts
2581
+ * import {
2582
+ * registrarActionsFilter,,
2583
+ * ENSNodeClient,
2584
+ * } from "@ensnode/ensnode-sdk";
2585
+ * import { namehash } from "viem/ens";
2586
+ *
2587
+ * const client: ENSNodeClient;
2588
+ *
2589
+ * // get latest registrar action records across all indexed subregistries
2590
+ * // NOTE: when no `limit` value is passed,
2591
+ * // the default RESPONSE_ITEMS_PER_PAGE_DEFAULT applies.
2592
+ * const registrarActions = await client.registrarActions();
2593
+ *
2594
+ * // get latest 5 registrar action records across all indexed subregistries
2595
+ * // NOTE: when a `limit` value is passed, it must be lower than or equal to
2596
+ * // the RESPONSE_ITEMS_PER_PAGE_MAX value.
2597
+ * const registrarActions = await client.registrarActions({
2598
+ * limit: 5,
2599
+ * });
2600
+ *
2601
+ * // get latest registrar action records associated with
2602
+ * // subregistry managing `eth` name
2603
+ * await client.registrarActions({
2604
+ * filters: [registrarActionsFilter.byParentNode(namehash('eth'))],
2605
+ * });
2606
+ *
2607
+ * // get latest registrar action records which include referral info
2608
+ * await client.registrarActions({
2609
+ * filters: [registrarActionsFilter.withReferral(true)],
2610
+ * });
2611
+ *
2612
+ * // get latest 10 registrar action records associated with
2613
+ * // subregistry managing `base.eth` name
2614
+ * await client.registrarActions({
2615
+ * filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
2616
+ * limit: 10
2617
+ * });
2618
+ * ```
2619
+ */
2620
+ async registrarActions(request = {}) {
2621
+ const buildUrlPath = (filters) => {
2622
+ const bySubregistryNodeFilter = filters?.find(
2623
+ (f) => f.filterType === RegistrarActionsFilterTypes.BySubregistryNode
2624
+ );
2625
+ return bySubregistryNodeFilter ? new URL(`/api/registrar-actions/${bySubregistryNodeFilter.value}`, this.options.url) : new URL(`/api/registrar-actions`, this.options.url);
2626
+ };
2627
+ const buildWithReferralArg = (filters) => {
2628
+ const withReferralFilter = filters?.find(
2629
+ (f) => f.filterType === RegistrarActionsFilterTypes.WithEncodedReferral
2630
+ );
2631
+ return withReferralFilter ? { key: "withReferral", value: "true" } : null;
2632
+ };
2633
+ const buildOrderArg = (order) => {
2634
+ switch (order) {
2635
+ case RegistrarActionsOrders.LatestRegistrarActions: {
2636
+ const [field, direction] = order.split("=");
2637
+ return {
2638
+ key: `sort[${field}]`,
2639
+ value: `${direction}`
2640
+ };
2641
+ }
2642
+ }
2643
+ };
2644
+ const url = buildUrlPath(request.filters);
2645
+ if (request.order) {
2646
+ const orderArgs = buildOrderArg(request.order);
2647
+ url.searchParams.set(orderArgs.key, orderArgs.value);
2648
+ }
2649
+ if (request.itemsPerPage) {
2650
+ url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
2651
+ }
2652
+ const referralArg = buildWithReferralArg(request.filters);
2653
+ if (referralArg) {
2654
+ url.searchParams.set(referralArg.key, referralArg.value);
2655
+ }
2656
+ const response = await fetch(url);
2657
+ let responseData;
2658
+ try {
2659
+ responseData = await response.json();
2660
+ } catch {
2661
+ throw new Error("Malformed response data: invalid JSON");
2662
+ }
2663
+ if (!response.ok) {
2664
+ let errorResponse;
2665
+ try {
2666
+ errorResponse = deserializeErrorResponse(responseData);
2667
+ } catch {
2668
+ console.log("Registrar Actions API: handling a known server error.");
2669
+ }
2670
+ if (typeof errorResponse !== "undefined") {
2671
+ throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
2672
+ }
2673
+ }
2674
+ return deserializeRegistrarActionsResponse(responseData);
2675
+ }
2676
+ };
2677
+
2678
+ // src/identity/identity.ts
2679
+ import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
2680
+
2681
+ // src/identity/types.ts
2682
+ var ResolutionStatusIds = {
2683
+ /**
2684
+ * Represents that the `Identity` is not resolved yet.
2685
+ */
2686
+ Unresolved: "unresolved",
2687
+ /**
2688
+ * Represents that resolution of the `Identity` resulted in a named identity.
2689
+ */
2690
+ Named: "named",
2691
+ /**
2692
+ * Represents that resolution of the `Identity` resulted in an unnamed identity.
2693
+ */
2694
+ Unnamed: "unnamed",
2695
+ /**
2696
+ * Represents that attempted resolution of the `Identity` resulted in an error
2697
+ * and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
2698
+ */
2699
+ Unknown: "unknown"
2700
+ };
2701
+
2702
+ // src/identity/identity.ts
2703
+ function buildUnresolvedIdentity(address, namespaceId, chainId) {
2704
+ return {
2705
+ resolutionStatus: ResolutionStatusIds.Unresolved,
2706
+ chainId: chainId ?? getENSRootChainId3(namespaceId),
2707
+ address
2708
+ };
2709
+ }
2710
+ function isResolvedIdentity(identity) {
2711
+ return identity.resolutionStatus !== ResolutionStatusIds.Unresolved;
2712
+ }
2713
+
2714
+ // src/resolution/ensip19-chainid.ts
2715
+ import { mainnet as mainnet2 } from "viem/chains";
2716
+ import { getENSRootChainId as getENSRootChainId4 } from "@ensnode/datasources";
2717
+ var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
2718
+ const ensRootChainId = getENSRootChainId4(namespaceId);
2719
+ return chainId === ensRootChainId ? mainnet2.id : chainId;
2720
+ };
2721
+ var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
2722
+ return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId4(namespaceId) : chainId;
1349
2723
  };
1350
2724
 
1351
2725
  // src/resolution/resolver-records-selection.ts
1352
2726
  var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
1353
2727
 
1354
- // src/resolution/default-records-selection.ts
1355
- import {
1356
- DatasourceNames,
1357
- ENSNamespaceIds as ENSNamespaceIds2,
1358
- maybeGetDatasource
1359
- } from "@ensnode/datasources";
1360
- var getENSIP19SupportedCoinTypes = (namespace) => uniq(
1361
- [
1362
- maybeGetDatasource(namespace, DatasourceNames.ReverseResolverBase),
1363
- maybeGetDatasource(namespace, DatasourceNames.ReverseResolverLinea),
1364
- maybeGetDatasource(namespace, DatasourceNames.ReverseResolverOptimism),
1365
- maybeGetDatasource(namespace, DatasourceNames.ReverseResolverArbitrum),
1366
- maybeGetDatasource(namespace, DatasourceNames.ReverseResolverScroll)
1367
- ].filter((ds) => ds !== void 0).map((ds) => ds.chain.id)
1368
- ).map(evmChainIdToCoinType);
1369
- var TEXTS = [
1370
- "url",
1371
- "avatar",
1372
- "header",
1373
- "description",
1374
- "email",
1375
- "com.twitter",
1376
- "com.farcaster",
1377
- "com.github"
1378
- ];
1379
- var DefaultRecordsSelection = {
1380
- [ENSNamespaceIds2.Mainnet]: {
1381
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Mainnet)],
1382
- texts: TEXTS
1383
- },
1384
- [ENSNamespaceIds2.Sepolia]: {
1385
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Sepolia)],
1386
- texts: TEXTS
1387
- },
1388
- [ENSNamespaceIds2.Holesky]: {
1389
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Holesky)],
1390
- texts: TEXTS
1391
- },
1392
- [ENSNamespaceIds2.EnsTestEnv]: {
1393
- addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.EnsTestEnv)],
1394
- texts: TEXTS
1395
- }
1396
- };
2728
+ // src/tracing/index.ts
2729
+ var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
2730
+ TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
2731
+ TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
2732
+ return TraceableENSProtocol2;
2733
+ })(TraceableENSProtocol || {});
2734
+ var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
2735
+ ForwardResolutionProtocolStep2["Operation"] = "forward-resolution";
2736
+ ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
2737
+ ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
2738
+ ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
2739
+ ForwardResolutionProtocolStep2["AccelerateKnownOffchainLookupResolver"] = "accelerate-known-offchain-lookup-resolver";
2740
+ ForwardResolutionProtocolStep2["AccelerateKnownOnchainStaticResolver"] = "accelerate-known-onchain-static-resolver";
2741
+ ForwardResolutionProtocolStep2["RequireResolver"] = "require-resolver";
2742
+ ForwardResolutionProtocolStep2["ExecuteResolveCalls"] = "execute-resolve-calls";
2743
+ return ForwardResolutionProtocolStep2;
2744
+ })(ForwardResolutionProtocolStep || {});
2745
+ var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
2746
+ ReverseResolutionProtocolStep2["Operation"] = "reverse-resolution";
2747
+ ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
2748
+ ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
2749
+ ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
2750
+ ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
2751
+ return ReverseResolutionProtocolStep2;
2752
+ })(ReverseResolutionProtocolStep || {});
2753
+ var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
2754
+ var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
2755
+ var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
2756
+ var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
1397
2757
  export {
2758
+ ADDR_REVERSE_NODE,
1398
2759
  ATTR_PROTOCOL_NAME,
1399
2760
  ATTR_PROTOCOL_STEP,
1400
2761
  ATTR_PROTOCOL_STEP_RESULT,
1401
2762
  BASENAMES_NODE,
2763
+ ChainIndexingConfigTypeIds,
1402
2764
  ChainIndexingStatusIds,
1403
- ChainIndexingStrategyIds,
1404
2765
  ClientError,
1405
- DEFAULT_ENSNODE_API_URL,
2766
+ CrossChainIndexingStrategyIds,
2767
+ CurrencyIds,
1406
2768
  DEFAULT_EVM_CHAIN_ID,
1407
2769
  DEFAULT_EVM_COIN_TYPE,
1408
- DefaultRecordsSelection,
1409
2770
  ENSNamespaceIds,
1410
2771
  ENSNodeClient,
1411
2772
  ETH_COIN_TYPE,
1412
2773
  ETH_NODE,
1413
2774
  ForwardResolutionProtocolStep,
2775
+ ITEMS_PER_PAGE_DEFAULT,
2776
+ ITEMS_PER_PAGE_MAX,
1414
2777
  IndexingStatusResponseCodes,
1415
2778
  LINEANAMES_NODE,
1416
2779
  LruCache,
1417
- OverallIndexingStatusIds,
2780
+ OmnichainIndexingStatusIds,
1418
2781
  PROTOCOL_ATTRIBUTE_PREFIX,
2782
+ PaginatedAggregatedReferrersResponseCodes,
1419
2783
  PluginName,
1420
- REVERSE_ROOT_NODES,
1421
2784
  ROOT_NODE,
2785
+ RegistrarActionTypes,
2786
+ RegistrarActionsFilterTypes,
2787
+ RegistrarActionsOrders,
2788
+ RegistrarActionsResponseCodes,
2789
+ ResolutionStatusIds,
1422
2790
  ReverseResolutionProtocolStep,
2791
+ TheGraphCannotFallbackReasonSchema,
2792
+ TheGraphFallbackSchema,
1423
2793
  TraceableENSProtocol,
2794
+ TtlCache,
1424
2795
  accountIdEqual,
2796
+ addDuration,
2797
+ addPrices,
1425
2798
  addrReverseLabel,
2799
+ asLowerCaseAddress,
2800
+ beautifyName,
2801
+ bigIntToNumber,
1426
2802
  bigintToCoinType,
1427
2803
  buildEnsRainbowClientLabelSet,
1428
2804
  buildLabelSetId,
1429
2805
  buildLabelSetVersion,
1430
- checkChainIndexingStatusesForBackfillOverallStatus,
1431
- checkChainIndexingStatusesForCompletedOverallStatus,
1432
- checkChainIndexingStatusesForFollowingOverallStatus,
1433
- checkChainIndexingStatusesForUnstartedOverallStatus,
2806
+ buildUnresolvedIdentity,
2807
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
2808
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
2809
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing,
2810
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted,
1434
2811
  coinTypeReverseLabel,
1435
2812
  coinTypeToEvmChainId,
1436
2813
  createIndexingConfig,
2814
+ createRealtimeIndexingStatusProjection,
2815
+ decodeDNSEncodedLiteralName,
2816
+ decodeDNSEncodedName,
2817
+ decodeEncodedReferrer,
2818
+ deserializeAccountId,
1437
2819
  deserializeBlockNumber,
1438
2820
  deserializeBlockRef,
1439
2821
  deserializeBlockrange,
1440
2822
  deserializeChainId,
2823
+ deserializeChainIndexingStatusSnapshot,
2824
+ deserializeCrossChainIndexingStatusSnapshot,
1441
2825
  deserializeDatetime,
1442
2826
  deserializeDuration,
1443
- deserializeENSIndexerIndexingStatus,
2827
+ deserializeENSApiPublicConfig,
1444
2828
  deserializeENSIndexerPublicConfig,
1445
2829
  deserializeErrorResponse,
2830
+ deserializeIndexingStatusResponse,
2831
+ deserializeOmnichainIndexingStatusSnapshot,
2832
+ deserializePaginatedAggregatedReferrersResponse,
2833
+ deserializeRealtimeIndexingStatusProjection,
2834
+ deserializeRegistrarActionsResponse,
2835
+ deserializeUnixTimestamp,
1446
2836
  deserializeUrl,
2837
+ durationBetween,
1447
2838
  encodeLabelHash,
1448
2839
  evmChainIdToCoinType,
1449
- getActiveChains,
2840
+ getCurrencyInfo,
2841
+ getENSRootChainId,
2842
+ getEthnamesSubregistryId,
1450
2843
  getNameHierarchy,
1451
2844
  getOmnichainIndexingCursor,
1452
- getOverallApproxRealtimeDistance,
1453
- getOverallIndexingStatus,
1454
- getStandbyChains,
2845
+ getOmnichainIndexingStatus,
2846
+ getResolvePrimaryNameChainIdParam,
1455
2847
  getTimestampForHighestOmnichainKnownBlock,
1456
2848
  getTimestampForLowestOmnichainStartBlock,
1457
- interpretLiteralLabel,
1458
- interpretLiteralName,
1459
- invariant_isSubgraphCompatibleRequirements,
1460
- invariant_reverseResolversPluginNeedsResolverRecords,
1461
- isLabelIndexable,
2849
+ hasNullByte,
2850
+ interpretedLabelsToInterpretedName,
2851
+ isEncodedLabelHash,
2852
+ isHttpProtocol,
2853
+ isLabelHash,
1462
2854
  isNormalizedLabel,
1463
2855
  isNormalizedName,
2856
+ isPriceCurrencyEqual,
2857
+ isPriceEqual,
2858
+ isRegistrarActionPricingAvailable,
2859
+ isRegistrarActionReferralAvailable,
2860
+ isResolvedIdentity,
1464
2861
  isSelectionEmpty,
1465
2862
  isSubgraphCompatible,
2863
+ isWebSocketProtocol,
1466
2864
  labelHashToBytes,
1467
- makeDatabaseSchemaNameSchema,
1468
- makeDependencyInfoSchema,
1469
- makeENSIndexerPublicConfigSchema,
1470
- makeFullyPinnedLabelSetSchema,
1471
- makeIndexedChainIdsSchema,
1472
- makeLabelSetIdSchema,
1473
- makeLabelSetVersionSchema,
1474
- makePluginsListSchema,
2865
+ labelhashLiteralLabel,
2866
+ literalLabelToInterpretedLabel,
2867
+ literalLabelsToInterpretedName,
2868
+ literalLabelsToLiteralName,
2869
+ makeENSApiPublicConfigSchema,
1475
2870
  makeSubdomainNode,
1476
- maybeHealLabelByReverseAddress,
1477
2871
  parseNonNegativeInteger,
1478
2872
  parseReverseName,
2873
+ priceDai,
2874
+ priceEth,
2875
+ priceUsdc,
2876
+ registrarActionsFilter,
2877
+ registrarActionsPrerequisites,
1479
2878
  reverseName,
2879
+ serializeAccountId,
1480
2880
  serializeChainId,
1481
- serializeChainIndexingStatuses,
2881
+ serializeChainIndexingSnapshots,
2882
+ serializeCrossChainIndexingStatusSnapshotOmnichain,
1482
2883
  serializeDatetime,
1483
- serializeENSIndexerIndexingStatus,
2884
+ serializeENSApiPublicConfig,
1484
2885
  serializeENSIndexerPublicConfig,
1485
2886
  serializeIndexedChainIds,
2887
+ serializeIndexingStatusResponse,
2888
+ serializeNamedRegistrarAction,
2889
+ serializeOmnichainIndexingStatusSnapshot,
2890
+ serializePaginatedAggregatedReferrersResponse,
2891
+ serializePrice,
2892
+ serializePriceEth,
2893
+ serializeRealtimeIndexingStatusProjection,
2894
+ serializeRegistrarAction,
2895
+ serializeRegistrarActionPricing,
2896
+ serializeRegistrarActionsResponse,
2897
+ serializeRegistrationLifecycle,
2898
+ serializeSubregistry,
1486
2899
  serializeUrl,
1487
- sortAscChainStatusesByStartBlock,
2900
+ sortChainStatusesByStartBlockAsc,
2901
+ staleWhileRevalidate,
2902
+ stripNullBytes,
2903
+ translateDefaultableChainIdToChainId,
1488
2904
  uint256ToHex32,
1489
2905
  uniq,
1490
- validateSupportedLabelSetAndVersion
2906
+ validateSupportedLabelSetAndVersion,
2907
+ zeroEncodedReferrer
1491
2908
  };
1492
2909
  //# sourceMappingURL=index.js.map