@ensnode/ensnode-sdk 0.0.0-next-20260102143513

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.cjs ADDED
@@ -0,0 +1,4396 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ ADDR_REVERSE_NODE: () => ADDR_REVERSE_NODE,
34
+ ATTR_PROTOCOL_NAME: () => ATTR_PROTOCOL_NAME,
35
+ ATTR_PROTOCOL_STEP: () => ATTR_PROTOCOL_STEP,
36
+ ATTR_PROTOCOL_STEP_RESULT: () => ATTR_PROTOCOL_STEP_RESULT,
37
+ AssetNamespaces: () => AssetNamespaces,
38
+ BASENAMES_NODE: () => BASENAMES_NODE,
39
+ ChainIndexingConfigTypeIds: () => ChainIndexingConfigTypeIds,
40
+ ChainIndexingStatusIds: () => ChainIndexingStatusIds,
41
+ ClientError: () => ClientError,
42
+ CrossChainIndexingStrategyIds: () => CrossChainIndexingStrategyIds,
43
+ CurrencyIds: () => CurrencyIds,
44
+ DEFAULT_EVM_CHAIN_ID: () => DEFAULT_EVM_CHAIN_ID,
45
+ DEFAULT_EVM_COIN_TYPE: () => DEFAULT_EVM_COIN_TYPE,
46
+ ENSNamespaceIds: () => import_datasources.ENSNamespaceIds,
47
+ ENSNodeClient: () => ENSNodeClient,
48
+ ENS_ROOT: () => ENS_ROOT,
49
+ ETH_COIN_TYPE: () => ETH_COIN_TYPE,
50
+ ETH_NODE: () => ETH_NODE,
51
+ ForwardResolutionProtocolStep: () => ForwardResolutionProtocolStep,
52
+ IndexingStatusResponseCodes: () => IndexingStatusResponseCodes,
53
+ LINEANAMES_NODE: () => LINEANAMES_NODE,
54
+ LruCache: () => LruCache,
55
+ NFTMintStatuses: () => NFTMintStatuses,
56
+ NFTTransferTypes: () => NFTTransferTypes,
57
+ NameTokenOwnershipTypes: () => NameTokenOwnershipTypes,
58
+ NameTokensResponseCodes: () => NameTokensResponseCodes,
59
+ NameTokensResponseErrorCodes: () => NameTokensResponseErrorCodes,
60
+ OmnichainIndexingStatusIds: () => OmnichainIndexingStatusIds,
61
+ PROTOCOL_ATTRIBUTE_PREFIX: () => PROTOCOL_ATTRIBUTE_PREFIX,
62
+ PluginName: () => PluginName,
63
+ RECORDS_PER_PAGE_DEFAULT: () => RECORDS_PER_PAGE_DEFAULT,
64
+ RECORDS_PER_PAGE_MAX: () => RECORDS_PER_PAGE_MAX,
65
+ ROOT_NODE: () => ROOT_NODE,
66
+ ReferrerDetailResponseCodes: () => ReferrerDetailResponseCodes,
67
+ ReferrerLeaderboardPageResponseCodes: () => ReferrerLeaderboardPageResponseCodes,
68
+ RegistrarActionTypes: () => RegistrarActionTypes,
69
+ RegistrarActionsFilterTypes: () => RegistrarActionsFilterTypes,
70
+ RegistrarActionsOrders: () => RegistrarActionsOrders,
71
+ RegistrarActionsResponseCodes: () => RegistrarActionsResponseCodes,
72
+ ResolutionStatusIds: () => ResolutionStatusIds,
73
+ ReverseResolutionProtocolStep: () => ReverseResolutionProtocolStep,
74
+ SWRCache: () => SWRCache,
75
+ TheGraphCannotFallbackReasonSchema: () => TheGraphCannotFallbackReasonSchema,
76
+ TheGraphFallbackSchema: () => TheGraphFallbackSchema,
77
+ TraceableENSProtocol: () => TraceableENSProtocol,
78
+ TtlCache: () => TtlCache,
79
+ ZERO_ENCODED_REFERRER: () => ZERO_ENCODED_REFERRER,
80
+ accountIdEqual: () => accountIdEqual,
81
+ addDuration: () => addDuration,
82
+ addPrices: () => addPrices,
83
+ addrReverseLabel: () => addrReverseLabel,
84
+ asLowerCaseAddress: () => asLowerCaseAddress,
85
+ beautifyName: () => beautifyName,
86
+ bigIntToNumber: () => bigIntToNumber,
87
+ bigintToCoinType: () => bigintToCoinType,
88
+ buildAssetId: () => buildAssetId,
89
+ buildEnsRainbowClientLabelSet: () => buildEnsRainbowClientLabelSet,
90
+ buildLabelSetId: () => buildLabelSetId,
91
+ buildLabelSetVersion: () => buildLabelSetVersion,
92
+ buildPageContext: () => buildPageContext,
93
+ buildUnresolvedIdentity: () => buildUnresolvedIdentity,
94
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
95
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
96
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing,
97
+ checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted,
98
+ coinTypeReverseLabel: () => coinTypeReverseLabel,
99
+ coinTypeToEvmChainId: () => coinTypeToEvmChainId,
100
+ createIndexingConfig: () => createIndexingConfig,
101
+ createRealtimeIndexingStatusProjection: () => createRealtimeIndexingStatusProjection,
102
+ decodeDNSEncodedLiteralName: () => decodeDNSEncodedLiteralName,
103
+ decodeDNSEncodedName: () => decodeDNSEncodedName,
104
+ decodeEncodedReferrer: () => decodeEncodedReferrer,
105
+ deserializeAssetId: () => deserializeAssetId,
106
+ deserializeBlockNumber: () => deserializeBlockNumber,
107
+ deserializeBlockRef: () => deserializeBlockRef,
108
+ deserializeBlockrange: () => deserializeBlockrange,
109
+ deserializeChainId: () => deserializeChainId,
110
+ deserializeChainIndexingStatusSnapshot: () => deserializeChainIndexingStatusSnapshot,
111
+ deserializeConfigResponse: () => deserializeConfigResponse,
112
+ deserializeCrossChainIndexingStatusSnapshot: () => deserializeCrossChainIndexingStatusSnapshot,
113
+ deserializeDatetime: () => deserializeDatetime,
114
+ deserializeDuration: () => deserializeDuration,
115
+ deserializeENSApiPublicConfig: () => deserializeENSApiPublicConfig,
116
+ deserializeENSIndexerPublicConfig: () => deserializeENSIndexerPublicConfig,
117
+ deserializeErrorResponse: () => deserializeErrorResponse,
118
+ deserializeIndexingStatusResponse: () => deserializeIndexingStatusResponse,
119
+ deserializeOmnichainIndexingStatusSnapshot: () => deserializeOmnichainIndexingStatusSnapshot,
120
+ deserializeRealtimeIndexingStatusProjection: () => deserializeRealtimeIndexingStatusProjection,
121
+ deserializeReferrerDetailResponse: () => deserializeReferrerDetailResponse,
122
+ deserializeReferrerLeaderboardPageResponse: () => deserializeReferrerLeaderboardPageResponse,
123
+ deserializeRegistrarActionsResponse: () => deserializeRegistrarActionsResponse,
124
+ deserializeUnixTimestamp: () => deserializeUnixTimestamp,
125
+ deserializeUrl: () => deserializeUrl,
126
+ deserializedNameTokensResponse: () => deserializedNameTokensResponse,
127
+ durationBetween: () => durationBetween,
128
+ encodeLabelHash: () => encodeLabelHash,
129
+ evmChainIdToCoinType: () => evmChainIdToCoinType,
130
+ formatAccountId: () => formatAccountId,
131
+ formatAssetId: () => formatAssetId,
132
+ formatNFTTransferEventMetadata: () => formatNFTTransferEventMetadata,
133
+ getBasenamesSubregistryId: () => getBasenamesSubregistryId,
134
+ getBasenamesSubregistryManagedName: () => getBasenamesSubregistryManagedName,
135
+ getCurrencyInfo: () => getCurrencyInfo,
136
+ getDatasourceContract: () => getDatasourceContract,
137
+ getENSRootChainId: () => import_datasources2.getENSRootChainId,
138
+ getEthnamesSubregistryId: () => getEthnamesSubregistryId,
139
+ getEthnamesSubregistryManagedName: () => getEthnamesSubregistryManagedName,
140
+ getLatestIndexedBlockRef: () => getLatestIndexedBlockRef,
141
+ getLineanamesSubregistryId: () => getLineanamesSubregistryId,
142
+ getLineanamesSubregistryManagedName: () => getLineanamesSubregistryManagedName,
143
+ getNFTTransferType: () => getNFTTransferType,
144
+ getNameHierarchy: () => getNameHierarchy,
145
+ getNameTokenOwnership: () => getNameTokenOwnership,
146
+ getNameWrapperAccounts: () => getNameWrapperAccounts,
147
+ getOmnichainIndexingCursor: () => getOmnichainIndexingCursor,
148
+ getOmnichainIndexingStatus: () => getOmnichainIndexingStatus,
149
+ getParentNameFQDN: () => getParentNameFQDN,
150
+ getResolvePrimaryNameChainIdParam: () => getResolvePrimaryNameChainIdParam,
151
+ getTimestampForHighestOmnichainKnownBlock: () => getTimestampForHighestOmnichainKnownBlock,
152
+ getTimestampForLowestOmnichainStartBlock: () => getTimestampForLowestOmnichainStartBlock,
153
+ hasNullByte: () => hasNullByte,
154
+ interpretedLabelsToInterpretedName: () => interpretedLabelsToInterpretedName,
155
+ isEncodedLabelHash: () => isEncodedLabelHash,
156
+ isHttpProtocol: () => isHttpProtocol,
157
+ isLabelHash: () => isLabelHash,
158
+ isNormalizedLabel: () => isNormalizedLabel,
159
+ isNormalizedName: () => isNormalizedName,
160
+ isPriceCurrencyEqual: () => isPriceCurrencyEqual,
161
+ isPriceEqual: () => isPriceEqual,
162
+ isRegistrarActionPricingAvailable: () => isRegistrarActionPricingAvailable,
163
+ isRegistrarActionReferralAvailable: () => isRegistrarActionReferralAvailable,
164
+ isResolvedIdentity: () => isResolvedIdentity,
165
+ isSelectionEmpty: () => isSelectionEmpty,
166
+ isSubgraphCompatible: () => isSubgraphCompatible,
167
+ isWebSocketProtocol: () => isWebSocketProtocol,
168
+ labelHashToBytes: () => labelHashToBytes,
169
+ labelhashLiteralLabel: () => labelhashLiteralLabel,
170
+ literalLabelToInterpretedLabel: () => literalLabelToInterpretedLabel,
171
+ literalLabelsToInterpretedName: () => literalLabelsToInterpretedName,
172
+ literalLabelsToLiteralName: () => literalLabelsToLiteralName,
173
+ makeENSApiPublicConfigSchema: () => makeENSApiPublicConfigSchema,
174
+ makeSubdomainNode: () => makeSubdomainNode,
175
+ maybeGetDatasourceContract: () => maybeGetDatasourceContract,
176
+ nameTokensPrerequisites: () => nameTokensPrerequisites,
177
+ parseAccountId: () => parseAccountId,
178
+ parseAssetId: () => parseAssetId,
179
+ parseNonNegativeInteger: () => parseNonNegativeInteger,
180
+ parseReverseName: () => parseReverseName,
181
+ priceDai: () => priceDai,
182
+ priceEth: () => priceEth,
183
+ priceUsdc: () => priceUsdc,
184
+ registrarActionsFilter: () => registrarActionsFilter,
185
+ registrarActionsPrerequisites: () => registrarActionsPrerequisites,
186
+ reverseName: () => reverseName,
187
+ serializeAssetId: () => serializeAssetId,
188
+ serializeChainId: () => serializeChainId,
189
+ serializeChainIndexingSnapshots: () => serializeChainIndexingSnapshots,
190
+ serializeConfigResponse: () => serializeConfigResponse,
191
+ serializeCrossChainIndexingStatusSnapshotOmnichain: () => serializeCrossChainIndexingStatusSnapshotOmnichain,
192
+ serializeDatetime: () => serializeDatetime,
193
+ serializeDomainAssetId: () => serializeDomainAssetId,
194
+ serializeENSApiPublicConfig: () => serializeENSApiPublicConfig,
195
+ serializeENSIndexerPublicConfig: () => serializeENSIndexerPublicConfig,
196
+ serializeIndexedChainIds: () => serializeIndexedChainIds,
197
+ serializeIndexingStatusResponse: () => serializeIndexingStatusResponse,
198
+ serializeNameToken: () => serializeNameToken,
199
+ serializeNameTokensResponse: () => serializeNameTokensResponse,
200
+ serializeNamedRegistrarAction: () => serializeNamedRegistrarAction,
201
+ serializeOmnichainIndexingStatusSnapshot: () => serializeOmnichainIndexingStatusSnapshot,
202
+ serializePrice: () => serializePrice,
203
+ serializePriceEth: () => serializePriceEth,
204
+ serializeRealtimeIndexingStatusProjection: () => serializeRealtimeIndexingStatusProjection,
205
+ serializeReferrerDetailResponse: () => serializeReferrerDetailResponse,
206
+ serializeReferrerLeaderboardPageResponse: () => serializeReferrerLeaderboardPageResponse,
207
+ serializeRegisteredNameTokens: () => serializeRegisteredNameTokens,
208
+ serializeRegistrarAction: () => serializeRegistrarAction,
209
+ serializeRegistrarActionPricing: () => serializeRegistrarActionPricing,
210
+ serializeRegistrarActionsResponse: () => serializeRegistrarActionsResponse,
211
+ serializeUrl: () => serializeUrl,
212
+ sortChainStatusesByStartBlockAsc: () => sortChainStatusesByStartBlockAsc,
213
+ stripNullBytes: () => stripNullBytes,
214
+ translateDefaultableChainIdToChainId: () => translateDefaultableChainIdToChainId,
215
+ uint256ToHex32: () => uint256ToHex32,
216
+ uniq: () => uniq,
217
+ validateSupportedLabelSetAndVersion: () => validateSupportedLabelSetAndVersion
218
+ });
219
+ module.exports = __toCommonJS(index_exports);
220
+
221
+ // src/ensapi/config/deserialize.ts
222
+ var import_v46 = require("zod/v4");
223
+
224
+ // src/ensapi/config/zod-schemas.ts
225
+ var import_v45 = require("zod/v4");
226
+
227
+ // src/ensindexer/config/zod-schemas.ts
228
+ var import_v43 = __toESM(require("zod/v4"), 1);
229
+
230
+ // src/shared/account-id.ts
231
+ var import_viem = require("viem");
232
+ var accountIdEqual = (a, b) => {
233
+ return a.chainId === b.chainId && (0, import_viem.isAddressEqual)(a.address, b.address);
234
+ };
235
+
236
+ // src/shared/address.ts
237
+ function asLowerCaseAddress(address) {
238
+ return address.toLowerCase();
239
+ }
240
+
241
+ // src/shared/cache/lru-cache.ts
242
+ var LruCache = class {
243
+ _cache = /* @__PURE__ */ new Map();
244
+ _capacity;
245
+ /**
246
+ * Create a new LRU cache with the given capacity.
247
+ *
248
+ * @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
249
+ * @throws Error if capacity is not a non-negative integer.
250
+ */
251
+ constructor(capacity) {
252
+ if (!Number.isInteger(capacity)) {
253
+ throw new Error(
254
+ `LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
255
+ );
256
+ }
257
+ if (capacity < 0) {
258
+ throw new Error(
259
+ `LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
260
+ );
261
+ }
262
+ this._capacity = capacity;
263
+ }
264
+ set(key, value) {
265
+ this._cache.set(key, value);
266
+ if (this._cache.size > this._capacity) {
267
+ const oldestKey = this._cache.keys().next().value;
268
+ this._cache.delete(oldestKey);
269
+ }
270
+ }
271
+ get(key) {
272
+ const value = this._cache.get(key);
273
+ if (value) {
274
+ this._cache.delete(key);
275
+ this._cache.set(key, value);
276
+ }
277
+ return value;
278
+ }
279
+ clear() {
280
+ this._cache.clear();
281
+ }
282
+ get size() {
283
+ return this._cache.size;
284
+ }
285
+ get capacity() {
286
+ return this._capacity;
287
+ }
288
+ };
289
+
290
+ // src/shared/cache/swr-cache.ts
291
+ var import_date_fns = require("date-fns");
292
+ var import_getUnixTime = require("date-fns/getUnixTime");
293
+
294
+ // src/shared/deserialize.ts
295
+ var import_v42 = require("zod/v4");
296
+
297
+ // src/shared/zod-schemas.ts
298
+ var import_caip = require("caip");
299
+ var import_viem8 = require("viem");
300
+ var import_v4 = __toESM(require("zod/v4"), 1);
301
+
302
+ // src/ens/index.ts
303
+ var import_datasources2 = require("@ensnode/datasources");
304
+
305
+ // src/ens/coin-type.ts
306
+ var import_utils = require("@ensdomains/address-encoder/utils");
307
+ var ETH_COIN_TYPE = 60;
308
+ var DEFAULT_EVM_CHAIN_ID = 0;
309
+ var DEFAULT_EVM_COIN_TYPE = 2147483648;
310
+ var coinTypeToEvmChainId = (coinType) => {
311
+ if (coinType === ETH_COIN_TYPE) return 1;
312
+ return (0, import_utils.coinTypeToEvmChainId)(coinType);
313
+ };
314
+ var evmChainIdToCoinType = (chainId) => {
315
+ if (chainId === 1) return ETH_COIN_TYPE;
316
+ return (0, import_utils.evmChainIdToCoinType)(chainId);
317
+ };
318
+ var bigintToCoinType = (value) => {
319
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
320
+ throw new Error(`'${value}' cannot represent as CoinType, it is too large.`);
321
+ }
322
+ return Number(value);
323
+ };
324
+
325
+ // src/ens/constants.ts
326
+ var import_viem2 = require("viem");
327
+ var ROOT_NODE = (0, import_viem2.namehash)("");
328
+ var ETH_NODE = (0, import_viem2.namehash)("eth");
329
+ var BASENAMES_NODE = (0, import_viem2.namehash)("base.eth");
330
+ var LINEANAMES_NODE = (0, import_viem2.namehash)("linea.eth");
331
+ var ADDR_REVERSE_NODE = (0, import_viem2.namehash)("addr.reverse");
332
+
333
+ // src/ens/dns-encoded-name.ts
334
+ var import_viem3 = require("viem");
335
+ function decodeDNSEncodedLiteralName(packet) {
336
+ return decodeDNSEncodedName(packet);
337
+ }
338
+ function decodeDNSEncodedName(packet) {
339
+ const segments = [];
340
+ const bytes = (0, import_viem3.hexToBytes)(packet);
341
+ if (bytes.length === 0) throw new Error(`Packet is empty.`);
342
+ let offset = 0;
343
+ while (offset < bytes.length) {
344
+ const len = bytes[offset];
345
+ if (len === void 0) {
346
+ throw new Error(`Invariant: bytes[offset] is undefined after offset < bytes.length check.`);
347
+ }
348
+ if (len < 0 || len > 255) {
349
+ throw new Error(
350
+ `Invariant: this should be literally impossible, but an unsigned byte was less than zero or greater than 255. The value in question is ${len}`
351
+ );
352
+ }
353
+ if (len === 0) break;
354
+ const segment = (0, import_viem3.bytesToString)(bytes.subarray(offset + 1, offset + len + 1));
355
+ segments.push(segment);
356
+ offset += len + 1;
357
+ }
358
+ if (offset >= bytes.length) throw new Error(`Overflow, offset >= bytes.length`);
359
+ if (offset !== bytes.length - 1) throw new Error(`Junk at end of name`);
360
+ return segments;
361
+ }
362
+
363
+ // src/ens/labelhash.ts
364
+ var import_viem4 = require("viem");
365
+ function isLabelHash(maybeLabelHash) {
366
+ const expectedLength = maybeLabelHash.length === 66;
367
+ const expectedEncoding = (0, import_viem4.isHex)(maybeLabelHash);
368
+ const expectedCasing = maybeLabelHash === maybeLabelHash.toLowerCase();
369
+ return expectedLength && expectedEncoding && expectedCasing;
370
+ }
371
+
372
+ // src/ens/encode-labelhash.ts
373
+ var encodeLabelHash = (labelHash) => `[${labelHash.slice(2)}]`;
374
+ function isEncodedLabelHash(maybeEncodedLabelHash) {
375
+ const expectedFormatting = maybeEncodedLabelHash.startsWith("[") && maybeEncodedLabelHash.endsWith("]");
376
+ const includesLabelHash = isLabelHash(`0x${maybeEncodedLabelHash.slice(1, -1)}`);
377
+ return expectedFormatting && includesLabelHash;
378
+ }
379
+
380
+ // src/ens/is-normalized.ts
381
+ var import_ens = require("viem/ens");
382
+ function isNormalizedName(name) {
383
+ try {
384
+ return name === (0, import_ens.normalize)(name);
385
+ } catch {
386
+ return false;
387
+ }
388
+ }
389
+ function isNormalizedLabel(label) {
390
+ if (label === "") return false;
391
+ if (label.includes(".")) return false;
392
+ try {
393
+ return label === (0, import_ens.normalize)(label);
394
+ } catch {
395
+ return false;
396
+ }
397
+ }
398
+
399
+ // src/ens/names.ts
400
+ var import_ens_normalize = require("@adraffy/ens-normalize");
401
+ var ENS_ROOT = "";
402
+ var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
403
+ var getParentNameFQDN = (name) => {
404
+ if (name === ENS_ROOT) {
405
+ throw new Error("There is no parent name for ENS Root.");
406
+ }
407
+ const labels = name.split(".");
408
+ if (labels.length === 1) {
409
+ return ENS_ROOT;
410
+ }
411
+ return labels.slice(1).join(".");
412
+ };
413
+ var beautifyName = (name) => {
414
+ const beautifiedLabels = name.split(".").map((label) => {
415
+ if (isNormalizedLabel(label)) {
416
+ return (0, import_ens_normalize.ens_beautify)(label);
417
+ } else {
418
+ return label;
419
+ }
420
+ });
421
+ return beautifiedLabels.join(".");
422
+ };
423
+
424
+ // src/ens/parse-reverse-name.ts
425
+ var import_viem5 = require("viem");
426
+ var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
427
+ var parseAddressLabel = (addressLabel) => {
428
+ const maybeAddress = `0x${addressLabel}`;
429
+ if (!(0, import_viem5.isAddress)(maybeAddress)) {
430
+ throw new Error(`Invalid EVM address "${maybeAddress}"`);
431
+ }
432
+ return asLowerCaseAddress(maybeAddress);
433
+ };
434
+ var parseCoinTypeLabel = (coinTypeLabel) => {
435
+ if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
436
+ if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
437
+ return bigintToCoinType((0, import_viem5.hexToBigInt)(`0x${coinTypeLabel}`));
438
+ };
439
+ function parseReverseName(name) {
440
+ const match = name.match(REVERSE_NAME_REGEX);
441
+ if (!match) return null;
442
+ try {
443
+ const [, addressLabel, coinTypeLabel] = match;
444
+ if (!addressLabel) return null;
445
+ if (!coinTypeLabel) return null;
446
+ return {
447
+ address: parseAddressLabel(addressLabel),
448
+ coinType: parseCoinTypeLabel(coinTypeLabel)
449
+ };
450
+ } catch {
451
+ return null;
452
+ }
453
+ }
454
+
455
+ // src/ens/reverse-name.ts
456
+ var addrReverseLabel = (address) => address.slice(2);
457
+ var coinTypeReverseLabel = (coinType) => coinType.toString(16);
458
+ function reverseName(address, coinType) {
459
+ const label = addrReverseLabel(address);
460
+ const middle = (() => {
461
+ switch (coinType) {
462
+ case ETH_COIN_TYPE:
463
+ return "addr";
464
+ case DEFAULT_EVM_COIN_TYPE:
465
+ return "default";
466
+ default:
467
+ return coinTypeReverseLabel(coinType);
468
+ }
469
+ })();
470
+ return `${label}.${middle}.reverse`;
471
+ }
472
+
473
+ // src/ens/subname-helpers.ts
474
+ var import_viem6 = require("viem");
475
+ var makeSubdomainNode = (labelHash, node) => (0, import_viem6.keccak256)((0, import_viem6.concat)([node, labelHash]));
476
+ var uint256ToHex32 = (num) => (0, import_viem6.toHex)(num, { size: 32 });
477
+
478
+ // src/ens/types.ts
479
+ var import_datasources = require("@ensnode/datasources");
480
+
481
+ // src/shared/currencies.ts
482
+ var CurrencyIds = {
483
+ ETH: "ETH",
484
+ USDC: "USDC",
485
+ DAI: "DAI"
486
+ };
487
+ var currencyInfo = {
488
+ [CurrencyIds.ETH]: {
489
+ id: CurrencyIds.ETH,
490
+ name: "ETH",
491
+ decimals: 18
492
+ },
493
+ [CurrencyIds.USDC]: {
494
+ id: CurrencyIds.USDC,
495
+ name: "USDC",
496
+ decimals: 6
497
+ },
498
+ [CurrencyIds.DAI]: {
499
+ id: CurrencyIds.DAI,
500
+ name: "Dai Stablecoin",
501
+ decimals: 18
502
+ }
503
+ };
504
+ function getCurrencyInfo(currencyId) {
505
+ return currencyInfo[currencyId];
506
+ }
507
+ function priceEth(amount) {
508
+ return {
509
+ amount,
510
+ currency: CurrencyIds.ETH
511
+ };
512
+ }
513
+ function priceUsdc(amount) {
514
+ return {
515
+ amount,
516
+ currency: CurrencyIds.USDC
517
+ };
518
+ }
519
+ function priceDai(amount) {
520
+ return {
521
+ amount,
522
+ currency: CurrencyIds.DAI
523
+ };
524
+ }
525
+ function isPriceCurrencyEqual(priceA, priceB) {
526
+ return priceA.currency === priceB.currency;
527
+ }
528
+ function isPriceEqual(priceA, priceB) {
529
+ return isPriceCurrencyEqual(priceA, priceB) && priceA.amount === priceB.amount;
530
+ }
531
+ function addPrices(...prices) {
532
+ const firstPrice = prices[0];
533
+ const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
534
+ if (allPricesInSameCurrency === false) {
535
+ throw new Error("All prices must have the same currency to be added together.");
536
+ }
537
+ const { currency } = firstPrice;
538
+ return prices.reduce(
539
+ (acc, price) => ({
540
+ amount: acc.amount + price.amount,
541
+ currency
542
+ }),
543
+ {
544
+ amount: 0n,
545
+ currency: firstPrice.currency
546
+ }
547
+ );
548
+ }
549
+
550
+ // src/shared/reinterpretation.ts
551
+ var import_viem7 = require("viem");
552
+ function reinterpretLabel(label) {
553
+ if (label === "") {
554
+ throw new Error(
555
+ `Cannot reinterpret an empty label that violates the invariants of an InterpretedLabel.`
556
+ );
557
+ }
558
+ if (isEncodedLabelHash(label)) return label;
559
+ if (isNormalizedLabel(label)) return label;
560
+ return encodeLabelHash((0, import_viem7.labelhash)(label));
561
+ }
562
+ function reinterpretName(name) {
563
+ if (name === "") return name;
564
+ const interpretedLabels = name.split(".");
565
+ const reinterpretedLabels = interpretedLabels.map(reinterpretLabel);
566
+ const reinterpretedName = reinterpretedLabels.join(".");
567
+ return reinterpretedName;
568
+ }
569
+
570
+ // src/shared/zod-schemas.ts
571
+ var makeFiniteNonNegativeNumberSchema = (valueLabel = "Value") => import_v4.default.number({
572
+ // NOTE: Zod's implementation of `number` automatically rejects NaN and Infinity values.
573
+ // and therefore the finite check is implicit.
574
+ error: `${valueLabel} must be a finite number.`
575
+ }).nonnegative({
576
+ error: `${valueLabel} must be a non-negative number (>=0).`
577
+ });
578
+ var makeIntegerSchema = (valueLabel = "Value") => import_v4.default.int({
579
+ error: `${valueLabel} must be an integer.`
580
+ });
581
+ var makePositiveIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(valueLabel).positive({
582
+ error: `${valueLabel} must be a positive integer (>0).`
583
+ });
584
+ var makeNonNegativeIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(valueLabel).nonnegative({
585
+ error: `${valueLabel} must be a non-negative integer (>=0).`
586
+ });
587
+ var makeDurationSchema = (valueLabel = "Value") => import_v4.default.coerce.number({
588
+ error: `${valueLabel} must be a number.`
589
+ }).pipe(makeNonNegativeIntegerSchema(valueLabel));
590
+ var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel).transform((val) => val);
591
+ var makeChainIdStringSchema = (valueLabel = "Chain ID String") => import_v4.default.string({ error: `${valueLabel} must be a string representing a chain ID.` }).pipe(import_v4.default.coerce.number({ error: `${valueLabel} must represent a positive integer (>0).` })).pipe(makeChainIdSchema(`The numeric value represented by ${valueLabel}`));
592
+ var makeLowercaseAddressSchema = (valueLabel = "EVM address") => import_v4.default.string().check((ctx) => {
593
+ if (!(0, import_viem8.isAddress)(ctx.value)) {
594
+ ctx.issues.push({
595
+ code: "custom",
596
+ message: `${valueLabel} must be a valid EVM address`,
597
+ input: ctx.value
598
+ });
599
+ }
600
+ }).transform((val) => asLowerCaseAddress(val));
601
+ var makeDatetimeSchema = (valueLabel = "Datetime string") => import_v4.default.iso.datetime({ error: `${valueLabel} must be a string in ISO 8601 format.` }).transform((v) => new Date(v));
602
+ var makeUnixTimestampSchema = (valueLabel = "Timestamp") => makeIntegerSchema(valueLabel);
603
+ var makeUrlSchema = (valueLabel = "Value") => import_v4.default.url({
604
+ error: `${valueLabel} must be a valid URL string (e.g., http://localhost:8080 or https://example.com).`,
605
+ abort: true
606
+ }).transform((v) => new URL(v));
607
+ var makeBlockNumberSchema = (valueLabel = "Block number") => makeNonNegativeIntegerSchema(valueLabel);
608
+ var makeBlockrangeSchema = (valueLabel = "Value") => import_v4.default.strictObject(
609
+ {
610
+ startBlock: makeBlockNumberSchema(`${valueLabel}.startBlock`).optional(),
611
+ endBlock: makeBlockNumberSchema(`${valueLabel}.endBlock`).optional()
612
+ },
613
+ {
614
+ error: `${valueLabel} must be a valid Blockrange object.`
615
+ }
616
+ ).refine(
617
+ (v) => {
618
+ if (v.startBlock && v.endBlock) {
619
+ return v.startBlock <= v.endBlock;
620
+ }
621
+ return true;
622
+ },
623
+ { error: `${valueLabel}: startBlock must be before or equal to endBlock` }
624
+ );
625
+ var makeBlockRefSchema = (valueLabel = "Value") => import_v4.default.strictObject(
626
+ {
627
+ timestamp: makeUnixTimestampSchema(`${valueLabel}.timestamp`),
628
+ number: makeBlockNumberSchema(`${valueLabel}.number`)
629
+ },
630
+ {
631
+ error: `${valueLabel} must be a valid BlockRef object.`
632
+ }
633
+ );
634
+ var makeENSNamespaceIdSchema = (valueLabel = "ENSNamespaceId") => import_v4.default.enum(import_datasources.ENSNamespaceIds, {
635
+ error() {
636
+ return `Invalid ${valueLabel}. Supported ENS namespace IDs are: ${Object.keys(import_datasources.ENSNamespaceIds).join(", ")}`;
637
+ }
638
+ });
639
+ var makePriceAmountSchema = (valueLabel = "Amount") => import_v4.default.coerce.bigint({
640
+ error: `${valueLabel} must represent a bigint.`
641
+ }).nonnegative({
642
+ error: `${valueLabel} must not be negative.`
643
+ });
644
+ var makePriceCurrencySchema = (currency, valueLabel = "Price Currency") => import_v4.default.strictObject({
645
+ amount: makePriceAmountSchema(`${valueLabel} amount`),
646
+ currency: import_v4.default.literal(currency, {
647
+ error: `${valueLabel} currency must be set to '${currency}'.`
648
+ })
649
+ });
650
+ var makePriceEthSchema = (valueLabel = "Price ETH") => makePriceCurrencySchema(CurrencyIds.ETH, valueLabel).transform((v) => v);
651
+ var makeAccountIdSchema = (valueLabel = "AccountId") => import_v4.default.strictObject({
652
+ chainId: makeChainIdSchema(`${valueLabel} chain ID`),
653
+ address: makeLowercaseAddressSchema(`${valueLabel} address`)
654
+ });
655
+ var makeAccountIdStringSchema = (valueLabel = "Account ID String") => import_v4.default.coerce.string().transform((v) => {
656
+ const result = new import_caip.AccountId(v);
657
+ return {
658
+ chainId: Number(result.chainId.reference),
659
+ address: result.address
660
+ };
661
+ }).pipe(makeAccountIdSchema(valueLabel));
662
+ var makeHexStringSchema = (options, valueLabel = "String representation of bytes array") => import_v4.default.string().check(function invariant_isHexEncoded(ctx) {
663
+ if (!(0, import_viem8.isHex)(ctx.value)) {
664
+ ctx.issues.push({
665
+ code: "custom",
666
+ input: ctx.value,
667
+ message: `${valueLabel} must be a hexadecimal value which starts with '0x'.`
668
+ });
669
+ }
670
+ }).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
671
+ const expectedBytesCount = options.bytesCount;
672
+ const actualBytesCount = (0, import_viem8.size)(ctx.value);
673
+ if (actualBytesCount !== expectedBytesCount) {
674
+ ctx.issues.push({
675
+ code: "custom",
676
+ input: ctx.value,
677
+ message: `${valueLabel} must represent exactly ${expectedBytesCount} bytes. Currently represented bytes count: ${actualBytesCount}.`
678
+ });
679
+ }
680
+ });
681
+ var makeNodeSchema = (valueLabel = "Node") => makeHexStringSchema({ bytesCount: 32 }, valueLabel);
682
+ var makeTransactionHashSchema = (valueLabel = "Transaction hash") => makeHexStringSchema({ bytesCount: 32 }, valueLabel);
683
+ var makeReinterpretedNameSchema = (valueLabel = "Reinterpreted Name") => import_v4.default.string().transform((v) => v).check((ctx) => {
684
+ try {
685
+ reinterpretName(ctx.value);
686
+ } catch (error) {
687
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
688
+ ctx.issues.push({
689
+ code: "custom",
690
+ input: ctx.value,
691
+ message: `${valueLabel} cannot be reinterpreted: ${errorMessage}`
692
+ });
693
+ }
694
+ }).transform(reinterpretName);
695
+
696
+ // src/shared/deserialize.ts
697
+ function deserializeChainId(maybeChainId, valueLabel) {
698
+ const schema = makeChainIdStringSchema(valueLabel);
699
+ const parsed = schema.safeParse(maybeChainId);
700
+ if (parsed.error) {
701
+ throw new Error(`Cannot deserialize ChainId:
702
+ ${(0, import_v42.prettifyError)(parsed.error)}
703
+ `);
704
+ }
705
+ return parsed.data;
706
+ }
707
+ function deserializeDatetime(maybeDatetime, valueLabel) {
708
+ const schema = makeDatetimeSchema(valueLabel);
709
+ const parsed = schema.safeParse(maybeDatetime);
710
+ if (parsed.error) {
711
+ throw new Error(`Cannot deserialize Datetime:
712
+ ${(0, import_v42.prettifyError)(parsed.error)}
713
+ `);
714
+ }
715
+ return parsed.data;
716
+ }
717
+ function deserializeUnixTimestamp(maybeTimestamp, valueLabel) {
718
+ const schema = makeUnixTimestampSchema(valueLabel);
719
+ const parsed = schema.safeParse(maybeTimestamp);
720
+ if (parsed.error) {
721
+ throw new Error(`Cannot deserialize Unix Timestamp:
722
+ ${(0, import_v42.prettifyError)(parsed.error)}
723
+ `);
724
+ }
725
+ return parsed.data;
726
+ }
727
+ function deserializeUrl(maybeUrl, valueLabel) {
728
+ const schema = makeUrlSchema(valueLabel);
729
+ const parsed = schema.safeParse(maybeUrl);
730
+ if (parsed.error) {
731
+ throw new Error(`Cannot deserialize URL:
732
+ ${(0, import_v42.prettifyError)(parsed.error)}
733
+ `);
734
+ }
735
+ return parsed.data;
736
+ }
737
+ function deserializeBlockNumber(maybeBlockNumber, valueLabel) {
738
+ const schema = makeBlockNumberSchema(valueLabel);
739
+ const parsed = schema.safeParse(maybeBlockNumber);
740
+ if (parsed.error) {
741
+ throw new Error(`Cannot deserialize BlockNumber:
742
+ ${(0, import_v42.prettifyError)(parsed.error)}
743
+ `);
744
+ }
745
+ return parsed.data;
746
+ }
747
+ function deserializeBlockrange(maybeBlockrange, valueLabel) {
748
+ const schema = makeBlockrangeSchema(valueLabel);
749
+ const parsed = schema.safeParse(maybeBlockrange);
750
+ if (parsed.error) {
751
+ throw new Error(`Cannot deserialize Blockrange:
752
+ ${(0, import_v42.prettifyError)(parsed.error)}
753
+ `);
754
+ }
755
+ return parsed.data;
756
+ }
757
+ function deserializeBlockRef(maybeBlockRef, valueLabel) {
758
+ const schema = makeBlockRefSchema(valueLabel);
759
+ const parsed = schema.safeParse(maybeBlockRef);
760
+ if (parsed.error) {
761
+ throw new Error(`Cannot deserialize BlockRef:
762
+ ${(0, import_v42.prettifyError)(parsed.error)}
763
+ `);
764
+ }
765
+ return parsed.data;
766
+ }
767
+ function deserializeDuration(maybeDuration, valueLabel) {
768
+ const schema = makeDurationSchema(valueLabel);
769
+ const parsed = schema.safeParse(maybeDuration);
770
+ if (parsed.error) {
771
+ throw new RangeError(`Cannot deserialize Duration:
772
+ ${(0, import_v42.prettifyError)(parsed.error)}
773
+ `);
774
+ }
775
+ return parsed.data;
776
+ }
777
+ function parseAccountId(maybeAccountId, valueLabel) {
778
+ const schema = makeAccountIdStringSchema(valueLabel);
779
+ const parsed = schema.safeParse(maybeAccountId);
780
+ if (parsed.error) {
781
+ throw new RangeError(`Cannot deserialize AccountId:
782
+ ${(0, import_v42.prettifyError)(parsed.error)}
783
+ `);
784
+ }
785
+ return parsed.data;
786
+ }
787
+
788
+ // src/shared/datetime.ts
789
+ function durationBetween(start, end) {
790
+ return deserializeDuration(end - start, "Duration");
791
+ }
792
+ function addDuration(timestamp, duration) {
793
+ return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
794
+ }
795
+
796
+ // src/shared/cache/swr-cache.ts
797
+ var SWRCache = class {
798
+ constructor(options) {
799
+ this.options = options;
800
+ if (options.proactiveRevalidationInterval) {
801
+ this.backgroundInterval = setInterval(
802
+ () => this.revalidate(),
803
+ (0, import_date_fns.secondsToMilliseconds)(options.proactiveRevalidationInterval)
804
+ );
805
+ }
806
+ if (options.proactivelyInitialize) this.revalidate();
807
+ }
808
+ cache = null;
809
+ inProgressRevalidate = null;
810
+ backgroundInterval = null;
811
+ async revalidate() {
812
+ if (!this.inProgressRevalidate) {
813
+ this.inProgressRevalidate = this.options.fn().then((result) => {
814
+ this.cache = {
815
+ result,
816
+ updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
817
+ };
818
+ }).catch((error) => {
819
+ if (!this.cache) {
820
+ this.cache = {
821
+ // ensure thrown value is always an Error instance
822
+ result: error instanceof Error ? error : new Error(String(error)),
823
+ updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
824
+ };
825
+ }
826
+ }).finally(() => {
827
+ this.inProgressRevalidate = null;
828
+ });
829
+ }
830
+ return this.inProgressRevalidate;
831
+ }
832
+ /**
833
+ * Read the most recently cached result from the `SWRCache`.
834
+ *
835
+ * @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
836
+ * has never successfully returned.
837
+ */
838
+ async read() {
839
+ if (!this.cache) await this.revalidate();
840
+ if (!this.cache) throw new Error("never");
841
+ if (durationBetween(this.cache.updatedAt, (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())) > this.options.ttl) {
842
+ this.revalidate();
843
+ }
844
+ return this.cache.result;
845
+ }
846
+ /**
847
+ * Destroys the background revalidation interval, if exists.
848
+ */
849
+ destroy() {
850
+ if (this.backgroundInterval) {
851
+ clearInterval(this.backgroundInterval);
852
+ this.backgroundInterval = null;
853
+ }
854
+ }
855
+ };
856
+
857
+ // src/shared/cache/ttl-cache.ts
858
+ var import_getUnixTime2 = require("date-fns/getUnixTime");
859
+ var TtlCache = class {
860
+ _cache = /* @__PURE__ */ new Map();
861
+ _ttl;
862
+ /**
863
+ * Create a new TTL cache with the given TTL.
864
+ *
865
+ * @param ttl Time-to-live duration in seconds. Items expire after this duration.
866
+ */
867
+ constructor(ttl) {
868
+ this._ttl = ttl;
869
+ }
870
+ _cleanup() {
871
+ const now = (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date());
872
+ for (const [key, entry] of this._cache.entries()) {
873
+ if (entry.expiresAt <= now) {
874
+ this._cache.delete(key);
875
+ }
876
+ }
877
+ }
878
+ set(key, value) {
879
+ this._cleanup();
880
+ const expiresAt = addDuration((0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date()), this._ttl);
881
+ this._cache.set(key, { value, expiresAt });
882
+ }
883
+ get(key) {
884
+ this._cleanup();
885
+ const entry = this._cache.get(key);
886
+ if (!entry) {
887
+ return void 0;
888
+ }
889
+ if (entry.expiresAt <= (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date())) {
890
+ this._cache.delete(key);
891
+ return void 0;
892
+ }
893
+ return entry.value;
894
+ }
895
+ clear() {
896
+ this._cache.clear();
897
+ }
898
+ get size() {
899
+ this._cleanup();
900
+ return this._cache.size;
901
+ }
902
+ get capacity() {
903
+ return Number.MAX_SAFE_INTEGER;
904
+ }
905
+ has(key) {
906
+ this._cleanup();
907
+ const entry = this._cache.get(key);
908
+ if (!entry) {
909
+ return false;
910
+ }
911
+ if (entry.expiresAt <= (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date())) {
912
+ this._cache.delete(key);
913
+ return false;
914
+ }
915
+ return true;
916
+ }
917
+ delete(key) {
918
+ return this._cache.delete(key);
919
+ }
920
+ };
921
+
922
+ // src/shared/collections.ts
923
+ var uniq = (arr) => [...new Set(arr)];
924
+
925
+ // src/shared/datasource-contract.ts
926
+ var import_datasources3 = require("@ensnode/datasources");
927
+ var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
928
+ const datasource = (0, import_datasources3.maybeGetDatasource)(namespaceId, datasourceName);
929
+ if (!datasource) return void 0;
930
+ const address = datasource.contracts[contractName]?.address;
931
+ if (address === void 0 || Array.isArray(address)) return void 0;
932
+ return {
933
+ chainId: datasource.chain.id,
934
+ address
935
+ };
936
+ };
937
+ var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
938
+ const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
939
+ if (!contract) {
940
+ throw new Error(
941
+ `Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
942
+ );
943
+ }
944
+ return contract;
945
+ };
946
+
947
+ // src/shared/labelhash.ts
948
+ var import_viem9 = require("viem");
949
+ var labelhashLiteralLabel = (label) => (0, import_viem9.keccak256)((0, import_viem9.stringToBytes)(label));
950
+
951
+ // src/shared/interpretation.ts
952
+ function literalLabelToInterpretedLabel(label) {
953
+ if (isNormalizedLabel(label)) return label;
954
+ return encodeLabelHash(labelhashLiteralLabel(label));
955
+ }
956
+ function literalLabelsToInterpretedName(labels) {
957
+ return labels.map(literalLabelToInterpretedLabel).join(".");
958
+ }
959
+ function interpretedLabelsToInterpretedName(labels) {
960
+ return labels.join(".");
961
+ }
962
+ function literalLabelsToLiteralName(labels) {
963
+ return labels.join(".");
964
+ }
965
+
966
+ // src/shared/null-bytes.ts
967
+ var hasNullByte = (value) => value.indexOf("\0") !== -1;
968
+ var stripNullBytes = (value) => value.replaceAll("\0", "");
969
+
970
+ // src/shared/numbers.ts
971
+ function bigIntToNumber(n) {
972
+ if (n < Number.MIN_SAFE_INTEGER) {
973
+ throw new Error(
974
+ `The bigint '${n.toString()}' value is too low to be to converted into a number.'`
975
+ );
976
+ }
977
+ if (n > Number.MAX_SAFE_INTEGER) {
978
+ throw new Error(
979
+ `The bigint '${n.toString()}' value is too high to be to converted into a number.'`
980
+ );
981
+ }
982
+ return Number(n);
983
+ }
984
+
985
+ // src/shared/serialize.ts
986
+ var import_caip2 = require("caip");
987
+ function serializeChainId(chainId) {
988
+ return chainId.toString();
989
+ }
990
+ function serializeDatetime(datetime) {
991
+ return datetime.toISOString();
992
+ }
993
+ function serializeUrl(url) {
994
+ return url.toString();
995
+ }
996
+ function serializePrice(price) {
997
+ return {
998
+ currency: price.currency,
999
+ amount: price.amount.toString()
1000
+ };
1001
+ }
1002
+ function serializePriceEth(price) {
1003
+ return serializePrice(price);
1004
+ }
1005
+ function formatAccountId(accountId) {
1006
+ return import_caip2.AccountId.format({
1007
+ chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
1008
+ address: accountId.address
1009
+ }).toLowerCase();
1010
+ }
1011
+
1012
+ // src/shared/url.ts
1013
+ function isHttpProtocol(url) {
1014
+ return ["http:", "https:"].includes(url.protocol);
1015
+ }
1016
+ function isWebSocketProtocol(url) {
1017
+ return ["ws:", "wss:"].includes(url.protocol);
1018
+ }
1019
+
1020
+ // src/ensindexer/config/is-subgraph-compatible.ts
1021
+ var import_datasources4 = require("@ensnode/datasources");
1022
+
1023
+ // src/ensindexer/config/types.ts
1024
+ var PluginName = /* @__PURE__ */ ((PluginName2) => {
1025
+ PluginName2["Subgraph"] = "subgraph";
1026
+ PluginName2["Basenames"] = "basenames";
1027
+ PluginName2["Lineanames"] = "lineanames";
1028
+ PluginName2["ThreeDNS"] = "threedns";
1029
+ PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
1030
+ PluginName2["Registrars"] = "registrars";
1031
+ PluginName2["TokenScope"] = "tokenscope";
1032
+ return PluginName2;
1033
+ })(PluginName || {});
1034
+
1035
+ // src/ensindexer/config/is-subgraph-compatible.ts
1036
+ function isSubgraphCompatible(config) {
1037
+ const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
1038
+ const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
1039
+ const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
1040
+ const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === import_datasources4.ENSNamespaceIds.EnsTestEnv && isEnsTestEnvLabelSet;
1041
+ return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
1042
+ }
1043
+
1044
+ // src/ensindexer/config/validations.ts
1045
+ function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
1046
+ const versionInfo = ctx.value;
1047
+ if (versionInfo.ensDb !== versionInfo.ensIndexer) {
1048
+ ctx.issues.push({
1049
+ code: "custom",
1050
+ input: versionInfo,
1051
+ message: "`ensDb` version must be same as `ensIndexer` version"
1052
+ });
1053
+ }
1054
+ }
1055
+
1056
+ // src/ensindexer/config/zod-schemas.ts
1057
+ var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => import_v43.default.array(makeChainIdSchema(valueLabel), {
1058
+ error: `${valueLabel} must be an array.`
1059
+ }).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
1060
+ var makePluginsListSchema = (valueLabel = "Plugins") => import_v43.default.array(import_v43.default.string(), {
1061
+ error: `${valueLabel} must be a list of strings.`
1062
+ }).min(1, {
1063
+ error: `${valueLabel} must be a list of strings with at least one string value`
1064
+ }).refine((arr) => arr.length === uniq(arr).length, {
1065
+ error: `${valueLabel} cannot contain duplicate values.`
1066
+ });
1067
+ var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => import_v43.default.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
1068
+ error: `${valueLabel} is required and must be a non-empty string.`
1069
+ });
1070
+ var makeLabelSetIdSchema = (valueLabel) => {
1071
+ return import_v43.default.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-]+$/, {
1072
+ error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
1073
+ });
1074
+ };
1075
+ var makeLabelSetVersionSchema = (valueLabel) => {
1076
+ return import_v43.default.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
1077
+ };
1078
+ var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
1079
+ let valueLabelLabelSetId = valueLabel;
1080
+ let valueLabelLabelSetVersion = valueLabel;
1081
+ if (valueLabel === "LABEL_SET") {
1082
+ valueLabelLabelSetId = "LABEL_SET_ID";
1083
+ valueLabelLabelSetVersion = "LABEL_SET_VERSION";
1084
+ } else {
1085
+ valueLabelLabelSetId = `${valueLabel}.labelSetId`;
1086
+ valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
1087
+ }
1088
+ return import_v43.default.object({
1089
+ labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
1090
+ labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
1091
+ });
1092
+ };
1093
+ var makeNonEmptyStringSchema = (valueLabel = "Value") => import_v43.default.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
1094
+ var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => import_v43.default.strictObject(
1095
+ {
1096
+ nodejs: makeNonEmptyStringSchema(),
1097
+ ponder: makeNonEmptyStringSchema(),
1098
+ ensDb: makeNonEmptyStringSchema(),
1099
+ ensIndexer: makeNonEmptyStringSchema(),
1100
+ ensNormalize: makeNonEmptyStringSchema(),
1101
+ ensRainbow: makeNonEmptyStringSchema(),
1102
+ ensRainbowSchema: makePositiveIntegerSchema()
1103
+ },
1104
+ {
1105
+ error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
1106
+ }
1107
+ ).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
1108
+ function invariant_isSubgraphCompatibleRequirements(ctx) {
1109
+ const { value: config } = ctx;
1110
+ if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
1111
+ ctx.issues.push({
1112
+ code: "custom",
1113
+ input: config,
1114
+ message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
1115
+ });
1116
+ }
1117
+ }
1118
+ var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => import_v43.default.object({
1119
+ labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
1120
+ indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
1121
+ isSubgraphCompatible: import_v43.default.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
1122
+ namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
1123
+ plugins: makePluginsListSchema(`${valueLabel}.plugins`),
1124
+ databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
1125
+ versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
1126
+ }).check(invariant_isSubgraphCompatibleRequirements);
1127
+
1128
+ // src/shared/config/thegraph.ts
1129
+ var import_v44 = require("zod/v4");
1130
+ var TheGraphCannotFallbackReasonSchema = import_v44.z.enum({
1131
+ NotSubgraphCompatible: "not-subgraph-compatible",
1132
+ NoApiKey: "no-api-key",
1133
+ NoSubgraphUrl: "no-subgraph-url"
1134
+ });
1135
+ var TheGraphFallbackSchema = import_v44.z.discriminatedUnion("canFallback", [
1136
+ import_v44.z.strictObject({
1137
+ canFallback: import_v44.z.literal(true),
1138
+ url: import_v44.z.string()
1139
+ }),
1140
+ import_v44.z.strictObject({
1141
+ canFallback: import_v44.z.literal(false),
1142
+ reason: TheGraphCannotFallbackReasonSchema
1143
+ })
1144
+ ]);
1145
+
1146
+ // src/ensapi/config/zod-schemas.ts
1147
+ function makeENSApiPublicConfigSchema(valueLabel) {
1148
+ const label = valueLabel ?? "ENSApiPublicConfig";
1149
+ return import_v45.z.strictObject({
1150
+ version: import_v45.z.string().min(1, `${label}.version must be a non-empty string`),
1151
+ theGraphFallback: TheGraphFallbackSchema,
1152
+ ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
1153
+ });
1154
+ }
1155
+
1156
+ // src/ensapi/config/deserialize.ts
1157
+ function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
1158
+ const schema = makeENSApiPublicConfigSchema(valueLabel);
1159
+ try {
1160
+ return schema.parse(maybeConfig);
1161
+ } catch (error) {
1162
+ if (error instanceof import_v46.ZodError) {
1163
+ throw new Error(`Cannot deserialize ENSApiPublicConfig:
1164
+ ${(0, import_v46.prettifyError)(error)}
1165
+ `);
1166
+ }
1167
+ throw error;
1168
+ }
1169
+ }
1170
+
1171
+ // src/ensindexer/config/deserialize.ts
1172
+ var import_v47 = require("zod/v4");
1173
+ function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
1174
+ const schema = makeENSIndexerPublicConfigSchema(valueLabel);
1175
+ const parsed = schema.safeParse(maybeConfig);
1176
+ if (parsed.error) {
1177
+ throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
1178
+ ${(0, import_v47.prettifyError)(parsed.error)}
1179
+ `);
1180
+ }
1181
+ return parsed.data;
1182
+ }
1183
+
1184
+ // src/ensindexer/config/label-utils.ts
1185
+ var import_viem10 = require("viem");
1186
+ function labelHashToBytes(labelHash) {
1187
+ try {
1188
+ if (labelHash.length !== 66) {
1189
+ throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
1190
+ }
1191
+ if (labelHash !== labelHash.toLowerCase()) {
1192
+ throw new Error("Labelhash must be in lowercase");
1193
+ }
1194
+ if (!labelHash.startsWith("0x")) {
1195
+ throw new Error("Labelhash must be 0x-prefixed");
1196
+ }
1197
+ const bytes = (0, import_viem10.hexToBytes)(labelHash);
1198
+ if (bytes.length !== 32) {
1199
+ throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
1200
+ }
1201
+ return bytes;
1202
+ } catch (e) {
1203
+ if (e instanceof Error) {
1204
+ throw e;
1205
+ }
1206
+ throw new Error("Invalid hex format");
1207
+ }
1208
+ }
1209
+
1210
+ // src/ensindexer/config/labelset-utils.ts
1211
+ function buildLabelSetId(maybeLabelSetId) {
1212
+ return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
1213
+ }
1214
+ function buildLabelSetVersion(maybeLabelSetVersion) {
1215
+ return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
1216
+ }
1217
+ function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
1218
+ if (labelSetVersion !== void 0 && labelSetId === void 0) {
1219
+ throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
1220
+ }
1221
+ return { labelSetId, labelSetVersion };
1222
+ }
1223
+ function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
1224
+ if (clientSet.labelSetId === void 0) {
1225
+ return;
1226
+ }
1227
+ if (serverSet.labelSetId !== clientSet.labelSetId) {
1228
+ throw new Error(
1229
+ `Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
1230
+ );
1231
+ }
1232
+ if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
1233
+ throw new Error(
1234
+ `Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
1235
+ );
1236
+ }
1237
+ }
1238
+
1239
+ // src/ensindexer/config/parsing.ts
1240
+ function parseNonNegativeInteger(maybeNumber) {
1241
+ const trimmed = maybeNumber.trim();
1242
+ if (!trimmed) {
1243
+ throw new Error("Input cannot be empty");
1244
+ }
1245
+ if (trimmed === "-0") {
1246
+ throw new Error("Negative zero is not a valid non-negative integer");
1247
+ }
1248
+ const num = Number(maybeNumber);
1249
+ if (Number.isNaN(num)) {
1250
+ throw new Error(`"${maybeNumber}" is not a valid number`);
1251
+ }
1252
+ if (!Number.isFinite(num)) {
1253
+ throw new Error(`"${maybeNumber}" is not a finite number`);
1254
+ }
1255
+ if (!Number.isInteger(num)) {
1256
+ throw new Error(`"${maybeNumber}" is not an integer`);
1257
+ }
1258
+ if (num < 0) {
1259
+ throw new Error(`"${maybeNumber}" is not a non-negative integer`);
1260
+ }
1261
+ return num;
1262
+ }
1263
+
1264
+ // src/ensindexer/config/serialize.ts
1265
+ function serializeIndexedChainIds(indexedChainIds) {
1266
+ return Array.from(indexedChainIds);
1267
+ }
1268
+ function serializeENSIndexerPublicConfig(config) {
1269
+ const {
1270
+ labelSet,
1271
+ indexedChainIds,
1272
+ databaseSchemaName,
1273
+ isSubgraphCompatible: isSubgraphCompatible2,
1274
+ namespace,
1275
+ plugins,
1276
+ versionInfo
1277
+ } = config;
1278
+ return {
1279
+ labelSet,
1280
+ indexedChainIds: serializeIndexedChainIds(indexedChainIds),
1281
+ databaseSchemaName,
1282
+ isSubgraphCompatible: isSubgraphCompatible2,
1283
+ namespace,
1284
+ plugins,
1285
+ versionInfo
1286
+ };
1287
+ }
1288
+
1289
+ // src/ensindexer/indexing-status/deserialize.ts
1290
+ var import_v49 = require("zod/v4");
1291
+
1292
+ // src/ensindexer/indexing-status/zod-schemas.ts
1293
+ var import_v48 = __toESM(require("zod/v4"), 1);
1294
+
1295
+ // src/ensindexer/indexing-status/types.ts
1296
+ var ChainIndexingConfigTypeIds = {
1297
+ /**
1298
+ * Represents that indexing of the chain should be performed for an indefinite range.
1299
+ */
1300
+ Indefinite: "indefinite",
1301
+ /**
1302
+ * Represents that indexing of the chain should be performed for a definite range.
1303
+ */
1304
+ Definite: "definite"
1305
+ };
1306
+ var ChainIndexingStatusIds = {
1307
+ /**
1308
+ * Represents that indexing of the chain is not ready to begin yet because:
1309
+ * - ENSIndexer is in its initialization phase and the data to build a
1310
+ * "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
1311
+ * - ENSIndexer is using an omnichain indexing strategy and the
1312
+ * `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
1313
+ * {@link ChainIndexingSnapshot}.
1314
+ */
1315
+ Queued: "chain-queued",
1316
+ /**
1317
+ * Represents that indexing of the chain is in progress and under a special
1318
+ * "backfill" phase that optimizes for accelerated indexing until reaching the
1319
+ * "fixed target" `backfillEndBlock`.
1320
+ */
1321
+ Backfill: "chain-backfill",
1322
+ /**
1323
+ * Represents that the "backfill" phase of indexing the chain is completed
1324
+ * and that the chain is configured to be indexed for an indefinite range.
1325
+ * Therefore, indexing of the chain remains indefinitely in progress where
1326
+ * ENSIndexer will continuously work to discover and index new blocks as they
1327
+ * are added to the chain across time.
1328
+ */
1329
+ Following: "chain-following",
1330
+ /**
1331
+ * Represents that indexing of the chain is completed as the chain is configured
1332
+ * to be indexed for a definite range and the indexing of all blocks through
1333
+ * that definite range is completed.
1334
+ */
1335
+ Completed: "chain-completed"
1336
+ };
1337
+ var OmnichainIndexingStatusIds = {
1338
+ /**
1339
+ * Represents that omnichain indexing is not ready to begin yet because
1340
+ * ENSIndexer is in its initialization phase and the data to build a "true"
1341
+ * {@link OmnichainIndexingStatusSnapshot} is still being loaded.
1342
+ */
1343
+ Unstarted: "omnichain-unstarted",
1344
+ /**
1345
+ * Represents that omnichain indexing is in an overall "backfill" status because
1346
+ * - At least one indexed chain has a `chainStatus` of
1347
+ * {@link ChainIndexingStatusIds.Backfill}; and
1348
+ * - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
1349
+ */
1350
+ Backfill: "omnichain-backfill",
1351
+ /**
1352
+ * Represents that omnichain indexing is in an overall "following" status because
1353
+ * at least one indexed chain has a `chainStatus` of
1354
+ * {@link ChainIndexingStatusIds.Following}.
1355
+ */
1356
+ Following: "omnichain-following",
1357
+ /**
1358
+ * Represents that omnichain indexing has completed because all indexed chains have
1359
+ * a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
1360
+ */
1361
+ Completed: "omnichain-completed"
1362
+ };
1363
+ var CrossChainIndexingStrategyIds = {
1364
+ /**
1365
+ * Represents that the indexing of events across all indexed chains will
1366
+ * proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
1367
+ * and block number.
1368
+ *
1369
+ * This strategy is "deterministic" in that the order of processing cross-chain indexed
1370
+ * events and each resulting indexed data state transition recorded in ENSDb is always
1371
+ * the same for each ENSIndexer instance operating with an equivalent
1372
+ * `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
1373
+ * - increased indexing latency that must wait for the slowest indexed chain to
1374
+ * add new blocks or to discover new blocks through the configured RPCs.
1375
+ * - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
1376
+ * will be affected.
1377
+ */
1378
+ Omnichain: "omnichain"
1379
+ };
1380
+
1381
+ // src/shared/block-ref.ts
1382
+ function isBefore(blockA, blockB) {
1383
+ return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
1384
+ }
1385
+ function isEqualTo(blockA, blockB) {
1386
+ return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
1387
+ }
1388
+ function isBeforeOrEqualTo(blockA, blockB) {
1389
+ return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
1390
+ }
1391
+
1392
+ // src/ensindexer/indexing-status/helpers.ts
1393
+ function getOmnichainIndexingStatus(chains) {
1394
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
1395
+ return OmnichainIndexingStatusIds.Following;
1396
+ }
1397
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
1398
+ return OmnichainIndexingStatusIds.Backfill;
1399
+ }
1400
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
1401
+ return OmnichainIndexingStatusIds.Unstarted;
1402
+ }
1403
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
1404
+ return OmnichainIndexingStatusIds.Completed;
1405
+ }
1406
+ throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
1407
+ }
1408
+ function getTimestampForLowestOmnichainStartBlock(chains) {
1409
+ const earliestKnownBlockTimestamps = chains.map(
1410
+ (chain) => chain.config.startBlock.timestamp
1411
+ );
1412
+ return Math.min(...earliestKnownBlockTimestamps);
1413
+ }
1414
+ function getTimestampForHighestOmnichainKnownBlock(chains) {
1415
+ const latestKnownBlockTimestamps = [];
1416
+ for (const chain of chains) {
1417
+ switch (chain.chainStatus) {
1418
+ case ChainIndexingStatusIds.Queued:
1419
+ if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
1420
+ latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
1421
+ }
1422
+ break;
1423
+ case ChainIndexingStatusIds.Backfill:
1424
+ latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
1425
+ break;
1426
+ case ChainIndexingStatusIds.Completed:
1427
+ latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
1428
+ break;
1429
+ case ChainIndexingStatusIds.Following:
1430
+ latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
1431
+ break;
1432
+ }
1433
+ }
1434
+ return Math.max(...latestKnownBlockTimestamps);
1435
+ }
1436
+ function getOmnichainIndexingCursor(chains) {
1437
+ if (chains.length === 0) {
1438
+ throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
1439
+ }
1440
+ if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
1441
+ const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1442
+ return Math.min(...earliestStartBlockTimestamps) - 1;
1443
+ }
1444
+ const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
1445
+ if (latestIndexedBlockTimestamps.length < 1) {
1446
+ throw new Error("latestIndexedBlockTimestamps array must include at least one element");
1447
+ }
1448
+ return Math.max(...latestIndexedBlockTimestamps);
1449
+ }
1450
+ function createIndexingConfig(startBlock, endBlock) {
1451
+ if (endBlock) {
1452
+ return {
1453
+ configType: ChainIndexingConfigTypeIds.Definite,
1454
+ startBlock,
1455
+ endBlock
1456
+ };
1457
+ }
1458
+ return {
1459
+ configType: ChainIndexingConfigTypeIds.Indefinite,
1460
+ startBlock
1461
+ };
1462
+ }
1463
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
1464
+ return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
1465
+ }
1466
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
1467
+ const atLeastOneChainInTargetStatus = chains.some(
1468
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1469
+ );
1470
+ const otherChainsHaveValidStatuses = chains.every(
1471
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
1472
+ );
1473
+ return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
1474
+ }
1475
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
1476
+ const allChainsHaveValidStatuses = chains.every(
1477
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
1478
+ );
1479
+ return allChainsHaveValidStatuses;
1480
+ }
1481
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
1482
+ const allChainsHaveValidStatuses = chains.some(
1483
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Following
1484
+ );
1485
+ return allChainsHaveValidStatuses;
1486
+ }
1487
+ function sortChainStatusesByStartBlockAsc(chains) {
1488
+ chains.sort(
1489
+ ([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
1490
+ );
1491
+ return chains;
1492
+ }
1493
+ function getLatestIndexedBlockRef(indexingStatus, chainId) {
1494
+ const chainIndexingStatus = indexingStatus.omnichainSnapshot.chains.get(chainId);
1495
+ if (chainIndexingStatus === void 0) {
1496
+ return null;
1497
+ }
1498
+ if (chainIndexingStatus.chainStatus === ChainIndexingStatusIds.Queued) {
1499
+ return null;
1500
+ }
1501
+ return chainIndexingStatus.latestIndexedBlock;
1502
+ }
1503
+
1504
+ // src/ensindexer/indexing-status/validations.ts
1505
+ function invariant_chainSnapshotQueuedBlocks(ctx) {
1506
+ const { config } = ctx.value;
1507
+ if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
1508
+ return;
1509
+ }
1510
+ if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
1511
+ ctx.issues.push({
1512
+ code: "custom",
1513
+ input: ctx.value,
1514
+ message: "`config.startBlock` must be before or same as `config.endBlock`."
1515
+ });
1516
+ }
1517
+ }
1518
+ function invariant_chainSnapshotBackfillBlocks(ctx) {
1519
+ const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
1520
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1521
+ ctx.issues.push({
1522
+ code: "custom",
1523
+ input: ctx.value,
1524
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1525
+ });
1526
+ }
1527
+ if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
1528
+ ctx.issues.push({
1529
+ code: "custom",
1530
+ input: ctx.value,
1531
+ message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
1532
+ });
1533
+ }
1534
+ if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
1535
+ return;
1536
+ }
1537
+ if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
1538
+ ctx.issues.push({
1539
+ code: "custom",
1540
+ input: ctx.value,
1541
+ message: "`backfillEndBlock` must be the same as `config.endBlock`."
1542
+ });
1543
+ }
1544
+ }
1545
+ function invariant_chainSnapshotCompletedBlocks(ctx) {
1546
+ const { config, latestIndexedBlock } = ctx.value;
1547
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1548
+ ctx.issues.push({
1549
+ code: "custom",
1550
+ input: ctx.value,
1551
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1552
+ });
1553
+ }
1554
+ if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
1555
+ ctx.issues.push({
1556
+ code: "custom",
1557
+ input: ctx.value,
1558
+ message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
1559
+ });
1560
+ }
1561
+ }
1562
+ function invariant_chainSnapshotFollowingBlocks(ctx) {
1563
+ const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
1564
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1565
+ ctx.issues.push({
1566
+ code: "custom",
1567
+ input: ctx.value,
1568
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1569
+ });
1570
+ }
1571
+ if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
1572
+ ctx.issues.push({
1573
+ code: "custom",
1574
+ input: ctx.value,
1575
+ message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
1576
+ });
1577
+ }
1578
+ }
1579
+ function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
1580
+ const snapshot = ctx.value;
1581
+ const chains = Array.from(snapshot.chains.values());
1582
+ const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
1583
+ const actualOmnichainStatus = snapshot.omnichainStatus;
1584
+ if (expectedOmnichainStatus !== actualOmnichainStatus) {
1585
+ ctx.issues.push({
1586
+ code: "custom",
1587
+ input: snapshot,
1588
+ message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
1589
+ });
1590
+ }
1591
+ }
1592
+ function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
1593
+ const snapshot = ctx.value;
1594
+ const queuedChains = Array.from(snapshot.chains.values()).filter(
1595
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
1596
+ );
1597
+ if (queuedChains.length === 0) {
1598
+ return;
1599
+ }
1600
+ const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
1601
+ const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
1602
+ if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
1603
+ ctx.issues.push({
1604
+ code: "custom",
1605
+ input: snapshot,
1606
+ message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
1607
+ });
1608
+ }
1609
+ }
1610
+ function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
1611
+ const snapshot = ctx.value;
1612
+ const backfillChains = Array.from(snapshot.chains.values()).filter(
1613
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1614
+ );
1615
+ if (backfillChains.length === 0) {
1616
+ return;
1617
+ }
1618
+ const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
1619
+ const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
1620
+ if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
1621
+ ctx.issues.push({
1622
+ code: "custom",
1623
+ input: snapshot,
1624
+ message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
1625
+ });
1626
+ }
1627
+ }
1628
+ function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
1629
+ const snapshot = ctx.value;
1630
+ const indexedChains = Array.from(snapshot.chains.values()).filter(
1631
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
1632
+ );
1633
+ if (indexedChains.length === 0) {
1634
+ return;
1635
+ }
1636
+ const indexedChainLatestIndexedBlocks = indexedChains.map(
1637
+ (chain) => chain.latestIndexedBlock.timestamp
1638
+ );
1639
+ const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
1640
+ if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
1641
+ ctx.issues.push({
1642
+ code: "custom",
1643
+ input: snapshot,
1644
+ message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
1645
+ });
1646
+ }
1647
+ }
1648
+ function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
1649
+ const chains = ctx.value;
1650
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
1651
+ Array.from(chains.values())
1652
+ );
1653
+ if (hasValidChains === false) {
1654
+ ctx.issues.push({
1655
+ code: "custom",
1656
+ input: chains,
1657
+ message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
1658
+ });
1659
+ }
1660
+ }
1661
+ function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
1662
+ const chains = ctx.value;
1663
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
1664
+ Array.from(chains.values())
1665
+ );
1666
+ if (hasValidChains === false) {
1667
+ ctx.issues.push({
1668
+ code: "custom",
1669
+ input: chains,
1670
+ 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".`
1671
+ });
1672
+ }
1673
+ }
1674
+ function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
1675
+ const chains = ctx.value;
1676
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
1677
+ Array.from(chains.values())
1678
+ );
1679
+ if (hasValidChains === false) {
1680
+ ctx.issues.push({
1681
+ code: "custom",
1682
+ input: chains,
1683
+ message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
1684
+ });
1685
+ }
1686
+ }
1687
+ function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
1688
+ const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
1689
+ const { omnichainIndexingCursor } = omnichainSnapshot;
1690
+ if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
1691
+ console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
1692
+ slowestChainIndexingCursor,
1693
+ omnichainIndexingCursor
1694
+ });
1695
+ ctx.issues.push({
1696
+ code: "custom",
1697
+ input: ctx.value,
1698
+ message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
1699
+ });
1700
+ }
1701
+ }
1702
+ function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
1703
+ const { snapshotTime, omnichainSnapshot } = ctx.value;
1704
+ const chains = Array.from(omnichainSnapshot.chains.values());
1705
+ const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1706
+ const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
1707
+ const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
1708
+ const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
1709
+ const highestKnownBlockTimestamp = Math.max(
1710
+ ...startBlockTimestamps,
1711
+ ...endBlockTimestamps,
1712
+ ...backfillEndBlockTimestamps,
1713
+ ...latestKnownBlockTimestamps
1714
+ );
1715
+ if (snapshotTime < highestKnownBlockTimestamp) {
1716
+ ctx.issues.push({
1717
+ code: "custom",
1718
+ input: ctx.value,
1719
+ message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
1720
+ });
1721
+ }
1722
+ }
1723
+ function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
1724
+ const projection = ctx.value;
1725
+ const { snapshot, projectedAt } = projection;
1726
+ if (snapshot.snapshotTime > projectedAt) {
1727
+ ctx.issues.push({
1728
+ code: "custom",
1729
+ input: projection,
1730
+ message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
1731
+ });
1732
+ }
1733
+ }
1734
+ function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
1735
+ const projection = ctx.value;
1736
+ const { projectedAt, snapshot, worstCaseDistance } = projection;
1737
+ const { omnichainSnapshot } = snapshot;
1738
+ const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
1739
+ if (worstCaseDistance !== expectedWorstCaseDistance) {
1740
+ ctx.issues.push({
1741
+ code: "custom",
1742
+ input: projection,
1743
+ message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
1744
+ });
1745
+ }
1746
+ }
1747
+
1748
+ // src/ensindexer/indexing-status/zod-schemas.ts
1749
+ var makeChainIndexingConfigSchema = (valueLabel = "Value") => import_v48.default.discriminatedUnion("configType", [
1750
+ import_v48.default.strictObject({
1751
+ configType: import_v48.default.literal(ChainIndexingConfigTypeIds.Indefinite),
1752
+ startBlock: makeBlockRefSchema(valueLabel)
1753
+ }),
1754
+ import_v48.default.strictObject({
1755
+ configType: import_v48.default.literal(ChainIndexingConfigTypeIds.Definite),
1756
+ startBlock: makeBlockRefSchema(valueLabel),
1757
+ endBlock: makeBlockRefSchema(valueLabel)
1758
+ })
1759
+ ]);
1760
+ var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => import_v48.default.strictObject({
1761
+ chainStatus: import_v48.default.literal(ChainIndexingStatusIds.Queued),
1762
+ config: makeChainIndexingConfigSchema(valueLabel)
1763
+ }).check(invariant_chainSnapshotQueuedBlocks);
1764
+ var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => import_v48.default.strictObject({
1765
+ chainStatus: import_v48.default.literal(ChainIndexingStatusIds.Backfill),
1766
+ config: makeChainIndexingConfigSchema(valueLabel),
1767
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1768
+ backfillEndBlock: makeBlockRefSchema(valueLabel)
1769
+ }).check(invariant_chainSnapshotBackfillBlocks);
1770
+ var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => import_v48.default.strictObject({
1771
+ chainStatus: import_v48.default.literal(ChainIndexingStatusIds.Completed),
1772
+ config: import_v48.default.strictObject({
1773
+ configType: import_v48.default.literal(ChainIndexingConfigTypeIds.Definite),
1774
+ startBlock: makeBlockRefSchema(valueLabel),
1775
+ endBlock: makeBlockRefSchema(valueLabel)
1776
+ }),
1777
+ latestIndexedBlock: makeBlockRefSchema(valueLabel)
1778
+ }).check(invariant_chainSnapshotCompletedBlocks);
1779
+ var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => import_v48.default.strictObject({
1780
+ chainStatus: import_v48.default.literal(ChainIndexingStatusIds.Following),
1781
+ config: import_v48.default.strictObject({
1782
+ configType: import_v48.default.literal(ChainIndexingConfigTypeIds.Indefinite),
1783
+ startBlock: makeBlockRefSchema(valueLabel)
1784
+ }),
1785
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1786
+ latestKnownBlock: makeBlockRefSchema(valueLabel)
1787
+ }).check(invariant_chainSnapshotFollowingBlocks);
1788
+ var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => import_v48.default.discriminatedUnion("chainStatus", [
1789
+ makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
1790
+ makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
1791
+ makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
1792
+ makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
1793
+ ]);
1794
+ var makeChainIndexingStatusesSchema = (valueLabel = "Value") => import_v48.default.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
1795
+ error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
1796
+ }).transform((serializedChainsIndexingStatus) => {
1797
+ const chainsIndexingStatus = /* @__PURE__ */ new Map();
1798
+ for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
1799
+ chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
1800
+ }
1801
+ return chainsIndexingStatus;
1802
+ });
1803
+ var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => import_v48.default.strictObject({
1804
+ omnichainStatus: import_v48.default.literal(OmnichainIndexingStatusIds.Unstarted),
1805
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
1806
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1807
+ });
1808
+ var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => import_v48.default.strictObject({
1809
+ omnichainStatus: import_v48.default.literal(OmnichainIndexingStatusIds.Backfill),
1810
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
1811
+ (chains) => chains
1812
+ ),
1813
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1814
+ });
1815
+ var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => import_v48.default.strictObject({
1816
+ omnichainStatus: import_v48.default.literal(OmnichainIndexingStatusIds.Completed),
1817
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
1818
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1819
+ });
1820
+ var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => import_v48.default.strictObject({
1821
+ omnichainStatus: import_v48.default.literal(OmnichainIndexingStatusIds.Following),
1822
+ chains: makeChainIndexingStatusesSchema(valueLabel),
1823
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1824
+ });
1825
+ var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => import_v48.default.discriminatedUnion("omnichainStatus", [
1826
+ makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
1827
+ makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
1828
+ makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
1829
+ makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
1830
+ ]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
1831
+ invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
1832
+ ).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
1833
+ var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => import_v48.default.strictObject({
1834
+ strategy: import_v48.default.literal(CrossChainIndexingStrategyIds.Omnichain),
1835
+ slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
1836
+ snapshotTime: makeUnixTimestampSchema(valueLabel),
1837
+ omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
1838
+ }).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
1839
+ var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => import_v48.default.discriminatedUnion("strategy", [
1840
+ makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
1841
+ ]);
1842
+ var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => import_v48.default.strictObject({
1843
+ projectedAt: makeUnixTimestampSchema(valueLabel),
1844
+ worstCaseDistance: makeDurationSchema(valueLabel),
1845
+ snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
1846
+ }).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
1847
+
1848
+ // src/ensindexer/indexing-status/deserialize.ts
1849
+ function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1850
+ const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
1851
+ const parsed = schema.safeParse(maybeSnapshot);
1852
+ if (parsed.error) {
1853
+ throw new Error(
1854
+ `Cannot deserialize into ChainIndexingStatusSnapshot:
1855
+ ${(0, import_v49.prettifyError)(parsed.error)}
1856
+ `
1857
+ );
1858
+ }
1859
+ return parsed.data;
1860
+ }
1861
+ function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1862
+ const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
1863
+ const parsed = schema.safeParse(maybeSnapshot);
1864
+ if (parsed.error) {
1865
+ throw new Error(
1866
+ `Cannot deserialize into OmnichainIndexingStatusSnapshot:
1867
+ ${(0, import_v49.prettifyError)(parsed.error)}
1868
+ `
1869
+ );
1870
+ }
1871
+ return parsed.data;
1872
+ }
1873
+ function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1874
+ const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
1875
+ const parsed = schema.safeParse(maybeSnapshot);
1876
+ if (parsed.error) {
1877
+ throw new Error(
1878
+ `Cannot deserialize into CrossChainIndexingStatusSnapshot:
1879
+ ${(0, import_v49.prettifyError)(parsed.error)}
1880
+ `
1881
+ );
1882
+ }
1883
+ return parsed.data;
1884
+ }
1885
+ function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
1886
+ const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
1887
+ const parsed = schema.safeParse(maybeProjection);
1888
+ if (parsed.error) {
1889
+ throw new Error(
1890
+ `Cannot deserialize into RealtimeIndexingStatusProjection:
1891
+ ${(0, import_v49.prettifyError)(parsed.error)}
1892
+ `
1893
+ );
1894
+ }
1895
+ return parsed.data;
1896
+ }
1897
+
1898
+ // src/ensindexer/indexing-status/projection.ts
1899
+ function createRealtimeIndexingStatusProjection(snapshot, now) {
1900
+ const projectedAt = Math.max(now, snapshot.snapshotTime);
1901
+ return {
1902
+ projectedAt,
1903
+ worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
1904
+ snapshot
1905
+ };
1906
+ }
1907
+
1908
+ // src/ensindexer/indexing-status/serialize.ts
1909
+ function serializeCrossChainIndexingStatusSnapshotOmnichain({
1910
+ strategy,
1911
+ slowestChainIndexingCursor,
1912
+ snapshotTime,
1913
+ omnichainSnapshot
1914
+ }) {
1915
+ return {
1916
+ strategy,
1917
+ slowestChainIndexingCursor,
1918
+ snapshotTime,
1919
+ omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
1920
+ };
1921
+ }
1922
+ function serializeRealtimeIndexingStatusProjection(indexingProjection) {
1923
+ return {
1924
+ projectedAt: indexingProjection.projectedAt,
1925
+ worstCaseDistance: indexingProjection.worstCaseDistance,
1926
+ snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
1927
+ };
1928
+ }
1929
+ function serializeChainIndexingSnapshots(chains) {
1930
+ const serializedSnapshots = {};
1931
+ for (const [chainId, snapshot] of chains.entries()) {
1932
+ serializedSnapshots[serializeChainId(chainId)] = snapshot;
1933
+ }
1934
+ return serializedSnapshots;
1935
+ }
1936
+ function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
1937
+ switch (indexingStatus.omnichainStatus) {
1938
+ case OmnichainIndexingStatusIds.Unstarted:
1939
+ return {
1940
+ omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
1941
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1942
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1943
+ };
1944
+ case OmnichainIndexingStatusIds.Backfill:
1945
+ return {
1946
+ omnichainStatus: OmnichainIndexingStatusIds.Backfill,
1947
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1948
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1949
+ };
1950
+ case OmnichainIndexingStatusIds.Completed: {
1951
+ return {
1952
+ omnichainStatus: OmnichainIndexingStatusIds.Completed,
1953
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1954
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1955
+ };
1956
+ }
1957
+ case OmnichainIndexingStatusIds.Following:
1958
+ return {
1959
+ omnichainStatus: OmnichainIndexingStatusIds.Following,
1960
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1961
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1962
+ };
1963
+ }
1964
+ }
1965
+
1966
+ // src/ensapi/config/serialize.ts
1967
+ function serializeENSApiPublicConfig(config) {
1968
+ const { version, theGraphFallback, ensIndexerPublicConfig } = config;
1969
+ return {
1970
+ version,
1971
+ theGraphFallback,
1972
+ ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
1973
+ };
1974
+ }
1975
+
1976
+ // src/api/config/deserialize.ts
1977
+ function deserializeConfigResponse(serializedResponse) {
1978
+ return deserializeENSApiPublicConfig(serializedResponse);
1979
+ }
1980
+
1981
+ // src/api/config/serialize.ts
1982
+ function serializeConfigResponse(response) {
1983
+ return serializeENSApiPublicConfig(response);
1984
+ }
1985
+
1986
+ // src/api/indexing-status/deserialize.ts
1987
+ var import_v411 = require("zod/v4");
1988
+
1989
+ // src/api/indexing-status/zod-schemas.ts
1990
+ var import_v410 = __toESM(require("zod/v4"), 1);
1991
+
1992
+ // src/api/indexing-status/response.ts
1993
+ var IndexingStatusResponseCodes = {
1994
+ /**
1995
+ * Represents that the indexing status is available.
1996
+ */
1997
+ Ok: "ok",
1998
+ /**
1999
+ * Represents that the indexing status is unavailable.
2000
+ */
2001
+ Error: "error"
2002
+ };
2003
+
2004
+ // src/api/indexing-status/zod-schemas.ts
2005
+ var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => import_v410.default.strictObject({
2006
+ responseCode: import_v410.default.literal(IndexingStatusResponseCodes.Ok),
2007
+ realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
2008
+ });
2009
+ var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => import_v410.default.strictObject({
2010
+ responseCode: import_v410.default.literal(IndexingStatusResponseCodes.Error)
2011
+ });
2012
+ var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => import_v410.default.discriminatedUnion("responseCode", [
2013
+ makeIndexingStatusResponseOkSchema(valueLabel),
2014
+ makeIndexingStatusResponseErrorSchema(valueLabel)
2015
+ ]);
2016
+
2017
+ // src/api/indexing-status/deserialize.ts
2018
+ function deserializeIndexingStatusResponse(maybeResponse) {
2019
+ const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
2020
+ if (parsed.error) {
2021
+ throw new Error(`Cannot deserialize IndexingStatusResponse:
2022
+ ${(0, import_v411.prettifyError)(parsed.error)}
2023
+ `);
2024
+ }
2025
+ return parsed.data;
2026
+ }
2027
+
2028
+ // src/api/indexing-status/serialize.ts
2029
+ function serializeIndexingStatusResponse(response) {
2030
+ switch (response.responseCode) {
2031
+ case IndexingStatusResponseCodes.Ok:
2032
+ return {
2033
+ responseCode: response.responseCode,
2034
+ realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
2035
+ };
2036
+ case IndexingStatusResponseCodes.Error:
2037
+ return response;
2038
+ }
2039
+ }
2040
+
2041
+ // src/api/name-tokens/deserialize.ts
2042
+ var import_v416 = require("zod/v4");
2043
+
2044
+ // src/api/name-tokens/zod-schemas.ts
2045
+ var import_viem14 = require("viem");
2046
+ var import_v415 = __toESM(require("zod/v4"), 1);
2047
+
2048
+ // src/tokenscope/assets.ts
2049
+ var import_caip4 = require("caip");
2050
+ var import_viem13 = require("viem");
2051
+ var import_v413 = require("zod/v4");
2052
+
2053
+ // src/tokenscope/zod-schemas.ts
2054
+ var import_caip3 = require("caip");
2055
+ var import_viem12 = require("viem");
2056
+ var import_v412 = __toESM(require("zod/v4"), 1);
2057
+
2058
+ // src/tokenscope/name-token.ts
2059
+ var import_viem11 = require("viem");
2060
+ var import_datasources5 = require("@ensnode/datasources");
2061
+ var NameTokenOwnershipTypes = {
2062
+ /**
2063
+ * Name Token is owned by NameWrapper account.
2064
+ */
2065
+ NameWrapper: "namewrapper",
2066
+ /**
2067
+ * Name Token is owned fully onchain.
2068
+ *
2069
+ * This ownership type can only apply to direct subnames of `.eth`
2070
+ */
2071
+ FullyOnchain: "fully-onchain",
2072
+ /**
2073
+ * Name Token ownership has been transferred to the null address.
2074
+ */
2075
+ Burned: "burned",
2076
+ /**
2077
+ * Name Token ownership is unknown.
2078
+ */
2079
+ Unknown: "unknown"
2080
+ };
2081
+ function serializeNameToken(nameToken) {
2082
+ return {
2083
+ token: serializeAssetId(nameToken.token),
2084
+ ownership: nameToken.ownership,
2085
+ mintStatus: nameToken.mintStatus
2086
+ };
2087
+ }
2088
+ function getNameWrapperAccounts(namespaceId) {
2089
+ const ethnamesNameWrapperAccount = getDatasourceContract(
2090
+ namespaceId,
2091
+ import_datasources5.DatasourceNames.ENSRoot,
2092
+ "NameWrapper"
2093
+ );
2094
+ const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
2095
+ namespaceId,
2096
+ import_datasources5.DatasourceNames.Lineanames,
2097
+ "NameWrapper"
2098
+ );
2099
+ const nameWrapperAccounts = [
2100
+ // NameWrapper for direct subnames of .eth is defined for all ENS namespaces
2101
+ ethnamesNameWrapperAccount
2102
+ ];
2103
+ if (lineanamesNameWrapperAccount) {
2104
+ nameWrapperAccounts.push(lineanamesNameWrapperAccount);
2105
+ }
2106
+ return nameWrapperAccounts;
2107
+ }
2108
+ function getNameTokenOwnership(namespaceId, name, owner) {
2109
+ const nameWrapperAccounts = getNameWrapperAccounts(namespaceId);
2110
+ const hasNameWrapperOwnership = nameWrapperAccounts.some(
2111
+ (nameWrapperAccount) => accountIdEqual(owner, nameWrapperAccount)
2112
+ );
2113
+ if (hasNameWrapperOwnership) {
2114
+ return {
2115
+ ownershipType: NameTokenOwnershipTypes.NameWrapper,
2116
+ owner
2117
+ };
2118
+ }
2119
+ if ((0, import_viem11.isAddressEqual)(owner.address, import_viem11.zeroAddress)) {
2120
+ return {
2121
+ ownershipType: NameTokenOwnershipTypes.Burned,
2122
+ owner
2123
+ };
2124
+ }
2125
+ const parentName = getParentNameFQDN(name);
2126
+ if (parentName === "eth") {
2127
+ return {
2128
+ ownershipType: NameTokenOwnershipTypes.FullyOnchain,
2129
+ owner
2130
+ };
2131
+ }
2132
+ return {
2133
+ ownershipType: NameTokenOwnershipTypes.Unknown,
2134
+ owner
2135
+ };
2136
+ }
2137
+
2138
+ // src/tokenscope/zod-schemas.ts
2139
+ var tokenIdSchemaSerializable = import_v412.default.string();
2140
+ var tokenIdSchemaNative = import_v412.default.preprocess(
2141
+ (v) => typeof v === "string" ? BigInt(v) : v,
2142
+ import_v412.default.bigint().positive()
2143
+ );
2144
+ function makeTokenIdSchema(_valueLabel = "Token ID Schema", serializable = false) {
2145
+ if (serializable) {
2146
+ return tokenIdSchemaSerializable;
2147
+ } else {
2148
+ return tokenIdSchemaNative;
2149
+ }
2150
+ }
2151
+ var makeAssetIdSchema = (valueLabel = "Asset ID Schema", serializable) => {
2152
+ return import_v412.default.object({
2153
+ assetNamespace: import_v412.default.enum(AssetNamespaces),
2154
+ contract: makeAccountIdSchema(valueLabel),
2155
+ tokenId: makeTokenIdSchema(valueLabel, serializable ?? false)
2156
+ });
2157
+ };
2158
+ var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => import_v412.default.preprocess((v) => {
2159
+ if (typeof v === "string") {
2160
+ const result = new import_caip3.AssetId(v);
2161
+ return {
2162
+ assetNamespace: result.assetName.namespace,
2163
+ contract: {
2164
+ chainId: Number(result.chainId.reference),
2165
+ address: result.assetName.reference
2166
+ },
2167
+ tokenId: result.tokenId
2168
+ };
2169
+ }
2170
+ return v;
2171
+ }, makeAssetIdSchema(valueLabel));
2172
+ function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
2173
+ const ownership = ctx.value;
2174
+ if (ctx.value.owner.address === import_viem12.zeroAddress) {
2175
+ ctx.issues.push({
2176
+ code: "custom",
2177
+ input: ctx.value,
2178
+ message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' other than the zero address.`
2179
+ });
2180
+ }
2181
+ }
2182
+ var makeNameTokenOwnershipNameWrapperSchema = (valueLabel = "Name Token Ownership NameWrapper") => import_v412.default.object({
2183
+ ownershipType: import_v412.default.literal(NameTokenOwnershipTypes.NameWrapper),
2184
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2185
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2186
+ var makeNameTokenOwnershipFullyOnchainSchema = (valueLabel = "Name Token Ownership Fully Onchain") => import_v412.default.object({
2187
+ ownershipType: import_v412.default.literal(NameTokenOwnershipTypes.FullyOnchain),
2188
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2189
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2190
+ var makeNameTokenOwnershipBurnedSchema = (valueLabel = "Name Token Ownership Burned") => import_v412.default.object({
2191
+ ownershipType: import_v412.default.literal(NameTokenOwnershipTypes.Burned),
2192
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2193
+ }).check(invariant_nameTokenOwnershipHasZeroAddressOwner);
2194
+ var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Unknown") => import_v412.default.object({
2195
+ ownershipType: import_v412.default.literal(NameTokenOwnershipTypes.Unknown),
2196
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2197
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2198
+ function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
2199
+ const ownership = ctx.value;
2200
+ if (ctx.value.owner.address !== import_viem12.zeroAddress) {
2201
+ ctx.issues.push({
2202
+ code: "custom",
2203
+ input: ctx.value,
2204
+ message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' set to the zero address.`
2205
+ });
2206
+ }
2207
+ }
2208
+ var makeNameTokenOwnershipSchema = (valueLabel = "Name Token Ownership") => import_v412.default.discriminatedUnion("ownershipType", [
2209
+ makeNameTokenOwnershipNameWrapperSchema(valueLabel),
2210
+ makeNameTokenOwnershipFullyOnchainSchema(valueLabel),
2211
+ makeNameTokenOwnershipBurnedSchema(valueLabel),
2212
+ makeNameTokenOwnershipUnknownSchema(valueLabel)
2213
+ ]);
2214
+ var makeNameTokenSchema = (valueLabel = "Name Token Schema", serializable) => import_v412.default.object({
2215
+ token: makeAssetIdSchema(`${valueLabel}.token`, serializable),
2216
+ ownership: makeNameTokenOwnershipSchema(`${valueLabel}.ownership`),
2217
+ mintStatus: import_v412.default.enum(NFTMintStatuses)
2218
+ });
2219
+
2220
+ // src/tokenscope/assets.ts
2221
+ var AssetNamespaces = {
2222
+ ERC721: "erc721",
2223
+ ERC1155: "erc1155"
2224
+ };
2225
+ function serializeAssetId(assetId) {
2226
+ return {
2227
+ assetNamespace: assetId.assetNamespace,
2228
+ contract: assetId.contract,
2229
+ tokenId: uint256ToHex32(assetId.tokenId)
2230
+ };
2231
+ }
2232
+ function deserializeAssetId(maybeAssetId, valueLabel) {
2233
+ const schema = makeAssetIdSchema(valueLabel);
2234
+ const parsed = schema.safeParse(maybeAssetId);
2235
+ if (parsed.error) {
2236
+ throw new RangeError(`Cannot deserialize AssetId:
2237
+ ${(0, import_v413.prettifyError)(parsed.error)}
2238
+ `);
2239
+ }
2240
+ return parsed.data;
2241
+ }
2242
+ function formatAssetId(assetId) {
2243
+ const { assetNamespace, contract, tokenId } = serializeAssetId(assetId);
2244
+ return import_caip4.AssetId.format({
2245
+ chainId: { namespace: "eip155", reference: contract.chainId.toString() },
2246
+ assetName: { namespace: assetNamespace, reference: contract.address },
2247
+ tokenId
2248
+ }).toLowerCase();
2249
+ }
2250
+ function parseAssetId(maybeAssetId, valueLabel) {
2251
+ const schema = makeAssetIdStringSchema(valueLabel);
2252
+ const parsed = schema.safeParse(maybeAssetId);
2253
+ if (parsed.error) {
2254
+ throw new RangeError(`Cannot parse AssetId:
2255
+ ${(0, import_v413.prettifyError)(parsed.error)}
2256
+ `);
2257
+ }
2258
+ return parsed.data;
2259
+ }
2260
+ var buildAssetId = (contract, tokenId, assetNamespace) => {
2261
+ return {
2262
+ assetNamespace,
2263
+ contract,
2264
+ tokenId
2265
+ };
2266
+ };
2267
+ function serializeDomainAssetId(domainAsset) {
2268
+ return {
2269
+ ...serializeAssetId(domainAsset),
2270
+ domainId: domainAsset.domainId
2271
+ };
2272
+ }
2273
+ var NFTMintStatuses = {
2274
+ Minted: "minted",
2275
+ Burned: "burned"
2276
+ };
2277
+ var formatNFTTransferEventMetadata = (metadata) => {
2278
+ const serializedAssetId = serializeAssetId(metadata.nft);
2279
+ return [
2280
+ `Event: ${metadata.eventHandlerName}`,
2281
+ `Chain ID: ${metadata.chainId}`,
2282
+ `Block Number: ${metadata.blockNumber}`,
2283
+ `Transaction Hash: ${metadata.transactionHash}`,
2284
+ `NFT: ${serializedAssetId}`
2285
+ ].map((line) => ` - ${line}`).join("\n");
2286
+ };
2287
+ var NFTTransferTypes = {
2288
+ /**
2289
+ * Initial transfer from zeroAddress to a non-zeroAddress
2290
+ * Can happen at most once to a NFT AssetId
2291
+ *
2292
+ * Invariants:
2293
+ * - NFT is not indexed and therefore has no previous mint status or owner
2294
+ * - new NFT mint status is `minted`
2295
+ * - new NFT owner is a non-zeroAddress
2296
+ */
2297
+ Mint: "mint",
2298
+ /**
2299
+ * Subsequent transfer from zeroAddress to a non-zeroAddress
2300
+ * Can happen any number of times to a NFT AssetId as it passes in a cycle from
2301
+ * mint -> burn -> remint -> burn -> remint -> ...
2302
+ *
2303
+ * Invariants:
2304
+ * - NFT is indexed
2305
+ * - previous NFT mint status was `burned`
2306
+ * - previous NFT owner is the zeroAddress
2307
+ * - new NFT mint status is `minted`
2308
+ * - new NFT owner is a non-zeroAddress
2309
+ */
2310
+ Remint: "remint",
2311
+ /**
2312
+ * Special transfer type for improperly implemented NFT contracts that allow a NFT
2313
+ * that is currently minted to be reminted before an intermediate burn.
2314
+ *
2315
+ * Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
2316
+ * previously indexed nft had status `minted` with a non-zeroAddress owner.
2317
+ *
2318
+ * Invariants:
2319
+ * - NFT is indexed
2320
+ * - previous NFT mint status was `minted`
2321
+ * - previous NFT owner was a non-zeroAddress
2322
+ * - new NFT mint status is `minted`
2323
+ * - new NFT owner is a non-zeroAddress
2324
+ */
2325
+ MintedRemint: "minted-remint",
2326
+ /**
2327
+ * Transfer from a non-zeroAddress to zeroAddress
2328
+ *
2329
+ * Invariants:
2330
+ * - NFT is indexed
2331
+ * - previous NFT mint status was `minted`
2332
+ * - previous NFT owner is a non-zeroAddress
2333
+ * - new NFT mint status is `burned`
2334
+ * - new NFT owner is the zeroAddress
2335
+ */
2336
+ Burn: "burn",
2337
+ /**
2338
+ * Transfer from a non-zeroAddress to a distinct non-zeroAddress
2339
+ *
2340
+ * Invariants:
2341
+ * - NFT is indexed
2342
+ * - previous and new NFT mint status is `minted`
2343
+ * - previous and new NFT owner are distinct non-zeroAddress
2344
+ */
2345
+ Transfer: "transfer",
2346
+ /**
2347
+ * Transfer from a non-zeroAddress to the same non-zeroAddress
2348
+ *
2349
+ * Invariants:
2350
+ * - NFT is indexed
2351
+ * - previous and new NFT mint status is `minted`
2352
+ * - previous and new NFT owner are equivalent non-zeroAddress
2353
+ */
2354
+ SelfTransfer: "self-transfer",
2355
+ /**
2356
+ * Transfer from zeroAddress to zeroAddress for an indexed NFT
2357
+ *
2358
+ * Invariants:
2359
+ * - NFT is indexed
2360
+ * - previous and new NFT mint status is `burned`
2361
+ * - previous and new NFT owner are zeroAddress
2362
+ */
2363
+ RemintBurn: "remint-burn",
2364
+ /**
2365
+ * Special transfer type for improperly implemented NFT contracts that allow a NFT
2366
+ * that is currently minted to be reminted again before an intermediate burn.
2367
+ *
2368
+ * Transfer from zeroAddress to zeroAddress for an indexed NFT where the
2369
+ * previously indexed nft had status `minted` with a non-zeroAddress owner.
2370
+ *
2371
+ * Invariants:
2372
+ * - NFT is indexed
2373
+ * - previous NFT mint status was `minted`
2374
+ * - previous NFT owner was a non-zeroAddress
2375
+ * - new NFT mint status is `burned`
2376
+ * - new NFT owner is the zeroAddress
2377
+ */
2378
+ MintedRemintBurn: "minted-remint-burn",
2379
+ /**
2380
+ * Transfer from zeroAddress to zeroAddress for an unindexed NFT
2381
+ *
2382
+ * Invariants:
2383
+ * - NFT is not indexed and therefore has no previous mint status or owner
2384
+ * - NFT should remain unindexed and without any mint status or owner
2385
+ */
2386
+ MintBurn: "mint-burn"
2387
+ };
2388
+ var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
2389
+ const isIndexed = currentlyIndexedOwner !== void 0;
2390
+ const isIndexedAsMinted = isIndexed && !(0, import_viem13.isAddressEqual)(currentlyIndexedOwner, import_viem13.zeroAddress);
2391
+ const isMint = (0, import_viem13.isAddressEqual)(from, import_viem13.zeroAddress);
2392
+ const isBurn = (0, import_viem13.isAddressEqual)(to, import_viem13.zeroAddress);
2393
+ const isSelfTransfer = (0, import_viem13.isAddressEqual)(from, to);
2394
+ if (isIndexed && !(0, import_viem13.isAddressEqual)(currentlyIndexedOwner, from)) {
2395
+ if (isMint && allowMintedRemint) {
2396
+ } else {
2397
+ throw new Error(
2398
+ `Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
2399
+ ${formatNFTTransferEventMetadata(metadata)}`
2400
+ );
2401
+ }
2402
+ }
2403
+ if (isSelfTransfer) {
2404
+ if (isMint) {
2405
+ if (!isIndexed) {
2406
+ return NFTTransferTypes.MintBurn;
2407
+ } else if (!isIndexedAsMinted) {
2408
+ return NFTTransferTypes.RemintBurn;
2409
+ } else if (allowMintedRemint) {
2410
+ return NFTTransferTypes.MintedRemintBurn;
2411
+ } else {
2412
+ throw new Error(
2413
+ `Error: Invalid state transition from minted -> remint-burn
2414
+ ${formatNFTTransferEventMetadata(metadata)}`
2415
+ );
2416
+ }
2417
+ } else {
2418
+ if (!isIndexed) {
2419
+ throw new Error(
2420
+ `Error: Invalid state transition from unindexed -> self-transfer
2421
+ ${formatNFTTransferEventMetadata(metadata)}`
2422
+ );
2423
+ } else if (!isIndexedAsMinted) {
2424
+ throw new Error(
2425
+ `Error: invalid state transition from burned -> self-transfer
2426
+ ${formatNFTTransferEventMetadata(metadata)}`
2427
+ );
2428
+ } else {
2429
+ return NFTTransferTypes.SelfTransfer;
2430
+ }
2431
+ }
2432
+ } else if (isMint) {
2433
+ if (!isIndexed) {
2434
+ return NFTTransferTypes.Mint;
2435
+ } else if (!isIndexedAsMinted) {
2436
+ return NFTTransferTypes.Remint;
2437
+ } else if (allowMintedRemint) {
2438
+ return NFTTransferTypes.MintedRemint;
2439
+ } else {
2440
+ throw new Error(
2441
+ `Error: Invalid state transition from minted -> mint
2442
+ ${formatNFTTransferEventMetadata(metadata)}`
2443
+ );
2444
+ }
2445
+ } else if (isBurn) {
2446
+ if (!isIndexed) {
2447
+ throw new Error(
2448
+ `Error: Invalid state transition from unindexed -> burn
2449
+ ${formatNFTTransferEventMetadata(metadata)}`
2450
+ );
2451
+ } else if (!isIndexedAsMinted) {
2452
+ throw new Error(
2453
+ `Error: Invalid state transition from burned -> burn
2454
+ ${formatNFTTransferEventMetadata(metadata)}`
2455
+ );
2456
+ } else {
2457
+ return NFTTransferTypes.Burn;
2458
+ }
2459
+ } else {
2460
+ if (!isIndexed) {
2461
+ throw new Error(
2462
+ `Error: Invalid state transition from unindexed -> transfer
2463
+ ${formatNFTTransferEventMetadata(metadata)}`
2464
+ );
2465
+ } else if (!isIndexedAsMinted) {
2466
+ throw new Error(
2467
+ `Error: Invalid state transition from burned -> transfer
2468
+ ${formatNFTTransferEventMetadata(metadata)}`
2469
+ );
2470
+ } else {
2471
+ return NFTTransferTypes.Transfer;
2472
+ }
2473
+ }
2474
+ };
2475
+
2476
+ // src/api/shared/errors/zod-schemas.ts
2477
+ var import_v414 = __toESM(require("zod/v4"), 1);
2478
+ var ErrorResponseSchema = import_v414.default.object({
2479
+ message: import_v414.default.string(),
2480
+ details: import_v414.default.optional(import_v414.default.unknown())
2481
+ });
2482
+
2483
+ // src/api/name-tokens/response.ts
2484
+ var NameTokensResponseCodes = {
2485
+ /**
2486
+ * Represents a response when Name Tokens API can respond with requested data.
2487
+ */
2488
+ Ok: "ok",
2489
+ /**
2490
+ * Represents a response when Name Tokens API could not respond with requested data.
2491
+ */
2492
+ Error: "error"
2493
+ };
2494
+ var NameTokensResponseErrorCodes = {
2495
+ /**
2496
+ * Name tokens not indexed
2497
+ *
2498
+ * Represents an error when tokens for the requested name are not indexed by
2499
+ * the ENSNode instance's configuration.
2500
+ */
2501
+ NameTokensNotIndexed: "name-tokens-not-indexed",
2502
+ /**
2503
+ * Unsupported ENSIndexer Config
2504
+ *
2505
+ * Represents a prerequisites error when connected ENSIndexer config lacks
2506
+ * params required to enable Name Tokens API.
2507
+ */
2508
+ EnsIndexerConfigUnsupported: "unsupported-ensindexer-config",
2509
+ /**
2510
+ * Unsupported Indexing Status
2511
+ *
2512
+ * Represents a prerequisites error when Indexing Status has not yet reached
2513
+ * status required to enable Name Tokens API.
2514
+ */
2515
+ IndexingStatusUnsupported: "unsupported-indexing-status"
2516
+ };
2517
+
2518
+ // src/api/name-tokens/zod-schemas.ts
2519
+ var makeRegisteredNameTokenSchema = (valueLabel = "Registered Name Token", serializable) => import_v415.default.object({
2520
+ domainId: makeNodeSchema(`${valueLabel}.domainId`),
2521
+ name: makeReinterpretedNameSchema(valueLabel),
2522
+ tokens: import_v415.default.array(makeNameTokenSchema(`${valueLabel}.tokens`, serializable)).nonempty(),
2523
+ expiresAt: makeUnixTimestampSchema(`${valueLabel}.expiresAt`),
2524
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2525
+ }).check(function invariant_nameIsAssociatedWithDomainId(ctx) {
2526
+ const { name, domainId } = ctx.value;
2527
+ if ((0, import_viem14.namehash)(name) !== domainId) {
2528
+ ctx.issues.push({
2529
+ code: "custom",
2530
+ input: ctx.value,
2531
+ message: `'name' must be associated with 'domainId': ${domainId}`
2532
+ });
2533
+ }
2534
+ }).check(
2535
+ function invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown(ctx) {
2536
+ const { tokens } = ctx.value;
2537
+ const containsOwnershipNameWrapper = tokens.some(
2538
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.NameWrapper
2539
+ );
2540
+ const containsOwnershipFullyOnchainOrUnknown = tokens.some(
2541
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain || t.ownership.ownershipType === NameTokenOwnershipTypes.Unknown
2542
+ );
2543
+ if (containsOwnershipNameWrapper && !containsOwnershipFullyOnchainOrUnknown) {
2544
+ ctx.issues.push({
2545
+ code: "custom",
2546
+ input: ctx.value,
2547
+ message: `'tokens' must contain name token with ownership type 'fully-onchain' or 'unknown' when name token with ownership type 'namewrapper' in listed`
2548
+ });
2549
+ }
2550
+ }
2551
+ ).check(function invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective(ctx) {
2552
+ const { tokens } = ctx.value;
2553
+ const tokensCountWithOwnershipFullyOnchain = tokens.filter(
2554
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain
2555
+ ).length;
2556
+ if (tokensCountWithOwnershipFullyOnchain > 1) {
2557
+ ctx.issues.push({
2558
+ code: "custom",
2559
+ input: ctx.value,
2560
+ message: `'tokens' must contain at most one name token with ownership type 'fully-onchain', current count: ${tokensCountWithOwnershipFullyOnchain}`
2561
+ });
2562
+ }
2563
+ });
2564
+ var makeNameTokensResponseOkSchema = (valueLabel = "Name Tokens Response OK", serializable) => import_v415.default.strictObject({
2565
+ responseCode: import_v415.default.literal(NameTokensResponseCodes.Ok),
2566
+ registeredNameTokens: makeRegisteredNameTokenSchema(`${valueLabel}.nameTokens`, serializable)
2567
+ });
2568
+ var makeNameTokensResponseErrorNameTokensNotIndexedSchema = (_valueLabel = "Name Tokens Response Error Name Not Indexed") => import_v415.default.strictObject({
2569
+ responseCode: import_v415.default.literal(NameTokensResponseCodes.Error),
2570
+ errorCode: import_v415.default.literal(NameTokensResponseErrorCodes.NameTokensNotIndexed),
2571
+ error: ErrorResponseSchema
2572
+ });
2573
+ var makeNameTokensResponseErrorEnsIndexerConfigUnsupported = (_valueLabel = "Name Tokens Response Error ENSIndexer Config Unsupported") => import_v415.default.strictObject({
2574
+ responseCode: import_v415.default.literal(NameTokensResponseCodes.Error),
2575
+ errorCode: import_v415.default.literal(NameTokensResponseErrorCodes.EnsIndexerConfigUnsupported),
2576
+ error: ErrorResponseSchema
2577
+ });
2578
+ var makeNameTokensResponseErrorNameIndexingStatusUnsupported = (_valueLabel = "Name Tokens Response Error Indexing Status Unsupported") => import_v415.default.strictObject({
2579
+ responseCode: import_v415.default.literal(NameTokensResponseCodes.Error),
2580
+ errorCode: import_v415.default.literal(NameTokensResponseErrorCodes.IndexingStatusUnsupported),
2581
+ error: ErrorResponseSchema
2582
+ });
2583
+ var makeNameTokensResponseErrorSchema = (valueLabel = "Name Tokens Response Error") => import_v415.default.discriminatedUnion("errorCode", [
2584
+ makeNameTokensResponseErrorNameTokensNotIndexedSchema(valueLabel),
2585
+ makeNameTokensResponseErrorEnsIndexerConfigUnsupported(valueLabel),
2586
+ makeNameTokensResponseErrorNameIndexingStatusUnsupported(valueLabel)
2587
+ ]);
2588
+ var makeNameTokensResponseSchema = (valueLabel = "Name Tokens Response", serializable) => {
2589
+ return import_v415.default.discriminatedUnion("responseCode", [
2590
+ makeNameTokensResponseOkSchema(valueLabel, serializable ?? false),
2591
+ makeNameTokensResponseErrorSchema(valueLabel)
2592
+ ]);
2593
+ };
2594
+
2595
+ // src/api/name-tokens/deserialize.ts
2596
+ function deserializedNameTokensResponse(maybeResponse) {
2597
+ const parsed = makeNameTokensResponseSchema("Name Tokens Response", false).safeParse(
2598
+ maybeResponse
2599
+ );
2600
+ if (parsed.error) {
2601
+ throw new Error(`Cannot deserialize NameTokensResponse:
2602
+ ${(0, import_v416.prettifyError)(parsed.error)}
2603
+ `);
2604
+ }
2605
+ return parsed.data;
2606
+ }
2607
+
2608
+ // src/api/name-tokens/prerequisites.ts
2609
+ var nameTokensPrerequisites = Object.freeze({
2610
+ /**
2611
+ * Required plugins to enable Name Tokens API routes.
2612
+ *
2613
+ * 1. `registrars` plugin is required so that data in the `registrationLifecycles`
2614
+ * table is populated.
2615
+ * 2. `tokenscope` plugin is required so that data in the `nameTokens`
2616
+ * table is populated.
2617
+ */
2618
+ requiredPlugins: ["registrars" /* Registrars */, "tokenscope" /* TokenScope */],
2619
+ /**
2620
+ * Check if provided ENSApiPublicConfig supports the Name Tokens API.
2621
+ */
2622
+ hasEnsIndexerConfigSupport(config) {
2623
+ return nameTokensPrerequisites.requiredPlugins.every(
2624
+ (plugin) => config.plugins.includes(plugin)
2625
+ );
2626
+ },
2627
+ /**
2628
+ * Required Indexing Status IDs
2629
+ *
2630
+ * Database indexes are created by the time the omnichain indexing status
2631
+ * is either `completed` or `following`.
2632
+ */
2633
+ supportedIndexingStatusIds: [
2634
+ OmnichainIndexingStatusIds.Completed,
2635
+ OmnichainIndexingStatusIds.Following
2636
+ ],
2637
+ /**
2638
+ * Check if provided indexing status supports the Name Tokens API.
2639
+ */
2640
+ hasIndexingStatusSupport(omnichainIndexingStatusId) {
2641
+ return nameTokensPrerequisites.supportedIndexingStatusIds.some(
2642
+ (supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
2643
+ );
2644
+ }
2645
+ });
2646
+
2647
+ // src/api/name-tokens/serialize.ts
2648
+ function serializeRegisteredNameTokens({
2649
+ domainId,
2650
+ name,
2651
+ tokens,
2652
+ expiresAt,
2653
+ accurateAsOf
2654
+ }) {
2655
+ return {
2656
+ domainId,
2657
+ name,
2658
+ tokens: tokens.map(serializeNameToken),
2659
+ expiresAt,
2660
+ accurateAsOf
2661
+ };
2662
+ }
2663
+ function serializeNameTokensResponse(response) {
2664
+ switch (response.responseCode) {
2665
+ case NameTokensResponseCodes.Ok:
2666
+ return {
2667
+ responseCode: response.responseCode,
2668
+ registeredNameTokens: serializeRegisteredNameTokens(response.registeredNameTokens)
2669
+ };
2670
+ case NameTokensResponseCodes.Error:
2671
+ return response;
2672
+ }
2673
+ }
2674
+
2675
+ // src/api/registrar-actions/deserialize.ts
2676
+ var import_v420 = require("zod/v4");
2677
+
2678
+ // src/api/registrar-actions/zod-schemas.ts
2679
+ var import_ens7 = require("viem/ens");
2680
+ var import_v419 = __toESM(require("zod/v4"), 1);
2681
+
2682
+ // ../ens-referrals/src/address.ts
2683
+ var import_viem15 = require("viem");
2684
+
2685
+ // ../ens-referrals/src/encoding.ts
2686
+ var import_viem16 = require("viem");
2687
+ var ENCODED_REFERRER_BYTE_OFFSET = 12;
2688
+ var ENCODED_REFERRER_BYTE_LENGTH = 32;
2689
+ var EXPECTED_ENCODED_REFERRER_PADDING = (0, import_viem16.pad)("0x", {
2690
+ size: ENCODED_REFERRER_BYTE_OFFSET,
2691
+ dir: "left"
2692
+ });
2693
+ var ZERO_ENCODED_REFERRER = (0, import_viem16.pad)("0x", {
2694
+ size: ENCODED_REFERRER_BYTE_LENGTH,
2695
+ dir: "left"
2696
+ });
2697
+ function decodeEncodedReferrer(encodedReferrer) {
2698
+ if ((0, import_viem16.size)(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
2699
+ throw new Error(
2700
+ `Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
2701
+ );
2702
+ }
2703
+ const padding = (0, import_viem16.slice)(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
2704
+ if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
2705
+ return import_viem16.zeroAddress;
2706
+ }
2707
+ const decodedReferrer = (0, import_viem16.slice)(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
2708
+ try {
2709
+ return (0, import_viem16.getAddress)(decodedReferrer);
2710
+ } catch {
2711
+ throw new Error(`Decoded referrer value must be a valid EVM address.`);
2712
+ }
2713
+ }
2714
+
2715
+ // ../ens-referrals/src/leaderboard-page.ts
2716
+ var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
2717
+
2718
+ // ../ens-referrals/src/link.ts
2719
+ var import_viem17 = require("viem");
2720
+
2721
+ // ../ens-referrals/src/referrer-detail.ts
2722
+ var ReferrerDetailTypeIds = {
2723
+ /**
2724
+ * Represents a referrer who is ranked on the leaderboard.
2725
+ */
2726
+ Ranked: "ranked",
2727
+ /**
2728
+ * Represents a referrer who is not ranked on the leaderboard.
2729
+ */
2730
+ Unranked: "unranked"
2731
+ };
2732
+
2733
+ // src/registrars/zod-schemas.ts
2734
+ var import_v417 = __toESM(require("zod/v4"), 1);
2735
+
2736
+ // src/registrars/registrar-action.ts
2737
+ var RegistrarActionTypes = {
2738
+ Registration: "registration",
2739
+ Renewal: "renewal"
2740
+ };
2741
+ function isRegistrarActionPricingAvailable(registrarActionPricing) {
2742
+ const { baseCost, premium, total } = registrarActionPricing;
2743
+ return baseCost !== null && premium !== null && total !== null;
2744
+ }
2745
+ function isRegistrarActionReferralAvailable(registrarActionReferral) {
2746
+ const { encodedReferrer, decodedReferrer } = registrarActionReferral;
2747
+ return encodedReferrer !== null && decodedReferrer !== null;
2748
+ }
2749
+ function serializeRegistrarActionPricing(pricing) {
2750
+ if (isRegistrarActionPricingAvailable(pricing)) {
2751
+ return {
2752
+ baseCost: serializePriceEth(pricing.baseCost),
2753
+ premium: serializePriceEth(pricing.premium),
2754
+ total: serializePriceEth(pricing.total)
2755
+ };
2756
+ }
2757
+ return pricing;
2758
+ }
2759
+ function serializeRegistrarAction(registrarAction) {
2760
+ return {
2761
+ id: registrarAction.id,
2762
+ type: registrarAction.type,
2763
+ incrementalDuration: registrarAction.incrementalDuration,
2764
+ registrant: registrarAction.registrant,
2765
+ registrationLifecycle: registrarAction.registrationLifecycle,
2766
+ pricing: serializeRegistrarActionPricing(registrarAction.pricing),
2767
+ referral: registrarAction.referral,
2768
+ block: registrarAction.block,
2769
+ transactionHash: registrarAction.transactionHash,
2770
+ eventIds: registrarAction.eventIds
2771
+ };
2772
+ }
2773
+
2774
+ // src/registrars/zod-schemas.ts
2775
+ var makeSubregistrySchema = (valueLabel = "Subregistry") => import_v417.default.object({
2776
+ subregistryId: makeAccountIdSchema(`${valueLabel} Subregistry ID`),
2777
+ node: makeNodeSchema(`${valueLabel} Node`)
2778
+ });
2779
+ var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => import_v417.default.object({
2780
+ subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
2781
+ node: makeNodeSchema(`${valueLabel} Node`),
2782
+ expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
2783
+ });
2784
+ function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
2785
+ const { baseCost, premium, total } = ctx.value;
2786
+ const actualTotal = addPrices(baseCost, premium);
2787
+ if (!isPriceEqual(actualTotal, total)) {
2788
+ ctx.issues.push({
2789
+ code: "custom",
2790
+ input: ctx.value,
2791
+ message: `'total' must be equal to the sum of 'baseCost' and 'premium'`
2792
+ });
2793
+ }
2794
+ }
2795
+ var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => import_v417.default.union([
2796
+ // pricing available
2797
+ import_v417.default.object({
2798
+ baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
2799
+ premium: makePriceEthSchema(`${valueLabel} Premium`),
2800
+ total: makePriceEthSchema(`${valueLabel} Total`)
2801
+ }).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
2802
+ // pricing unknown
2803
+ import_v417.default.object({
2804
+ baseCost: import_v417.default.null(),
2805
+ premium: import_v417.default.null(),
2806
+ total: import_v417.default.null()
2807
+ }).transform((v) => v)
2808
+ ]);
2809
+ function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
2810
+ const { encodedReferrer, decodedReferrer } = ctx.value;
2811
+ try {
2812
+ const expectedDecodedReferrer = decodeEncodedReferrer(encodedReferrer).toLowerCase();
2813
+ if (decodedReferrer !== expectedDecodedReferrer) {
2814
+ ctx.issues.push({
2815
+ code: "custom",
2816
+ input: ctx.value,
2817
+ message: `'decodedReferrer' must be based on 'encodedReferrer'`
2818
+ });
2819
+ }
2820
+ } catch (error) {
2821
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
2822
+ ctx.issues.push({
2823
+ code: "custom",
2824
+ input: ctx.value,
2825
+ message: errorMessage
2826
+ });
2827
+ }
2828
+ }
2829
+ var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => import_v417.default.union([
2830
+ // referral available
2831
+ import_v417.default.object({
2832
+ encodedReferrer: makeHexStringSchema(
2833
+ { bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
2834
+ `${valueLabel} Encoded Referrer`
2835
+ ),
2836
+ decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
2837
+ }).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
2838
+ // referral not applicable
2839
+ import_v417.default.object({
2840
+ encodedReferrer: import_v417.default.null(),
2841
+ decodedReferrer: import_v417.default.null()
2842
+ })
2843
+ ]);
2844
+ function invariant_eventIdsInitialElementIsTheActionId(ctx) {
2845
+ const { id, eventIds } = ctx.value;
2846
+ if (eventIds[0] !== id) {
2847
+ ctx.issues.push({
2848
+ code: "custom",
2849
+ input: ctx.value,
2850
+ message: "The initial element of `eventIds` must be the `id` value"
2851
+ });
2852
+ }
2853
+ }
2854
+ var EventIdSchema = import_v417.default.string().nonempty();
2855
+ var EventIdsSchema = import_v417.default.array(EventIdSchema).min(1).transform((v) => v);
2856
+ var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => import_v417.default.object({
2857
+ id: EventIdSchema,
2858
+ incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
2859
+ registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
2860
+ registrationLifecycle: makeRegistrationLifecycleSchema(
2861
+ `${valueLabel} Registration Lifecycle`
2862
+ ),
2863
+ pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
2864
+ referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
2865
+ block: makeBlockRefSchema(`${valueLabel} Block`),
2866
+ transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
2867
+ eventIds: EventIdsSchema
2868
+ }).check(invariant_eventIdsInitialElementIsTheActionId);
2869
+ var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
2870
+ type: import_v417.default.literal(RegistrarActionTypes.Registration)
2871
+ });
2872
+ var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
2873
+ type: import_v417.default.literal(RegistrarActionTypes.Renewal)
2874
+ });
2875
+ var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => import_v417.default.discriminatedUnion("type", [
2876
+ makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
2877
+ makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
2878
+ ]);
2879
+
2880
+ // src/api/shared/pagination/zod-schemas.ts
2881
+ var import_v418 = __toESM(require("zod/v4"), 1);
2882
+
2883
+ // src/api/shared/pagination/request.ts
2884
+ var RECORDS_PER_PAGE_DEFAULT = 10;
2885
+ var RECORDS_PER_PAGE_MAX = 100;
2886
+
2887
+ // src/api/shared/pagination/zod-schemas.ts
2888
+ var makeRequestPageParamsSchema = (valueLabel = "RequestPageParams") => import_v418.default.object({
2889
+ page: makePositiveIntegerSchema(`${valueLabel}.page`),
2890
+ recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
2891
+ RECORDS_PER_PAGE_MAX,
2892
+ `${valueLabel}.recordsPerPage must not exceed ${RECORDS_PER_PAGE_MAX}`
2893
+ )
2894
+ });
2895
+ var makeResponsePageContextSchemaWithNoRecords = (valueLabel = "ResponsePageContextWithNoRecords") => import_v418.default.object({
2896
+ totalRecords: import_v418.default.literal(0),
2897
+ totalPages: import_v418.default.literal(1),
2898
+ hasNext: import_v418.default.literal(false),
2899
+ hasPrev: import_v418.default.literal(false),
2900
+ startIndex: import_v418.default.undefined(),
2901
+ endIndex: import_v418.default.undefined()
2902
+ }).extend(makeRequestPageParamsSchema(valueLabel).shape);
2903
+ function invariant_responsePageWithRecordsIsCorrect(ctx) {
2904
+ const { hasNext, hasPrev, recordsPerPage, page, totalRecords, startIndex, endIndex } = ctx.value;
2905
+ const expectedHasNext = page * recordsPerPage < totalRecords;
2906
+ if (hasNext !== expectedHasNext) {
2907
+ ctx.issues.push({
2908
+ code: "custom",
2909
+ input: ctx.value,
2910
+ message: `hasNext must be equal to '${expectedHasNext ? "true" : "false"}'`
2911
+ });
2912
+ }
2913
+ const expectedHasPrev = page > 1;
2914
+ if (hasPrev !== expectedHasPrev) {
2915
+ ctx.issues.push({
2916
+ code: "custom",
2917
+ input: ctx.value,
2918
+ message: `hasPrev must be equal to '${expectedHasPrev ? "true" : "false"}'`
2919
+ });
2920
+ }
2921
+ if (endIndex < startIndex) {
2922
+ ctx.issues.push({
2923
+ code: "custom",
2924
+ input: ctx.value,
2925
+ message: `endIndex must be greater than or equal to startIndex`
2926
+ });
2927
+ }
2928
+ if (endIndex >= totalRecords) {
2929
+ ctx.issues.push({
2930
+ code: "custom",
2931
+ input: ctx.value,
2932
+ message: `endIndex must be lower than totalRecords`
2933
+ });
2934
+ }
2935
+ }
2936
+ var makeResponsePageContextSchemaWithRecords = (valueLabel = "ResponsePageContextWithRecords") => import_v418.default.object({
2937
+ totalRecords: makePositiveIntegerSchema(`${valueLabel}.totalRecords`),
2938
+ totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
2939
+ hasNext: import_v418.default.boolean(),
2940
+ hasPrev: import_v418.default.boolean(),
2941
+ startIndex: makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`),
2942
+ endIndex: makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`)
2943
+ }).extend(makeRequestPageParamsSchema(valueLabel).shape).check(invariant_responsePageWithRecordsIsCorrect);
2944
+ var makeResponsePageContextSchema = (valueLabel = "ResponsePageContext") => import_v418.default.union([
2945
+ makeResponsePageContextSchemaWithNoRecords(valueLabel),
2946
+ makeResponsePageContextSchemaWithRecords(valueLabel)
2947
+ ]);
2948
+
2949
+ // src/api/registrar-actions/response.ts
2950
+ var RegistrarActionsResponseCodes = {
2951
+ /**
2952
+ * Represents that Registrar Actions are available.
2953
+ */
2954
+ Ok: "ok",
2955
+ /**
2956
+ * Represents that Registrar Actions are unavailable.
2957
+ */
2958
+ Error: "error"
2959
+ };
2960
+
2961
+ // src/api/registrar-actions/zod-schemas.ts
2962
+ function invariant_registrationLifecycleNodeMatchesName(ctx) {
2963
+ const { name, action } = ctx.value;
2964
+ const expectedNode = action.registrationLifecycle.node;
2965
+ const actualNode = (0, import_ens7.namehash)(name);
2966
+ if (actualNode !== expectedNode) {
2967
+ ctx.issues.push({
2968
+ code: "custom",
2969
+ input: ctx.value,
2970
+ message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
2971
+ });
2972
+ }
2973
+ }
2974
+ var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => import_v419.default.object({
2975
+ action: makeRegistrarActionSchema(valueLabel),
2976
+ name: makeReinterpretedNameSchema(valueLabel)
2977
+ }).check(invariant_registrationLifecycleNodeMatchesName);
2978
+ var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => import_v419.default.strictObject({
2979
+ responseCode: import_v419.default.literal(RegistrarActionsResponseCodes.Ok),
2980
+ registrarActions: import_v419.default.array(makeNamedRegistrarActionSchema(valueLabel)),
2981
+ pageContext: makeResponsePageContextSchema(`${valueLabel}.pageContext`)
2982
+ });
2983
+ var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => import_v419.default.strictObject({
2984
+ responseCode: import_v419.default.literal(RegistrarActionsResponseCodes.Error),
2985
+ error: ErrorResponseSchema
2986
+ });
2987
+ var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => import_v419.default.discriminatedUnion("responseCode", [
2988
+ makeRegistrarActionsResponseOkSchema(valueLabel),
2989
+ makeRegistrarActionsResponseErrorSchema(valueLabel)
2990
+ ]);
2991
+
2992
+ // src/api/registrar-actions/deserialize.ts
2993
+ function deserializeRegistrarActionsResponse(maybeResponse) {
2994
+ const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
2995
+ if (parsed.error) {
2996
+ throw new Error(
2997
+ `Cannot deserialize RegistrarActionsResponse:
2998
+ ${(0, import_v420.prettifyError)(parsed.error)}
2999
+ `
3000
+ );
3001
+ }
3002
+ return parsed.data;
3003
+ }
3004
+
3005
+ // src/api/registrar-actions/request.ts
3006
+ var RegistrarActionsFilterTypes = {
3007
+ BySubregistryNode: "bySubregistryNode",
3008
+ WithEncodedReferral: "withEncodedReferral",
3009
+ ByDecodedReferrer: "byDecodedReferrer",
3010
+ BeginTimestamp: "beginTimestamp",
3011
+ EndTimestamp: "endTimestamp"
3012
+ };
3013
+ var RegistrarActionsOrders = {
3014
+ LatestRegistrarActions: "orderBy[timestamp]=desc"
3015
+ };
3016
+
3017
+ // src/api/registrar-actions/filters.ts
3018
+ function byParentNode(parentNode) {
3019
+ if (typeof parentNode === "undefined") {
3020
+ return void 0;
3021
+ }
3022
+ return {
3023
+ filterType: RegistrarActionsFilterTypes.BySubregistryNode,
3024
+ value: parentNode
3025
+ };
3026
+ }
3027
+ function withReferral(withReferral2) {
3028
+ if (!withReferral2) {
3029
+ return void 0;
3030
+ }
3031
+ return {
3032
+ filterType: RegistrarActionsFilterTypes.WithEncodedReferral
3033
+ };
3034
+ }
3035
+ function byDecodedReferrer(decodedReferrer) {
3036
+ if (typeof decodedReferrer === "undefined") {
3037
+ return void 0;
3038
+ }
3039
+ return {
3040
+ filterType: RegistrarActionsFilterTypes.ByDecodedReferrer,
3041
+ value: decodedReferrer
3042
+ };
3043
+ }
3044
+ function beginTimestamp(timestamp) {
3045
+ if (typeof timestamp === "undefined") {
3046
+ return void 0;
3047
+ }
3048
+ return {
3049
+ filterType: RegistrarActionsFilterTypes.BeginTimestamp,
3050
+ value: timestamp
3051
+ };
3052
+ }
3053
+ function endTimestamp(timestamp) {
3054
+ if (typeof timestamp === "undefined") {
3055
+ return void 0;
3056
+ }
3057
+ return {
3058
+ filterType: RegistrarActionsFilterTypes.EndTimestamp,
3059
+ value: timestamp
3060
+ };
3061
+ }
3062
+ var registrarActionsFilter = {
3063
+ byParentNode,
3064
+ withReferral,
3065
+ byDecodedReferrer,
3066
+ beginTimestamp,
3067
+ endTimestamp
3068
+ };
3069
+
3070
+ // src/api/registrar-actions/prerequisites.ts
3071
+ var registrarActionsPrerequisites = Object.freeze({
3072
+ /**
3073
+ * Required plugins to enable Registrar Actions API routes.
3074
+ *
3075
+ * 1. `registrars` plugin is required so that data in the `registrarActions`
3076
+ * table is populated.
3077
+ * 2. `subgraph`, `basenames`, and `lineanames` are required to get the data
3078
+ * for the name associated with each registrar action.
3079
+ * 3. In theory not all of `subgraph`, `basenames`, and `lineanames` plugins
3080
+ * might be required. Ex: At least one, but the current logic in
3081
+ * the `registrars` plugin always indexes registrar actions across
3082
+ * Ethnames (subgraph), Basenames, and Lineanames and therefore we need to
3083
+ * ensure each value in the registrar actions table has
3084
+ * an associated record in the domains table.
3085
+ */
3086
+ requiredPlugins: [
3087
+ "subgraph" /* Subgraph */,
3088
+ "basenames" /* Basenames */,
3089
+ "lineanames" /* Lineanames */,
3090
+ "registrars" /* Registrars */
3091
+ ],
3092
+ /**
3093
+ * Check if provided ENSApiPublicConfig supports the Registrar Actions API.
3094
+ */
3095
+ hasEnsIndexerConfigSupport(config) {
3096
+ return registrarActionsPrerequisites.requiredPlugins.every(
3097
+ (plugin) => config.plugins.includes(plugin)
3098
+ );
3099
+ },
3100
+ /**
3101
+ * Required Indexing Status IDs
3102
+ *
3103
+ * Database indexes are created by the time the omnichain indexing status
3104
+ * is either `completed` or `following`.
3105
+ */
3106
+ supportedIndexingStatusIds: [
3107
+ OmnichainIndexingStatusIds.Completed,
3108
+ OmnichainIndexingStatusIds.Following
3109
+ ],
3110
+ /**
3111
+ * Check if provided indexing status supports the Registrar Actions API.
3112
+ */
3113
+ hasIndexingStatusSupport(omnichainIndexingStatusId) {
3114
+ return registrarActionsPrerequisites.supportedIndexingStatusIds.some(
3115
+ (supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
3116
+ );
3117
+ }
3118
+ });
3119
+
3120
+ // src/registrars/basenames-subregistry.ts
3121
+ var import_datasources6 = require("@ensnode/datasources");
3122
+ function getBasenamesSubregistryId(namespace) {
3123
+ const datasource = (0, import_datasources6.maybeGetDatasource)(namespace, import_datasources6.DatasourceNames.Basenames);
3124
+ if (!datasource) {
3125
+ throw new Error(`Datasource not found for ${namespace} ${import_datasources6.DatasourceNames.Basenames}`);
3126
+ }
3127
+ const address = datasource.contracts.BaseRegistrar?.address;
3128
+ if (address === void 0 || Array.isArray(address)) {
3129
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
3130
+ }
3131
+ return {
3132
+ chainId: datasource.chain.id,
3133
+ address
3134
+ };
3135
+ }
3136
+ function getBasenamesSubregistryManagedName(namespaceId) {
3137
+ switch (namespaceId) {
3138
+ case import_datasources6.ENSNamespaceIds.Mainnet:
3139
+ return "base.eth";
3140
+ case import_datasources6.ENSNamespaceIds.Sepolia:
3141
+ return "basetest.eth";
3142
+ case import_datasources6.ENSNamespaceIds.Holesky:
3143
+ case import_datasources6.ENSNamespaceIds.EnsTestEnv:
3144
+ throw new Error(
3145
+ `No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`
3146
+ );
3147
+ }
3148
+ }
3149
+
3150
+ // src/registrars/ethnames-subregistry.ts
3151
+ var import_datasources7 = require("@ensnode/datasources");
3152
+ function getEthnamesSubregistryId(namespace) {
3153
+ const datasource = (0, import_datasources7.maybeGetDatasource)(namespace, import_datasources7.DatasourceNames.ENSRoot);
3154
+ if (!datasource) {
3155
+ throw new Error(`Datasource not found for ${namespace} ${import_datasources7.DatasourceNames.ENSRoot}`);
3156
+ }
3157
+ const address = datasource.contracts.BaseRegistrar?.address;
3158
+ if (address === void 0 || Array.isArray(address)) {
3159
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
3160
+ }
3161
+ return {
3162
+ chainId: datasource.chain.id,
3163
+ address
3164
+ };
3165
+ }
3166
+ function getEthnamesSubregistryManagedName(namespaceId) {
3167
+ switch (namespaceId) {
3168
+ case import_datasources7.ENSNamespaceIds.Mainnet:
3169
+ case import_datasources7.ENSNamespaceIds.Sepolia:
3170
+ case import_datasources7.ENSNamespaceIds.Holesky:
3171
+ case import_datasources7.ENSNamespaceIds.EnsTestEnv:
3172
+ return "eth";
3173
+ }
3174
+ }
3175
+
3176
+ // src/registrars/lineanames-subregistry.ts
3177
+ var import_datasources8 = require("@ensnode/datasources");
3178
+ function getLineanamesSubregistryId(namespace) {
3179
+ const datasource = (0, import_datasources8.maybeGetDatasource)(namespace, import_datasources8.DatasourceNames.Lineanames);
3180
+ if (!datasource) {
3181
+ throw new Error(`Datasource not found for ${namespace} ${import_datasources8.DatasourceNames.Lineanames}`);
3182
+ }
3183
+ const address = datasource.contracts.BaseRegistrar?.address;
3184
+ if (address === void 0 || Array.isArray(address)) {
3185
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
3186
+ }
3187
+ return {
3188
+ chainId: datasource.chain.id,
3189
+ address
3190
+ };
3191
+ }
3192
+ function getLineanamesSubregistryManagedName(namespaceId) {
3193
+ switch (namespaceId) {
3194
+ case import_datasources8.ENSNamespaceIds.Mainnet:
3195
+ return "linea.eth";
3196
+ case import_datasources8.ENSNamespaceIds.Sepolia:
3197
+ return "linea-sepolia.eth";
3198
+ case import_datasources8.ENSNamespaceIds.Holesky:
3199
+ case import_datasources8.ENSNamespaceIds.EnsTestEnv:
3200
+ throw new Error(
3201
+ `No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`
3202
+ );
3203
+ }
3204
+ }
3205
+
3206
+ // src/api/registrar-actions/serialize.ts
3207
+ function serializeNamedRegistrarAction({
3208
+ action,
3209
+ name
3210
+ }) {
3211
+ return {
3212
+ action: serializeRegistrarAction(action),
3213
+ name
3214
+ };
3215
+ }
3216
+ function serializeRegistrarActionsResponse(response) {
3217
+ switch (response.responseCode) {
3218
+ case RegistrarActionsResponseCodes.Ok:
3219
+ return {
3220
+ responseCode: response.responseCode,
3221
+ registrarActions: response.registrarActions.map(serializeNamedRegistrarAction),
3222
+ pageContext: response.pageContext
3223
+ };
3224
+ case RegistrarActionsResponseCodes.Error:
3225
+ return response;
3226
+ }
3227
+ }
3228
+
3229
+ // src/api/shared/errors/deserialize.ts
3230
+ var import_v421 = require("zod/v4");
3231
+ function deserializeErrorResponse(maybeErrorResponse) {
3232
+ const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
3233
+ if (parsed.error) {
3234
+ throw new Error(`Cannot deserialize ErrorResponse:
3235
+ ${(0, import_v421.prettifyError)(parsed.error)}
3236
+ `);
3237
+ }
3238
+ return parsed.data;
3239
+ }
3240
+
3241
+ // src/api/shared/pagination/build-page-context.ts
3242
+ function buildPageContext(page, recordsPerPage, totalRecords) {
3243
+ const totalPages = Math.max(1, Math.ceil(totalRecords / recordsPerPage));
3244
+ if (page > totalPages) {
3245
+ throw new Error(`Invalid page: page ${page} exceeds total pages ${totalPages}.`);
3246
+ }
3247
+ if (totalRecords === 0) {
3248
+ return {
3249
+ page,
3250
+ recordsPerPage,
3251
+ totalRecords: 0,
3252
+ totalPages: 1,
3253
+ hasNext: false,
3254
+ hasPrev: false,
3255
+ startIndex: void 0,
3256
+ endIndex: void 0
3257
+ };
3258
+ }
3259
+ const startIndex = (page - 1) * recordsPerPage;
3260
+ const maxTheoreticalIndexOnPage = startIndex + (recordsPerPage - 1);
3261
+ const endIndex = Math.min(maxTheoreticalIndexOnPage, totalRecords - 1);
3262
+ const hasNext = maxTheoreticalIndexOnPage < totalRecords - 1;
3263
+ const hasPrev = page > 1;
3264
+ return {
3265
+ page,
3266
+ recordsPerPage,
3267
+ totalRecords,
3268
+ totalPages,
3269
+ hasNext,
3270
+ hasPrev,
3271
+ startIndex,
3272
+ endIndex
3273
+ };
3274
+ }
3275
+
3276
+ // src/client-error.ts
3277
+ var ClientError = class _ClientError extends Error {
3278
+ details;
3279
+ constructor(message, details) {
3280
+ super(message);
3281
+ this.name = "ClientError";
3282
+ this.details = details;
3283
+ }
3284
+ static fromErrorResponse({ message, details }) {
3285
+ return new _ClientError(message, details);
3286
+ }
3287
+ };
3288
+
3289
+ // src/ensanalytics/deserialize.ts
3290
+ var import_v423 = require("zod/v4");
3291
+
3292
+ // src/ensanalytics/zod-schemas.ts
3293
+ var import_v422 = __toESM(require("zod/v4"), 1);
3294
+
3295
+ // src/ensanalytics/types.ts
3296
+ var ReferrerLeaderboardPageResponseCodes = {
3297
+ /**
3298
+ * Represents that the requested referrer leaderboard page is available.
3299
+ */
3300
+ Ok: "ok",
3301
+ /**
3302
+ * Represents that the referrer leaderboard data is not available.
3303
+ */
3304
+ Error: "error"
3305
+ };
3306
+ var ReferrerDetailResponseCodes = {
3307
+ /**
3308
+ * Represents that the referrer detail data is available.
3309
+ */
3310
+ Ok: "ok",
3311
+ /**
3312
+ * Represents that an error occurred while fetching the data.
3313
+ */
3314
+ Error: "error"
3315
+ };
3316
+
3317
+ // src/ensanalytics/zod-schemas.ts
3318
+ var makeRevenueContributionSchema = (valueLabel = "RevenueContribution") => import_v422.default.coerce.bigint({
3319
+ error: `${valueLabel} must represent a bigint.`
3320
+ }).nonnegative({
3321
+ error: `${valueLabel} must not be negative.`
3322
+ });
3323
+ var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => import_v422.default.object({
3324
+ totalAwardPoolValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.totalAwardPoolValue`),
3325
+ maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`),
3326
+ startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
3327
+ endTime: makeUnixTimestampSchema(`${valueLabel}.endTime`),
3328
+ subregistryId: makeAccountIdSchema(`${valueLabel}.subregistryId`)
3329
+ });
3330
+ var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => import_v422.default.object({
3331
+ referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
3332
+ totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
3333
+ totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
3334
+ totalRevenueContribution: makeRevenueContributionSchema(
3335
+ `${valueLabel}.totalRevenueContribution`
3336
+ ),
3337
+ score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
3338
+ rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
3339
+ isQualified: import_v422.default.boolean(),
3340
+ finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
3341
+ 1,
3342
+ `${valueLabel}.finalScoreBoost must be <= 1`
3343
+ ),
3344
+ finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
3345
+ awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
3346
+ 1,
3347
+ `${valueLabel}.awardPoolShare must be <= 1`
3348
+ ),
3349
+ awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
3350
+ });
3351
+ var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics") => import_v422.default.object({
3352
+ referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
3353
+ totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
3354
+ totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
3355
+ totalRevenueContribution: makeRevenueContributionSchema(
3356
+ `${valueLabel}.totalRevenueContribution`
3357
+ ),
3358
+ score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
3359
+ rank: import_v422.default.null(),
3360
+ isQualified: import_v422.default.literal(false),
3361
+ finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
3362
+ 1,
3363
+ `${valueLabel}.finalScoreBoost must be <= 1`
3364
+ ),
3365
+ finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
3366
+ awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
3367
+ 1,
3368
+ `${valueLabel}.awardPoolShare must be <= 1`
3369
+ ),
3370
+ awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
3371
+ });
3372
+ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => import_v422.default.object({
3373
+ grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
3374
+ grandTotalIncrementalDuration: makeDurationSchema(
3375
+ `${valueLabel}.grandTotalIncrementalDuration`
3376
+ ),
3377
+ grandTotalRevenueContribution: makeRevenueContributionSchema(
3378
+ `${valueLabel}.grandTotalRevenueContribution`
3379
+ ),
3380
+ grandTotalQualifiedReferrersFinalScore: makeFiniteNonNegativeNumberSchema(
3381
+ `${valueLabel}.grandTotalQualifiedReferrersFinalScore`
3382
+ ),
3383
+ minFinalScoreToQualify: makeFiniteNonNegativeNumberSchema(
3384
+ `${valueLabel}.minFinalScoreToQualify`
3385
+ )
3386
+ });
3387
+ var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => import_v422.default.object({
3388
+ page: makePositiveIntegerSchema(`${valueLabel}.page`),
3389
+ recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
3390
+ REFERRERS_PER_LEADERBOARD_PAGE_MAX,
3391
+ `${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
3392
+ ),
3393
+ totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
3394
+ totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
3395
+ hasNext: import_v422.default.boolean(),
3396
+ hasPrev: import_v422.default.boolean(),
3397
+ startIndex: import_v422.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
3398
+ endIndex: import_v422.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
3399
+ });
3400
+ var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => import_v422.default.object({
3401
+ rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
3402
+ referrers: import_v422.default.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[record]`)),
3403
+ aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
3404
+ pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
3405
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
3406
+ });
3407
+ var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => import_v422.default.object({
3408
+ responseCode: import_v422.default.literal(ReferrerLeaderboardPageResponseCodes.Ok),
3409
+ data: makeReferrerLeaderboardPageSchema(`${valueLabel}.data`)
3410
+ });
3411
+ var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => import_v422.default.object({
3412
+ responseCode: import_v422.default.literal(ReferrerLeaderboardPageResponseCodes.Error),
3413
+ error: import_v422.default.string(),
3414
+ errorMessage: import_v422.default.string()
3415
+ });
3416
+ var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => import_v422.default.union([
3417
+ makeReferrerLeaderboardPageResponseOkSchema(valueLabel),
3418
+ makeReferrerLeaderboardPageResponseErrorSchema(valueLabel)
3419
+ ]);
3420
+ var makeReferrerDetailRankedSchema = (valueLabel = "ReferrerDetailRanked") => import_v422.default.object({
3421
+ type: import_v422.default.literal(ReferrerDetailTypeIds.Ranked),
3422
+ rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
3423
+ referrer: makeAwardedReferrerMetricsSchema(`${valueLabel}.referrer`),
3424
+ aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
3425
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
3426
+ });
3427
+ var makeReferrerDetailUnrankedSchema = (valueLabel = "ReferrerDetailUnranked") => import_v422.default.object({
3428
+ type: import_v422.default.literal(ReferrerDetailTypeIds.Unranked),
3429
+ rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
3430
+ referrer: makeUnrankedReferrerMetricsSchema(`${valueLabel}.referrer`),
3431
+ aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
3432
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
3433
+ });
3434
+ var makeReferrerDetailResponseOkSchema = (valueLabel = "ReferrerDetailResponse") => import_v422.default.object({
3435
+ responseCode: import_v422.default.literal(ReferrerDetailResponseCodes.Ok),
3436
+ data: import_v422.default.union([
3437
+ makeReferrerDetailRankedSchema(`${valueLabel}.data`),
3438
+ makeReferrerDetailUnrankedSchema(`${valueLabel}.data`)
3439
+ ])
3440
+ });
3441
+ var makeReferrerDetailResponseErrorSchema = (_valueLabel = "ReferrerDetailResponse") => import_v422.default.object({
3442
+ responseCode: import_v422.default.literal(ReferrerDetailResponseCodes.Error),
3443
+ error: import_v422.default.string(),
3444
+ errorMessage: import_v422.default.string()
3445
+ });
3446
+ var makeReferrerDetailResponseSchema = (valueLabel = "ReferrerDetailResponse") => import_v422.default.union([
3447
+ makeReferrerDetailResponseOkSchema(valueLabel),
3448
+ makeReferrerDetailResponseErrorSchema(valueLabel)
3449
+ ]);
3450
+
3451
+ // src/ensanalytics/deserialize.ts
3452
+ function deserializeRevenueContribution(value) {
3453
+ return BigInt(value);
3454
+ }
3455
+ function deserializeReferralProgramRules(rules) {
3456
+ return rules;
3457
+ }
3458
+ function deserializeAwardedReferrerMetrics(metrics) {
3459
+ return {
3460
+ referrer: metrics.referrer,
3461
+ totalReferrals: metrics.totalReferrals,
3462
+ totalIncrementalDuration: metrics.totalIncrementalDuration,
3463
+ totalRevenueContribution: deserializeRevenueContribution(metrics.totalRevenueContribution),
3464
+ score: metrics.score,
3465
+ rank: metrics.rank,
3466
+ isQualified: metrics.isQualified,
3467
+ finalScoreBoost: metrics.finalScoreBoost,
3468
+ finalScore: metrics.finalScore,
3469
+ awardPoolShare: metrics.awardPoolShare,
3470
+ awardPoolApproxValue: metrics.awardPoolApproxValue
3471
+ };
3472
+ }
3473
+ function deserializeUnrankedReferrerMetrics(metrics) {
3474
+ return {
3475
+ referrer: metrics.referrer,
3476
+ totalReferrals: metrics.totalReferrals,
3477
+ totalIncrementalDuration: metrics.totalIncrementalDuration,
3478
+ totalRevenueContribution: deserializeRevenueContribution(metrics.totalRevenueContribution),
3479
+ score: metrics.score,
3480
+ rank: metrics.rank,
3481
+ isQualified: metrics.isQualified,
3482
+ finalScoreBoost: metrics.finalScoreBoost,
3483
+ finalScore: metrics.finalScore,
3484
+ awardPoolShare: metrics.awardPoolShare,
3485
+ awardPoolApproxValue: metrics.awardPoolApproxValue
3486
+ };
3487
+ }
3488
+ function deserializeAggregatedReferrerMetrics(metrics) {
3489
+ return {
3490
+ grandTotalReferrals: metrics.grandTotalReferrals,
3491
+ grandTotalIncrementalDuration: metrics.grandTotalIncrementalDuration,
3492
+ grandTotalRevenueContribution: deserializeRevenueContribution(
3493
+ metrics.grandTotalRevenueContribution
3494
+ ),
3495
+ grandTotalQualifiedReferrersFinalScore: metrics.grandTotalQualifiedReferrersFinalScore,
3496
+ minFinalScoreToQualify: metrics.minFinalScoreToQualify
3497
+ };
3498
+ }
3499
+ function deserializeReferrerLeaderboardPage(page) {
3500
+ return {
3501
+ rules: deserializeReferralProgramRules(page.rules),
3502
+ referrers: page.referrers.map(deserializeAwardedReferrerMetrics),
3503
+ aggregatedMetrics: deserializeAggregatedReferrerMetrics(page.aggregatedMetrics),
3504
+ pageContext: page.pageContext,
3505
+ accurateAsOf: page.accurateAsOf
3506
+ };
3507
+ }
3508
+ function deserializeReferrerDetailRanked(detail) {
3509
+ return {
3510
+ type: detail.type,
3511
+ rules: deserializeReferralProgramRules(detail.rules),
3512
+ referrer: deserializeAwardedReferrerMetrics(detail.referrer),
3513
+ aggregatedMetrics: deserializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
3514
+ accurateAsOf: detail.accurateAsOf
3515
+ };
3516
+ }
3517
+ function deserializeReferrerDetailUnranked(detail) {
3518
+ return {
3519
+ type: detail.type,
3520
+ rules: deserializeReferralProgramRules(detail.rules),
3521
+ referrer: deserializeUnrankedReferrerMetrics(detail.referrer),
3522
+ aggregatedMetrics: deserializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
3523
+ accurateAsOf: detail.accurateAsOf
3524
+ };
3525
+ }
3526
+ function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
3527
+ let deserialized;
3528
+ switch (maybeResponse.responseCode) {
3529
+ case "ok": {
3530
+ deserialized = {
3531
+ responseCode: maybeResponse.responseCode,
3532
+ data: deserializeReferrerLeaderboardPage(maybeResponse.data)
3533
+ };
3534
+ break;
3535
+ }
3536
+ case "error":
3537
+ deserialized = maybeResponse;
3538
+ break;
3539
+ }
3540
+ const schema = makeReferrerLeaderboardPageResponseSchema(valueLabel);
3541
+ const parsed = schema.safeParse(deserialized);
3542
+ if (parsed.error) {
3543
+ throw new Error(
3544
+ `Cannot deserialize SerializedReferrerLeaderboardPageResponse:
3545
+ ${(0, import_v423.prettifyError)(parsed.error)}
3546
+ `
3547
+ );
3548
+ }
3549
+ return parsed.data;
3550
+ }
3551
+ function deserializeReferrerDetailResponse(maybeResponse, valueLabel) {
3552
+ let deserialized;
3553
+ switch (maybeResponse.responseCode) {
3554
+ case "ok": {
3555
+ switch (maybeResponse.data.type) {
3556
+ case "ranked":
3557
+ deserialized = {
3558
+ responseCode: maybeResponse.responseCode,
3559
+ data: deserializeReferrerDetailRanked(maybeResponse.data)
3560
+ };
3561
+ break;
3562
+ case "unranked":
3563
+ deserialized = {
3564
+ responseCode: maybeResponse.responseCode,
3565
+ data: deserializeReferrerDetailUnranked(maybeResponse.data)
3566
+ };
3567
+ break;
3568
+ }
3569
+ break;
3570
+ }
3571
+ case "error":
3572
+ deserialized = maybeResponse;
3573
+ break;
3574
+ }
3575
+ const schema = makeReferrerDetailResponseSchema(valueLabel);
3576
+ const parsed = schema.safeParse(deserialized);
3577
+ if (parsed.error) {
3578
+ throw new Error(`Cannot deserialize ReferrerDetailResponse:
3579
+ ${(0, import_v423.prettifyError)(parsed.error)}
3580
+ `);
3581
+ }
3582
+ return parsed.data;
3583
+ }
3584
+
3585
+ // src/ensanalytics/serialize.ts
3586
+ function serializeRevenueContribution(revenueContribution) {
3587
+ return revenueContribution.toString();
3588
+ }
3589
+ function serializeReferralProgramRules(rules) {
3590
+ return rules;
3591
+ }
3592
+ function serializeAwardedReferrerMetrics(metrics) {
3593
+ return {
3594
+ referrer: metrics.referrer,
3595
+ totalReferrals: metrics.totalReferrals,
3596
+ totalIncrementalDuration: metrics.totalIncrementalDuration,
3597
+ totalRevenueContribution: serializeRevenueContribution(metrics.totalRevenueContribution),
3598
+ score: metrics.score,
3599
+ rank: metrics.rank,
3600
+ isQualified: metrics.isQualified,
3601
+ finalScoreBoost: metrics.finalScoreBoost,
3602
+ finalScore: metrics.finalScore,
3603
+ awardPoolShare: metrics.awardPoolShare,
3604
+ awardPoolApproxValue: metrics.awardPoolApproxValue
3605
+ };
3606
+ }
3607
+ function serializeUnrankedReferrerMetrics(metrics) {
3608
+ return {
3609
+ referrer: metrics.referrer,
3610
+ totalReferrals: metrics.totalReferrals,
3611
+ totalIncrementalDuration: metrics.totalIncrementalDuration,
3612
+ totalRevenueContribution: serializeRevenueContribution(metrics.totalRevenueContribution),
3613
+ score: metrics.score,
3614
+ rank: metrics.rank,
3615
+ isQualified: metrics.isQualified,
3616
+ finalScoreBoost: metrics.finalScoreBoost,
3617
+ finalScore: metrics.finalScore,
3618
+ awardPoolShare: metrics.awardPoolShare,
3619
+ awardPoolApproxValue: metrics.awardPoolApproxValue
3620
+ };
3621
+ }
3622
+ function serializeAggregatedReferrerMetrics(metrics) {
3623
+ return {
3624
+ grandTotalReferrals: metrics.grandTotalReferrals,
3625
+ grandTotalIncrementalDuration: metrics.grandTotalIncrementalDuration,
3626
+ grandTotalRevenueContribution: serializeRevenueContribution(
3627
+ metrics.grandTotalRevenueContribution
3628
+ ),
3629
+ grandTotalQualifiedReferrersFinalScore: metrics.grandTotalQualifiedReferrersFinalScore,
3630
+ minFinalScoreToQualify: metrics.minFinalScoreToQualify
3631
+ };
3632
+ }
3633
+ function serializeReferrerLeaderboardPage(page) {
3634
+ return {
3635
+ rules: serializeReferralProgramRules(page.rules),
3636
+ referrers: page.referrers.map(serializeAwardedReferrerMetrics),
3637
+ aggregatedMetrics: serializeAggregatedReferrerMetrics(page.aggregatedMetrics),
3638
+ pageContext: page.pageContext,
3639
+ accurateAsOf: page.accurateAsOf
3640
+ };
3641
+ }
3642
+ function serializeReferrerDetailRanked(detail) {
3643
+ return {
3644
+ type: detail.type,
3645
+ rules: serializeReferralProgramRules(detail.rules),
3646
+ referrer: serializeAwardedReferrerMetrics(detail.referrer),
3647
+ aggregatedMetrics: serializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
3648
+ accurateAsOf: detail.accurateAsOf
3649
+ };
3650
+ }
3651
+ function serializeReferrerDetailUnranked(detail) {
3652
+ return {
3653
+ type: detail.type,
3654
+ rules: serializeReferralProgramRules(detail.rules),
3655
+ referrer: serializeUnrankedReferrerMetrics(detail.referrer),
3656
+ aggregatedMetrics: serializeAggregatedReferrerMetrics(detail.aggregatedMetrics),
3657
+ accurateAsOf: detail.accurateAsOf
3658
+ };
3659
+ }
3660
+ function serializeReferrerLeaderboardPageResponse(response) {
3661
+ switch (response.responseCode) {
3662
+ case ReferrerLeaderboardPageResponseCodes.Ok:
3663
+ return {
3664
+ responseCode: response.responseCode,
3665
+ data: serializeReferrerLeaderboardPage(response.data)
3666
+ };
3667
+ case ReferrerLeaderboardPageResponseCodes.Error:
3668
+ return response;
3669
+ }
3670
+ }
3671
+ function serializeReferrerDetailResponse(response) {
3672
+ switch (response.responseCode) {
3673
+ case ReferrerDetailResponseCodes.Ok:
3674
+ switch (response.data.type) {
3675
+ case "ranked":
3676
+ return {
3677
+ responseCode: response.responseCode,
3678
+ data: serializeReferrerDetailRanked(response.data)
3679
+ };
3680
+ case "unranked":
3681
+ return {
3682
+ responseCode: response.responseCode,
3683
+ data: serializeReferrerDetailUnranked(response.data)
3684
+ };
3685
+ }
3686
+ break;
3687
+ case ReferrerDetailResponseCodes.Error:
3688
+ return response;
3689
+ }
3690
+ }
3691
+
3692
+ // src/client.ts
3693
+ var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
3694
+ var ENSNodeClient = class _ENSNodeClient {
3695
+ options;
3696
+ static defaultOptions() {
3697
+ return {
3698
+ url: new URL(DEFAULT_ENSNODE_API_URL)
3699
+ };
3700
+ }
3701
+ constructor(options = {}) {
3702
+ this.options = {
3703
+ ..._ENSNodeClient.defaultOptions(),
3704
+ ...options
3705
+ };
3706
+ }
3707
+ getOptions() {
3708
+ return Object.freeze({
3709
+ url: new URL(this.options.url.href)
3710
+ });
3711
+ }
3712
+ /**
3713
+ * Resolves records for an ENS name (Forward Resolution).
3714
+ *
3715
+ * The returned `name` field, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
3716
+ * If the name record returned by the resolver is not normalized, `null` is returned as if no name record was set.
3717
+ *
3718
+ * @param name The ENS Name whose records to resolve
3719
+ * @param selection selection of Resolver records
3720
+ * @param options additional options
3721
+ * @param options.accelerate whether to attempt Protocol Acceleration (default false)
3722
+ * @param options.trace whether to include a trace in the response (default false)
3723
+ * @returns ResolveRecordsResponse<SELECTION>
3724
+ * @throws If the request fails or the ENSNode API returns an error response
3725
+ *
3726
+ * @example
3727
+ * ```typescript
3728
+ * const { records } = await client.resolveRecords("jesse.base.eth", {
3729
+ * addresses: [60],
3730
+ * texts: ["avatar", "com.twitter"]
3731
+ * });
3732
+ *
3733
+ * console.log(records);
3734
+ * // {
3735
+ * // addresses: {
3736
+ * // 60: "0xabcd..."
3737
+ * // },
3738
+ * // texts: {
3739
+ * // avatar: "https://example.com/image.jpg",
3740
+ * // "com.twitter": null, // if not set, for example
3741
+ * // }
3742
+ * // }
3743
+ * ```
3744
+ */
3745
+ async resolveRecords(name, selection, options) {
3746
+ const url = new URL(`/api/resolve/records/${encodeURIComponent(name)}`, this.options.url);
3747
+ if (selection.name) {
3748
+ url.searchParams.set("name", "true");
3749
+ }
3750
+ if (selection.addresses && selection.addresses.length > 0) {
3751
+ url.searchParams.set("addresses", selection.addresses.join(","));
3752
+ }
3753
+ if (selection.texts && selection.texts.length > 0) {
3754
+ url.searchParams.set("texts", selection.texts.join(","));
3755
+ }
3756
+ if (options?.trace) url.searchParams.set("trace", "true");
3757
+ if (options?.accelerate) url.searchParams.set("accelerate", "true");
3758
+ const response = await fetch(url);
3759
+ if (!response.ok) {
3760
+ const error = await response.json();
3761
+ throw ClientError.fromErrorResponse(error);
3762
+ }
3763
+ const data = await response.json();
3764
+ return data;
3765
+ }
3766
+ /**
3767
+ * Resolves the primary name of a specified address (Reverse Resolution) on a specific chain.
3768
+ *
3769
+ * If the chainId-specific Primary Name is not defined, but the `address` specifies a valid
3770
+ * [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default
3771
+ * Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to determine the
3772
+ * `address`'s Default Name directly.
3773
+ *
3774
+ * The returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
3775
+ * If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.
3776
+ *
3777
+ * @param address The Address whose Primary Name to resolve
3778
+ * @param chainId The chain id within which to query the address' ENSIP-19 Multichain Primary Name
3779
+ * @param options additional options
3780
+ * @param options.accelerate whether to attempt Protocol Acceleration (default false)
3781
+ * @param options.trace whether to include a trace in the response (default false)
3782
+ * @returns ResolvePrimaryNameResponse
3783
+ * @throws If the request fails or the ENSNode API returns an error response
3784
+ *
3785
+ * @example
3786
+ * ```typescript
3787
+ * // Resolve the address' Primary Name on Ethereum Mainnet
3788
+ * const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 1);
3789
+ * // name === 'gregskril.eth'
3790
+ *
3791
+ * // Resolve the address' Primary Name on Base
3792
+ * const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 8453);
3793
+ * // name === 'greg.base.eth'
3794
+ *
3795
+ * // Resolve the address' Default Primary Name
3796
+ * const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 0);
3797
+ * // name === 'gregskril.eth'
3798
+ * ```
3799
+ */
3800
+ async resolvePrimaryName(address, chainId, options) {
3801
+ const url = new URL(`/api/resolve/primary-name/${address}/${chainId}`, this.options.url);
3802
+ if (options?.trace) url.searchParams.set("trace", "true");
3803
+ if (options?.accelerate) url.searchParams.set("accelerate", "true");
3804
+ const response = await fetch(url);
3805
+ if (!response.ok) {
3806
+ const error = await response.json();
3807
+ throw ClientError.fromErrorResponse(error);
3808
+ }
3809
+ const data = await response.json();
3810
+ return data;
3811
+ }
3812
+ /**
3813
+ * Resolves the primary names of a specified address across multiple chains.
3814
+ *
3815
+ * For each Primary Name, if the chainId-specific Primary Name is not defined, but the `address`
3816
+ * specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
3817
+ * the Default Name will be returned. You _may not_ query the Default EVM Chain Id (`0`) directly,
3818
+ * and should rely on the aforementioned per-chain defaulting behavior.
3819
+ *
3820
+ * Each returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
3821
+ * If the primary name set for the address on any chain is not normalized, `null` is returned for
3822
+ * that chain as if no primary name was set.
3823
+ *
3824
+ * @param address The Address whose Primary Names to resolve
3825
+ * @param options additional options
3826
+ * @param options.chainIds The set of chain ids within which to query the address' ENSIP-19
3827
+ * Multichain Primary Name (default: all ENSIP-19 supported chains)
3828
+ * @param options.accelerate whether to attempt Protocol Acceleration (default: true)
3829
+ * @param options.trace whether to include a trace in the response (default: false)
3830
+ * @returns ResolvePrimaryNamesResponse
3831
+ * @throws If the request fails or the ENSNode API returns an error response
3832
+ *
3833
+ * @example
3834
+ * ```typescript
3835
+ * // Resolve the address' Primary Names on all ENSIP-19 supported chain ids
3836
+ * const { names } = await client.resolvePrimaryNames("0x179A862703a4adfb29896552DF9e307980D19285");
3837
+ *
3838
+ * console.log(names);
3839
+ * // {
3840
+ * // "1": "gregskril.eth", // Default Primary Name
3841
+ * // "10": "gregskril.eth", // Default Primary Name
3842
+ * // "8453": "greg.base.eth", // Base-specific Primary Name!
3843
+ * // "42161": "gregskril.eth", // Default Primary Name
3844
+ * // "59144": "gregskril.eth", // Default Primary Name
3845
+ * // "534352": "gregskril.eth" // Default Primary Name
3846
+ * // }
3847
+ *
3848
+ * // Resolve the address' Primary Names on specific chain Ids
3849
+ * const { names } = await client.resolvePrimaryNames("0xabcd...", [1, 8453]);
3850
+ *
3851
+ * console.log(names);
3852
+ * // {
3853
+ * // "1": "gregskril.eth",
3854
+ * // "8453": "greg.base.eth", // base-specific Primary Name!
3855
+ * // }
3856
+ * ```
3857
+ */
3858
+ async resolvePrimaryNames(address, options) {
3859
+ const url = new URL(`/api/resolve/primary-names/${address}`, this.options.url);
3860
+ if (options?.chainIds) url.searchParams.set("chainIds", options.chainIds.join(","));
3861
+ if (options?.trace) url.searchParams.set("trace", "true");
3862
+ if (options?.accelerate) url.searchParams.set("accelerate", "true");
3863
+ const response = await fetch(url);
3864
+ if (!response.ok) {
3865
+ const error = await response.json();
3866
+ throw ClientError.fromErrorResponse(error);
3867
+ }
3868
+ const data = await response.json();
3869
+ return data;
3870
+ }
3871
+ /**
3872
+ * Fetch ENSNode Config
3873
+ *
3874
+ * Fetch the ENSNode's configuration.
3875
+ *
3876
+ * @returns {ConfigResponse}
3877
+ *
3878
+ * @throws if the ENSNode request fails
3879
+ * @throws if the ENSNode API returns an error response
3880
+ * @throws if the ENSNode response breaks required invariants
3881
+ */
3882
+ async config() {
3883
+ const url = new URL(`/api/config`, this.options.url);
3884
+ const response = await fetch(url);
3885
+ let responseData;
3886
+ try {
3887
+ responseData = await response.json();
3888
+ } catch {
3889
+ throw new Error("Malformed response data: invalid JSON");
3890
+ }
3891
+ if (!response.ok) {
3892
+ const errorResponse = deserializeErrorResponse(responseData);
3893
+ throw new Error(`Fetching ENSNode Config Failed: ${errorResponse.message}`);
3894
+ }
3895
+ return deserializeConfigResponse(responseData);
3896
+ }
3897
+ /**
3898
+ * Fetch ENSNode Indexing Status
3899
+ *
3900
+ * @returns {IndexingStatusResponse}
3901
+ *
3902
+ * @throws if the ENSNode request fails
3903
+ * @throws if the ENSNode API returns an error response
3904
+ * @throws if the ENSNode response breaks required invariants
3905
+ */
3906
+ async indexingStatus() {
3907
+ const url = new URL(`/api/indexing-status`, this.options.url);
3908
+ const response = await fetch(url);
3909
+ let responseData;
3910
+ try {
3911
+ responseData = await response.json();
3912
+ } catch {
3913
+ throw new Error("Malformed response data: invalid JSON");
3914
+ }
3915
+ if (!response.ok) {
3916
+ let errorResponse;
3917
+ try {
3918
+ errorResponse = deserializeErrorResponse(responseData);
3919
+ } catch {
3920
+ console.log("Indexing Status API: handling a known indexing status server error.");
3921
+ }
3922
+ if (typeof errorResponse !== "undefined") {
3923
+ throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
3924
+ }
3925
+ }
3926
+ return deserializeIndexingStatusResponse(responseData);
3927
+ }
3928
+ /**
3929
+ * Fetch Referrer Leaderboard Page
3930
+ *
3931
+ * Retrieves a paginated list of referrer leaderboard metrics with contribution percentages.
3932
+ * Each referrer's contribution is calculated as a percentage of the grand totals across all referrers.
3933
+ *
3934
+ * @param request - Pagination parameters
3935
+ * @param request.page - The page number to retrieve (1-indexed, default: 1)
3936
+ * @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
3937
+ * @returns {ReferrerLeaderboardPageResponse}
3938
+ *
3939
+ * @throws if the ENSNode request fails
3940
+ * @throws if the ENSNode API returns an error response
3941
+ * @throws if the ENSNode response breaks required invariants
3942
+ *
3943
+ * @example
3944
+ * ```typescript
3945
+ * // Get first page with default page size (25 records)
3946
+ * const response = await client.getReferrerLeaderboardPage();
3947
+ * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
3948
+ * const {
3949
+ * aggregatedMetrics,
3950
+ * referrers,
3951
+ * rules,
3952
+ * pageContext,
3953
+ * updatedAt
3954
+ * } = response.data;
3955
+ * console.log(aggregatedMetrics);
3956
+ * console.log(referrers);
3957
+ * console.log(rules);
3958
+ * console.log(updatedAt);
3959
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
3960
+ * }
3961
+ * ```
3962
+ *
3963
+ * @example
3964
+ * ```typescript
3965
+ * // Get second page with 50 records per page
3966
+ * const response = await client.getReferrerLeaderboardPage({ page: 2, recordsPerPage: 50 });
3967
+ * ```
3968
+ *
3969
+ * @example
3970
+ * ```typescript
3971
+ * // Handle error response, ie. when Referrer Leaderboard is not currently available.
3972
+ * const response = await client.getReferrerLeaderboardPage();
3973
+ *
3974
+ * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Error) {
3975
+ * console.error(response.error);
3976
+ * console.error(response.errorMessage);
3977
+ * }
3978
+ * ```
3979
+ */
3980
+ async getReferrerLeaderboardPage(request) {
3981
+ const url = new URL(`/ensanalytics/referrers`, this.options.url);
3982
+ if (request?.page) url.searchParams.set("page", request.page.toString());
3983
+ if (request?.recordsPerPage)
3984
+ url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
3985
+ const response = await fetch(url);
3986
+ let responseData;
3987
+ try {
3988
+ responseData = await response.json();
3989
+ } catch {
3990
+ throw new Error("Malformed response data: invalid JSON");
3991
+ }
3992
+ return deserializeReferrerLeaderboardPageResponse(
3993
+ responseData
3994
+ );
3995
+ }
3996
+ /**
3997
+ * Fetch Referrer Detail
3998
+ *
3999
+ * Retrieves detailed information about a specific referrer, whether they are on the
4000
+ * leaderboard or not.
4001
+ *
4002
+ * The response data is a discriminated union type with a `type` field:
4003
+ *
4004
+ * **For referrers on the leaderboard** (`ReferrerDetailRanked`):
4005
+ * - `type`: {@link ReferrerDetailTypeIds.Ranked}
4006
+ * - `referrer`: The `AwardedReferrerMetrics` from @namehash/ens-referrals
4007
+ * - `rules`: The referral program rules
4008
+ * - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
4009
+ * - `accurateAsOf`: Unix timestamp indicating when the data was last updated
4010
+ *
4011
+ * **For referrers NOT on the leaderboard** (`ReferrerDetailUnranked`):
4012
+ * - `type`: {@link ReferrerDetailTypeIds.Unranked}
4013
+ * - `referrer`: The `UnrankedReferrerMetrics` from @namehash/ens-referrals
4014
+ * - `rules`: The referral program rules
4015
+ * - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
4016
+ * - `accurateAsOf`: Unix timestamp indicating when the data was last updated
4017
+ *
4018
+ * @see {@link https://www.npmjs.com/package/@namehash/ens-referrals|@namehash/ens-referrals} for calculation details
4019
+ *
4020
+ * @param request The referrer address to query
4021
+ * @returns {ReferrerDetailResponse} Returns the referrer detail response
4022
+ *
4023
+ * @throws if the ENSNode request fails
4024
+ * @throws if the response data is malformed
4025
+ *
4026
+ * @example
4027
+ * ```typescript
4028
+ * // Get referrer detail for a specific address
4029
+ * const response = await client.getReferrerDetail({
4030
+ * referrer: "0x1234567890123456789012345678901234567890"
4031
+ * });
4032
+ * if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
4033
+ * const { type, referrer, rules, aggregatedMetrics, accurateAsOf } = response.data;
4034
+ * console.log(type); // ReferrerDetailTypeIds.Ranked or ReferrerDetailTypeIds.Unranked
4035
+ * console.log(referrer);
4036
+ * console.log(accurateAsOf);
4037
+ * }
4038
+ * ```
4039
+ *
4040
+ * @example
4041
+ * ```typescript
4042
+ * // Use discriminated union to check if referrer is ranked
4043
+ * const response = await client.getReferrerDetail({
4044
+ * referrer: "0x1234567890123456789012345678901234567890"
4045
+ * });
4046
+ * if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
4047
+ * if (response.data.type === ReferrerDetailTypeIds.Ranked) {
4048
+ * // TypeScript knows this is ReferrerDetailRanked
4049
+ * console.log(`Rank: ${response.data.referrer.rank}`);
4050
+ * console.log(`Qualified: ${response.data.referrer.isQualified}`);
4051
+ * console.log(`Award Pool Share: ${response.data.referrer.awardPoolShare * 100}%`);
4052
+ * } else {
4053
+ * // TypeScript knows this is ReferrerDetailUnranked
4054
+ * console.log("Referrer is not on the leaderboard (no referrals yet)");
4055
+ * }
4056
+ * }
4057
+ * ```
4058
+ *
4059
+ * @example
4060
+ * ```typescript
4061
+ * // Handle error response, ie. when Referrer Detail is not currently available.
4062
+ * const response = await client.getReferrerDetail({
4063
+ * referrer: "0x1234567890123456789012345678901234567890"
4064
+ * });
4065
+ *
4066
+ * if (response.responseCode === ReferrerDetailResponseCodes.Error) {
4067
+ * console.error(response.error);
4068
+ * console.error(response.errorMessage);
4069
+ * }
4070
+ * ```
4071
+ */
4072
+ async getReferrerDetail(request) {
4073
+ const url = new URL(
4074
+ `/api/ensanalytics/referrers/${encodeURIComponent(request.referrer)}`,
4075
+ this.options.url
4076
+ );
4077
+ const response = await fetch(url);
4078
+ let responseData;
4079
+ try {
4080
+ responseData = await response.json();
4081
+ } catch {
4082
+ throw new Error("Malformed response data: invalid JSON");
4083
+ }
4084
+ return deserializeReferrerDetailResponse(responseData);
4085
+ }
4086
+ /**
4087
+ * Fetch ENSNode Registrar Actions
4088
+ *
4089
+ * Retrieves a paginated list of registrar actions with optional filters.
4090
+ *
4091
+ * @param request is a request configuration.
4092
+ * @param request.page sets the page number to retrieve (1-indexed, default: 1)
4093
+ * @param request.recordsPerPage sets the number of records per page (default: 10, max: 100)
4094
+ * @param request.filters is an optional request filter configuration.
4095
+ * @param request.order sets the order of results in the response by field and direction.
4096
+ * @returns {RegistrarActionsResponse}
4097
+ *
4098
+ * @throws if the ENSNode request fails
4099
+ * @throws if the ENSNode API returns an error response
4100
+ * @throws if the ENSNode response breaks required invariants
4101
+ *
4102
+ * @example
4103
+ * ```ts
4104
+ * import {
4105
+ * registrarActionsFilter,
4106
+ * ENSNodeClient,
4107
+ * } from "@ensnode/ensnode-sdk";
4108
+ * import { namehash } from "viem/ens";
4109
+ *
4110
+ * const client: ENSNodeClient;
4111
+ *
4112
+ * // Get first page with default page size (10 records)
4113
+ * const response = await client.registrarActions();
4114
+ * if (response.responseCode === RegistrarActionsResponseCodes.Ok) {
4115
+ * const { registrarActions, pageContext } = response;
4116
+ * console.log(registrarActions);
4117
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
4118
+ * }
4119
+ *
4120
+ * // Get second page with 25 records per page
4121
+ * const response = await client.registrarActions({
4122
+ * page: 2,
4123
+ * recordsPerPage: 25,
4124
+ * });
4125
+ *
4126
+ * // get latest registrar action records associated with
4127
+ * // subregistry managing `eth` name
4128
+ * await client.registrarActions({
4129
+ * filters: [registrarActionsFilter.byParentNode(namehash('eth'))],
4130
+ * });
4131
+ *
4132
+ * // get latest registrar action records which include referral info
4133
+ * await client.registrarActions({
4134
+ * filters: [registrarActionsFilter.withReferral(true)],
4135
+ * });
4136
+ *
4137
+ * // get latest registrar action records for a specific decoded referrer
4138
+ * await client.registrarActions({
4139
+ * filters: [registrarActionsFilter.byDecodedReferrer("0x1234567890123456789012345678901234567890")],
4140
+ * });
4141
+ *
4142
+ * // get latest 10 registrar action records associated with
4143
+ * // subregistry managing `base.eth` name
4144
+ * await client.registrarActions({
4145
+ * filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
4146
+ * recordsPerPage: 10
4147
+ * });
4148
+ *
4149
+ * // get registrar actions within a specific time range
4150
+ * const beginTimestamp = 1764547200; // Dec 1, 2025, 00:00:00 UTC
4151
+ * const endTimestamp = 1767225600; // Jan 1, 2026, 00:00:00 UTC
4152
+ * await client.registrarActions({
4153
+ * filters: [
4154
+ * registrarActionsFilter.beginTimestamp(beginTimestamp),
4155
+ * registrarActionsFilter.endTimestamp(endTimestamp),
4156
+ * ],
4157
+ * });
4158
+ *
4159
+ * // get registrar actions from a specific timestamp onwards
4160
+ * await client.registrarActions({
4161
+ * filters: [registrarActionsFilter.beginTimestamp(1764547200)],
4162
+ * });
4163
+ *
4164
+ * // get registrar actions up to a specific timestamp
4165
+ * await client.registrarActions({
4166
+ * filters: [registrarActionsFilter.endTimestamp(1767225600)],
4167
+ * });
4168
+ * ```
4169
+ */
4170
+ async registrarActions(request = {}) {
4171
+ const buildUrlPath = (filters) => {
4172
+ const bySubregistryNodeFilter = filters?.find(
4173
+ (f) => f.filterType === RegistrarActionsFilterTypes.BySubregistryNode
4174
+ );
4175
+ return bySubregistryNodeFilter ? new URL(`/api/registrar-actions/${bySubregistryNodeFilter.value}`, this.options.url) : new URL(`/api/registrar-actions`, this.options.url);
4176
+ };
4177
+ const buildWithReferralArg = (filters) => {
4178
+ const withReferralFilter = filters?.find(
4179
+ (f) => f.filterType === RegistrarActionsFilterTypes.WithEncodedReferral
4180
+ );
4181
+ return withReferralFilter ? { key: "withReferral", value: "true" } : null;
4182
+ };
4183
+ const buildDecodedReferrerArg = (filters) => {
4184
+ const decodedReferrerFilter = filters?.find(
4185
+ (f) => f.filterType === RegistrarActionsFilterTypes.ByDecodedReferrer
4186
+ );
4187
+ return decodedReferrerFilter ? { key: "decodedReferrer", value: decodedReferrerFilter.value } : null;
4188
+ };
4189
+ const buildBeginTimestampArg = (filters) => {
4190
+ const beginTimestampFilter = filters?.find(
4191
+ (f) => f.filterType === RegistrarActionsFilterTypes.BeginTimestamp
4192
+ );
4193
+ return beginTimestampFilter ? { key: "beginTimestamp", value: beginTimestampFilter.value.toString() } : null;
4194
+ };
4195
+ const buildEndTimestampArg = (filters) => {
4196
+ const endTimestampFilter = filters?.find(
4197
+ (f) => f.filterType === RegistrarActionsFilterTypes.EndTimestamp
4198
+ );
4199
+ return endTimestampFilter ? { key: "endTimestamp", value: endTimestampFilter.value.toString() } : null;
4200
+ };
4201
+ const buildOrderArg = (order) => {
4202
+ switch (order) {
4203
+ case RegistrarActionsOrders.LatestRegistrarActions: {
4204
+ const [field, direction] = order.split("=");
4205
+ return {
4206
+ key: `sort[${field}]`,
4207
+ value: `${direction}`
4208
+ };
4209
+ }
4210
+ }
4211
+ };
4212
+ const url = buildUrlPath(request.filters);
4213
+ if (request.order) {
4214
+ const orderArgs = buildOrderArg(request.order);
4215
+ url.searchParams.set(orderArgs.key, orderArgs.value);
4216
+ }
4217
+ if (request.page) {
4218
+ url.searchParams.set("page", request.page.toString());
4219
+ }
4220
+ if (request.recordsPerPage) {
4221
+ url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
4222
+ }
4223
+ const referralArg = buildWithReferralArg(request.filters);
4224
+ if (referralArg) {
4225
+ url.searchParams.set(referralArg.key, referralArg.value);
4226
+ }
4227
+ const decodedReferrerArg = buildDecodedReferrerArg(request.filters);
4228
+ if (decodedReferrerArg) {
4229
+ url.searchParams.set(decodedReferrerArg.key, decodedReferrerArg.value);
4230
+ }
4231
+ const beginTimestampArg = buildBeginTimestampArg(request.filters);
4232
+ if (beginTimestampArg) {
4233
+ url.searchParams.set(beginTimestampArg.key, beginTimestampArg.value);
4234
+ }
4235
+ const endTimestampArg = buildEndTimestampArg(request.filters);
4236
+ if (endTimestampArg) {
4237
+ url.searchParams.set(endTimestampArg.key, endTimestampArg.value);
4238
+ }
4239
+ const response = await fetch(url);
4240
+ let responseData;
4241
+ try {
4242
+ responseData = await response.json();
4243
+ } catch {
4244
+ throw new Error("Malformed response data: invalid JSON");
4245
+ }
4246
+ if (!response.ok) {
4247
+ let errorResponse;
4248
+ try {
4249
+ errorResponse = deserializeErrorResponse(responseData);
4250
+ } catch {
4251
+ console.log("Registrar Actions API: handling a known server error.");
4252
+ }
4253
+ if (typeof errorResponse !== "undefined") {
4254
+ throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
4255
+ }
4256
+ }
4257
+ return deserializeRegistrarActionsResponse(responseData);
4258
+ }
4259
+ /**
4260
+ * Fetch Name Tokens for requested name.
4261
+ *
4262
+ * @param request.name - Name for which Name Tokens will be fetched.
4263
+ * @returns {NameTokensResponse}
4264
+ *
4265
+ * @throws if the ENSNode request fails
4266
+ * @throws if the ENSNode API returns an error response
4267
+ * @throws if the ENSNode response breaks required invariants
4268
+ *
4269
+ * @example
4270
+ * ```ts
4271
+ * import {
4272
+ * ENSNodeClient,
4273
+ * } from "@ensnode/ensnode-sdk";
4274
+ * import { namehash } from "viem/ens";
4275
+ *
4276
+ * const client: ENSNodeClient;
4277
+ *
4278
+ * // get latest name token records from the indexed subregistry based on the requested name
4279
+ * const response = await client.nameTokens({
4280
+ * name: "vitalik.eth"
4281
+ * });
4282
+ *
4283
+ * const response = await client.nameTokens({
4284
+ * domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
4285
+ * })
4286
+ * ```
4287
+ */
4288
+ async nameTokens(request) {
4289
+ const url = new URL(`/api/name-tokens`, this.options.url);
4290
+ if (request.name !== void 0) {
4291
+ url.searchParams.set("name", request.name);
4292
+ } else if (request.domainId !== void 0) {
4293
+ url.searchParams.set("domainId", request.domainId);
4294
+ }
4295
+ const response = await fetch(url);
4296
+ let responseData;
4297
+ try {
4298
+ responseData = await response.json();
4299
+ } catch {
4300
+ throw new Error("Malformed response data: invalid JSON");
4301
+ }
4302
+ if (!response.ok) {
4303
+ let errorResponse;
4304
+ try {
4305
+ errorResponse = deserializeErrorResponse(responseData);
4306
+ } catch {
4307
+ console.log("Name Tokens API: handling a known server error.");
4308
+ }
4309
+ if (typeof errorResponse !== "undefined") {
4310
+ throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
4311
+ }
4312
+ }
4313
+ return deserializedNameTokensResponse(responseData);
4314
+ }
4315
+ };
4316
+
4317
+ // src/identity/identity.ts
4318
+ var import_datasources9 = require("@ensnode/datasources");
4319
+
4320
+ // src/identity/types.ts
4321
+ var ResolutionStatusIds = {
4322
+ /**
4323
+ * Represents that the `Identity` is not resolved yet.
4324
+ */
4325
+ Unresolved: "unresolved",
4326
+ /**
4327
+ * Represents that resolution of the `Identity` resulted in a named identity.
4328
+ */
4329
+ Named: "named",
4330
+ /**
4331
+ * Represents that resolution of the `Identity` resulted in an unnamed identity.
4332
+ */
4333
+ Unnamed: "unnamed",
4334
+ /**
4335
+ * Represents that attempted resolution of the `Identity` resulted in an error
4336
+ * and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
4337
+ */
4338
+ Unknown: "unknown"
4339
+ };
4340
+
4341
+ // src/identity/identity.ts
4342
+ function buildUnresolvedIdentity(address, namespaceId, chainId) {
4343
+ return {
4344
+ resolutionStatus: ResolutionStatusIds.Unresolved,
4345
+ chainId: chainId ?? (0, import_datasources9.getENSRootChainId)(namespaceId),
4346
+ address
4347
+ };
4348
+ }
4349
+ function isResolvedIdentity(identity) {
4350
+ return identity.resolutionStatus !== ResolutionStatusIds.Unresolved;
4351
+ }
4352
+
4353
+ // src/resolution/ensip19-chainid.ts
4354
+ var import_chains = require("viem/chains");
4355
+ var import_datasources10 = require("@ensnode/datasources");
4356
+ var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
4357
+ const ensRootChainId = (0, import_datasources10.getENSRootChainId)(namespaceId);
4358
+ return chainId === ensRootChainId ? import_chains.mainnet.id : chainId;
4359
+ };
4360
+ var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
4361
+ return chainId === DEFAULT_EVM_CHAIN_ID ? (0, import_datasources10.getENSRootChainId)(namespaceId) : chainId;
4362
+ };
4363
+
4364
+ // src/resolution/resolver-records-selection.ts
4365
+ var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
4366
+
4367
+ // src/tracing/ens-protocol-tracing.ts
4368
+ var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
4369
+ var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
4370
+ var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
4371
+ var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
4372
+ var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
4373
+ TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
4374
+ TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
4375
+ return TraceableENSProtocol2;
4376
+ })(TraceableENSProtocol || {});
4377
+ var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
4378
+ ForwardResolutionProtocolStep2["Operation"] = "forward-resolution";
4379
+ ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
4380
+ ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
4381
+ ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
4382
+ ForwardResolutionProtocolStep2["AccelerateKnownOffchainLookupResolver"] = "accelerate-known-offchain-lookup-resolver";
4383
+ ForwardResolutionProtocolStep2["AccelerateKnownOnchainStaticResolver"] = "accelerate-known-onchain-static-resolver";
4384
+ ForwardResolutionProtocolStep2["RequireResolver"] = "require-resolver";
4385
+ ForwardResolutionProtocolStep2["ExecuteResolveCalls"] = "execute-resolve-calls";
4386
+ return ForwardResolutionProtocolStep2;
4387
+ })(ForwardResolutionProtocolStep || {});
4388
+ var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
4389
+ ReverseResolutionProtocolStep2["Operation"] = "reverse-resolution";
4390
+ ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
4391
+ ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
4392
+ ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
4393
+ ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
4394
+ return ReverseResolutionProtocolStep2;
4395
+ })(ReverseResolutionProtocolStep || {});
4396
+ //# sourceMappingURL=index.cjs.map