@ensnode/ensnode-sdk 0.31.0 → 0.32.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,19 +1,133 @@
1
- // src/utils/constants.ts
1
+ // src/ens/constants.ts
2
2
  import { namehash } from "viem";
3
3
  var ROOT_NODE = namehash("");
4
4
  var REVERSE_ROOT_NODES = /* @__PURE__ */ new Set([namehash("addr.reverse")]);
5
- var ETH_COIN_TYPE = 60n;
6
5
 
7
- // src/utils/types.ts
8
- var PluginName = /* @__PURE__ */ ((PluginName2) => {
9
- PluginName2["Subgraph"] = "subgraph";
10
- PluginName2["Basenames"] = "basenames";
11
- PluginName2["Lineanames"] = "lineanames";
12
- PluginName2["ThreeDNS"] = "threedns";
13
- return PluginName2;
14
- })(PluginName || {});
6
+ // src/ens/subname-helpers.ts
7
+ import { concat, isAddress, isHash, keccak256, toHex } from "viem";
8
+ import { labelhash } from "viem/ens";
9
+
10
+ // src/ens/coin-type.ts
11
+ import {
12
+ coinTypeToEvmChainId as _coinTypeToEvmChainId,
13
+ evmChainIdToCoinType as _evmChainIdToCoinType
14
+ } from "@ensdomains/address-encoder/utils";
15
+ var ETH_COIN_TYPE = 60;
16
+ var DEFAULT_EVM_CHAIN_ID = 0;
17
+ var DEFAULT_EVM_COIN_TYPE = 2147483648;
18
+ var coinTypeToEvmChainId = (coinType) => {
19
+ if (coinType === ETH_COIN_TYPE) return 1;
20
+ return _coinTypeToEvmChainId(coinType);
21
+ };
22
+ var evmChainIdToCoinType = (chainId) => {
23
+ if (chainId === 1) return ETH_COIN_TYPE;
24
+ return _evmChainIdToCoinType(chainId);
25
+ };
26
+ var bigintToCoinType = (value) => {
27
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
28
+ throw new Error(`'${value}' cannot represent as CoinType, it is too large.`);
29
+ }
30
+ return Number(value);
31
+ };
15
32
 
16
- // src/utils/cache.ts
33
+ // src/ens/reverse-name.ts
34
+ var addrReverseLabel = (address) => address.slice(2).toLowerCase();
35
+ var coinTypeReverseLabel = (coinType) => coinType.toString(16);
36
+ function reverseName(address, coinType) {
37
+ const label = addrReverseLabel(address);
38
+ const middle = (() => {
39
+ switch (coinType) {
40
+ case ETH_COIN_TYPE:
41
+ return "addr";
42
+ case DEFAULT_EVM_COIN_TYPE:
43
+ return "default";
44
+ default:
45
+ return coinTypeReverseLabel(coinType);
46
+ }
47
+ })();
48
+ return `${label}.${middle}.reverse`;
49
+ }
50
+
51
+ // src/ens/subname-helpers.ts
52
+ var makeSubdomainNode = (labelHash, node) => keccak256(concat([node, labelHash]));
53
+ var maybeHealLabelByReverseAddress = ({
54
+ maybeReverseAddress,
55
+ labelHash
56
+ }) => {
57
+ if (!isAddress(maybeReverseAddress)) {
58
+ throw new Error(
59
+ `Invalid reverse address: '${maybeReverseAddress}'. Must be a valid EVM Address.`
60
+ );
61
+ }
62
+ if (!isHash(labelHash)) {
63
+ throw new Error(
64
+ `Invalid labelHash: '${labelHash}'. Must start with '0x' and represent 32 bytes.`
65
+ );
66
+ }
67
+ const assumedLabel = addrReverseLabel(maybeReverseAddress);
68
+ if (labelhash(assumedLabel) === labelHash) return assumedLabel;
69
+ return null;
70
+ };
71
+ var uint256ToHex32 = (num) => toHex(num, { size: 32 });
72
+ var UNINDEXABLE_LABEL_CHARACTERS = [
73
+ "\0",
74
+ // null byte: PostgreSQL does not allow storing this character in text fields.
75
+ ".",
76
+ // conflicts with ENS label separator logic.
77
+ "[",
78
+ // conflicts with "unknown label" representations.
79
+ "]"
80
+ // conflicts with "unknown label" representations.
81
+ ];
82
+ var UNINDEXABLE_LABEL_CHARACTER_CODES = new Set(
83
+ UNINDEXABLE_LABEL_CHARACTERS.map((char) => char.charCodeAt(0))
84
+ );
85
+ var isLabelIndexable = (label) => {
86
+ if (!label) return false;
87
+ for (let i = 0; i < label.length; i++) {
88
+ if (UNINDEXABLE_LABEL_CHARACTER_CODES.has(label.charCodeAt(i))) return false;
89
+ }
90
+ return true;
91
+ };
92
+
93
+ // src/ens/names.ts
94
+ var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
95
+
96
+ // src/ens/types.ts
97
+ import { ENSNamespaceIds } from "@ensnode/datasources";
98
+
99
+ // src/ens/parse-reverse-name.ts
100
+ import { getAddress, hexToBigInt } from "viem";
101
+ var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
102
+ var parseAddressLabel = (addressLabel) => getAddress(`0x${addressLabel}`);
103
+ var parseCoinTypeLabel = (coinTypeLabel) => {
104
+ if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
105
+ if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
106
+ return bigintToCoinType(hexToBigInt(`0x${coinTypeLabel}`));
107
+ };
108
+ function parseReverseName(name) {
109
+ const match = name.match(REVERSE_NAME_REGEX);
110
+ if (!match) return null;
111
+ try {
112
+ const [, addressLabel, coinTypeLabel] = match;
113
+ if (!addressLabel) return null;
114
+ if (!coinTypeLabel) return null;
115
+ return {
116
+ address: parseAddressLabel(addressLabel),
117
+ coinType: parseCoinTypeLabel(coinTypeLabel)
118
+ };
119
+ } catch {
120
+ return null;
121
+ }
122
+ }
123
+
124
+ // src/ensindexer/config/deserialize.ts
125
+ import { prettifyError as prettifyError2 } from "zod/v4";
126
+
127
+ // src/ensindexer/config/zod-schemas.ts
128
+ import z2 from "zod/v4";
129
+
130
+ // src/shared/cache.ts
17
131
  var LruCache = class {
18
132
  _cache = /* @__PURE__ */ new Map();
19
133
  _capacity;
@@ -62,59 +176,974 @@ var LruCache = class {
62
176
  }
63
177
  };
64
178
 
65
- // src/utils/subname-helpers.ts
66
- import { concat, isAddress, isHash, keccak256, toHex } from "viem";
67
- import { labelhash } from "viem/ens";
68
- var makeSubdomainNode = (labelHash, node) => keccak256(concat([node, labelHash]));
69
- var addrReverseLabel = (address) => address.slice(2).toLowerCase();
70
- var maybeHealLabelByReverseAddress = ({
71
- maybeReverseAddress,
72
- labelHash
73
- }) => {
74
- if (!isAddress(maybeReverseAddress)) {
179
+ // src/shared/collections.ts
180
+ var uniq = (arr) => [...new Set(arr)];
181
+
182
+ // src/shared/serialize.ts
183
+ function serializeChainId(chainId) {
184
+ return chainId.toString();
185
+ }
186
+ function serializeDatetime(datetime) {
187
+ return datetime.toISOString();
188
+ }
189
+ function serializeUrl(url) {
190
+ return url.toString();
191
+ }
192
+
193
+ // src/shared/deserialize.ts
194
+ import { prettifyError } from "zod/v4";
195
+
196
+ // src/shared/zod-schemas.ts
197
+ import z from "zod/v4";
198
+ var makeIntegerSchema = (valueLabel = "Value") => z.int({
199
+ error: `${valueLabel} must be an integer.`
200
+ });
201
+ var makePositiveIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(valueLabel).positive({
202
+ error: `${valueLabel} must be a positive integer (>0).`
203
+ });
204
+ var makeNonNegativeIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(valueLabel).nonnegative({
205
+ error: `${valueLabel} must be a non-negative integer (>=0).`
206
+ });
207
+ var makeDurationSchema = (valueLabel = "Value") => z.coerce.number({
208
+ error: `${valueLabel} must be a number.`
209
+ }).pipe(makeNonNegativeIntegerSchema(valueLabel));
210
+ var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel);
211
+ 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}`));
212
+ var makeDatetimeSchema = (valueLabel = "Datetime string") => z.iso.datetime({ error: `${valueLabel} must be a string in ISO 8601 format.` }).transform((v) => new Date(v));
213
+ var makeUnixTimestampSchema = (valueLabel = "Timestamp") => makeIntegerSchema(valueLabel);
214
+ var makeUrlSchema = (valueLabel = "Value") => z.url({
215
+ error: `${valueLabel} must be a valid URL string (e.g., http://localhost:8080 or https://example.com).`
216
+ }).transform((v) => new URL(v));
217
+ var makeBlockNumberSchema = (valueLabel = "Block number") => makeNonNegativeIntegerSchema(valueLabel);
218
+ var makeBlockrangeSchema = (valueLabel = "Value") => z.strictObject(
219
+ {
220
+ startBlock: makeBlockNumberSchema(`${valueLabel}.startBlock`).optional(),
221
+ endBlock: makeBlockNumberSchema(`${valueLabel}.endBlock`).optional()
222
+ },
223
+ {
224
+ error: `${valueLabel} must be a valid Blockrange object.`
225
+ }
226
+ ).refine(
227
+ (v) => {
228
+ if (v.startBlock && v.endBlock) {
229
+ return v.startBlock <= v.endBlock;
230
+ }
231
+ return true;
232
+ },
233
+ { error: `${valueLabel}: startBlock must be before or equal to endBlock` }
234
+ );
235
+ var makeBlockRefSchema = (valueLabel = "Value") => z.strictObject(
236
+ {
237
+ timestamp: makeUnixTimestampSchema(`${valueLabel}.timestamp`),
238
+ number: makeBlockNumberSchema(`${valueLabel}.number`)
239
+ },
240
+ {
241
+ error: `${valueLabel} must be a valid BlockRef object.`
242
+ }
243
+ );
244
+ var makeENSNamespaceIdSchema = (valueLabel = "ENSNamespaceId") => z.enum(ENSNamespaceIds, {
245
+ error() {
246
+ return `Invalid ${valueLabel}. Supported ENS namespace IDs are: ${Object.keys(ENSNamespaceIds).join(", ")}`;
247
+ }
248
+ });
249
+
250
+ // src/shared/deserialize.ts
251
+ function deserializeChainId(maybeChainId, valueLabel) {
252
+ const schema = makeChainIdStringSchema(valueLabel);
253
+ const parsed = schema.safeParse(maybeChainId);
254
+ if (parsed.error) {
255
+ throw new Error(`Cannot deserialize ChainId:
256
+ ${prettifyError(parsed.error)}
257
+ `);
258
+ }
259
+ return parsed.data;
260
+ }
261
+ function deserializeDatetime(maybeDatetime, valueLabel) {
262
+ const schema = makeDatetimeSchema(valueLabel);
263
+ const parsed = schema.safeParse(maybeDatetime);
264
+ if (parsed.error) {
265
+ throw new Error(`Cannot deserialize Datetime:
266
+ ${prettifyError(parsed.error)}
267
+ `);
268
+ }
269
+ return parsed.data;
270
+ }
271
+ function deserializeUrl(maybeUrl, valueLabel) {
272
+ const schema = makeUrlSchema(valueLabel);
273
+ const parsed = schema.safeParse(maybeUrl);
274
+ if (parsed.error) {
275
+ throw new Error(`Cannot deserialize URL:
276
+ ${prettifyError(parsed.error)}
277
+ `);
278
+ }
279
+ return parsed.data;
280
+ }
281
+ function deserializeBlockNumber(maybeBlockNumber, valueLabel) {
282
+ const schema = makeBlockNumberSchema(valueLabel);
283
+ const parsed = schema.safeParse(maybeBlockNumber);
284
+ if (parsed.error) {
285
+ throw new Error(`Cannot deserialize BlockNumber:
286
+ ${prettifyError(parsed.error)}
287
+ `);
288
+ }
289
+ return parsed.data;
290
+ }
291
+ function deserializeBlockrange(maybeBlockrange, valueLabel) {
292
+ const schema = makeBlockrangeSchema(valueLabel);
293
+ const parsed = schema.safeParse(maybeBlockrange);
294
+ if (parsed.error) {
295
+ throw new Error(`Cannot deserialize Blockrange:
296
+ ${prettifyError(parsed.error)}
297
+ `);
298
+ }
299
+ return parsed.data;
300
+ }
301
+ function deserializeBlockRef(maybeBlockRef, valueLabel) {
302
+ const schema = makeBlockRefSchema(valueLabel);
303
+ const parsed = schema.safeParse(maybeBlockRef);
304
+ if (parsed.error) {
305
+ throw new Error(`Cannot deserialize BlockRef:
306
+ ${prettifyError(parsed.error)}
307
+ `);
308
+ }
309
+ return parsed.data;
310
+ }
311
+ function deserializeDuration(maybeDuration, valueLabel) {
312
+ const schema = makeDurationSchema(valueLabel);
313
+ const parsed = schema.safeParse(maybeDuration);
314
+ if (parsed.error) {
315
+ throw new RangeError(`Cannot deserialize Duration:
316
+ ${prettifyError(parsed.error)}
317
+ `);
318
+ }
319
+ return parsed.data;
320
+ }
321
+
322
+ // src/shared/is-normalized.ts
323
+ import { normalize } from "viem/ens";
324
+ function isNormalized(name) {
325
+ try {
326
+ return name === normalize(name);
327
+ } catch {
328
+ return false;
329
+ }
330
+ }
331
+
332
+ // src/ensindexer/config/types.ts
333
+ var PluginName = /* @__PURE__ */ ((PluginName2) => {
334
+ PluginName2["Subgraph"] = "subgraph";
335
+ PluginName2["Basenames"] = "basenames";
336
+ PluginName2["Lineanames"] = "lineanames";
337
+ PluginName2["ThreeDNS"] = "threedns";
338
+ PluginName2["ReverseResolvers"] = "reverse-resolvers";
339
+ PluginName2["Referrals"] = "referrals";
340
+ return PluginName2;
341
+ })(PluginName || {});
342
+
343
+ // src/ensindexer/config/helpers.ts
344
+ function isSubgraphCompatible(config) {
345
+ const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
346
+ const indexingBehaviorIsSubgraphCompatible = !config.healReverseAddresses && !config.indexAdditionalResolverRecords;
347
+ return onlySubgraphPluginActivated && indexingBehaviorIsSubgraphCompatible;
348
+ }
349
+
350
+ // src/ensindexer/config/zod-schemas.ts
351
+ var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
352
+ error: `${valueLabel} must be an array.`
353
+ }).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
354
+ var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(
355
+ z2.enum(PluginName, {
356
+ error: `${valueLabel} must be a list with at least one valid plugin name. Valid plugins are: ${Object.values(
357
+ PluginName
358
+ ).join(", ")}`
359
+ })
360
+ ).min(1, {
361
+ error: `${valueLabel} must be a list with at least one valid plugin name. Valid plugins are: ${Object.values(
362
+ PluginName
363
+ ).join(", ")}`
364
+ }).refine((arr) => arr.length === uniq(arr).length, {
365
+ error: `${valueLabel} cannot contain duplicate values.`
366
+ });
367
+ var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
368
+ error: `${valueLabel} is required and must be a non-empty string.`
369
+ });
370
+ var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
371
+ var makeDependencyInfoSchema = (valueLabel = "Value") => z2.strictObject(
372
+ {
373
+ nodejs: makeNonEmptyStringSchema(),
374
+ ponder: makeNonEmptyStringSchema(),
375
+ ensRainbow: makeNonEmptyStringSchema(),
376
+ ensRainbowSchema: makePositiveIntegerSchema()
377
+ },
378
+ {
379
+ error: `${valueLabel} must be a valid DependencyInfo object.`
380
+ }
381
+ );
382
+ function invariant_reverseResolversPluginNeedsResolverRecords(ctx) {
383
+ const { value: config } = ctx;
384
+ const reverseResolversPluginActive = config.plugins.includes("reverse-resolvers" /* ReverseResolvers */);
385
+ if (reverseResolversPluginActive && !config.indexAdditionalResolverRecords) {
386
+ ctx.issues.push({
387
+ code: "custom",
388
+ input: config,
389
+ message: `The '${"reverse-resolvers" /* ReverseResolvers */}' plugin requires 'indexAdditionalResolverRecords' to be 'true'.`
390
+ });
391
+ }
392
+ }
393
+ function invariant_experimentalResolutionNeedsReverseResolversPlugin(ctx) {
394
+ const { value: config } = ctx;
395
+ const reverseResolversPluginActive = config.plugins.includes("reverse-resolvers" /* ReverseResolvers */);
396
+ if (config.experimentalResolution && !reverseResolversPluginActive) {
397
+ ctx.issues.push({
398
+ code: "custom",
399
+ input: config,
400
+ message: `'reverseResolversPluginActive' requires the ${"reverse-resolvers" /* ReverseResolvers */} plugin to be active.`
401
+ });
402
+ }
403
+ }
404
+ function invariant_isSubgraphCompatibleRequirements(ctx) {
405
+ const { value: config } = ctx;
406
+ if (config.isSubgraphCompatible !== isSubgraphCompatible(config)) {
407
+ const message = config.isSubgraphCompatible ? `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active. Also, both 'indexAdditionalResolverRecords' and 'healReverseAddresses' must be set to 'false'` : `Both 'indexAdditionalResolverRecords' and 'healReverseAddresses' were set to 'false', and the only active plugin was the '${"subgraph" /* Subgraph */}' plugin. The 'isSubgraphCompatible' must be set to 'true'`;
408
+ ctx.issues.push({
409
+ code: "custom",
410
+ input: config,
411
+ message
412
+ });
413
+ }
414
+ }
415
+ var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
416
+ ensAdminUrl: makeUrlSchema(`${valueLabel}.ensAdminUrl`),
417
+ ensNodePublicUrl: makeUrlSchema(`${valueLabel}.ensNodePublicUrl`),
418
+ experimentalResolution: z2.boolean({ error: `${valueLabel}.experimentalResolution` }),
419
+ healReverseAddresses: z2.boolean({ error: `${valueLabel}.healReverseAddresses` }),
420
+ indexAdditionalResolverRecords: z2.boolean({
421
+ error: `${valueLabel}.indexAdditionalResolverRecords`
422
+ }),
423
+ indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
424
+ isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
425
+ namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
426
+ plugins: makePluginsListSchema(`${valueLabel}.plugins`),
427
+ databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
428
+ dependencyInfo: makeDependencyInfoSchema(`${valueLabel}.dependencyInfo`)
429
+ }).check(invariant_reverseResolversPluginNeedsResolverRecords).check(invariant_experimentalResolutionNeedsReverseResolversPlugin).check(invariant_isSubgraphCompatibleRequirements);
430
+
431
+ // src/ensindexer/config/deserialize.ts
432
+ function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
433
+ const schema = makeENSIndexerPublicConfigSchema(valueLabel);
434
+ const parsed = schema.safeParse(maybeConfig);
435
+ if (parsed.error) {
436
+ throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
437
+ ${prettifyError2(parsed.error)}
438
+ `);
439
+ }
440
+ return parsed.data;
441
+ }
442
+
443
+ // src/ensindexer/config/serialize.ts
444
+ function serializeIndexedChainIds(indexedChainIds) {
445
+ return Array.from(indexedChainIds);
446
+ }
447
+ function serializeENSIndexerPublicConfig(config) {
448
+ const {
449
+ ensAdminUrl,
450
+ ensNodePublicUrl,
451
+ indexedChainIds,
452
+ databaseSchemaName,
453
+ experimentalResolution,
454
+ healReverseAddresses,
455
+ indexAdditionalResolverRecords,
456
+ isSubgraphCompatible: isSubgraphCompatible2,
457
+ namespace,
458
+ plugins,
459
+ dependencyInfo
460
+ } = config;
461
+ return {
462
+ ensAdminUrl: serializeUrl(ensAdminUrl),
463
+ ensNodePublicUrl: serializeUrl(ensNodePublicUrl),
464
+ indexedChainIds: serializeIndexedChainIds(indexedChainIds),
465
+ databaseSchemaName,
466
+ experimentalResolution,
467
+ healReverseAddresses,
468
+ indexAdditionalResolverRecords,
469
+ isSubgraphCompatible: isSubgraphCompatible2,
470
+ namespace,
471
+ plugins,
472
+ dependencyInfo
473
+ };
474
+ }
475
+
476
+ // src/ensindexer/indexing-status/deserialize.ts
477
+ import { prettifyError as prettifyError3 } from "zod/v4";
478
+
479
+ // src/ensindexer/indexing-status/zod-schemas.ts
480
+ import z3 from "zod/v4";
481
+
482
+ // src/shared/block-ref.ts
483
+ function isBefore(blockA, blockB) {
484
+ return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
485
+ }
486
+ function isEqualTo(blockA, blockB) {
487
+ return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
488
+ }
489
+ function isBeforeOrEqualTo(blockA, blockB) {
490
+ return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
491
+ }
492
+
493
+ // src/ensindexer/indexing-status/types.ts
494
+ var ChainIndexingStatusIds = {
495
+ Unstarted: "unstarted",
496
+ Backfill: "backfill",
497
+ Following: "following",
498
+ Completed: "completed"
499
+ };
500
+ var OverallIndexingStatusIds = {
501
+ Unstarted: "unstarted",
502
+ Backfill: "backfill",
503
+ Following: "following",
504
+ Completed: "completed",
505
+ IndexerError: "indexer-error"
506
+ };
507
+ var ChainIndexingStrategyIds = {
508
+ Indefinite: "indefinite",
509
+ Definite: "definite"
510
+ };
511
+
512
+ // src/ensindexer/indexing-status/helpers.ts
513
+ function getOverallIndexingStatus(chains) {
514
+ const chainStatuses = chains.map((chain) => chain.status);
515
+ let overallStatus;
516
+ if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Following)) {
517
+ overallStatus = OverallIndexingStatusIds.Following;
518
+ } else if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Backfill)) {
519
+ overallStatus = OverallIndexingStatusIds.Backfill;
520
+ } else if (chainStatuses.some((chainStatus) => chainStatus === ChainIndexingStatusIds.Unstarted)) {
521
+ overallStatus = OverallIndexingStatusIds.Unstarted;
522
+ } else {
523
+ overallStatus = OverallIndexingStatusIds.Completed;
524
+ }
525
+ return overallStatus;
526
+ }
527
+ function getOverallApproxRealtimeDistance(chains) {
528
+ const chainApproxRealtimeDistances = chains.filter((chain) => chain.status === ChainIndexingStatusIds.Following).map((chain) => chain.approxRealtimeDistance);
529
+ if (chainApproxRealtimeDistances.length === 0) {
75
530
  throw new Error(
76
- `Invalid reverse address: '${maybeReverseAddress}'. Must be a valid EVM Address.`
531
+ `The overall approximate realtime distance value is undefined if no indexed chain is in the '${OverallIndexingStatusIds.Following}' status`
77
532
  );
78
533
  }
79
- if (!isHash(labelHash)) {
80
- throw new Error(
81
- `Invalid labelHash: '${labelHash}'. Must start with '0x' and represent 32 bytes.`
534
+ const approxRealtimeDistance = Math.max(...chainApproxRealtimeDistances);
535
+ return approxRealtimeDistance;
536
+ }
537
+ function getOmnichainIndexingCursor(chains) {
538
+ return Math.min(...chains.map((chain) => chain.latestIndexedBlock.timestamp));
539
+ }
540
+ function getActiveChains(chains) {
541
+ return chains.filter(
542
+ (chain) => chain.status === ChainIndexingStatusIds.Backfill || chain.status === ChainIndexingStatusIds.Following
543
+ );
544
+ }
545
+ function getStandbyChains(chains) {
546
+ return chains.filter(
547
+ (chain) => chain.status === ChainIndexingStatusIds.Unstarted || chain.status === ChainIndexingStatusIds.Completed
548
+ );
549
+ }
550
+ function createIndexingConfig(startBlock, endBlock) {
551
+ if (endBlock) {
552
+ return {
553
+ strategy: ChainIndexingStrategyIds.Definite,
554
+ startBlock,
555
+ endBlock
556
+ };
557
+ }
558
+ return {
559
+ strategy: ChainIndexingStrategyIds.Indefinite,
560
+ startBlock,
561
+ endBlock: null
562
+ };
563
+ }
564
+ function checkChainIndexingStatusesForUnstartedOverallStatus(chains) {
565
+ return chains.every((chain) => chain.status === ChainIndexingStatusIds.Unstarted);
566
+ }
567
+ function checkChainIndexingStatusesForBackfillOverallStatus(chains) {
568
+ const atLeastOneChainInTargetStatus = chains.some(
569
+ (chain) => chain.status === ChainIndexingStatusIds.Backfill
570
+ );
571
+ const otherChainsHaveValidStatuses = chains.every(
572
+ (chain) => chain.status === ChainIndexingStatusIds.Unstarted || chain.status === ChainIndexingStatusIds.Backfill || chain.status === ChainIndexingStatusIds.Completed
573
+ );
574
+ return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
575
+ }
576
+ function checkChainIndexingStatusesForCompletedOverallStatus(chains) {
577
+ const allChainsHaveValidStatuses = chains.every(
578
+ (chain) => chain.status === ChainIndexingStatusIds.Completed
579
+ );
580
+ return allChainsHaveValidStatuses;
581
+ }
582
+ function checkChainIndexingStatusesForFollowingOverallStatus(chains) {
583
+ const allChainsHaveValidStatuses = chains.some(
584
+ (chain) => chain.status === ChainIndexingStatusIds.Following
585
+ );
586
+ return allChainsHaveValidStatuses;
587
+ }
588
+
589
+ // src/ensindexer/indexing-status/zod-schemas.ts
590
+ var makeChainIndexingConfigSchema = (valueLabel = "Value") => z3.discriminatedUnion("strategy", [
591
+ z3.strictObject({
592
+ strategy: z3.literal(ChainIndexingStrategyIds.Indefinite),
593
+ startBlock: makeBlockRefSchema(valueLabel),
594
+ endBlock: z3.null()
595
+ }),
596
+ z3.strictObject({
597
+ strategy: z3.literal(ChainIndexingStrategyIds.Definite),
598
+ startBlock: makeBlockRefSchema(valueLabel),
599
+ endBlock: makeBlockRefSchema(valueLabel)
600
+ })
601
+ ]);
602
+ var makeChainIndexingUnstartedStatusSchema = (valueLabel = "Value") => z3.strictObject({
603
+ status: z3.literal(ChainIndexingStatusIds.Unstarted),
604
+ config: makeChainIndexingConfigSchema(valueLabel)
605
+ }).refine(
606
+ ({ config }) => config.endBlock === null || isBeforeOrEqualTo(config.startBlock, config.endBlock),
607
+ {
608
+ error: `config.startBlock must be before or same as config.endBlock.`
609
+ }
610
+ );
611
+ var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictObject({
612
+ status: z3.literal(ChainIndexingStatusIds.Backfill),
613
+ config: makeChainIndexingConfigSchema(valueLabel),
614
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
615
+ backfillEndBlock: makeBlockRefSchema(valueLabel)
616
+ }).refine(
617
+ ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
618
+ {
619
+ error: `config.startBlock must be before or same as latestIndexedBlock.`
620
+ }
621
+ ).refine(
622
+ ({ latestIndexedBlock, backfillEndBlock }) => isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock),
623
+ {
624
+ error: `latestIndexedBlock must be before or same as backfillEndBlock.`
625
+ }
626
+ ).refine(
627
+ ({ config, backfillEndBlock }) => config.endBlock === null || isEqualTo(backfillEndBlock, config.endBlock),
628
+ {
629
+ error: `backfillEndBlock must be the same as config.endBlock.`
630
+ }
631
+ );
632
+ var makeChainIndexingFollowingStatusSchema = (valueLabel = "Value") => z3.strictObject({
633
+ status: z3.literal(ChainIndexingStatusIds.Following),
634
+ config: z3.strictObject({
635
+ strategy: z3.literal(ChainIndexingStrategyIds.Indefinite),
636
+ startBlock: makeBlockRefSchema(valueLabel)
637
+ }),
638
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
639
+ latestKnownBlock: makeBlockRefSchema(valueLabel),
640
+ approxRealtimeDistance: makeDurationSchema(valueLabel)
641
+ }).refine(
642
+ ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
643
+ {
644
+ error: `config.startBlock must be before or same as latestIndexedBlock.`
645
+ }
646
+ ).refine(
647
+ ({ latestIndexedBlock, latestKnownBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock),
648
+ {
649
+ error: `latestIndexedBlock must be before or same as latestKnownBlock.`
650
+ }
651
+ );
652
+ var makeChainIndexingCompletedStatusSchema = (valueLabel = "Value") => z3.strictObject({
653
+ status: z3.literal(ChainIndexingStatusIds.Completed),
654
+ config: z3.strictObject({
655
+ strategy: z3.literal(ChainIndexingStrategyIds.Definite),
656
+ startBlock: makeBlockRefSchema(valueLabel),
657
+ endBlock: makeBlockRefSchema(valueLabel)
658
+ }),
659
+ latestIndexedBlock: makeBlockRefSchema(valueLabel)
660
+ }).refine(
661
+ ({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
662
+ {
663
+ error: `config.startBlock must be before or same as latestIndexedBlock.`
664
+ }
665
+ ).refine(
666
+ ({ config, latestIndexedBlock }) => isEqualTo(latestIndexedBlock, config.endBlock),
667
+ {
668
+ error: `latestIndexedBlock must be the same as config.endBlock.`
669
+ }
670
+ );
671
+ var makeChainIndexingStatusSchema = (valueLabel = "Value") => z3.discriminatedUnion("status", [
672
+ makeChainIndexingUnstartedStatusSchema(valueLabel),
673
+ makeChainIndexingBackfillStatusSchema(valueLabel),
674
+ makeChainIndexingFollowingStatusSchema(valueLabel),
675
+ makeChainIndexingCompletedStatusSchema(valueLabel)
676
+ ]);
677
+ var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z3.record(makeChainIdStringSchema(), makeChainIndexingStatusSchema(valueLabel), {
678
+ error: "Chains configuration must be an object mapping valid chain IDs to their configs."
679
+ }).transform((serializedChainsIndexingStatus) => {
680
+ const chainsIndexingStatus = /* @__PURE__ */ new Map();
681
+ for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
682
+ chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
683
+ }
684
+ return chainsIndexingStatus;
685
+ });
686
+ var makeUnstartedOverallStatusSchema = (valueLabel) => z3.strictObject({
687
+ overallStatus: z3.literal(OverallIndexingStatusIds.Unstarted),
688
+ chains: makeChainIndexingStatusesSchema(valueLabel).refine(
689
+ (chains) => checkChainIndexingStatusesForUnstartedOverallStatus(Array.from(chains.values())),
690
+ {
691
+ error: `${valueLabel} at least one chain must be in "unstarted" status and
692
+ each chain has to have a status of either "unstarted", or "completed"`
693
+ }
694
+ ).transform((chains) => chains)
695
+ }).refine(
696
+ (indexingStatus) => {
697
+ const chains = Array.from(indexingStatus.chains.values());
698
+ return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
699
+ },
700
+ { error: `${valueLabel} is an invalid overallStatus.` }
701
+ );
702
+ var makeBackfillOverallStatusSchema = (valueLabel) => z3.strictObject({
703
+ overallStatus: z3.literal(OverallIndexingStatusIds.Backfill),
704
+ chains: makeChainIndexingStatusesSchema(valueLabel).refine(
705
+ (chains) => checkChainIndexingStatusesForBackfillOverallStatus(Array.from(chains.values())),
706
+ {
707
+ error: `${valueLabel} at least one chain must be in "backfill" status and
708
+ each chain has to have a status of either "unstarted", "backfill" or "completed"`
709
+ }
710
+ ).transform((chains) => chains),
711
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
712
+ }).refine(
713
+ (indexingStatus) => {
714
+ const chains = Array.from(indexingStatus.chains.values());
715
+ return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
716
+ },
717
+ { error: `${valueLabel} is an invalid overallStatus.` }
718
+ ).refine(
719
+ (indexingStatus) => {
720
+ const chains = Array.from(indexingStatus.chains.values());
721
+ const standbyChainStartBlocks = getStandbyChains(chains).map(
722
+ (chain) => chain.config.startBlock.timestamp
82
723
  );
724
+ const standbyChainEarliestStartBlocks = Math.min(...standbyChainStartBlocks);
725
+ return indexingStatus.omnichainIndexingCursor <= standbyChainEarliestStartBlocks;
726
+ },
727
+ {
728
+ error: "omnichainIndexingCursor must be lower than or equal to the earliest config.startBlock across all standby chains"
83
729
  }
84
- const assumedLabel = addrReverseLabel(maybeReverseAddress);
85
- if (labelhash(assumedLabel) === labelHash) return assumedLabel;
86
- return null;
87
- };
88
- var uint256ToHex32 = (num) => toHex(num, { size: 32 });
89
- var UNINDEXABLE_LABEL_CHARACTERS = [
90
- "\0",
91
- // null byte: PostgreSQL does not allow storing this character in text fields.
92
- ".",
93
- // conflicts with ENS label separator logic.
94
- "[",
95
- // conflicts with "unknown label" representations.
96
- "]"
97
- // conflicts with "unknown label" representations.
98
- ];
99
- var UNINDEXABLE_LABEL_CHARACTER_CODES = new Set(
100
- UNINDEXABLE_LABEL_CHARACTERS.map((char) => char.charCodeAt(0))
101
730
  );
102
- var isLabelIndexable = (label) => {
103
- if (!label) return false;
104
- for (let i = 0; i < label.length; i++) {
105
- if (UNINDEXABLE_LABEL_CHARACTER_CODES.has(label.charCodeAt(i))) return false;
731
+ var makeCompletedOverallStatusSchema = (valueLabel) => z3.strictObject({
732
+ overallStatus: z3.literal(OverallIndexingStatusIds.Completed),
733
+ chains: makeChainIndexingStatusesSchema(valueLabel).refine(
734
+ (chains) => checkChainIndexingStatusesForCompletedOverallStatus(Array.from(chains.values())),
735
+ {
736
+ error: `${valueLabel} all chains must have "completed" status`
737
+ }
738
+ ).transform((chains) => chains)
739
+ }).refine(
740
+ (indexingStatus) => {
741
+ const chains = Array.from(indexingStatus.chains.values());
742
+ return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
743
+ },
744
+ { error: `${valueLabel} is an invalid overallStatus.` }
745
+ );
746
+ var makeFollowingOverallStatusSchema = (valueLabel) => z3.strictObject({
747
+ overallStatus: z3.literal(OverallIndexingStatusIds.Following),
748
+ chains: makeChainIndexingStatusesSchema(valueLabel),
749
+ overallApproxRealtimeDistance: makeDurationSchema(valueLabel),
750
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
751
+ }).refine(
752
+ (indexingStatus) => {
753
+ const chains = Array.from(indexingStatus.chains.values());
754
+ return getOverallIndexingStatus(chains) === indexingStatus.overallStatus;
755
+ },
756
+ { error: `${valueLabel} is an invalid overallStatus.` }
757
+ ).refine(
758
+ (indexingStatus) => checkChainIndexingStatusesForFollowingOverallStatus(
759
+ Array.from(indexingStatus.chains.values())
760
+ ),
761
+ {
762
+ error: `${valueLabel} at least one chain must be in "following" status`
106
763
  }
107
- return true;
764
+ ).refine(
765
+ (indexingStatus) => {
766
+ const chains = Array.from(indexingStatus.chains.values());
767
+ return getOverallApproxRealtimeDistance(chains) === indexingStatus.overallApproxRealtimeDistance;
768
+ },
769
+ { error: `${valueLabel} is an invalid overallApproxRealtimeDistance.` }
770
+ ).refine(
771
+ (indexingStatus) => {
772
+ const chains = Array.from(indexingStatus.chains.values());
773
+ const standbyChainStartBlocks = getStandbyChains(chains).map(
774
+ (chain) => chain.config.startBlock.timestamp
775
+ );
776
+ const standbyChainEarliestStartBlocks = Math.min(...standbyChainStartBlocks);
777
+ return indexingStatus.omnichainIndexingCursor <= standbyChainEarliestStartBlocks;
778
+ },
779
+ {
780
+ error: "omnichainIndexingCursor must be lower than or equal to the earliest config.startBlock across all standby chains"
781
+ }
782
+ );
783
+ var makeErrorSchemaOverallStatusSchema = (valueLabel) => z3.strictObject({
784
+ overallStatus: z3.literal(OverallIndexingStatusIds.IndexerError)
785
+ });
786
+ var makeENSIndexerIndexingStatusSchema = (valueLabel = "ENSIndexerIndexingStatus") => z3.discriminatedUnion("overallStatus", [
787
+ makeUnstartedOverallStatusSchema(valueLabel),
788
+ makeBackfillOverallStatusSchema(valueLabel),
789
+ makeCompletedOverallStatusSchema(valueLabel),
790
+ makeFollowingOverallStatusSchema(valueLabel),
791
+ makeErrorSchemaOverallStatusSchema(valueLabel)
792
+ ]);
793
+
794
+ // src/ensindexer/indexing-status/deserialize.ts
795
+ function deserializeENSIndexerIndexingStatus(maybeStatus, valueLabel) {
796
+ const schema = makeENSIndexerIndexingStatusSchema(valueLabel);
797
+ const parsed = schema.safeParse(maybeStatus);
798
+ if (parsed.error) {
799
+ throw new Error(
800
+ `Cannot deserialize ENSIndexerIndexingStatus:
801
+ ${prettifyError3(parsed.error)}
802
+ `
803
+ );
804
+ }
805
+ return parsed.data;
806
+ }
807
+
808
+ // src/ensindexer/indexing-status/serialize.ts
809
+ function serializeChainIndexingStatuses(chainIndexingStatuses) {
810
+ const serializedChainsIndexingStatuses = {};
811
+ for (const [chainId, chainIndexingStatus] of chainIndexingStatuses.entries()) {
812
+ serializedChainsIndexingStatuses[serializeChainId(chainId)] = chainIndexingStatus;
813
+ }
814
+ return serializedChainsIndexingStatuses;
815
+ }
816
+ function serializeENSIndexerIndexingStatus(indexingStatus) {
817
+ switch (indexingStatus.overallStatus) {
818
+ case OverallIndexingStatusIds.IndexerError:
819
+ return {
820
+ overallStatus: OverallIndexingStatusIds.IndexerError
821
+ };
822
+ case OverallIndexingStatusIds.Unstarted:
823
+ return {
824
+ overallStatus: OverallIndexingStatusIds.Unstarted,
825
+ chains: serializeChainIndexingStatuses(indexingStatus.chains)
826
+ };
827
+ case OverallIndexingStatusIds.Backfill:
828
+ return {
829
+ overallStatus: OverallIndexingStatusIds.Backfill,
830
+ chains: serializeChainIndexingStatuses(indexingStatus.chains),
831
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
832
+ };
833
+ case OverallIndexingStatusIds.Completed: {
834
+ return {
835
+ overallStatus: OverallIndexingStatusIds.Completed,
836
+ chains: serializeChainIndexingStatuses(indexingStatus.chains)
837
+ };
838
+ }
839
+ case OverallIndexingStatusIds.Following:
840
+ return {
841
+ overallStatus: OverallIndexingStatusIds.Following,
842
+ chains: serializeChainIndexingStatuses(indexingStatus.chains),
843
+ overallApproxRealtimeDistance: indexingStatus.overallApproxRealtimeDistance,
844
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
845
+ };
846
+ }
847
+ }
848
+
849
+ // src/tracing/index.ts
850
+ var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
851
+ TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
852
+ TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
853
+ return TraceableENSProtocol2;
854
+ })(TraceableENSProtocol || {});
855
+ var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
856
+ ForwardResolutionProtocolStep2["Operation"] = "operation";
857
+ ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
858
+ ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
859
+ ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
860
+ ForwardResolutionProtocolStep2["AccelerateKnownOffchainLookupResolver"] = "accelerate-known-offchain-lookup-resolver";
861
+ ForwardResolutionProtocolStep2["AccelerateKnownOnchainStaticResolver"] = "accelerate-known-onchain-static-resolver";
862
+ ForwardResolutionProtocolStep2["RequireResolver"] = "require-resolver";
863
+ ForwardResolutionProtocolStep2["ExecuteResolveCalls"] = "execute-resolve-calls";
864
+ return ForwardResolutionProtocolStep2;
865
+ })(ForwardResolutionProtocolStep || {});
866
+ var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
867
+ ReverseResolutionProtocolStep2["Operation"] = "operation";
868
+ ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
869
+ ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
870
+ ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
871
+ ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
872
+ return ReverseResolutionProtocolStep2;
873
+ })(ReverseResolutionProtocolStep || {});
874
+ var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
875
+ var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
876
+ var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
877
+ var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
878
+ function hrTimeToMicroseconds(time) {
879
+ return time[0] * 1e6 + time[1] / 1e3;
880
+ }
881
+ var readableSpanToProtocolSpan = (span) => ({
882
+ id: span.spanContext().spanId,
883
+ traceId: span.spanContext().traceId,
884
+ parentSpanContext: span.parentSpanContext,
885
+ name: span.name,
886
+ timestamp: hrTimeToMicroseconds(span.startTime),
887
+ duration: hrTimeToMicroseconds(span.duration),
888
+ // only export `ens.*` attributes to avoid leaking internal details
889
+ attributes: Object.fromEntries(
890
+ Object.entries(span.attributes).filter(
891
+ ([key]) => key.startsWith(`${PROTOCOL_ATTRIBUTE_PREFIX}.`)
892
+ )
893
+ ),
894
+ status: span.status,
895
+ events: span.events
896
+ });
897
+
898
+ // src/client.ts
899
+ var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
900
+ var ENSNodeClient = class _ENSNodeClient {
901
+ options;
902
+ static defaultOptions() {
903
+ return {
904
+ url: new URL(DEFAULT_ENSNODE_API_URL)
905
+ };
906
+ }
907
+ constructor(options = {}) {
908
+ this.options = {
909
+ ..._ENSNodeClient.defaultOptions(),
910
+ ...options
911
+ };
912
+ }
913
+ getOptions() {
914
+ return Object.freeze({
915
+ url: new URL(this.options.url.href)
916
+ });
917
+ }
918
+ /**
919
+ * Resolves records for an ENS name (Forward Resolution).
920
+ *
921
+ * @param name The ENS Name whose records to resolve
922
+ * @param selection selection of Resolver records
923
+ * @param options additional options
924
+ * @param options.accelerate whether to attempt Protocol Acceleration (default true)
925
+ * @param options.trace whether to include a trace in the response (default false)
926
+ * @returns ResolveRecordsResponse<SELECTION>
927
+ * @throws If the request fails or the ENSNode API returns an error response
928
+ *
929
+ * @example
930
+ * ```typescript
931
+ * const { records } = await client.resolveRecords("jesse.base.eth", {
932
+ * addresses: [60],
933
+ * texts: ["avatar", "com.twitter"]
934
+ * });
935
+ *
936
+ * console.log(records);
937
+ * // {
938
+ * // addresses: {
939
+ * // 60: "0xabcd..."
940
+ * // },
941
+ * // texts: {
942
+ * // avatar: "https://example.com/image.jpg",
943
+ * // "com.twitter": null, // if not set, for example
944
+ * // }
945
+ * // }
946
+ * ```
947
+ */
948
+ async resolveRecords(name, selection, options) {
949
+ const url = new URL(`/api/resolve/records/${encodeURIComponent(name)}`, this.options.url);
950
+ if (selection.name) {
951
+ url.searchParams.set("name", "true");
952
+ }
953
+ if (selection.addresses && selection.addresses.length > 0) {
954
+ url.searchParams.set("addresses", selection.addresses.join(","));
955
+ }
956
+ if (selection.texts && selection.texts.length > 0) {
957
+ url.searchParams.set("texts", selection.texts.join(","));
958
+ }
959
+ if (options?.trace) url.searchParams.set("trace", "true");
960
+ if (options?.accelerate === false) url.searchParams.set("accelerate", "false");
961
+ const response = await fetch(url);
962
+ if (!response.ok) {
963
+ const error = await response.json();
964
+ throw new Error(`Records Resolution Failed: ${error.message}`);
965
+ }
966
+ const data = await response.json();
967
+ return data;
968
+ }
969
+ /**
970
+ * Resolves the primary name of a specified address (Reverse Resolution) on a specific chain.
971
+ *
972
+ * If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
973
+ * the Default Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to
974
+ * determine the `address`'s Default Name directly.
975
+ *
976
+ * @param address The Address whose Primary Name to resolve
977
+ * @param chainId The chain id within which to query the address' ENSIP-19 Multichain Primary Name
978
+ * @param options additional options
979
+ * @param options.accelerate whether to attempt Protocol Acceleration (default true)
980
+ * @param options.trace whether to include a trace in the response (default false)
981
+ * @returns ResolvePrimaryNameResponse
982
+ * @throws If the request fails or the ENSNode API returns an error response
983
+ *
984
+ * @example
985
+ * ```typescript
986
+ * // Resolve the address' Primary Name on Ethereum Mainnet
987
+ * const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 1);
988
+ * // name === 'gregskril.eth'
989
+ *
990
+ * // Resolve the address' Primary Name on Base
991
+ * const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 8453);
992
+ * // name === 'greg.base.eth'
993
+ *
994
+ * // Resolve the address' Default Primary Name
995
+ * const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 0);
996
+ * // name === 'gregskril.eth'
997
+ * ```
998
+ */
999
+ async resolvePrimaryName(address, chainId, options) {
1000
+ const url = new URL(`/api/resolve/primary-name/${address}/${chainId}`, this.options.url);
1001
+ if (options?.trace) url.searchParams.set("trace", "true");
1002
+ if (options?.accelerate === false) url.searchParams.set("accelerate", "false");
1003
+ const response = await fetch(url);
1004
+ if (!response.ok) {
1005
+ const error = await response.json();
1006
+ throw new Error(`Primary Name Resolution Failed: ${error.message}`);
1007
+ }
1008
+ const data = await response.json();
1009
+ return data;
1010
+ }
1011
+ /**
1012
+ * Resolves the primary names of a specified address across multiple chains.
1013
+ *
1014
+ * If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
1015
+ * the Default Name will be returned for all chainIds for which there is not a chain-specific
1016
+ * Primary Name. To avoid misuse, you _may not_ query the Default EVM Chain Id (`0`) directly, and
1017
+ * should rely on the aforementioned per-chain defaulting behavior.
1018
+ *
1019
+ * @param address The Address whose Primary Names to resolve
1020
+ * @param options additional options
1021
+ * @param options.chainIds The set of chain ids within which to query the address' ENSIP-19
1022
+ * Multichain Primary Name (default: all ENSIP-19 supported chains)
1023
+ * @param options.accelerate whether to attempt Protocol Acceleration (default: true)
1024
+ * @param options.trace whether to include a trace in the response (default: false)
1025
+ * @returns ResolvePrimaryNamesResponse
1026
+ * @throws If the request fails or the ENSNode API returns an error response
1027
+ *
1028
+ * @example
1029
+ * ```typescript
1030
+ * // Resolve the address' Primary Names on all ENSIP-19 supported chain ids
1031
+ * const { names } = await client.resolvePrimaryNames("0x179A862703a4adfb29896552DF9e307980D19285");
1032
+ *
1033
+ * console.log(names);
1034
+ * // {
1035
+ * // "1": "gregskril.eth",
1036
+ * // "10": "gregskril.eth",
1037
+ * // "8453": "greg.base.eth", // base-specific Primary Name!
1038
+ * // "42161": "gregskril.eth",
1039
+ * // "59144": "gregskril.eth",
1040
+ * // "534352": "gregskril.eth"
1041
+ * // }
1042
+ *
1043
+ * // Resolve the address' Primary Names on specific chain Ids
1044
+ * const { names } = await client.resolvePrimaryNames("0xabcd...", [1, 8453]);
1045
+ *
1046
+ * console.log(names);
1047
+ * // {
1048
+ * // "1": "gregskril.eth",
1049
+ * // "8453": "greg.base.eth", // base-specific Primary Name!
1050
+ * // }
1051
+ * ```
1052
+ */
1053
+ async resolvePrimaryNames(address, options) {
1054
+ const url = new URL(`/api/resolve/primary-names/${address}`, this.options.url);
1055
+ if (options?.chainIds) url.searchParams.set("chainIds", options.chainIds.join(","));
1056
+ if (options?.trace) url.searchParams.set("trace", "true");
1057
+ if (options?.accelerate === false) url.searchParams.set("accelerate", "false");
1058
+ const response = await fetch(url);
1059
+ if (!response.ok) {
1060
+ const error = await response.json();
1061
+ throw new Error(`Primary Names Resolution Failed: ${error.message}`);
1062
+ }
1063
+ const data = await response.json();
1064
+ return data;
1065
+ }
1066
+ };
1067
+
1068
+ // src/resolution/resolver-records-selection.ts
1069
+ var DEFAULT_RECORDS_SELECTION = {
1070
+ addresses: [ETH_COIN_TYPE],
1071
+ texts: [
1072
+ "url",
1073
+ "avatar",
1074
+ "header",
1075
+ "description",
1076
+ "email",
1077
+ "com.twitter",
1078
+ "com.farcaster",
1079
+ "com.github"
1080
+ ]
108
1081
  };
1082
+ var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
109
1083
  export {
1084
+ ATTR_PROTOCOL_NAME,
1085
+ ATTR_PROTOCOL_STEP,
1086
+ ATTR_PROTOCOL_STEP_RESULT,
1087
+ ChainIndexingStatusIds,
1088
+ ChainIndexingStrategyIds,
1089
+ DEFAULT_ENSNODE_API_URL,
1090
+ DEFAULT_EVM_CHAIN_ID,
1091
+ DEFAULT_EVM_COIN_TYPE,
1092
+ DEFAULT_RECORDS_SELECTION,
1093
+ ENSNamespaceIds,
1094
+ ENSNodeClient,
110
1095
  ETH_COIN_TYPE,
1096
+ ForwardResolutionProtocolStep,
111
1097
  LruCache,
1098
+ OverallIndexingStatusIds,
112
1099
  PluginName,
113
1100
  REVERSE_ROOT_NODES,
114
1101
  ROOT_NODE,
1102
+ ReverseResolutionProtocolStep,
1103
+ TraceableENSProtocol,
1104
+ addrReverseLabel,
1105
+ bigintToCoinType,
1106
+ checkChainIndexingStatusesForBackfillOverallStatus,
1107
+ checkChainIndexingStatusesForCompletedOverallStatus,
1108
+ checkChainIndexingStatusesForFollowingOverallStatus,
1109
+ checkChainIndexingStatusesForUnstartedOverallStatus,
1110
+ coinTypeReverseLabel,
1111
+ coinTypeToEvmChainId,
1112
+ createIndexingConfig,
1113
+ deserializeBlockNumber,
1114
+ deserializeBlockRef,
1115
+ deserializeBlockrange,
1116
+ deserializeChainId,
1117
+ deserializeDatetime,
1118
+ deserializeDuration,
1119
+ deserializeENSIndexerIndexingStatus,
1120
+ deserializeENSIndexerPublicConfig,
1121
+ deserializeUrl,
1122
+ evmChainIdToCoinType,
1123
+ getActiveChains,
1124
+ getNameHierarchy,
1125
+ getOmnichainIndexingCursor,
1126
+ getOverallApproxRealtimeDistance,
1127
+ getOverallIndexingStatus,
1128
+ getStandbyChains,
1129
+ hrTimeToMicroseconds,
115
1130
  isLabelIndexable,
1131
+ isNormalized,
1132
+ isSelectionEmpty,
1133
+ isSubgraphCompatible,
116
1134
  makeSubdomainNode,
117
1135
  maybeHealLabelByReverseAddress,
118
- uint256ToHex32
1136
+ parseReverseName,
1137
+ readableSpanToProtocolSpan,
1138
+ reverseName,
1139
+ serializeChainId,
1140
+ serializeChainIndexingStatuses,
1141
+ serializeDatetime,
1142
+ serializeENSIndexerIndexingStatus,
1143
+ serializeENSIndexerPublicConfig,
1144
+ serializeIndexedChainIds,
1145
+ serializeUrl,
1146
+ uint256ToHex32,
1147
+ uniq
119
1148
  };
120
1149
  //# sourceMappingURL=index.js.map