@ensnode/ensnode-sdk 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,32 +1,12 @@
1
- // src/api/deserialize.ts
2
- import { prettifyError as prettifyError2 } from "zod/v4";
1
+ // src/ensapi/config/deserialize.ts
2
+ import { prettifyError as prettifyError2, ZodError } from "zod/v4";
3
3
 
4
- // src/api/zod-schemas.ts
5
- import { namehash as namehash2 } from "viem";
6
- import z7 from "zod/v4";
4
+ // src/ensapi/config/zod-schemas.ts
5
+ import { z as z3 } from "zod/v4";
7
6
 
8
- // src/ensindexer/indexing-status/zod-schemas.ts
7
+ // src/ensindexer/config/zod-schemas.ts
9
8
  import z2 from "zod/v4";
10
9
 
11
- // src/ens/is-normalized.ts
12
- import { normalize } from "viem/ens";
13
- function isNormalizedName(name) {
14
- try {
15
- return name === normalize(name);
16
- } catch {
17
- return false;
18
- }
19
- }
20
- function isNormalizedLabel(label) {
21
- if (label === "") return false;
22
- if (label.includes(".")) return false;
23
- try {
24
- return label === normalize(label);
25
- } catch {
26
- return false;
27
- }
28
- }
29
-
30
10
  // src/shared/account-id.ts
31
11
  import { isAddressEqual } from "viem";
32
12
  var accountIdEqual = (a, b) => {
@@ -180,9 +160,39 @@ function isEncodedLabelHash(maybeEncodedLabelHash) {
180
160
  return expectedFormatting && includesLabelHash;
181
161
  }
182
162
 
163
+ // src/ens/is-normalized.ts
164
+ import { normalize } from "viem/ens";
165
+ function isNormalizedName(name) {
166
+ try {
167
+ return name === normalize(name);
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+ function isNormalizedLabel(label) {
173
+ if (label === "") return false;
174
+ if (label.includes(".")) return false;
175
+ try {
176
+ return label === normalize(label);
177
+ } catch {
178
+ return false;
179
+ }
180
+ }
181
+
183
182
  // src/ens/names.ts
184
183
  import { ens_beautify } from "@adraffy/ens-normalize";
184
+ var ENS_ROOT = "";
185
185
  var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
186
+ var getParentNameFQDN = (name) => {
187
+ if (name === ENS_ROOT) {
188
+ throw new Error("There is no parent name for ENS Root.");
189
+ }
190
+ const labels = name.split(".");
191
+ if (labels.length === 1) {
192
+ return ENS_ROOT;
193
+ }
194
+ return labels.slice(1).join(".");
195
+ };
186
196
  var beautifyName = (name) => {
187
197
  const beautifiedLabels = name.split(".").map((label) => {
188
198
  if (isNormalizedLabel(label)) {
@@ -425,7 +435,7 @@ var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
425
435
  chainId: makeChainIdSchema(`${valueLabel} chain ID`),
426
436
  address: makeLowercaseAddressSchema(`${valueLabel} address`)
427
437
  });
428
- var makeSerializedAccountIdSchema = (valueLabel = "Account ID") => z.coerce.string().transform((v) => {
438
+ var makeAccountIdStringSchema = (valueLabel = "Account ID String") => z.coerce.string().transform((v) => {
429
439
  const result = new CaipAccountId(v);
430
440
  return {
431
441
  chainId: Number(result.chainId.reference),
@@ -437,7 +447,7 @@ var makeHexStringSchema = (options, valueLabel = "String representation of bytes
437
447
  ctx.issues.push({
438
448
  code: "custom",
439
449
  input: ctx.value,
440
- message: `${valueLabel} must start with '0x'.`
450
+ message: `${valueLabel} must be a hexadecimal value which starts with '0x'.`
441
451
  });
442
452
  }
443
453
  }).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
@@ -547,8 +557,8 @@ ${prettifyError(parsed.error)}
547
557
  }
548
558
  return parsed.data;
549
559
  }
550
- function deserializeAccountId(maybeAccountId, valueLabel) {
551
- const schema = makeSerializedAccountIdSchema(valueLabel);
560
+ function parseAccountId(maybeAccountId, valueLabel) {
561
+ const schema = makeAccountIdStringSchema(valueLabel);
552
562
  const parsed = schema.safeParse(maybeAccountId);
553
563
  if (parsed.error) {
554
564
  throw new RangeError(`Cannot deserialize AccountId:
@@ -811,6 +821,28 @@ var TtlCache = class {
811
821
  // src/shared/collections.ts
812
822
  var uniq = (arr) => [...new Set(arr)];
813
823
 
824
+ // src/shared/datasource-contract.ts
825
+ import { maybeGetDatasource } from "@ensnode/datasources";
826
+ var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
827
+ const datasource = maybeGetDatasource(namespaceId, datasourceName);
828
+ if (!datasource) return void 0;
829
+ const address = datasource.contracts[contractName]?.address;
830
+ if (address === void 0 || Array.isArray(address)) return void 0;
831
+ return {
832
+ chainId: datasource.chain.id,
833
+ address
834
+ };
835
+ };
836
+ var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
837
+ const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
838
+ if (!contract) {
839
+ throw new Error(
840
+ `Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
841
+ );
842
+ }
843
+ return contract;
844
+ };
845
+
814
846
  // src/shared/labelhash.ts
815
847
  import { keccak256 as keccak2562, stringToBytes } from "viem";
816
848
  var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
@@ -869,7 +901,7 @@ function serializePrice(price) {
869
901
  function serializePriceEth(price) {
870
902
  return serializePrice(price);
871
903
  }
872
- function serializeAccountId(accountId) {
904
+ function formatAccountId(accountId) {
873
905
  return CaipAccountId2.format({
874
906
  chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
875
907
  address: accountId.address
@@ -884,770 +916,1647 @@ function isWebSocketProtocol(url) {
884
916
  return ["ws:", "wss:"].includes(url.protocol);
885
917
  }
886
918
 
887
- // src/ensindexer/indexing-status/types.ts
888
- var ChainIndexingConfigTypeIds = {
889
- /**
890
- * Represents that indexing of the chain should be performed for an indefinite range.
891
- */
892
- Indefinite: "indefinite",
893
- /**
894
- * Represents that indexing of the chain should be performed for a definite range.
895
- */
896
- Definite: "definite"
897
- };
898
- var ChainIndexingStatusIds = {
899
- /**
900
- * Represents that indexing of the chain is not ready to begin yet because:
901
- * - ENSIndexer is in its initialization phase and the data to build a
902
- * "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
903
- * - ENSIndexer is using an omnichain indexing strategy and the
904
- * `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
905
- * {@link ChainIndexingSnapshot}.
906
- */
907
- Queued: "chain-queued",
908
- /**
909
- * Represents that indexing of the chain is in progress and under a special
910
- * "backfill" phase that optimizes for accelerated indexing until reaching the
911
- * "fixed target" `backfillEndBlock`.
912
- */
913
- Backfill: "chain-backfill",
914
- /**
915
- * Represents that the "backfill" phase of indexing the chain is completed
916
- * and that the chain is configured to be indexed for an indefinite range.
917
- * Therefore, indexing of the chain remains indefinitely in progress where
918
- * ENSIndexer will continuously work to discover and index new blocks as they
919
- * are added to the chain across time.
920
- */
921
- Following: "chain-following",
922
- /**
923
- * Represents that indexing of the chain is completed as the chain is configured
924
- * to be indexed for a definite range and the indexing of all blocks through
925
- * that definite range is completed.
926
- */
927
- Completed: "chain-completed"
928
- };
929
- var OmnichainIndexingStatusIds = {
930
- /**
931
- * Represents that omnichain indexing is not ready to begin yet because
932
- * ENSIndexer is in its initialization phase and the data to build a "true"
933
- * {@link OmnichainIndexingStatusSnapshot} is still being loaded.
934
- */
935
- Unstarted: "omnichain-unstarted",
936
- /**
937
- * Represents that omnichain indexing is in an overall "backfill" status because
938
- * - At least one indexed chain has a `chainStatus` of
939
- * {@link ChainIndexingStatusIds.Backfill}; and
940
- * - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
941
- */
942
- Backfill: "omnichain-backfill",
943
- /**
944
- * Represents that omnichain indexing is in an overall "following" status because
945
- * at least one indexed chain has a `chainStatus` of
946
- * {@link ChainIndexingStatusIds.Following}.
947
- */
948
- Following: "omnichain-following",
949
- /**
950
- * Represents that omnichain indexing has completed because all indexed chains have
951
- * a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
952
- */
953
- Completed: "omnichain-completed"
954
- };
955
- var CrossChainIndexingStrategyIds = {
956
- /**
957
- * Represents that the indexing of events across all indexed chains will
958
- * proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
959
- * and block number.
960
- *
961
- * This strategy is "deterministic" in that the order of processing cross-chain indexed
962
- * events and each resulting indexed data state transition recorded in ENSDb is always
963
- * the same for each ENSIndexer instance operating with an equivalent
964
- * `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
965
- * - increased indexing latency that must wait for the slowest indexed chain to
966
- * add new blocks or to discover new blocks through the configured RPCs.
967
- * - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
968
- * will be affected.
969
- */
970
- Omnichain: "omnichain"
971
- };
919
+ // src/ensindexer/config/is-subgraph-compatible.ts
920
+ import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
972
921
 
973
- // src/shared/block-ref.ts
974
- function isBefore(blockA, blockB) {
975
- return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
976
- }
977
- function isEqualTo(blockA, blockB) {
978
- return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
979
- }
980
- function isBeforeOrEqualTo(blockA, blockB) {
981
- return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
922
+ // src/ensindexer/config/types.ts
923
+ var PluginName = /* @__PURE__ */ ((PluginName2) => {
924
+ PluginName2["Subgraph"] = "subgraph";
925
+ PluginName2["Basenames"] = "basenames";
926
+ PluginName2["Lineanames"] = "lineanames";
927
+ PluginName2["ThreeDNS"] = "threedns";
928
+ PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
929
+ PluginName2["Registrars"] = "registrars";
930
+ PluginName2["TokenScope"] = "tokenscope";
931
+ return PluginName2;
932
+ })(PluginName || {});
933
+
934
+ // src/ensindexer/config/is-subgraph-compatible.ts
935
+ function isSubgraphCompatible(config) {
936
+ const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
937
+ const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
938
+ const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
939
+ const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
940
+ return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
982
941
  }
983
942
 
984
- // src/ensindexer/indexing-status/helpers.ts
985
- function getOmnichainIndexingStatus(chains) {
986
- if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
987
- return OmnichainIndexingStatusIds.Following;
943
+ // src/ensindexer/config/validations.ts
944
+ function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
945
+ const versionInfo = ctx.value;
946
+ if (versionInfo.ensDb !== versionInfo.ensIndexer) {
947
+ ctx.issues.push({
948
+ code: "custom",
949
+ input: versionInfo,
950
+ message: "`ensDb` version must be same as `ensIndexer` version"
951
+ });
988
952
  }
989
- if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
990
- return OmnichainIndexingStatusIds.Backfill;
953
+ }
954
+
955
+ // src/ensindexer/config/zod-schemas.ts
956
+ var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
957
+ error: `${valueLabel} must be an array.`
958
+ }).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
959
+ var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(z2.string(), {
960
+ error: `${valueLabel} must be a list of strings.`
961
+ }).min(1, {
962
+ error: `${valueLabel} must be a list of strings with at least one string value`
963
+ }).refine((arr) => arr.length === uniq(arr).length, {
964
+ error: `${valueLabel} cannot contain duplicate values.`
965
+ });
966
+ var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
967
+ error: `${valueLabel} is required and must be a non-empty string.`
968
+ });
969
+ var makeLabelSetIdSchema = (valueLabel) => {
970
+ return z2.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
971
+ error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
972
+ });
973
+ };
974
+ var makeLabelSetVersionSchema = (valueLabel) => {
975
+ return z2.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
976
+ };
977
+ var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
978
+ let valueLabelLabelSetId = valueLabel;
979
+ let valueLabelLabelSetVersion = valueLabel;
980
+ if (valueLabel === "LABEL_SET") {
981
+ valueLabelLabelSetId = "LABEL_SET_ID";
982
+ valueLabelLabelSetVersion = "LABEL_SET_VERSION";
983
+ } else {
984
+ valueLabelLabelSetId = `${valueLabel}.labelSetId`;
985
+ valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
991
986
  }
992
- if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
993
- return OmnichainIndexingStatusIds.Unstarted;
987
+ return z2.object({
988
+ labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
989
+ labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
990
+ });
991
+ };
992
+ var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
993
+ var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z2.strictObject(
994
+ {
995
+ nodejs: makeNonEmptyStringSchema(),
996
+ ponder: makeNonEmptyStringSchema(),
997
+ ensDb: makeNonEmptyStringSchema(),
998
+ ensIndexer: makeNonEmptyStringSchema(),
999
+ ensNormalize: makeNonEmptyStringSchema(),
1000
+ ensRainbow: makeNonEmptyStringSchema(),
1001
+ ensRainbowSchema: makePositiveIntegerSchema()
1002
+ },
1003
+ {
1004
+ error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
994
1005
  }
995
- if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
996
- return OmnichainIndexingStatusIds.Completed;
1006
+ ).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
1007
+ function invariant_isSubgraphCompatibleRequirements(ctx) {
1008
+ const { value: config } = ctx;
1009
+ if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
1010
+ ctx.issues.push({
1011
+ code: "custom",
1012
+ input: config,
1013
+ message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
1014
+ });
997
1015
  }
998
- throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
999
- }
1000
- function getTimestampForLowestOmnichainStartBlock(chains) {
1001
- const earliestKnownBlockTimestamps = chains.map(
1002
- (chain) => chain.config.startBlock.timestamp
1003
- );
1004
- return Math.min(...earliestKnownBlockTimestamps);
1005
1016
  }
1006
- function getTimestampForHighestOmnichainKnownBlock(chains) {
1007
- const latestKnownBlockTimestamps = [];
1008
- for (const chain of chains) {
1009
- switch (chain.chainStatus) {
1010
- case ChainIndexingStatusIds.Queued:
1011
- if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
1012
- latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
1013
- }
1014
- break;
1015
- case ChainIndexingStatusIds.Backfill:
1016
- latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
1017
- break;
1018
- case ChainIndexingStatusIds.Completed:
1019
- latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
1020
- break;
1021
- case ChainIndexingStatusIds.Following:
1022
- latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
1023
- break;
1017
+ var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
1018
+ labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
1019
+ indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
1020
+ isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
1021
+ namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
1022
+ plugins: makePluginsListSchema(`${valueLabel}.plugins`),
1023
+ databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
1024
+ versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
1025
+ }).check(invariant_isSubgraphCompatibleRequirements);
1026
+
1027
+ // src/ensapi/config/zod-schemas.ts
1028
+ var TheGraphCannotFallbackReasonSchema = z3.enum({
1029
+ NotSubgraphCompatible: "not-subgraph-compatible",
1030
+ NoApiKey: "no-api-key",
1031
+ NoSubgraphUrl: "no-subgraph-url"
1032
+ });
1033
+ var TheGraphFallbackSchema = z3.strictObject({
1034
+ canFallback: z3.boolean(),
1035
+ reason: TheGraphCannotFallbackReasonSchema.nullable()
1036
+ });
1037
+ function makeENSApiPublicConfigSchema(valueLabel) {
1038
+ const label = valueLabel ?? "ENSApiPublicConfig";
1039
+ return z3.strictObject({
1040
+ version: z3.string().min(1, `${label}.version must be a non-empty string`),
1041
+ theGraphFallback: TheGraphFallbackSchema,
1042
+ ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
1043
+ });
1044
+ }
1045
+
1046
+ // src/ensapi/config/deserialize.ts
1047
+ function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
1048
+ const schema = makeENSApiPublicConfigSchema(valueLabel);
1049
+ try {
1050
+ return schema.parse(maybeConfig);
1051
+ } catch (error) {
1052
+ if (error instanceof ZodError) {
1053
+ throw new Error(`Cannot deserialize ENSApiPublicConfig:
1054
+ ${prettifyError2(error)}
1055
+ `);
1056
+ }
1057
+ throw error;
1058
+ }
1059
+ }
1060
+
1061
+ // src/ensindexer/config/deserialize.ts
1062
+ import { prettifyError as prettifyError3 } from "zod/v4";
1063
+ function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
1064
+ const schema = makeENSIndexerPublicConfigSchema(valueLabel);
1065
+ const parsed = schema.safeParse(maybeConfig);
1066
+ if (parsed.error) {
1067
+ throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
1068
+ ${prettifyError3(parsed.error)}
1069
+ `);
1070
+ }
1071
+ return parsed.data;
1072
+ }
1073
+
1074
+ // src/ensindexer/config/label-utils.ts
1075
+ import { hexToBytes as hexToBytes2 } from "viem";
1076
+ function labelHashToBytes(labelHash) {
1077
+ try {
1078
+ if (labelHash.length !== 66) {
1079
+ throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
1080
+ }
1081
+ if (labelHash !== labelHash.toLowerCase()) {
1082
+ throw new Error("Labelhash must be in lowercase");
1083
+ }
1084
+ if (!labelHash.startsWith("0x")) {
1085
+ throw new Error("Labelhash must be 0x-prefixed");
1086
+ }
1087
+ const bytes = hexToBytes2(labelHash);
1088
+ if (bytes.length !== 32) {
1089
+ throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
1090
+ }
1091
+ return bytes;
1092
+ } catch (e) {
1093
+ if (e instanceof Error) {
1094
+ throw e;
1024
1095
  }
1096
+ throw new Error("Invalid hex format");
1097
+ }
1098
+ }
1099
+
1100
+ // src/ensindexer/config/labelset-utils.ts
1101
+ function buildLabelSetId(maybeLabelSetId) {
1102
+ return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
1103
+ }
1104
+ function buildLabelSetVersion(maybeLabelSetVersion) {
1105
+ return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
1106
+ }
1107
+ function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
1108
+ if (labelSetVersion !== void 0 && labelSetId === void 0) {
1109
+ throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
1110
+ }
1111
+ return { labelSetId, labelSetVersion };
1112
+ }
1113
+ function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
1114
+ if (clientSet.labelSetId === void 0) {
1115
+ return;
1116
+ }
1117
+ if (serverSet.labelSetId !== clientSet.labelSetId) {
1118
+ throw new Error(
1119
+ `Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
1120
+ );
1121
+ }
1122
+ if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
1123
+ throw new Error(
1124
+ `Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
1125
+ );
1126
+ }
1127
+ }
1128
+
1129
+ // src/ensindexer/config/parsing.ts
1130
+ function parseNonNegativeInteger(maybeNumber) {
1131
+ const trimmed = maybeNumber.trim();
1132
+ if (!trimmed) {
1133
+ throw new Error("Input cannot be empty");
1134
+ }
1135
+ if (trimmed === "-0") {
1136
+ throw new Error("Negative zero is not a valid non-negative integer");
1137
+ }
1138
+ const num = Number(maybeNumber);
1139
+ if (Number.isNaN(num)) {
1140
+ throw new Error(`"${maybeNumber}" is not a valid number`);
1141
+ }
1142
+ if (!Number.isFinite(num)) {
1143
+ throw new Error(`"${maybeNumber}" is not a finite number`);
1144
+ }
1145
+ if (!Number.isInteger(num)) {
1146
+ throw new Error(`"${maybeNumber}" is not an integer`);
1147
+ }
1148
+ if (num < 0) {
1149
+ throw new Error(`"${maybeNumber}" is not a non-negative integer`);
1150
+ }
1151
+ return num;
1152
+ }
1153
+
1154
+ // src/ensindexer/config/serialize.ts
1155
+ function serializeIndexedChainIds(indexedChainIds) {
1156
+ return Array.from(indexedChainIds);
1157
+ }
1158
+ function serializeENSIndexerPublicConfig(config) {
1159
+ const {
1160
+ labelSet,
1161
+ indexedChainIds,
1162
+ databaseSchemaName,
1163
+ isSubgraphCompatible: isSubgraphCompatible2,
1164
+ namespace,
1165
+ plugins,
1166
+ versionInfo
1167
+ } = config;
1168
+ return {
1169
+ labelSet,
1170
+ indexedChainIds: serializeIndexedChainIds(indexedChainIds),
1171
+ databaseSchemaName,
1172
+ isSubgraphCompatible: isSubgraphCompatible2,
1173
+ namespace,
1174
+ plugins,
1175
+ versionInfo
1176
+ };
1177
+ }
1178
+
1179
+ // src/ensindexer/indexing-status/deserialize.ts
1180
+ import { prettifyError as prettifyError4 } from "zod/v4";
1181
+
1182
+ // src/ensindexer/indexing-status/zod-schemas.ts
1183
+ import z4 from "zod/v4";
1184
+
1185
+ // src/ensindexer/indexing-status/types.ts
1186
+ var ChainIndexingConfigTypeIds = {
1187
+ /**
1188
+ * Represents that indexing of the chain should be performed for an indefinite range.
1189
+ */
1190
+ Indefinite: "indefinite",
1191
+ /**
1192
+ * Represents that indexing of the chain should be performed for a definite range.
1193
+ */
1194
+ Definite: "definite"
1195
+ };
1196
+ var ChainIndexingStatusIds = {
1197
+ /**
1198
+ * Represents that indexing of the chain is not ready to begin yet because:
1199
+ * - ENSIndexer is in its initialization phase and the data to build a
1200
+ * "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
1201
+ * - ENSIndexer is using an omnichain indexing strategy and the
1202
+ * `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
1203
+ * {@link ChainIndexingSnapshot}.
1204
+ */
1205
+ Queued: "chain-queued",
1206
+ /**
1207
+ * Represents that indexing of the chain is in progress and under a special
1208
+ * "backfill" phase that optimizes for accelerated indexing until reaching the
1209
+ * "fixed target" `backfillEndBlock`.
1210
+ */
1211
+ Backfill: "chain-backfill",
1212
+ /**
1213
+ * Represents that the "backfill" phase of indexing the chain is completed
1214
+ * and that the chain is configured to be indexed for an indefinite range.
1215
+ * Therefore, indexing of the chain remains indefinitely in progress where
1216
+ * ENSIndexer will continuously work to discover and index new blocks as they
1217
+ * are added to the chain across time.
1218
+ */
1219
+ Following: "chain-following",
1220
+ /**
1221
+ * Represents that indexing of the chain is completed as the chain is configured
1222
+ * to be indexed for a definite range and the indexing of all blocks through
1223
+ * that definite range is completed.
1224
+ */
1225
+ Completed: "chain-completed"
1226
+ };
1227
+ var OmnichainIndexingStatusIds = {
1228
+ /**
1229
+ * Represents that omnichain indexing is not ready to begin yet because
1230
+ * ENSIndexer is in its initialization phase and the data to build a "true"
1231
+ * {@link OmnichainIndexingStatusSnapshot} is still being loaded.
1232
+ */
1233
+ Unstarted: "omnichain-unstarted",
1234
+ /**
1235
+ * Represents that omnichain indexing is in an overall "backfill" status because
1236
+ * - At least one indexed chain has a `chainStatus` of
1237
+ * {@link ChainIndexingStatusIds.Backfill}; and
1238
+ * - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
1239
+ */
1240
+ Backfill: "omnichain-backfill",
1241
+ /**
1242
+ * Represents that omnichain indexing is in an overall "following" status because
1243
+ * at least one indexed chain has a `chainStatus` of
1244
+ * {@link ChainIndexingStatusIds.Following}.
1245
+ */
1246
+ Following: "omnichain-following",
1247
+ /**
1248
+ * Represents that omnichain indexing has completed because all indexed chains have
1249
+ * a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
1250
+ */
1251
+ Completed: "omnichain-completed"
1252
+ };
1253
+ var CrossChainIndexingStrategyIds = {
1254
+ /**
1255
+ * Represents that the indexing of events across all indexed chains will
1256
+ * proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
1257
+ * and block number.
1258
+ *
1259
+ * This strategy is "deterministic" in that the order of processing cross-chain indexed
1260
+ * events and each resulting indexed data state transition recorded in ENSDb is always
1261
+ * the same for each ENSIndexer instance operating with an equivalent
1262
+ * `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
1263
+ * - increased indexing latency that must wait for the slowest indexed chain to
1264
+ * add new blocks or to discover new blocks through the configured RPCs.
1265
+ * - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
1266
+ * will be affected.
1267
+ */
1268
+ Omnichain: "omnichain"
1269
+ };
1270
+
1271
+ // src/shared/block-ref.ts
1272
+ function isBefore(blockA, blockB) {
1273
+ return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
1274
+ }
1275
+ function isEqualTo(blockA, blockB) {
1276
+ return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
1277
+ }
1278
+ function isBeforeOrEqualTo(blockA, blockB) {
1279
+ return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
1280
+ }
1281
+
1282
+ // src/ensindexer/indexing-status/helpers.ts
1283
+ function getOmnichainIndexingStatus(chains) {
1284
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
1285
+ return OmnichainIndexingStatusIds.Following;
1286
+ }
1287
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
1288
+ return OmnichainIndexingStatusIds.Backfill;
1289
+ }
1290
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
1291
+ return OmnichainIndexingStatusIds.Unstarted;
1292
+ }
1293
+ if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
1294
+ return OmnichainIndexingStatusIds.Completed;
1295
+ }
1296
+ throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
1297
+ }
1298
+ function getTimestampForLowestOmnichainStartBlock(chains) {
1299
+ const earliestKnownBlockTimestamps = chains.map(
1300
+ (chain) => chain.config.startBlock.timestamp
1301
+ );
1302
+ return Math.min(...earliestKnownBlockTimestamps);
1303
+ }
1304
+ function getTimestampForHighestOmnichainKnownBlock(chains) {
1305
+ const latestKnownBlockTimestamps = [];
1306
+ for (const chain of chains) {
1307
+ switch (chain.chainStatus) {
1308
+ case ChainIndexingStatusIds.Queued:
1309
+ if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
1310
+ latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
1311
+ }
1312
+ break;
1313
+ case ChainIndexingStatusIds.Backfill:
1314
+ latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
1315
+ break;
1316
+ case ChainIndexingStatusIds.Completed:
1317
+ latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
1318
+ break;
1319
+ case ChainIndexingStatusIds.Following:
1320
+ latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
1321
+ break;
1322
+ }
1323
+ }
1324
+ return Math.max(...latestKnownBlockTimestamps);
1325
+ }
1326
+ function getOmnichainIndexingCursor(chains) {
1327
+ if (chains.length === 0) {
1328
+ throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
1329
+ }
1330
+ if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
1331
+ const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1332
+ return Math.min(...earliestStartBlockTimestamps) - 1;
1333
+ }
1334
+ const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
1335
+ if (latestIndexedBlockTimestamps.length < 1) {
1336
+ throw new Error("latestIndexedBlockTimestamps array must include at least one element");
1337
+ }
1338
+ return Math.max(...latestIndexedBlockTimestamps);
1339
+ }
1340
+ function createIndexingConfig(startBlock, endBlock) {
1341
+ if (endBlock) {
1342
+ return {
1343
+ configType: ChainIndexingConfigTypeIds.Definite,
1344
+ startBlock,
1345
+ endBlock
1346
+ };
1347
+ }
1348
+ return {
1349
+ configType: ChainIndexingConfigTypeIds.Indefinite,
1350
+ startBlock
1351
+ };
1352
+ }
1353
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
1354
+ return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
1355
+ }
1356
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
1357
+ const atLeastOneChainInTargetStatus = chains.some(
1358
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1359
+ );
1360
+ const otherChainsHaveValidStatuses = chains.every(
1361
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
1362
+ );
1363
+ return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
1364
+ }
1365
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
1366
+ const allChainsHaveValidStatuses = chains.every(
1367
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
1368
+ );
1369
+ return allChainsHaveValidStatuses;
1370
+ }
1371
+ function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
1372
+ const allChainsHaveValidStatuses = chains.some(
1373
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Following
1374
+ );
1375
+ return allChainsHaveValidStatuses;
1376
+ }
1377
+ function sortChainStatusesByStartBlockAsc(chains) {
1378
+ chains.sort(
1379
+ ([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
1380
+ );
1381
+ return chains;
1382
+ }
1383
+ function getLatestIndexedBlockRef(indexingStatus, chainId) {
1384
+ const chainIndexingStatus = indexingStatus.omnichainSnapshot.chains.get(chainId);
1385
+ if (chainIndexingStatus === void 0) {
1386
+ return null;
1387
+ }
1388
+ if (chainIndexingStatus.chainStatus === ChainIndexingStatusIds.Queued) {
1389
+ return null;
1390
+ }
1391
+ return chainIndexingStatus.latestIndexedBlock;
1392
+ }
1393
+
1394
+ // src/ensindexer/indexing-status/validations.ts
1395
+ function invariant_chainSnapshotQueuedBlocks(ctx) {
1396
+ const { config } = ctx.value;
1397
+ if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
1398
+ return;
1399
+ }
1400
+ if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
1401
+ ctx.issues.push({
1402
+ code: "custom",
1403
+ input: ctx.value,
1404
+ message: "`config.startBlock` must be before or same as `config.endBlock`."
1405
+ });
1406
+ }
1407
+ }
1408
+ function invariant_chainSnapshotBackfillBlocks(ctx) {
1409
+ const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
1410
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1411
+ ctx.issues.push({
1412
+ code: "custom",
1413
+ input: ctx.value,
1414
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1415
+ });
1416
+ }
1417
+ if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
1418
+ ctx.issues.push({
1419
+ code: "custom",
1420
+ input: ctx.value,
1421
+ message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
1422
+ });
1423
+ }
1424
+ if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
1425
+ return;
1426
+ }
1427
+ if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
1428
+ ctx.issues.push({
1429
+ code: "custom",
1430
+ input: ctx.value,
1431
+ message: "`backfillEndBlock` must be the same as `config.endBlock`."
1432
+ });
1433
+ }
1434
+ }
1435
+ function invariant_chainSnapshotCompletedBlocks(ctx) {
1436
+ const { config, latestIndexedBlock } = ctx.value;
1437
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1438
+ ctx.issues.push({
1439
+ code: "custom",
1440
+ input: ctx.value,
1441
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1442
+ });
1443
+ }
1444
+ if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
1445
+ ctx.issues.push({
1446
+ code: "custom",
1447
+ input: ctx.value,
1448
+ message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
1449
+ });
1450
+ }
1451
+ }
1452
+ function invariant_chainSnapshotFollowingBlocks(ctx) {
1453
+ const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
1454
+ if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1455
+ ctx.issues.push({
1456
+ code: "custom",
1457
+ input: ctx.value,
1458
+ message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1459
+ });
1460
+ }
1461
+ if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
1462
+ ctx.issues.push({
1463
+ code: "custom",
1464
+ input: ctx.value,
1465
+ message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
1466
+ });
1467
+ }
1468
+ }
1469
+ function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
1470
+ const snapshot = ctx.value;
1471
+ const chains = Array.from(snapshot.chains.values());
1472
+ const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
1473
+ const actualOmnichainStatus = snapshot.omnichainStatus;
1474
+ if (expectedOmnichainStatus !== actualOmnichainStatus) {
1475
+ ctx.issues.push({
1476
+ code: "custom",
1477
+ input: snapshot,
1478
+ message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
1479
+ });
1480
+ }
1481
+ }
1482
+ function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
1483
+ const snapshot = ctx.value;
1484
+ const queuedChains = Array.from(snapshot.chains.values()).filter(
1485
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
1486
+ );
1487
+ if (queuedChains.length === 0) {
1488
+ return;
1489
+ }
1490
+ const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
1491
+ const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
1492
+ if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
1493
+ ctx.issues.push({
1494
+ code: "custom",
1495
+ input: snapshot,
1496
+ message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
1497
+ });
1498
+ }
1499
+ }
1500
+ function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
1501
+ const snapshot = ctx.value;
1502
+ const backfillChains = Array.from(snapshot.chains.values()).filter(
1503
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1504
+ );
1505
+ if (backfillChains.length === 0) {
1506
+ return;
1507
+ }
1508
+ const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
1509
+ const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
1510
+ if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
1511
+ ctx.issues.push({
1512
+ code: "custom",
1513
+ input: snapshot,
1514
+ message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
1515
+ });
1516
+ }
1517
+ }
1518
+ function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
1519
+ const snapshot = ctx.value;
1520
+ const indexedChains = Array.from(snapshot.chains.values()).filter(
1521
+ (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
1522
+ );
1523
+ if (indexedChains.length === 0) {
1524
+ return;
1525
+ }
1526
+ const indexedChainLatestIndexedBlocks = indexedChains.map(
1527
+ (chain) => chain.latestIndexedBlock.timestamp
1528
+ );
1529
+ const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
1530
+ if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
1531
+ ctx.issues.push({
1532
+ code: "custom",
1533
+ input: snapshot,
1534
+ message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
1535
+ });
1536
+ }
1537
+ }
1538
+ function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
1539
+ const chains = ctx.value;
1540
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
1541
+ Array.from(chains.values())
1542
+ );
1543
+ if (hasValidChains === false) {
1544
+ ctx.issues.push({
1545
+ code: "custom",
1546
+ input: chains,
1547
+ message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
1548
+ });
1549
+ }
1550
+ }
1551
+ function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
1552
+ const chains = ctx.value;
1553
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
1554
+ Array.from(chains.values())
1555
+ );
1556
+ if (hasValidChains === false) {
1557
+ ctx.issues.push({
1558
+ code: "custom",
1559
+ input: chains,
1560
+ 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".`
1561
+ });
1562
+ }
1563
+ }
1564
+ function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
1565
+ const chains = ctx.value;
1566
+ const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
1567
+ Array.from(chains.values())
1568
+ );
1569
+ if (hasValidChains === false) {
1570
+ ctx.issues.push({
1571
+ code: "custom",
1572
+ input: chains,
1573
+ message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
1574
+ });
1575
+ }
1576
+ }
1577
+ function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
1578
+ const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
1579
+ const { omnichainIndexingCursor } = omnichainSnapshot;
1580
+ if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
1581
+ console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
1582
+ slowestChainIndexingCursor,
1583
+ omnichainIndexingCursor
1584
+ });
1585
+ ctx.issues.push({
1586
+ code: "custom",
1587
+ input: ctx.value,
1588
+ message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
1589
+ });
1590
+ }
1591
+ }
1592
+ function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
1593
+ const { snapshotTime, omnichainSnapshot } = ctx.value;
1594
+ const chains = Array.from(omnichainSnapshot.chains.values());
1595
+ const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1596
+ const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
1597
+ const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
1598
+ const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
1599
+ const highestKnownBlockTimestamp = Math.max(
1600
+ ...startBlockTimestamps,
1601
+ ...endBlockTimestamps,
1602
+ ...backfillEndBlockTimestamps,
1603
+ ...latestKnownBlockTimestamps
1604
+ );
1605
+ if (snapshotTime < highestKnownBlockTimestamp) {
1606
+ ctx.issues.push({
1607
+ code: "custom",
1608
+ input: ctx.value,
1609
+ message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
1610
+ });
1611
+ }
1612
+ }
1613
+ function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
1614
+ const projection = ctx.value;
1615
+ const { snapshot, projectedAt } = projection;
1616
+ if (snapshot.snapshotTime > projectedAt) {
1617
+ ctx.issues.push({
1618
+ code: "custom",
1619
+ input: projection,
1620
+ message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
1621
+ });
1622
+ }
1623
+ }
1624
+ function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
1625
+ const projection = ctx.value;
1626
+ const { projectedAt, snapshot, worstCaseDistance } = projection;
1627
+ const { omnichainSnapshot } = snapshot;
1628
+ const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
1629
+ if (worstCaseDistance !== expectedWorstCaseDistance) {
1630
+ ctx.issues.push({
1631
+ code: "custom",
1632
+ input: projection,
1633
+ message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
1634
+ });
1635
+ }
1636
+ }
1637
+
1638
+ // src/ensindexer/indexing-status/zod-schemas.ts
1639
+ var makeChainIndexingConfigSchema = (valueLabel = "Value") => z4.discriminatedUnion("configType", [
1640
+ z4.strictObject({
1641
+ configType: z4.literal(ChainIndexingConfigTypeIds.Indefinite),
1642
+ startBlock: makeBlockRefSchema(valueLabel)
1643
+ }),
1644
+ z4.strictObject({
1645
+ configType: z4.literal(ChainIndexingConfigTypeIds.Definite),
1646
+ startBlock: makeBlockRefSchema(valueLabel),
1647
+ endBlock: makeBlockRefSchema(valueLabel)
1648
+ })
1649
+ ]);
1650
+ var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => z4.strictObject({
1651
+ chainStatus: z4.literal(ChainIndexingStatusIds.Queued),
1652
+ config: makeChainIndexingConfigSchema(valueLabel)
1653
+ }).check(invariant_chainSnapshotQueuedBlocks);
1654
+ var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => z4.strictObject({
1655
+ chainStatus: z4.literal(ChainIndexingStatusIds.Backfill),
1656
+ config: makeChainIndexingConfigSchema(valueLabel),
1657
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1658
+ backfillEndBlock: makeBlockRefSchema(valueLabel)
1659
+ }).check(invariant_chainSnapshotBackfillBlocks);
1660
+ var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => z4.strictObject({
1661
+ chainStatus: z4.literal(ChainIndexingStatusIds.Completed),
1662
+ config: z4.strictObject({
1663
+ configType: z4.literal(ChainIndexingConfigTypeIds.Definite),
1664
+ startBlock: makeBlockRefSchema(valueLabel),
1665
+ endBlock: makeBlockRefSchema(valueLabel)
1666
+ }),
1667
+ latestIndexedBlock: makeBlockRefSchema(valueLabel)
1668
+ }).check(invariant_chainSnapshotCompletedBlocks);
1669
+ var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => z4.strictObject({
1670
+ chainStatus: z4.literal(ChainIndexingStatusIds.Following),
1671
+ config: z4.strictObject({
1672
+ configType: z4.literal(ChainIndexingConfigTypeIds.Indefinite),
1673
+ startBlock: makeBlockRefSchema(valueLabel)
1674
+ }),
1675
+ latestIndexedBlock: makeBlockRefSchema(valueLabel),
1676
+ latestKnownBlock: makeBlockRefSchema(valueLabel)
1677
+ }).check(invariant_chainSnapshotFollowingBlocks);
1678
+ var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => z4.discriminatedUnion("chainStatus", [
1679
+ makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
1680
+ makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
1681
+ makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
1682
+ makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
1683
+ ]);
1684
+ var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z4.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
1685
+ error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
1686
+ }).transform((serializedChainsIndexingStatus) => {
1687
+ const chainsIndexingStatus = /* @__PURE__ */ new Map();
1688
+ for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
1689
+ chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
1690
+ }
1691
+ return chainsIndexingStatus;
1692
+ });
1693
+ var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => z4.strictObject({
1694
+ omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Unstarted),
1695
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
1696
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1697
+ });
1698
+ var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => z4.strictObject({
1699
+ omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Backfill),
1700
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
1701
+ (chains) => chains
1702
+ ),
1703
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1704
+ });
1705
+ var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => z4.strictObject({
1706
+ omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Completed),
1707
+ chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
1708
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1709
+ });
1710
+ var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => z4.strictObject({
1711
+ omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Following),
1712
+ chains: makeChainIndexingStatusesSchema(valueLabel),
1713
+ omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
1714
+ });
1715
+ var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => z4.discriminatedUnion("omnichainStatus", [
1716
+ makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
1717
+ makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
1718
+ makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
1719
+ makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
1720
+ ]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
1721
+ invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
1722
+ ).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
1723
+ var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => z4.strictObject({
1724
+ strategy: z4.literal(CrossChainIndexingStrategyIds.Omnichain),
1725
+ slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
1726
+ snapshotTime: makeUnixTimestampSchema(valueLabel),
1727
+ omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
1728
+ }).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
1729
+ var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => z4.discriminatedUnion("strategy", [
1730
+ makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
1731
+ ]);
1732
+ var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => z4.strictObject({
1733
+ projectedAt: makeUnixTimestampSchema(valueLabel),
1734
+ worstCaseDistance: makeDurationSchema(valueLabel),
1735
+ snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
1736
+ }).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
1737
+
1738
+ // src/ensindexer/indexing-status/deserialize.ts
1739
+ function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1740
+ const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
1741
+ const parsed = schema.safeParse(maybeSnapshot);
1742
+ if (parsed.error) {
1743
+ throw new Error(
1744
+ `Cannot deserialize into ChainIndexingStatusSnapshot:
1745
+ ${prettifyError4(parsed.error)}
1746
+ `
1747
+ );
1025
1748
  }
1026
- return Math.max(...latestKnownBlockTimestamps);
1749
+ return parsed.data;
1027
1750
  }
1028
- function getOmnichainIndexingCursor(chains) {
1029
- if (chains.length === 0) {
1030
- throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
1031
- }
1032
- if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
1033
- const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1034
- return Math.min(...earliestStartBlockTimestamps) - 1;
1751
+ function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1752
+ const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
1753
+ const parsed = schema.safeParse(maybeSnapshot);
1754
+ if (parsed.error) {
1755
+ throw new Error(
1756
+ `Cannot deserialize into OmnichainIndexingStatusSnapshot:
1757
+ ${prettifyError4(parsed.error)}
1758
+ `
1759
+ );
1035
1760
  }
1036
- const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
1037
- if (latestIndexedBlockTimestamps.length < 1) {
1038
- throw new Error("latestIndexedBlockTimestamps array must include at least one element");
1761
+ return parsed.data;
1762
+ }
1763
+ function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
1764
+ const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
1765
+ const parsed = schema.safeParse(maybeSnapshot);
1766
+ if (parsed.error) {
1767
+ throw new Error(
1768
+ `Cannot deserialize into CrossChainIndexingStatusSnapshot:
1769
+ ${prettifyError4(parsed.error)}
1770
+ `
1771
+ );
1039
1772
  }
1040
- return Math.max(...latestIndexedBlockTimestamps);
1773
+ return parsed.data;
1041
1774
  }
1042
- function createIndexingConfig(startBlock, endBlock) {
1043
- if (endBlock) {
1044
- return {
1045
- configType: ChainIndexingConfigTypeIds.Definite,
1046
- startBlock,
1047
- endBlock
1048
- };
1775
+ function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
1776
+ const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
1777
+ const parsed = schema.safeParse(maybeProjection);
1778
+ if (parsed.error) {
1779
+ throw new Error(
1780
+ `Cannot deserialize into RealtimeIndexingStatusProjection:
1781
+ ${prettifyError4(parsed.error)}
1782
+ `
1783
+ );
1049
1784
  }
1785
+ return parsed.data;
1786
+ }
1787
+
1788
+ // src/ensindexer/indexing-status/projection.ts
1789
+ function createRealtimeIndexingStatusProjection(snapshot, now) {
1790
+ const projectedAt = Math.max(now, snapshot.snapshotTime);
1050
1791
  return {
1051
- configType: ChainIndexingConfigTypeIds.Indefinite,
1052
- startBlock
1792
+ projectedAt,
1793
+ worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
1794
+ snapshot
1053
1795
  };
1054
1796
  }
1055
- function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
1056
- return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
1797
+
1798
+ // src/ensindexer/indexing-status/serialize.ts
1799
+ function serializeCrossChainIndexingStatusSnapshotOmnichain({
1800
+ strategy,
1801
+ slowestChainIndexingCursor,
1802
+ snapshotTime,
1803
+ omnichainSnapshot
1804
+ }) {
1805
+ return {
1806
+ strategy,
1807
+ slowestChainIndexingCursor,
1808
+ snapshotTime,
1809
+ omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
1810
+ };
1057
1811
  }
1058
- function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
1059
- const atLeastOneChainInTargetStatus = chains.some(
1060
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1061
- );
1062
- const otherChainsHaveValidStatuses = chains.every(
1063
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
1064
- );
1065
- return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
1812
+ function serializeRealtimeIndexingStatusProjection(indexingProjection) {
1813
+ return {
1814
+ projectedAt: indexingProjection.projectedAt,
1815
+ worstCaseDistance: indexingProjection.worstCaseDistance,
1816
+ snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
1817
+ };
1066
1818
  }
1067
- function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
1068
- const allChainsHaveValidStatuses = chains.every(
1069
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
1070
- );
1071
- return allChainsHaveValidStatuses;
1819
+ function serializeChainIndexingSnapshots(chains) {
1820
+ const serializedSnapshots = {};
1821
+ for (const [chainId, snapshot] of chains.entries()) {
1822
+ serializedSnapshots[serializeChainId(chainId)] = snapshot;
1823
+ }
1824
+ return serializedSnapshots;
1072
1825
  }
1073
- function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
1074
- const allChainsHaveValidStatuses = chains.some(
1075
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Following
1076
- );
1077
- return allChainsHaveValidStatuses;
1826
+ function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
1827
+ switch (indexingStatus.omnichainStatus) {
1828
+ case OmnichainIndexingStatusIds.Unstarted:
1829
+ return {
1830
+ omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
1831
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1832
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1833
+ };
1834
+ case OmnichainIndexingStatusIds.Backfill:
1835
+ return {
1836
+ omnichainStatus: OmnichainIndexingStatusIds.Backfill,
1837
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1838
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1839
+ };
1840
+ case OmnichainIndexingStatusIds.Completed: {
1841
+ return {
1842
+ omnichainStatus: OmnichainIndexingStatusIds.Completed,
1843
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1844
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1845
+ };
1846
+ }
1847
+ case OmnichainIndexingStatusIds.Following:
1848
+ return {
1849
+ omnichainStatus: OmnichainIndexingStatusIds.Following,
1850
+ chains: serializeChainIndexingSnapshots(indexingStatus.chains),
1851
+ omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
1852
+ };
1853
+ }
1078
1854
  }
1079
- function sortChainStatusesByStartBlockAsc(chains) {
1080
- chains.sort(
1081
- ([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
1082
- );
1083
- return chains;
1855
+
1856
+ // src/ensapi/config/serialize.ts
1857
+ function serializeENSApiPublicConfig(config) {
1858
+ const { version, theGraphFallback, ensIndexerPublicConfig } = config;
1859
+ return {
1860
+ version,
1861
+ theGraphFallback,
1862
+ ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
1863
+ };
1084
1864
  }
1085
- function getLatestIndexedBlockRef(indexingStatus, chainId) {
1086
- const chainIndexingStatus = indexingStatus.omnichainSnapshot.chains.get(chainId);
1087
- if (chainIndexingStatus === void 0) {
1088
- return null;
1865
+
1866
+ // src/api/config/deserialize.ts
1867
+ function deserializeConfigResponse(serializedResponse) {
1868
+ return deserializeENSApiPublicConfig(serializedResponse);
1869
+ }
1870
+
1871
+ // src/api/config/serialize.ts
1872
+ function serializeConfigResponse(response) {
1873
+ return serializeENSApiPublicConfig(response);
1874
+ }
1875
+
1876
+ // src/api/indexing-status/deserialize.ts
1877
+ import { prettifyError as prettifyError5 } from "zod/v4";
1878
+
1879
+ // src/api/indexing-status/zod-schemas.ts
1880
+ import z5 from "zod/v4";
1881
+
1882
+ // src/api/indexing-status/response.ts
1883
+ var IndexingStatusResponseCodes = {
1884
+ /**
1885
+ * Represents that the indexing status is available.
1886
+ */
1887
+ Ok: "ok",
1888
+ /**
1889
+ * Represents that the indexing status is unavailable.
1890
+ */
1891
+ Error: "error"
1892
+ };
1893
+
1894
+ // src/api/indexing-status/zod-schemas.ts
1895
+ var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z5.strictObject({
1896
+ responseCode: z5.literal(IndexingStatusResponseCodes.Ok),
1897
+ realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
1898
+ });
1899
+ var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => z5.strictObject({
1900
+ responseCode: z5.literal(IndexingStatusResponseCodes.Error)
1901
+ });
1902
+ var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z5.discriminatedUnion("responseCode", [
1903
+ makeIndexingStatusResponseOkSchema(valueLabel),
1904
+ makeIndexingStatusResponseErrorSchema(valueLabel)
1905
+ ]);
1906
+
1907
+ // src/api/indexing-status/deserialize.ts
1908
+ function deserializeIndexingStatusResponse(maybeResponse) {
1909
+ const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
1910
+ if (parsed.error) {
1911
+ throw new Error(`Cannot deserialize IndexingStatusResponse:
1912
+ ${prettifyError5(parsed.error)}
1913
+ `);
1089
1914
  }
1090
- if (chainIndexingStatus.chainStatus === ChainIndexingStatusIds.Queued) {
1091
- return null;
1915
+ return parsed.data;
1916
+ }
1917
+
1918
+ // src/api/indexing-status/serialize.ts
1919
+ function serializeIndexingStatusResponse(response) {
1920
+ switch (response.responseCode) {
1921
+ case IndexingStatusResponseCodes.Ok:
1922
+ return {
1923
+ responseCode: response.responseCode,
1924
+ realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
1925
+ };
1926
+ case IndexingStatusResponseCodes.Error:
1927
+ return response;
1092
1928
  }
1093
- return chainIndexingStatus.latestIndexedBlock;
1094
1929
  }
1095
-
1096
- // src/ensindexer/indexing-status/validations.ts
1097
- function invariant_chainSnapshotQueuedBlocks(ctx) {
1098
- const { config } = ctx.value;
1099
- if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
1100
- return;
1101
- }
1102
- if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
1103
- ctx.issues.push({
1104
- code: "custom",
1105
- input: ctx.value,
1106
- message: "`config.startBlock` must be before or same as `config.endBlock`."
1107
- });
1108
- }
1930
+
1931
+ // src/api/name-tokens/deserialize.ts
1932
+ import { prettifyError as prettifyError7 } from "zod/v4";
1933
+
1934
+ // src/api/name-tokens/zod-schemas.ts
1935
+ import { namehash as namehash2 } from "viem";
1936
+ import z8 from "zod/v4";
1937
+
1938
+ // src/tokenscope/assets.ts
1939
+ import { AssetId as CaipAssetId2 } from "caip";
1940
+ import { isAddressEqual as isAddressEqual3, zeroAddress as zeroAddress3 } from "viem";
1941
+ import { prettifyError as prettifyError6 } from "zod/v4";
1942
+
1943
+ // src/tokenscope/zod-schemas.ts
1944
+ import { AssetId as CaipAssetId } from "caip";
1945
+ import { zeroAddress as zeroAddress2 } from "viem";
1946
+ import z6 from "zod/v4";
1947
+
1948
+ // src/tokenscope/name-token.ts
1949
+ import { isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
1950
+ import { DatasourceNames } from "@ensnode/datasources";
1951
+ var NameTokenOwnershipTypes = {
1952
+ /**
1953
+ * Name Token is owned by NameWrapper account.
1954
+ */
1955
+ NameWrapper: "namewrapper",
1956
+ /**
1957
+ * Name Token is owned fully onchain.
1958
+ *
1959
+ * This ownership type can only apply to direct subnames of `.eth`
1960
+ */
1961
+ FullyOnchain: "fully-onchain",
1962
+ /**
1963
+ * Name Token ownership has been transferred to the null address.
1964
+ */
1965
+ Burned: "burned",
1966
+ /**
1967
+ * Name Token ownership is unknown.
1968
+ */
1969
+ Unknown: "unknown"
1970
+ };
1971
+ function serializeNameToken(nameToken) {
1972
+ return {
1973
+ token: serializeAssetId(nameToken.token),
1974
+ ownership: nameToken.ownership,
1975
+ mintStatus: nameToken.mintStatus
1976
+ };
1977
+ }
1978
+ function getNameWrapperAccounts(namespaceId) {
1979
+ const ethnamesNameWrapperAccount = getDatasourceContract(
1980
+ namespaceId,
1981
+ DatasourceNames.ENSRoot,
1982
+ "NameWrapper"
1983
+ );
1984
+ const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
1985
+ namespaceId,
1986
+ DatasourceNames.Lineanames,
1987
+ "NameWrapper"
1988
+ );
1989
+ const nameWrapperAccounts = [
1990
+ // NameWrapper for direct subnames of .eth is defined for all ENS namespaces
1991
+ ethnamesNameWrapperAccount
1992
+ ];
1993
+ if (lineanamesNameWrapperAccount) {
1994
+ nameWrapperAccounts.push(lineanamesNameWrapperAccount);
1995
+ }
1996
+ return nameWrapperAccounts;
1109
1997
  }
1110
- function invariant_chainSnapshotBackfillBlocks(ctx) {
1111
- const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
1112
- if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1113
- ctx.issues.push({
1114
- code: "custom",
1115
- input: ctx.value,
1116
- message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1117
- });
1118
- }
1119
- if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
1120
- ctx.issues.push({
1121
- code: "custom",
1122
- input: ctx.value,
1123
- message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
1124
- });
1998
+ function getNameTokenOwnership(namespaceId, name, owner) {
1999
+ const nameWrapperAccounts = getNameWrapperAccounts(namespaceId);
2000
+ const hasNameWrapperOwnership = nameWrapperAccounts.some(
2001
+ (nameWrapperAccount) => accountIdEqual(owner, nameWrapperAccount)
2002
+ );
2003
+ if (hasNameWrapperOwnership) {
2004
+ return {
2005
+ ownershipType: NameTokenOwnershipTypes.NameWrapper,
2006
+ owner
2007
+ };
1125
2008
  }
1126
- if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
1127
- return;
2009
+ if (isAddressEqual2(owner.address, zeroAddress)) {
2010
+ return {
2011
+ ownershipType: NameTokenOwnershipTypes.Burned,
2012
+ owner
2013
+ };
1128
2014
  }
1129
- if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
1130
- ctx.issues.push({
1131
- code: "custom",
1132
- input: ctx.value,
1133
- message: "`backfillEndBlock` must be the same as `config.endBlock`."
1134
- });
2015
+ const parentName = getParentNameFQDN(name);
2016
+ if (parentName === "eth") {
2017
+ return {
2018
+ ownershipType: NameTokenOwnershipTypes.FullyOnchain,
2019
+ owner
2020
+ };
1135
2021
  }
2022
+ return {
2023
+ ownershipType: NameTokenOwnershipTypes.Unknown,
2024
+ owner
2025
+ };
1136
2026
  }
1137
- function invariant_chainSnapshotCompletedBlocks(ctx) {
1138
- const { config, latestIndexedBlock } = ctx.value;
1139
- if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1140
- ctx.issues.push({
1141
- code: "custom",
1142
- input: ctx.value,
1143
- message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1144
- });
2027
+
2028
+ // src/tokenscope/zod-schemas.ts
2029
+ var makeAssetIdSchema = (valueLabel = "Asset ID Schema") => z6.object({
2030
+ assetNamespace: z6.enum(AssetNamespaces),
2031
+ contract: makeAccountIdSchema(valueLabel),
2032
+ tokenId: z6.preprocess((v) => typeof v === "string" ? BigInt(v) : v, z6.bigint().positive())
2033
+ });
2034
+ var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => z6.preprocess((v) => {
2035
+ if (typeof v === "string") {
2036
+ const result = new CaipAssetId(v);
2037
+ return {
2038
+ assetNamespace: result.assetName.namespace,
2039
+ contract: {
2040
+ chainId: Number(result.chainId.reference),
2041
+ address: result.assetName.reference
2042
+ },
2043
+ tokenId: result.tokenId
2044
+ };
1145
2045
  }
1146
- if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
2046
+ return v;
2047
+ }, makeAssetIdSchema(valueLabel));
2048
+ function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
2049
+ const ownership = ctx.value;
2050
+ if (ctx.value.owner.address === zeroAddress2) {
1147
2051
  ctx.issues.push({
1148
2052
  code: "custom",
1149
2053
  input: ctx.value,
1150
- message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
2054
+ message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' other than the zero address.`
1151
2055
  });
1152
2056
  }
1153
2057
  }
1154
- function invariant_chainSnapshotFollowingBlocks(ctx) {
1155
- const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
1156
- if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
1157
- ctx.issues.push({
1158
- code: "custom",
1159
- input: ctx.value,
1160
- message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
1161
- });
1162
- }
1163
- if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
2058
+ var makeNameTokenOwnershipNameWrapperSchema = (valueLabel = "Name Token Ownership NameWrapper") => z6.object({
2059
+ ownershipType: z6.literal(NameTokenOwnershipTypes.NameWrapper),
2060
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2061
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2062
+ var makeNameTokenOwnershipFullyOnchainSchema = (valueLabel = "Name Token Ownership Fully Onchain") => z6.object({
2063
+ ownershipType: z6.literal(NameTokenOwnershipTypes.FullyOnchain),
2064
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2065
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2066
+ var makeNameTokenOwnershipBurnedSchema = (valueLabel = "Name Token Ownership Burned") => z6.object({
2067
+ ownershipType: z6.literal(NameTokenOwnershipTypes.Burned),
2068
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2069
+ }).check(invariant_nameTokenOwnershipHasZeroAddressOwner);
2070
+ var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Unknown") => z6.object({
2071
+ ownershipType: z6.literal(NameTokenOwnershipTypes.Unknown),
2072
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2073
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2074
+ function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
2075
+ const ownership = ctx.value;
2076
+ if (ctx.value.owner.address !== zeroAddress2) {
1164
2077
  ctx.issues.push({
1165
2078
  code: "custom",
1166
2079
  input: ctx.value,
1167
- message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
1168
- });
1169
- }
1170
- }
1171
- function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
1172
- const snapshot = ctx.value;
1173
- const chains = Array.from(snapshot.chains.values());
1174
- const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
1175
- const actualOmnichainStatus = snapshot.omnichainStatus;
1176
- if (expectedOmnichainStatus !== actualOmnichainStatus) {
1177
- ctx.issues.push({
1178
- code: "custom",
1179
- input: snapshot,
1180
- message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
2080
+ message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' set to the zero address.`
1181
2081
  });
1182
2082
  }
1183
2083
  }
1184
- function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
1185
- const snapshot = ctx.value;
1186
- const queuedChains = Array.from(snapshot.chains.values()).filter(
1187
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
1188
- );
1189
- if (queuedChains.length === 0) {
1190
- return;
1191
- }
1192
- const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
1193
- const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
1194
- if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
1195
- ctx.issues.push({
1196
- code: "custom",
1197
- input: snapshot,
1198
- message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
1199
- });
1200
- }
2084
+ var makeNameTokenOwnershipSchema = (valueLabel = "Name Token Ownership") => z6.discriminatedUnion("ownershipType", [
2085
+ makeNameTokenOwnershipNameWrapperSchema(valueLabel),
2086
+ makeNameTokenOwnershipFullyOnchainSchema(valueLabel),
2087
+ makeNameTokenOwnershipBurnedSchema(valueLabel),
2088
+ makeNameTokenOwnershipUnknownSchema(valueLabel)
2089
+ ]);
2090
+ var makeNameTokenSchema = (valueLabel = "Name Token Schema") => z6.object({
2091
+ token: makeAssetIdSchema(`${valueLabel}.token`),
2092
+ ownership: makeNameTokenOwnershipSchema(`${valueLabel}.ownership`),
2093
+ mintStatus: z6.enum(NFTMintStatuses)
2094
+ });
2095
+
2096
+ // src/tokenscope/assets.ts
2097
+ var AssetNamespaces = {
2098
+ ERC721: "erc721",
2099
+ ERC1155: "erc1155"
2100
+ };
2101
+ function serializeAssetId(assetId) {
2102
+ return {
2103
+ assetNamespace: assetId.assetNamespace,
2104
+ contract: assetId.contract,
2105
+ tokenId: uint256ToHex32(assetId.tokenId)
2106
+ };
1201
2107
  }
1202
- function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
1203
- const snapshot = ctx.value;
1204
- const backfillChains = Array.from(snapshot.chains.values()).filter(
1205
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
1206
- );
1207
- if (backfillChains.length === 0) {
1208
- return;
1209
- }
1210
- const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
1211
- const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
1212
- if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
1213
- ctx.issues.push({
1214
- code: "custom",
1215
- input: snapshot,
1216
- message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
1217
- });
2108
+ function deserializeAssetId(maybeAssetId, valueLabel) {
2109
+ const schema = makeAssetIdSchema(valueLabel);
2110
+ const parsed = schema.safeParse(maybeAssetId);
2111
+ if (parsed.error) {
2112
+ throw new RangeError(`Cannot deserialize AssetId:
2113
+ ${prettifyError6(parsed.error)}
2114
+ `);
1218
2115
  }
2116
+ return parsed.data;
1219
2117
  }
1220
- function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
1221
- const snapshot = ctx.value;
1222
- const indexedChains = Array.from(snapshot.chains.values()).filter(
1223
- (chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
1224
- );
1225
- if (indexedChains.length === 0) {
1226
- return;
1227
- }
1228
- const indexedChainLatestIndexedBlocks = indexedChains.map(
1229
- (chain) => chain.latestIndexedBlock.timestamp
1230
- );
1231
- const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
1232
- if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
1233
- ctx.issues.push({
1234
- code: "custom",
1235
- input: snapshot,
1236
- message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
1237
- });
1238
- }
2118
+ function formatAssetId(assetId) {
2119
+ const { assetNamespace, contract, tokenId } = serializeAssetId(assetId);
2120
+ return CaipAssetId2.format({
2121
+ chainId: { namespace: "eip155", reference: contract.chainId.toString() },
2122
+ assetName: { namespace: assetNamespace, reference: contract.address },
2123
+ tokenId
2124
+ }).toLowerCase();
1239
2125
  }
1240
- function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
1241
- const chains = ctx.value;
1242
- const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
1243
- Array.from(chains.values())
1244
- );
1245
- if (hasValidChains === false) {
1246
- ctx.issues.push({
1247
- code: "custom",
1248
- input: chains,
1249
- message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
1250
- });
2126
+ function parseAssetId(maybeAssetId, valueLabel) {
2127
+ const schema = makeAssetIdStringSchema(valueLabel);
2128
+ const parsed = schema.safeParse(maybeAssetId);
2129
+ if (parsed.error) {
2130
+ throw new RangeError(`Cannot parse AssetId:
2131
+ ${prettifyError6(parsed.error)}
2132
+ `);
1251
2133
  }
2134
+ return parsed.data;
1252
2135
  }
1253
- function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
1254
- const chains = ctx.value;
1255
- const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
1256
- Array.from(chains.values())
1257
- );
1258
- if (hasValidChains === false) {
1259
- ctx.issues.push({
1260
- code: "custom",
1261
- input: chains,
1262
- 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".`
1263
- });
1264
- }
2136
+ var buildAssetId = (contract, tokenId, assetNamespace) => {
2137
+ return {
2138
+ assetNamespace,
2139
+ contract,
2140
+ tokenId
2141
+ };
2142
+ };
2143
+ function serializeDomainAssetId(domainAsset) {
2144
+ return {
2145
+ ...serializeAssetId(domainAsset),
2146
+ domainId: domainAsset.domainId
2147
+ };
1265
2148
  }
1266
- function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
1267
- const chains = ctx.value;
1268
- const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
1269
- Array.from(chains.values())
1270
- );
1271
- if (hasValidChains === false) {
1272
- ctx.issues.push({
1273
- code: "custom",
1274
- input: chains,
1275
- message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
1276
- });
2149
+ var NFTMintStatuses = {
2150
+ Minted: "minted",
2151
+ Burned: "burned"
2152
+ };
2153
+ var formatNFTTransferEventMetadata = (metadata) => {
2154
+ const serializedAssetId = serializeAssetId(metadata.nft);
2155
+ return [
2156
+ `Event: ${metadata.eventHandlerName}`,
2157
+ `Chain ID: ${metadata.chainId}`,
2158
+ `Block Number: ${metadata.blockNumber}`,
2159
+ `Transaction Hash: ${metadata.transactionHash}`,
2160
+ `NFT: ${serializedAssetId}`
2161
+ ].map((line) => ` - ${line}`).join("\n");
2162
+ };
2163
+ var NFTTransferTypes = {
2164
+ /**
2165
+ * Initial transfer from zeroAddress to a non-zeroAddress
2166
+ * Can happen at most once to a NFT AssetId
2167
+ *
2168
+ * Invariants:
2169
+ * - NFT is not indexed and therefore has no previous mint status or owner
2170
+ * - new NFT mint status is `minted`
2171
+ * - new NFT owner is a non-zeroAddress
2172
+ */
2173
+ Mint: "mint",
2174
+ /**
2175
+ * Subsequent transfer from zeroAddress to a non-zeroAddress
2176
+ * Can happen any number of times to a NFT AssetId as it passes in a cycle from
2177
+ * mint -> burn -> remint -> burn -> remint -> ...
2178
+ *
2179
+ * Invariants:
2180
+ * - NFT is indexed
2181
+ * - previous NFT mint status was `burned`
2182
+ * - previous NFT owner is the zeroAddress
2183
+ * - new NFT mint status is `minted`
2184
+ * - new NFT owner is a non-zeroAddress
2185
+ */
2186
+ Remint: "remint",
2187
+ /**
2188
+ * Special transfer type for improperly implemented NFT contracts that allow a NFT
2189
+ * that is currently minted to be reminted before an intermediate burn.
2190
+ *
2191
+ * Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
2192
+ * previously indexed nft had status `minted` with a non-zeroAddress owner.
2193
+ *
2194
+ * Invariants:
2195
+ * - NFT is indexed
2196
+ * - previous NFT mint status was `minted`
2197
+ * - previous NFT owner was a non-zeroAddress
2198
+ * - new NFT mint status is `minted`
2199
+ * - new NFT owner is a non-zeroAddress
2200
+ */
2201
+ MintedRemint: "minted-remint",
2202
+ /**
2203
+ * Transfer from a non-zeroAddress to zeroAddress
2204
+ *
2205
+ * Invariants:
2206
+ * - NFT is indexed
2207
+ * - previous NFT mint status was `minted`
2208
+ * - previous NFT owner is a non-zeroAddress
2209
+ * - new NFT mint status is `burned`
2210
+ * - new NFT owner is the zeroAddress
2211
+ */
2212
+ Burn: "burn",
2213
+ /**
2214
+ * Transfer from a non-zeroAddress to a distinct non-zeroAddress
2215
+ *
2216
+ * Invariants:
2217
+ * - NFT is indexed
2218
+ * - previous and new NFT mint status is `minted`
2219
+ * - previous and new NFT owner are distinct non-zeroAddress
2220
+ */
2221
+ Transfer: "transfer",
2222
+ /**
2223
+ * Transfer from a non-zeroAddress to the same non-zeroAddress
2224
+ *
2225
+ * Invariants:
2226
+ * - NFT is indexed
2227
+ * - previous and new NFT mint status is `minted`
2228
+ * - previous and new NFT owner are equivalent non-zeroAddress
2229
+ */
2230
+ SelfTransfer: "self-transfer",
2231
+ /**
2232
+ * Transfer from zeroAddress to zeroAddress for an indexed NFT
2233
+ *
2234
+ * Invariants:
2235
+ * - NFT is indexed
2236
+ * - previous and new NFT mint status is `burned`
2237
+ * - previous and new NFT owner are zeroAddress
2238
+ */
2239
+ RemintBurn: "remint-burn",
2240
+ /**
2241
+ * Special transfer type for improperly implemented NFT contracts that allow a NFT
2242
+ * that is currently minted to be reminted again before an intermediate burn.
2243
+ *
2244
+ * Transfer from zeroAddress to zeroAddress for an indexed NFT where the
2245
+ * previously indexed nft had status `minted` with a non-zeroAddress owner.
2246
+ *
2247
+ * Invariants:
2248
+ * - NFT is indexed
2249
+ * - previous NFT mint status was `minted`
2250
+ * - previous NFT owner was a non-zeroAddress
2251
+ * - new NFT mint status is `burned`
2252
+ * - new NFT owner is the zeroAddress
2253
+ */
2254
+ MintedRemintBurn: "minted-remint-burn",
2255
+ /**
2256
+ * Transfer from zeroAddress to zeroAddress for an unindexed NFT
2257
+ *
2258
+ * Invariants:
2259
+ * - NFT is not indexed and therefore has no previous mint status or owner
2260
+ * - NFT should remain unindexed and without any mint status or owner
2261
+ */
2262
+ MintBurn: "mint-burn"
2263
+ };
2264
+ var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
2265
+ const isIndexed = currentlyIndexedOwner !== void 0;
2266
+ const isIndexedAsMinted = isIndexed && !isAddressEqual3(currentlyIndexedOwner, zeroAddress3);
2267
+ const isMint = isAddressEqual3(from, zeroAddress3);
2268
+ const isBurn = isAddressEqual3(to, zeroAddress3);
2269
+ const isSelfTransfer = isAddressEqual3(from, to);
2270
+ if (isIndexed && !isAddressEqual3(currentlyIndexedOwner, from)) {
2271
+ if (isMint && allowMintedRemint) {
2272
+ } else {
2273
+ throw new Error(
2274
+ `Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
2275
+ ${formatNFTTransferEventMetadata(metadata)}`
2276
+ );
2277
+ }
1277
2278
  }
1278
- }
1279
- function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
1280
- const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
1281
- const { omnichainIndexingCursor } = omnichainSnapshot;
1282
- if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
1283
- console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
1284
- slowestChainIndexingCursor,
1285
- omnichainIndexingCursor
1286
- });
2279
+ if (isSelfTransfer) {
2280
+ if (isMint) {
2281
+ if (!isIndexed) {
2282
+ return NFTTransferTypes.MintBurn;
2283
+ } else if (!isIndexedAsMinted) {
2284
+ return NFTTransferTypes.RemintBurn;
2285
+ } else if (allowMintedRemint) {
2286
+ return NFTTransferTypes.MintedRemintBurn;
2287
+ } else {
2288
+ throw new Error(
2289
+ `Error: Invalid state transition from minted -> remint-burn
2290
+ ${formatNFTTransferEventMetadata(metadata)}`
2291
+ );
2292
+ }
2293
+ } else {
2294
+ if (!isIndexed) {
2295
+ throw new Error(
2296
+ `Error: Invalid state transition from unindexed -> self-transfer
2297
+ ${formatNFTTransferEventMetadata(metadata)}`
2298
+ );
2299
+ } else if (!isIndexedAsMinted) {
2300
+ throw new Error(
2301
+ `Error: invalid state transition from burned -> self-transfer
2302
+ ${formatNFTTransferEventMetadata(metadata)}`
2303
+ );
2304
+ } else {
2305
+ return NFTTransferTypes.SelfTransfer;
2306
+ }
2307
+ }
2308
+ } else if (isMint) {
2309
+ if (!isIndexed) {
2310
+ return NFTTransferTypes.Mint;
2311
+ } else if (!isIndexedAsMinted) {
2312
+ return NFTTransferTypes.Remint;
2313
+ } else if (allowMintedRemint) {
2314
+ return NFTTransferTypes.MintedRemint;
2315
+ } else {
2316
+ throw new Error(
2317
+ `Error: Invalid state transition from minted -> mint
2318
+ ${formatNFTTransferEventMetadata(metadata)}`
2319
+ );
2320
+ }
2321
+ } else if (isBurn) {
2322
+ if (!isIndexed) {
2323
+ throw new Error(
2324
+ `Error: Invalid state transition from unindexed -> burn
2325
+ ${formatNFTTransferEventMetadata(metadata)}`
2326
+ );
2327
+ } else if (!isIndexedAsMinted) {
2328
+ throw new Error(
2329
+ `Error: Invalid state transition from burned -> burn
2330
+ ${formatNFTTransferEventMetadata(metadata)}`
2331
+ );
2332
+ } else {
2333
+ return NFTTransferTypes.Burn;
2334
+ }
2335
+ } else {
2336
+ if (!isIndexed) {
2337
+ throw new Error(
2338
+ `Error: Invalid state transition from unindexed -> transfer
2339
+ ${formatNFTTransferEventMetadata(metadata)}`
2340
+ );
2341
+ } else if (!isIndexedAsMinted) {
2342
+ throw new Error(
2343
+ `Error: Invalid state transition from burned -> transfer
2344
+ ${formatNFTTransferEventMetadata(metadata)}`
2345
+ );
2346
+ } else {
2347
+ return NFTTransferTypes.Transfer;
2348
+ }
2349
+ }
2350
+ };
2351
+
2352
+ // src/api/shared/errors/zod-schemas.ts
2353
+ import z7 from "zod/v4";
2354
+ var ErrorResponseSchema = z7.object({
2355
+ message: z7.string(),
2356
+ details: z7.optional(z7.unknown())
2357
+ });
2358
+
2359
+ // src/api/name-tokens/response.ts
2360
+ var NameTokensResponseCodes = {
2361
+ /**
2362
+ * Represents a response when Name Tokens API can respond with requested data.
2363
+ */
2364
+ Ok: "ok",
2365
+ /**
2366
+ * Represents a response when Name Tokens API could not respond with requested data.
2367
+ */
2368
+ Error: "error"
2369
+ };
2370
+ var NameTokensResponseErrorCodes = {
2371
+ /**
2372
+ * Name tokens not indexed
2373
+ *
2374
+ * Represents an error when tokens for the requested name are not indexed by
2375
+ * the ENSNode instance's configuration.
2376
+ */
2377
+ NameTokensNotIndexed: "name-tokens-not-indexed",
2378
+ /**
2379
+ * Unsupported ENSIndexer Config
2380
+ *
2381
+ * Represents a prerequisites error when connected ENSIndexer config lacks
2382
+ * params required to enable Name Tokens API.
2383
+ */
2384
+ EnsIndexerConfigUnsupported: "unsupported-ensindexer-config",
2385
+ /**
2386
+ * Unsupported Indexing Status
2387
+ *
2388
+ * Represents a prerequisites error when Indexing Status has not yet reached
2389
+ * status required to enable Name Tokens API.
2390
+ */
2391
+ IndexingStatusUnsupported: "unsupported-indexing-status"
2392
+ };
2393
+
2394
+ // src/api/name-tokens/zod-schemas.ts
2395
+ function invariant_nameIsAssociatedWithDomainId(ctx) {
2396
+ const { name, domainId } = ctx.value;
2397
+ if (namehash2(name) !== domainId) {
1287
2398
  ctx.issues.push({
1288
2399
  code: "custom",
1289
2400
  input: ctx.value,
1290
- message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
2401
+ message: `'name' must be associated with 'domainId': ${domainId}`
1291
2402
  });
1292
2403
  }
1293
2404
  }
1294
- function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
1295
- const { snapshotTime, omnichainSnapshot } = ctx.value;
1296
- const chains = Array.from(omnichainSnapshot.chains.values());
1297
- const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
1298
- const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
1299
- const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
1300
- const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
1301
- const highestKnownBlockTimestamp = Math.max(
1302
- ...startBlockTimestamps,
1303
- ...endBlockTimestamps,
1304
- ...backfillEndBlockTimestamps,
1305
- ...latestKnownBlockTimestamps
2405
+ function invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown(ctx) {
2406
+ const { tokens } = ctx.value;
2407
+ const containsOwnershipNameWrapper = tokens.some(
2408
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.NameWrapper
1306
2409
  );
1307
- if (snapshotTime < highestKnownBlockTimestamp) {
2410
+ const containsOwnershipFullyOnchainOrUnknown = tokens.some(
2411
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain || t.ownership.ownershipType === NameTokenOwnershipTypes.Unknown
2412
+ );
2413
+ if (containsOwnershipNameWrapper && !containsOwnershipFullyOnchainOrUnknown) {
1308
2414
  ctx.issues.push({
1309
2415
  code: "custom",
1310
2416
  input: ctx.value,
1311
- message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
1312
- });
1313
- }
1314
- }
1315
- function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
1316
- const projection = ctx.value;
1317
- const { snapshot, projectedAt } = projection;
1318
- if (snapshot.snapshotTime > projectedAt) {
1319
- ctx.issues.push({
1320
- code: "custom",
1321
- input: projection,
1322
- message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
2417
+ message: `'tokens' must contain name token with ownership type 'fully-onchain' or 'unknown' when name token with ownership type 'namewrapper' in listed`
1323
2418
  });
1324
2419
  }
1325
2420
  }
1326
- function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
1327
- const projection = ctx.value;
1328
- const { projectedAt, snapshot, worstCaseDistance } = projection;
1329
- const { omnichainSnapshot } = snapshot;
1330
- const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
1331
- if (worstCaseDistance !== expectedWorstCaseDistance) {
2421
+ function invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective(ctx) {
2422
+ const { tokens } = ctx.value;
2423
+ const tokensCountWithOwnershipFullyOnchain = tokens.filter(
2424
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain
2425
+ ).length;
2426
+ if (tokensCountWithOwnershipFullyOnchain > 1) {
1332
2427
  ctx.issues.push({
1333
2428
  code: "custom",
1334
- input: projection,
1335
- message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
2429
+ input: ctx.value,
2430
+ message: `'tokens' must contain at most one name token with ownership type 'fully-onchain', current count: ${tokensCountWithOwnershipFullyOnchain}`
1336
2431
  });
1337
2432
  }
1338
2433
  }
1339
-
1340
- // src/ensindexer/indexing-status/zod-schemas.ts
1341
- var makeChainIndexingConfigSchema = (valueLabel = "Value") => z2.discriminatedUnion("configType", [
1342
- z2.strictObject({
1343
- configType: z2.literal(ChainIndexingConfigTypeIds.Indefinite),
1344
- startBlock: makeBlockRefSchema(valueLabel)
1345
- }),
1346
- z2.strictObject({
1347
- configType: z2.literal(ChainIndexingConfigTypeIds.Definite),
1348
- startBlock: makeBlockRefSchema(valueLabel),
1349
- endBlock: makeBlockRefSchema(valueLabel)
1350
- })
1351
- ]);
1352
- var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => z2.strictObject({
1353
- chainStatus: z2.literal(ChainIndexingStatusIds.Queued),
1354
- config: makeChainIndexingConfigSchema(valueLabel)
1355
- }).check(invariant_chainSnapshotQueuedBlocks);
1356
- var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => z2.strictObject({
1357
- chainStatus: z2.literal(ChainIndexingStatusIds.Backfill),
1358
- config: makeChainIndexingConfigSchema(valueLabel),
1359
- latestIndexedBlock: makeBlockRefSchema(valueLabel),
1360
- backfillEndBlock: makeBlockRefSchema(valueLabel)
1361
- }).check(invariant_chainSnapshotBackfillBlocks);
1362
- var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => z2.strictObject({
1363
- chainStatus: z2.literal(ChainIndexingStatusIds.Completed),
1364
- config: z2.strictObject({
1365
- configType: z2.literal(ChainIndexingConfigTypeIds.Definite),
1366
- startBlock: makeBlockRefSchema(valueLabel),
1367
- endBlock: makeBlockRefSchema(valueLabel)
1368
- }),
1369
- latestIndexedBlock: makeBlockRefSchema(valueLabel)
1370
- }).check(invariant_chainSnapshotCompletedBlocks);
1371
- var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => z2.strictObject({
1372
- chainStatus: z2.literal(ChainIndexingStatusIds.Following),
1373
- config: z2.strictObject({
1374
- configType: z2.literal(ChainIndexingConfigTypeIds.Indefinite),
1375
- startBlock: makeBlockRefSchema(valueLabel)
1376
- }),
1377
- latestIndexedBlock: makeBlockRefSchema(valueLabel),
1378
- latestKnownBlock: makeBlockRefSchema(valueLabel)
1379
- }).check(invariant_chainSnapshotFollowingBlocks);
1380
- var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => z2.discriminatedUnion("chainStatus", [
1381
- makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
1382
- makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
1383
- makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
1384
- makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
1385
- ]);
1386
- var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z2.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
1387
- error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
1388
- }).transform((serializedChainsIndexingStatus) => {
1389
- const chainsIndexingStatus = /* @__PURE__ */ new Map();
1390
- for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
1391
- chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
1392
- }
1393
- return chainsIndexingStatus;
1394
- });
1395
- var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => z2.strictObject({
1396
- omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Unstarted),
1397
- chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
1398
- omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
2434
+ var makeRegisteredNameTokenSchema = (valueLabel = "Registered Name Token") => z8.object({
2435
+ domainId: makeNodeSchema(`${valueLabel}.domainId`),
2436
+ name: makeReinterpretedNameSchema(valueLabel),
2437
+ tokens: z8.array(makeNameTokenSchema(`${valueLabel}.tokens`)).nonempty(),
2438
+ expiresAt: makeUnixTimestampSchema(`${valueLabel}.expiresAt`),
2439
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2440
+ }).check(invariant_nameIsAssociatedWithDomainId).check(invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective).check(invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown);
2441
+ var makeNameTokensResponseOkSchema = (valueLabel = "Name Tokens Response OK") => z8.strictObject({
2442
+ responseCode: z8.literal(NameTokensResponseCodes.Ok),
2443
+ registeredNameTokens: makeRegisteredNameTokenSchema(`${valueLabel}.nameTokens`)
1399
2444
  });
1400
- var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => z2.strictObject({
1401
- omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Backfill),
1402
- chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
1403
- (chains) => chains
1404
- ),
1405
- omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
2445
+ var makeNameTokensResponseErrorNameTokensNotIndexedSchema = (_valueLabel = "Name Tokens Response Error Name Not Indexed") => z8.strictObject({
2446
+ responseCode: z8.literal(NameTokensResponseCodes.Error),
2447
+ errorCode: z8.literal(NameTokensResponseErrorCodes.NameTokensNotIndexed),
2448
+ error: ErrorResponseSchema
1406
2449
  });
1407
- var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => z2.strictObject({
1408
- omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Completed),
1409
- chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
1410
- omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
2450
+ var makeNameTokensResponseErrorEnsIndexerConfigUnsupported = (_valueLabel = "Name Tokens Response Error ENSIndexer Config Unsupported") => z8.strictObject({
2451
+ responseCode: z8.literal(NameTokensResponseCodes.Error),
2452
+ errorCode: z8.literal(NameTokensResponseErrorCodes.EnsIndexerConfigUnsupported),
2453
+ error: ErrorResponseSchema
1411
2454
  });
1412
- var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => z2.strictObject({
1413
- omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Following),
1414
- chains: makeChainIndexingStatusesSchema(valueLabel),
1415
- omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
2455
+ var makeNameTokensResponseErrorNameIndexingStatusUnsupported = (_valueLabel = "Name Tokens Response Error Indexing Status Unsupported") => z8.strictObject({
2456
+ responseCode: z8.literal(NameTokensResponseCodes.Error),
2457
+ errorCode: z8.literal(NameTokensResponseErrorCodes.IndexingStatusUnsupported),
2458
+ error: ErrorResponseSchema
1416
2459
  });
1417
- var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => z2.discriminatedUnion("omnichainStatus", [
1418
- makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
1419
- makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
1420
- makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
1421
- makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
1422
- ]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
1423
- invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
1424
- ).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
1425
- var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => z2.strictObject({
1426
- strategy: z2.literal(CrossChainIndexingStrategyIds.Omnichain),
1427
- slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
1428
- snapshotTime: makeUnixTimestampSchema(valueLabel),
1429
- omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
1430
- }).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
1431
- var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => z2.discriminatedUnion("strategy", [
1432
- makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
2460
+ var makeNameTokensResponseErrorSchema = (valueLabel = "Name Tokens Response Error") => z8.discriminatedUnion("errorCode", [
2461
+ makeNameTokensResponseErrorNameTokensNotIndexedSchema(valueLabel),
2462
+ makeNameTokensResponseErrorEnsIndexerConfigUnsupported(valueLabel),
2463
+ makeNameTokensResponseErrorNameIndexingStatusUnsupported(valueLabel)
2464
+ ]);
2465
+ var makeNameTokensResponseSchema = (valueLabel = "Name Tokens Response") => z8.discriminatedUnion("responseCode", [
2466
+ makeNameTokensResponseOkSchema(valueLabel),
2467
+ makeNameTokensResponseErrorSchema(valueLabel)
1433
2468
  ]);
1434
- var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => z2.strictObject({
1435
- projectedAt: makeUnixTimestampSchema(valueLabel),
1436
- worstCaseDistance: makeDurationSchema(valueLabel),
1437
- snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
1438
- }).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
1439
-
1440
- // src/ensindexer/config/zod-schemas.ts
1441
- import z3 from "zod/v4";
1442
-
1443
- // src/ensindexer/config/is-subgraph-compatible.ts
1444
- import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
1445
-
1446
- // src/ensindexer/config/types.ts
1447
- var PluginName = /* @__PURE__ */ ((PluginName2) => {
1448
- PluginName2["Subgraph"] = "subgraph";
1449
- PluginName2["Basenames"] = "basenames";
1450
- PluginName2["Lineanames"] = "lineanames";
1451
- PluginName2["ThreeDNS"] = "threedns";
1452
- PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
1453
- PluginName2["Registrars"] = "registrars";
1454
- PluginName2["TokenScope"] = "tokenscope";
1455
- return PluginName2;
1456
- })(PluginName || {});
1457
-
1458
- // src/ensindexer/config/is-subgraph-compatible.ts
1459
- function isSubgraphCompatible(config) {
1460
- const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
1461
- const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
1462
- const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
1463
- const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
1464
- return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
1465
- }
1466
2469
 
1467
- // src/ensindexer/config/validations.ts
1468
- function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
1469
- const versionInfo = ctx.value;
1470
- if (versionInfo.ensDb !== versionInfo.ensIndexer) {
1471
- ctx.issues.push({
1472
- code: "custom",
1473
- input: versionInfo,
1474
- message: "`ensDb` version must be same as `ensIndexer` version"
1475
- });
2470
+ // src/api/name-tokens/deserialize.ts
2471
+ function deserializedNameTokensResponse(maybeResponse) {
2472
+ const parsed = makeNameTokensResponseSchema().safeParse(maybeResponse);
2473
+ if (parsed.error) {
2474
+ throw new Error(`Cannot deserialize NameTokensResponse:
2475
+ ${prettifyError7(parsed.error)}
2476
+ `);
1476
2477
  }
2478
+ return parsed.data;
1477
2479
  }
1478
2480
 
1479
- // src/ensindexer/config/zod-schemas.ts
1480
- var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z3.array(makeChainIdSchema(valueLabel), {
1481
- error: `${valueLabel} must be an array.`
1482
- }).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
1483
- var makePluginsListSchema = (valueLabel = "Plugins") => z3.array(z3.string(), {
1484
- error: `${valueLabel} must be a list of strings.`
1485
- }).min(1, {
1486
- error: `${valueLabel} must be a list of strings with at least one string value`
1487
- }).refine((arr) => arr.length === uniq(arr).length, {
1488
- error: `${valueLabel} cannot contain duplicate values.`
1489
- });
1490
- var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z3.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
1491
- error: `${valueLabel} is required and must be a non-empty string.`
1492
- });
1493
- var makeLabelSetIdSchema = (valueLabel) => {
1494
- return z3.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
1495
- error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
1496
- });
1497
- };
1498
- var makeLabelSetVersionSchema = (valueLabel) => {
1499
- return z3.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
1500
- };
1501
- var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
1502
- let valueLabelLabelSetId = valueLabel;
1503
- let valueLabelLabelSetVersion = valueLabel;
1504
- if (valueLabel === "LABEL_SET") {
1505
- valueLabelLabelSetId = "LABEL_SET_ID";
1506
- valueLabelLabelSetVersion = "LABEL_SET_VERSION";
1507
- } else {
1508
- valueLabelLabelSetId = `${valueLabel}.labelSetId`;
1509
- valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
1510
- }
1511
- return z3.object({
1512
- labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
1513
- labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
1514
- });
1515
- };
1516
- var makeNonEmptyStringSchema = (valueLabel = "Value") => z3.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
1517
- var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z3.strictObject(
1518
- {
1519
- nodejs: makeNonEmptyStringSchema(),
1520
- ponder: makeNonEmptyStringSchema(),
1521
- ensDb: makeNonEmptyStringSchema(),
1522
- ensIndexer: makeNonEmptyStringSchema(),
1523
- ensNormalize: makeNonEmptyStringSchema(),
1524
- ensRainbow: makeNonEmptyStringSchema(),
1525
- ensRainbowSchema: makePositiveIntegerSchema()
2481
+ // src/api/name-tokens/prerequisites.ts
2482
+ var nameTokensPrerequisites = Object.freeze({
2483
+ /**
2484
+ * Required plugins to enable Name Tokens API routes.
2485
+ *
2486
+ * 1. `registrars` plugin is required so that data in the `registrationLifecycles`
2487
+ * table is populated.
2488
+ * 2. `tokenscope` plugin is required so that data in the `nameTokens`
2489
+ * table is populated.
2490
+ */
2491
+ requiredPlugins: ["registrars" /* Registrars */, "tokenscope" /* TokenScope */],
2492
+ /**
2493
+ * Check if provided ENSApiPublicConfig supports the Name Tokens API.
2494
+ */
2495
+ hasEnsIndexerConfigSupport(config) {
2496
+ return nameTokensPrerequisites.requiredPlugins.every(
2497
+ (plugin) => config.plugins.includes(plugin)
2498
+ );
1526
2499
  },
1527
- {
1528
- error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
1529
- }
1530
- ).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
1531
- function invariant_isSubgraphCompatibleRequirements(ctx) {
1532
- const { value: config } = ctx;
1533
- if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
1534
- ctx.issues.push({
1535
- code: "custom",
1536
- input: config,
1537
- message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
1538
- });
1539
- }
1540
- }
1541
- var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z3.object({
1542
- labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
1543
- indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
1544
- isSubgraphCompatible: z3.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
1545
- namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
1546
- plugins: makePluginsListSchema(`${valueLabel}.plugins`),
1547
- databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
1548
- versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
1549
- }).check(invariant_isSubgraphCompatibleRequirements);
1550
-
1551
- // src/shared/config/build-rpc-urls.ts
1552
- import {
1553
- arbitrum,
1554
- arbitrumSepolia,
1555
- base,
1556
- baseSepolia,
1557
- holesky,
1558
- linea,
1559
- lineaSepolia,
1560
- mainnet,
1561
- optimism,
1562
- optimismSepolia,
1563
- scroll,
1564
- scrollSepolia,
1565
- sepolia
1566
- } from "viem/chains";
1567
-
1568
- // src/shared/config/rpc-configs-from-env.ts
1569
- import { getENSNamespace } from "@ensnode/datasources";
1570
-
1571
- // src/shared/config/validatons.ts
1572
- import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
1573
- function invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL(ctx) {
1574
- const endpoints = ctx.value;
1575
- const httpEndpoints = endpoints.filter(isHttpProtocol);
1576
- if (httpEndpoints.length < 1) {
1577
- ctx.issues.push({
1578
- code: "custom",
1579
- input: endpoints,
1580
- message: `RPC endpoint configuration for a chain must include at least one http/https protocol URL.`
1581
- });
2500
+ /**
2501
+ * Required Indexing Status IDs
2502
+ *
2503
+ * Database indexes are created by the time the omnichain indexing status
2504
+ * is either `completed` or `following`.
2505
+ */
2506
+ supportedIndexingStatusIds: [
2507
+ OmnichainIndexingStatusIds.Completed,
2508
+ OmnichainIndexingStatusIds.Following
2509
+ ],
2510
+ /**
2511
+ * Check if provided indexing status supports the Name Tokens API.
2512
+ */
2513
+ hasIndexingStatusSupport(omnichainIndexingStatusId) {
2514
+ return nameTokensPrerequisites.supportedIndexingStatusIds.some(
2515
+ (supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
2516
+ );
1582
2517
  }
2518
+ });
2519
+
2520
+ // src/api/name-tokens/serialize.ts
2521
+ function serializeRegisteredNameTokens({
2522
+ domainId,
2523
+ name,
2524
+ tokens,
2525
+ expiresAt,
2526
+ accurateAsOf
2527
+ }) {
2528
+ return {
2529
+ domainId,
2530
+ name,
2531
+ tokens: tokens.map(serializeNameToken),
2532
+ expiresAt,
2533
+ accurateAsOf
2534
+ };
1583
2535
  }
1584
- function invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL(ctx) {
1585
- const endpoints = ctx.value;
1586
- const wsEndpoints = endpoints.filter(isWebSocketProtocol);
1587
- if (wsEndpoints.length > 1) {
1588
- ctx.issues.push({
1589
- code: "custom",
1590
- input: endpoints,
1591
- message: `RPC endpoint configuration for a chain must include at most one websocket (ws/wss) protocol URL.`
1592
- });
2536
+ function serializeNameTokensResponse(response) {
2537
+ switch (response.responseCode) {
2538
+ case NameTokensResponseCodes.Ok:
2539
+ return {
2540
+ responseCode: response.responseCode,
2541
+ registeredNameTokens: serializeRegisteredNameTokens(response.registeredNameTokens)
2542
+ };
2543
+ case NameTokensResponseCodes.Error:
2544
+ return response;
1593
2545
  }
1594
2546
  }
1595
2547
 
1596
- // src/shared/config/zod-schemas.ts
1597
- import { z as z4 } from "zod/v4";
1598
- import { ENSNamespaceIds as ENSNamespaceIds3 } from "@ensnode/datasources";
1599
- var DatabaseSchemaNameSchema = z4.string({
1600
- error: "DATABASE_SCHEMA is required."
1601
- }).trim().min(1, {
1602
- error: "DATABASE_SCHEMA is required and cannot be an empty string."
1603
- });
1604
- var RpcConfigSchema = z4.string().transform((val) => val.split(",")).pipe(z4.array(makeUrlSchema("RPC URL"))).check(invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL).check(invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL);
1605
- var RpcConfigsSchema = z4.record(makeChainIdStringSchema("RPC URL"), RpcConfigSchema, {
1606
- error: "Chains configuration must be an object mapping valid chain IDs to their configs."
1607
- }).transform((records) => {
1608
- const rpcConfigs = /* @__PURE__ */ new Map();
1609
- for (const [chainIdString, rpcConfig] of Object.entries(records)) {
1610
- const httpRPCs = rpcConfig.filter(isHttpProtocol);
1611
- const websocketRPC = rpcConfig.find(isWebSocketProtocol);
1612
- rpcConfigs.set(deserializeChainId(chainIdString), {
1613
- httpRPCs,
1614
- websocketRPC
1615
- });
1616
- }
1617
- return rpcConfigs;
1618
- });
1619
- var EnsIndexerUrlSchema = makeUrlSchema("ENSINDEXER_URL");
1620
- var ENSNamespaceSchema = z4.enum(ENSNamespaceIds3, {
1621
- error: ({ input }) => `Invalid NAMESPACE. Got '${input}', but supported ENS namespaces are: ${Object.keys(ENSNamespaceIds3).join(", ")}`
1622
- });
1623
- var PortSchema = z4.coerce.number({ error: "PORT must be a number." }).min(1, { error: "PORT must be greater than 1." }).max(65535, { error: "PORT must be less than 65535" }).optional();
1624
- var TheGraphApiKeySchema = z4.string().optional();
1625
-
1626
- // src/shared/datasources-with-resolvers.ts
1627
- import {
1628
- DatasourceNames,
1629
- maybeGetDatasource
1630
- } from "@ensnode/datasources";
1631
- var DATASOURCE_NAMES_WITH_RESOLVERS = [
1632
- DatasourceNames.ENSRoot,
1633
- DatasourceNames.Basenames,
1634
- DatasourceNames.Lineanames,
1635
- DatasourceNames.ThreeDNSOptimism,
1636
- DatasourceNames.ThreeDNSBase
1637
- ];
1638
-
1639
- // src/shared/log-level.ts
1640
- import { z as z5 } from "zod/v4";
1641
- var LogLevelSchema = z5.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]);
2548
+ // src/api/registrar-actions/deserialize.ts
2549
+ import { prettifyError as prettifyError8 } from "zod/v4";
1642
2550
 
1643
- // src/shared/protocol-acceleration/interpret-record-values.ts
1644
- import { isAddress as isAddress3, isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
2551
+ // src/api/registrar-actions/zod-schemas.ts
2552
+ import { namehash as namehash3 } from "viem/ens";
2553
+ import z11 from "zod/v4";
1645
2554
 
1646
2555
  // ../ens-referrals/src/address.ts
1647
- import { isAddress as isAddress4 } from "viem";
2556
+ import { isAddress as isAddress3 } from "viem";
1648
2557
 
1649
2558
  // ../ens-referrals/src/encoding.ts
1650
- import { getAddress, pad, size as size2, slice, zeroAddress as zeroAddress2 } from "viem";
2559
+ import { getAddress, pad, size as size2, slice, zeroAddress as zeroAddress4 } from "viem";
1651
2560
  var ENCODED_REFERRER_BYTE_OFFSET = 12;
1652
2561
  var ENCODED_REFERRER_BYTE_LENGTH = 32;
1653
2562
  var EXPECTED_ENCODED_REFERRER_PADDING = pad("0x", {
@@ -1666,7 +2575,7 @@ function decodeEncodedReferrer(encodedReferrer) {
1666
2575
  }
1667
2576
  const padding = slice(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
1668
2577
  if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
1669
- return zeroAddress2;
2578
+ return zeroAddress4;
1670
2579
  }
1671
2580
  const decodedReferrer = slice(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
1672
2581
  try {
@@ -1682,25 +2591,20 @@ var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
1682
2591
  // ../ens-referrals/src/link.ts
1683
2592
  import { getAddress as getAddress2 } from "viem";
1684
2593
 
1685
- // src/registrars/zod-schemas.ts
1686
- import z6 from "zod/v4";
1687
-
1688
- // src/registrars/subregistry.ts
1689
- function serializeSubregistry(subregistry) {
1690
- return {
1691
- subregistryId: serializeAccountId(subregistry.subregistryId),
1692
- node: subregistry.node
1693
- };
1694
- }
2594
+ // ../ens-referrals/src/referrer-detail.ts
2595
+ var ReferrerDetailTypeIds = {
2596
+ /**
2597
+ * Represents a referrer who is ranked on the leaderboard.
2598
+ */
2599
+ Ranked: "ranked",
2600
+ /**
2601
+ * Represents a referrer who is not ranked on the leaderboard.
2602
+ */
2603
+ Unranked: "unranked"
2604
+ };
1695
2605
 
1696
- // src/registrars/registration-lifecycle.ts
1697
- function serializeRegistrationLifecycle(registrationLifecycle) {
1698
- return {
1699
- subregistry: serializeSubregistry(registrationLifecycle.subregistry),
1700
- node: registrationLifecycle.node,
1701
- expiresAt: registrationLifecycle.expiresAt
1702
- };
1703
- }
2606
+ // src/registrars/zod-schemas.ts
2607
+ import z9 from "zod/v4";
1704
2608
 
1705
2609
  // src/registrars/registrar-action.ts
1706
2610
  var RegistrarActionTypes = {
@@ -1731,7 +2635,7 @@ function serializeRegistrarAction(registrarAction) {
1731
2635
  type: registrarAction.type,
1732
2636
  incrementalDuration: registrarAction.incrementalDuration,
1733
2637
  registrant: registrarAction.registrant,
1734
- registrationLifecycle: serializeRegistrationLifecycle(registrarAction.registrationLifecycle),
2638
+ registrationLifecycle: registrarAction.registrationLifecycle,
1735
2639
  pricing: serializeRegistrarActionPricing(registrarAction.pricing),
1736
2640
  referral: registrarAction.referral,
1737
2641
  block: registrarAction.block,
@@ -1741,11 +2645,11 @@ function serializeRegistrarAction(registrarAction) {
1741
2645
  }
1742
2646
 
1743
2647
  // src/registrars/zod-schemas.ts
1744
- var makeSubregistrySchema = (valueLabel = "Subregistry") => z6.object({
1745
- subregistryId: makeSerializedAccountIdSchema(`${valueLabel} Subregistry ID`),
2648
+ var makeSubregistrySchema = (valueLabel = "Subregistry") => z9.object({
2649
+ subregistryId: makeAccountIdSchema(`${valueLabel} Subregistry ID`),
1746
2650
  node: makeNodeSchema(`${valueLabel} Node`)
1747
2651
  });
1748
- var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => z6.object({
2652
+ var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => z9.object({
1749
2653
  subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
1750
2654
  node: makeNodeSchema(`${valueLabel} Node`),
1751
2655
  expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
@@ -1761,18 +2665,18 @@ function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
1761
2665
  });
1762
2666
  }
1763
2667
  }
1764
- var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => z6.union([
2668
+ var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => z9.union([
1765
2669
  // pricing available
1766
- z6.object({
2670
+ z9.object({
1767
2671
  baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
1768
2672
  premium: makePriceEthSchema(`${valueLabel} Premium`),
1769
2673
  total: makePriceEthSchema(`${valueLabel} Total`)
1770
2674
  }).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
1771
2675
  // pricing unknown
1772
- z6.object({
1773
- baseCost: z6.null(),
1774
- premium: z6.null(),
1775
- total: z6.null()
2676
+ z9.object({
2677
+ baseCost: z9.null(),
2678
+ premium: z9.null(),
2679
+ total: z9.null()
1776
2680
  }).transform((v) => v)
1777
2681
  ]);
1778
2682
  function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
@@ -1794,422 +2698,225 @@ function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
1794
2698
  message: errorMessage
1795
2699
  });
1796
2700
  }
1797
- }
1798
- var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => z6.union([
1799
- // referral available
1800
- z6.object({
1801
- encodedReferrer: makeHexStringSchema(
1802
- { bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
1803
- `${valueLabel} Encoded Referrer`
1804
- ),
1805
- decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
1806
- }).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
1807
- // referral not applicable
1808
- z6.object({
1809
- encodedReferrer: z6.null(),
1810
- decodedReferrer: z6.null()
1811
- })
1812
- ]);
1813
- function invariant_eventIdsInitialElementIsTheActionId(ctx) {
1814
- const { id, eventIds } = ctx.value;
1815
- if (eventIds[0] !== id) {
1816
- ctx.issues.push({
1817
- code: "custom",
1818
- input: ctx.value,
1819
- message: "The initial element of `eventIds` must be the `id` value"
1820
- });
1821
- }
1822
- }
1823
- var EventIdSchema = z6.string().nonempty();
1824
- var EventIdsSchema = z6.array(EventIdSchema).min(1).transform((v) => v);
1825
- var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z6.object({
1826
- id: EventIdSchema,
1827
- incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
1828
- registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
1829
- registrationLifecycle: makeRegistrationLifecycleSchema(
1830
- `${valueLabel} Registration Lifecycle`
1831
- ),
1832
- pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
1833
- referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
1834
- block: makeBlockRefSchema(`${valueLabel} Block`),
1835
- transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
1836
- eventIds: EventIdsSchema
1837
- }).check(invariant_eventIdsInitialElementIsTheActionId);
1838
- var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
1839
- type: z6.literal(RegistrarActionTypes.Registration)
1840
- });
1841
- var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
1842
- type: z6.literal(RegistrarActionTypes.Renewal)
1843
- });
1844
- var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => z6.discriminatedUnion("type", [
1845
- makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
1846
- makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
1847
- ]);
1848
-
1849
- // src/api/types.ts
1850
- var IndexingStatusResponseCodes = {
1851
- /**
1852
- * Represents that the indexing status is available.
1853
- */
1854
- Ok: "ok",
1855
- /**
1856
- * Represents that the indexing status is unavailable.
1857
- */
1858
- Error: "error"
1859
- };
1860
- var RegistrarActionsFilterTypes = {
1861
- BySubregistryNode: "bySubregistryNode",
1862
- WithEncodedReferral: "withEncodedReferral"
1863
- };
1864
- var RegistrarActionsOrders = {
1865
- LatestRegistrarActions: "orderBy[timestamp]=desc"
1866
- };
1867
- var RegistrarActionsResponseCodes = {
1868
- /**
1869
- * Represents that Registrar Actions are available.
1870
- */
1871
- Ok: "ok",
1872
- /**
1873
- * Represents that Registrar Actions are unavailable.
1874
- */
1875
- Error: "error"
1876
- };
1877
-
1878
- // src/api/zod-schemas.ts
1879
- var ErrorResponseSchema = z7.object({
1880
- message: z7.string(),
1881
- details: z7.optional(z7.unknown())
1882
- });
1883
- var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z7.strictObject({
1884
- responseCode: z7.literal(IndexingStatusResponseCodes.Ok),
1885
- realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
1886
- });
1887
- var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => z7.strictObject({
1888
- responseCode: z7.literal(IndexingStatusResponseCodes.Error)
1889
- });
1890
- var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z7.discriminatedUnion("responseCode", [
1891
- makeIndexingStatusResponseOkSchema(valueLabel),
1892
- makeIndexingStatusResponseErrorSchema(valueLabel)
1893
- ]);
1894
- function invariant_registrationLifecycleNodeMatchesName(ctx) {
1895
- const { name, action } = ctx.value;
1896
- const expectedNode = action.registrationLifecycle.node;
1897
- const actualNode = namehash2(name);
1898
- if (actualNode !== expectedNode) {
1899
- ctx.issues.push({
1900
- code: "custom",
1901
- input: ctx.value,
1902
- message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
1903
- });
1904
- }
1905
- }
1906
- var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z7.object({
1907
- action: makeRegistrarActionSchema(valueLabel),
1908
- name: makeReinterpretedNameSchema(valueLabel)
1909
- }).check(invariant_registrationLifecycleNodeMatchesName);
1910
- var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z7.strictObject({
1911
- responseCode: z7.literal(RegistrarActionsResponseCodes.Ok),
1912
- registrarActions: z7.array(makeNamedRegistrarActionSchema(valueLabel))
1913
- });
1914
- var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => z7.strictObject({
1915
- responseCode: z7.literal(RegistrarActionsResponseCodes.Error),
1916
- error: ErrorResponseSchema
1917
- });
1918
- var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => z7.discriminatedUnion("responseCode", [
1919
- makeRegistrarActionsResponseOkSchema(valueLabel),
1920
- makeRegistrarActionsResponseErrorSchema(valueLabel)
1921
- ]);
1922
-
1923
- // src/api/deserialize.ts
1924
- function deserializeErrorResponse(maybeErrorResponse) {
1925
- const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
1926
- if (parsed.error) {
1927
- throw new Error(`Cannot deserialize ErrorResponse:
1928
- ${prettifyError2(parsed.error)}
1929
- `);
1930
- }
1931
- return parsed.data;
1932
- }
1933
- function deserializeIndexingStatusResponse(maybeResponse) {
1934
- const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
1935
- if (parsed.error) {
1936
- throw new Error(`Cannot deserialize IndexingStatusResponse:
1937
- ${prettifyError2(parsed.error)}
1938
- `);
1939
- }
1940
- return parsed.data;
1941
- }
1942
- function deserializeRegistrarActionsResponse(maybeResponse) {
1943
- const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
1944
- if (parsed.error) {
1945
- throw new Error(
1946
- `Cannot deserialize RegistrarActionsResponse:
1947
- ${prettifyError2(parsed.error)}
1948
- `
1949
- );
1950
- }
1951
- return parsed.data;
1952
- }
1953
-
1954
- // src/api/registrar-actions/filters.ts
1955
- function byParentNode(parentNode) {
1956
- if (typeof parentNode === "undefined") {
1957
- return void 0;
1958
- }
1959
- return {
1960
- filterType: RegistrarActionsFilterTypes.BySubregistryNode,
1961
- value: parentNode
1962
- };
1963
- }
1964
- function withReferral(withReferral2) {
1965
- if (!withReferral2) {
1966
- return void 0;
1967
- }
1968
- return {
1969
- filterType: RegistrarActionsFilterTypes.WithEncodedReferral
1970
- };
1971
- }
1972
- var registrarActionsFilter = {
1973
- byParentNode,
1974
- withReferral
1975
- };
1976
-
1977
- // src/ensindexer/config/deserialize.ts
1978
- import { prettifyError as prettifyError3 } from "zod/v4";
1979
- function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
1980
- const schema = makeENSIndexerPublicConfigSchema(valueLabel);
1981
- const parsed = schema.safeParse(maybeConfig);
1982
- if (parsed.error) {
1983
- throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
1984
- ${prettifyError3(parsed.error)}
1985
- `);
1986
- }
1987
- return parsed.data;
1988
- }
1989
-
1990
- // src/ensindexer/config/label-utils.ts
1991
- import { hexToBytes as hexToBytes2 } from "viem";
1992
- function labelHashToBytes(labelHash) {
1993
- try {
1994
- if (labelHash.length !== 66) {
1995
- throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
1996
- }
1997
- if (labelHash !== labelHash.toLowerCase()) {
1998
- throw new Error("Labelhash must be in lowercase");
1999
- }
2000
- if (!labelHash.startsWith("0x")) {
2001
- throw new Error("Labelhash must be 0x-prefixed");
2002
- }
2003
- const bytes = hexToBytes2(labelHash);
2004
- if (bytes.length !== 32) {
2005
- throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
2006
- }
2007
- return bytes;
2008
- } catch (e) {
2009
- if (e instanceof Error) {
2010
- throw e;
2011
- }
2012
- throw new Error("Invalid hex format");
2013
- }
2014
- }
2015
-
2016
- // src/ensindexer/config/labelset-utils.ts
2017
- function buildLabelSetId(maybeLabelSetId) {
2018
- return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
2019
- }
2020
- function buildLabelSetVersion(maybeLabelSetVersion) {
2021
- return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
2022
- }
2023
- function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
2024
- if (labelSetVersion !== void 0 && labelSetId === void 0) {
2025
- throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
2026
- }
2027
- return { labelSetId, labelSetVersion };
2028
- }
2029
- function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
2030
- if (clientSet.labelSetId === void 0) {
2031
- return;
2032
- }
2033
- if (serverSet.labelSetId !== clientSet.labelSetId) {
2034
- throw new Error(
2035
- `Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
2036
- );
2037
- }
2038
- if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
2039
- throw new Error(
2040
- `Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
2041
- );
2701
+ }
2702
+ var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => z9.union([
2703
+ // referral available
2704
+ z9.object({
2705
+ encodedReferrer: makeHexStringSchema(
2706
+ { bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
2707
+ `${valueLabel} Encoded Referrer`
2708
+ ),
2709
+ decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
2710
+ }).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
2711
+ // referral not applicable
2712
+ z9.object({
2713
+ encodedReferrer: z9.null(),
2714
+ decodedReferrer: z9.null()
2715
+ })
2716
+ ]);
2717
+ function invariant_eventIdsInitialElementIsTheActionId(ctx) {
2718
+ const { id, eventIds } = ctx.value;
2719
+ if (eventIds[0] !== id) {
2720
+ ctx.issues.push({
2721
+ code: "custom",
2722
+ input: ctx.value,
2723
+ message: "The initial element of `eventIds` must be the `id` value"
2724
+ });
2042
2725
  }
2043
2726
  }
2727
+ var EventIdSchema = z9.string().nonempty();
2728
+ var EventIdsSchema = z9.array(EventIdSchema).min(1).transform((v) => v);
2729
+ var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z9.object({
2730
+ id: EventIdSchema,
2731
+ incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
2732
+ registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
2733
+ registrationLifecycle: makeRegistrationLifecycleSchema(
2734
+ `${valueLabel} Registration Lifecycle`
2735
+ ),
2736
+ pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
2737
+ referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
2738
+ block: makeBlockRefSchema(`${valueLabel} Block`),
2739
+ transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
2740
+ eventIds: EventIdsSchema
2741
+ }).check(invariant_eventIdsInitialElementIsTheActionId);
2742
+ var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
2743
+ type: z9.literal(RegistrarActionTypes.Registration)
2744
+ });
2745
+ var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
2746
+ type: z9.literal(RegistrarActionTypes.Renewal)
2747
+ });
2748
+ var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => z9.discriminatedUnion("type", [
2749
+ makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
2750
+ makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
2751
+ ]);
2044
2752
 
2045
- // src/ensindexer/config/parsing.ts
2046
- function parseNonNegativeInteger(maybeNumber) {
2047
- const trimmed = maybeNumber.trim();
2048
- if (!trimmed) {
2049
- throw new Error("Input cannot be empty");
2050
- }
2051
- if (trimmed === "-0") {
2052
- throw new Error("Negative zero is not a valid non-negative integer");
2053
- }
2054
- const num = Number(maybeNumber);
2055
- if (Number.isNaN(num)) {
2056
- throw new Error(`"${maybeNumber}" is not a valid number`);
2753
+ // src/api/shared/pagination/zod-schemas.ts
2754
+ import z10 from "zod/v4";
2755
+
2756
+ // src/api/shared/pagination/request.ts
2757
+ var RECORDS_PER_PAGE_DEFAULT = 10;
2758
+ var RECORDS_PER_PAGE_MAX = 100;
2759
+
2760
+ // src/api/shared/pagination/zod-schemas.ts
2761
+ var makeRequestPageParamsSchema = (valueLabel = "RequestPageParams") => z10.object({
2762
+ page: makePositiveIntegerSchema(`${valueLabel}.page`),
2763
+ recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
2764
+ RECORDS_PER_PAGE_MAX,
2765
+ `${valueLabel}.recordsPerPage must not exceed ${RECORDS_PER_PAGE_MAX}`
2766
+ )
2767
+ });
2768
+ var makeResponsePageContextSchemaWithNoRecords = (valueLabel = "ResponsePageContextWithNoRecords") => z10.object({
2769
+ totalRecords: z10.literal(0),
2770
+ totalPages: z10.literal(1),
2771
+ hasNext: z10.literal(false),
2772
+ hasPrev: z10.literal(false),
2773
+ startIndex: z10.undefined(),
2774
+ endIndex: z10.undefined()
2775
+ }).extend(makeRequestPageParamsSchema(valueLabel).shape);
2776
+ function invariant_responsePageWithRecordsIsCorrect(ctx) {
2777
+ const { hasNext, hasPrev, recordsPerPage, page, totalRecords, startIndex, endIndex } = ctx.value;
2778
+ const expectedHasNext = page * recordsPerPage < totalRecords;
2779
+ if (hasNext !== expectedHasNext) {
2780
+ ctx.issues.push({
2781
+ code: "custom",
2782
+ input: ctx.value,
2783
+ message: `hasNext must be equal to '${expectedHasNext ? "true" : "false"}'`
2784
+ });
2057
2785
  }
2058
- if (!Number.isFinite(num)) {
2059
- throw new Error(`"${maybeNumber}" is not a finite number`);
2786
+ const expectedHasPrev = page > 1;
2787
+ if (hasPrev !== expectedHasPrev) {
2788
+ ctx.issues.push({
2789
+ code: "custom",
2790
+ input: ctx.value,
2791
+ message: `hasPrev must be equal to '${expectedHasPrev ? "true" : "false"}'`
2792
+ });
2060
2793
  }
2061
- if (!Number.isInteger(num)) {
2062
- throw new Error(`"${maybeNumber}" is not an integer`);
2794
+ if (endIndex < startIndex) {
2795
+ ctx.issues.push({
2796
+ code: "custom",
2797
+ input: ctx.value,
2798
+ message: `endIndex must be greater than or equal to startIndex`
2799
+ });
2063
2800
  }
2064
- if (num < 0) {
2065
- throw new Error(`"${maybeNumber}" is not a non-negative integer`);
2801
+ if (endIndex >= totalRecords) {
2802
+ ctx.issues.push({
2803
+ code: "custom",
2804
+ input: ctx.value,
2805
+ message: `endIndex must be lower than totalRecords`
2806
+ });
2066
2807
  }
2067
- return num;
2068
2808
  }
2809
+ var makeResponsePageContextSchemaWithRecords = (valueLabel = "ResponsePageContextWithRecords") => z10.object({
2810
+ totalRecords: makePositiveIntegerSchema(`${valueLabel}.totalRecords`),
2811
+ totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
2812
+ hasNext: z10.boolean(),
2813
+ hasPrev: z10.boolean(),
2814
+ startIndex: makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`),
2815
+ endIndex: makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`)
2816
+ }).extend(makeRequestPageParamsSchema(valueLabel).shape).check(invariant_responsePageWithRecordsIsCorrect);
2817
+ var makeResponsePageContextSchema = (valueLabel = "ResponsePageContext") => z10.union([
2818
+ makeResponsePageContextSchemaWithNoRecords(valueLabel),
2819
+ makeResponsePageContextSchemaWithRecords(valueLabel)
2820
+ ]);
2069
2821
 
2070
- // src/ensindexer/config/serialize.ts
2071
- function serializeIndexedChainIds(indexedChainIds) {
2072
- return Array.from(indexedChainIds);
2073
- }
2074
- function serializeENSIndexerPublicConfig(config) {
2075
- const {
2076
- labelSet,
2077
- indexedChainIds,
2078
- databaseSchemaName,
2079
- isSubgraphCompatible: isSubgraphCompatible2,
2080
- namespace,
2081
- plugins,
2082
- versionInfo
2083
- } = config;
2084
- return {
2085
- labelSet,
2086
- indexedChainIds: serializeIndexedChainIds(indexedChainIds),
2087
- databaseSchemaName,
2088
- isSubgraphCompatible: isSubgraphCompatible2,
2089
- namespace,
2090
- plugins,
2091
- versionInfo
2092
- };
2093
- }
2822
+ // src/api/registrar-actions/response.ts
2823
+ var RegistrarActionsResponseCodes = {
2824
+ /**
2825
+ * Represents that Registrar Actions are available.
2826
+ */
2827
+ Ok: "ok",
2828
+ /**
2829
+ * Represents that Registrar Actions are unavailable.
2830
+ */
2831
+ Error: "error"
2832
+ };
2094
2833
 
2095
- // src/ensindexer/indexing-status/deserialize.ts
2096
- import { prettifyError as prettifyError4 } from "zod/v4";
2097
- function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
2098
- const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
2099
- const parsed = schema.safeParse(maybeSnapshot);
2100
- if (parsed.error) {
2101
- throw new Error(
2102
- `Cannot deserialize into ChainIndexingStatusSnapshot:
2103
- ${prettifyError4(parsed.error)}
2104
- `
2105
- );
2106
- }
2107
- return parsed.data;
2108
- }
2109
- function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
2110
- const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
2111
- const parsed = schema.safeParse(maybeSnapshot);
2112
- if (parsed.error) {
2113
- throw new Error(
2114
- `Cannot deserialize into OmnichainIndexingStatusSnapshot:
2115
- ${prettifyError4(parsed.error)}
2116
- `
2117
- );
2118
- }
2119
- return parsed.data;
2120
- }
2121
- function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
2122
- const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
2123
- const parsed = schema.safeParse(maybeSnapshot);
2124
- if (parsed.error) {
2125
- throw new Error(
2126
- `Cannot deserialize into CrossChainIndexingStatusSnapshot:
2127
- ${prettifyError4(parsed.error)}
2128
- `
2129
- );
2834
+ // src/api/registrar-actions/zod-schemas.ts
2835
+ function invariant_registrationLifecycleNodeMatchesName(ctx) {
2836
+ const { name, action } = ctx.value;
2837
+ const expectedNode = action.registrationLifecycle.node;
2838
+ const actualNode = namehash3(name);
2839
+ if (actualNode !== expectedNode) {
2840
+ ctx.issues.push({
2841
+ code: "custom",
2842
+ input: ctx.value,
2843
+ message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
2844
+ });
2130
2845
  }
2131
- return parsed.data;
2132
2846
  }
2133
- function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
2134
- const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
2135
- const parsed = schema.safeParse(maybeProjection);
2847
+ var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z11.object({
2848
+ action: makeRegistrarActionSchema(valueLabel),
2849
+ name: makeReinterpretedNameSchema(valueLabel)
2850
+ }).check(invariant_registrationLifecycleNodeMatchesName);
2851
+ var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z11.strictObject({
2852
+ responseCode: z11.literal(RegistrarActionsResponseCodes.Ok),
2853
+ registrarActions: z11.array(makeNamedRegistrarActionSchema(valueLabel)),
2854
+ pageContext: makeResponsePageContextSchema(`${valueLabel}.pageContext`)
2855
+ });
2856
+ var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => z11.strictObject({
2857
+ responseCode: z11.literal(RegistrarActionsResponseCodes.Error),
2858
+ error: ErrorResponseSchema
2859
+ });
2860
+ var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => z11.discriminatedUnion("responseCode", [
2861
+ makeRegistrarActionsResponseOkSchema(valueLabel),
2862
+ makeRegistrarActionsResponseErrorSchema(valueLabel)
2863
+ ]);
2864
+
2865
+ // src/api/registrar-actions/deserialize.ts
2866
+ function deserializeRegistrarActionsResponse(maybeResponse) {
2867
+ const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
2136
2868
  if (parsed.error) {
2137
2869
  throw new Error(
2138
- `Cannot deserialize into RealtimeIndexingStatusProjection:
2139
- ${prettifyError4(parsed.error)}
2870
+ `Cannot deserialize RegistrarActionsResponse:
2871
+ ${prettifyError8(parsed.error)}
2140
2872
  `
2141
2873
  );
2142
2874
  }
2143
2875
  return parsed.data;
2144
2876
  }
2145
2877
 
2146
- // src/ensindexer/indexing-status/projection.ts
2147
- function createRealtimeIndexingStatusProjection(snapshot, now) {
2148
- const projectedAt = Math.max(now, snapshot.snapshotTime);
2149
- return {
2150
- projectedAt,
2151
- worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
2152
- snapshot
2153
- };
2154
- }
2878
+ // src/api/registrar-actions/request.ts
2879
+ var RegistrarActionsFilterTypes = {
2880
+ BySubregistryNode: "bySubregistryNode",
2881
+ WithEncodedReferral: "withEncodedReferral",
2882
+ ByDecodedReferrer: "byDecodedReferrer"
2883
+ };
2884
+ var RegistrarActionsOrders = {
2885
+ LatestRegistrarActions: "orderBy[timestamp]=desc"
2886
+ };
2155
2887
 
2156
- // src/ensindexer/indexing-status/serialize.ts
2157
- function serializeCrossChainIndexingStatusSnapshotOmnichain({
2158
- strategy,
2159
- slowestChainIndexingCursor,
2160
- snapshotTime,
2161
- omnichainSnapshot
2162
- }) {
2163
- return {
2164
- strategy,
2165
- slowestChainIndexingCursor,
2166
- snapshotTime,
2167
- omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
2168
- };
2169
- }
2170
- function serializeRealtimeIndexingStatusProjection(indexingProjection) {
2171
- return {
2172
- projectedAt: indexingProjection.projectedAt,
2173
- worstCaseDistance: indexingProjection.worstCaseDistance,
2174
- snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
2175
- };
2176
- }
2177
- function serializeChainIndexingSnapshots(chains) {
2178
- const serializedSnapshots = {};
2179
- for (const [chainId, snapshot] of chains.entries()) {
2180
- serializedSnapshots[serializeChainId(chainId)] = snapshot;
2888
+ // src/api/registrar-actions/filters.ts
2889
+ function byParentNode(parentNode) {
2890
+ if (typeof parentNode === "undefined") {
2891
+ return void 0;
2181
2892
  }
2182
- return serializedSnapshots;
2183
- }
2184
- function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
2185
- switch (indexingStatus.omnichainStatus) {
2186
- case OmnichainIndexingStatusIds.Unstarted:
2187
- return {
2188
- omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
2189
- chains: serializeChainIndexingSnapshots(indexingStatus.chains),
2190
- omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
2191
- };
2192
- case OmnichainIndexingStatusIds.Backfill:
2193
- return {
2194
- omnichainStatus: OmnichainIndexingStatusIds.Backfill,
2195
- chains: serializeChainIndexingSnapshots(indexingStatus.chains),
2196
- omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
2197
- };
2198
- case OmnichainIndexingStatusIds.Completed: {
2199
- return {
2200
- omnichainStatus: OmnichainIndexingStatusIds.Completed,
2201
- chains: serializeChainIndexingSnapshots(indexingStatus.chains),
2202
- omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
2203
- };
2204
- }
2205
- case OmnichainIndexingStatusIds.Following:
2206
- return {
2207
- omnichainStatus: OmnichainIndexingStatusIds.Following,
2208
- chains: serializeChainIndexingSnapshots(indexingStatus.chains),
2209
- omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
2210
- };
2893
+ return {
2894
+ filterType: RegistrarActionsFilterTypes.BySubregistryNode,
2895
+ value: parentNode
2896
+ };
2897
+ }
2898
+ function withReferral(withReferral2) {
2899
+ if (!withReferral2) {
2900
+ return void 0;
2901
+ }
2902
+ return {
2903
+ filterType: RegistrarActionsFilterTypes.WithEncodedReferral
2904
+ };
2905
+ }
2906
+ function byDecodedReferrer(decodedReferrer) {
2907
+ if (typeof decodedReferrer === "undefined") {
2908
+ return void 0;
2211
2909
  }
2910
+ return {
2911
+ filterType: RegistrarActionsFilterTypes.ByDecodedReferrer,
2912
+ value: decodedReferrer
2913
+ };
2212
2914
  }
2915
+ var registrarActionsFilter = {
2916
+ byParentNode,
2917
+ withReferral,
2918
+ byDecodedReferrer
2919
+ };
2213
2920
 
2214
2921
  // src/api/registrar-actions/prerequisites.ts
2215
2922
  var registrarActionsPrerequisites = Object.freeze({
@@ -2261,12 +2968,50 @@ var registrarActionsPrerequisites = Object.freeze({
2261
2968
  }
2262
2969
  });
2263
2970
 
2971
+ // src/registrars/basenames-subregistry.ts
2972
+ import {
2973
+ DatasourceNames as DatasourceNames2,
2974
+ ENSNamespaceIds as ENSNamespaceIds3,
2975
+ maybeGetDatasource as maybeGetDatasource2
2976
+ } from "@ensnode/datasources";
2977
+ function getBasenamesSubregistryId(namespace) {
2978
+ const datasource = maybeGetDatasource2(namespace, DatasourceNames2.Basenames);
2979
+ if (!datasource) {
2980
+ throw new Error(`Datasource not found for ${namespace} ${DatasourceNames2.Basenames}`);
2981
+ }
2982
+ const address = datasource.contracts.BaseRegistrar?.address;
2983
+ if (address === void 0 || Array.isArray(address)) {
2984
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
2985
+ }
2986
+ return {
2987
+ chainId: datasource.chain.id,
2988
+ address
2989
+ };
2990
+ }
2991
+ function getBasenamesSubregistryManagedName(namespaceId) {
2992
+ switch (namespaceId) {
2993
+ case ENSNamespaceIds3.Mainnet:
2994
+ return "base.eth";
2995
+ case ENSNamespaceIds3.Sepolia:
2996
+ return "basetest.eth";
2997
+ case ENSNamespaceIds3.Holesky:
2998
+ case ENSNamespaceIds3.EnsTestEnv:
2999
+ throw new Error(
3000
+ `No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`
3001
+ );
3002
+ }
3003
+ }
3004
+
2264
3005
  // src/registrars/ethnames-subregistry.ts
2265
- import { DatasourceNames as DatasourceNames2, maybeGetDatasource as maybeGetDatasource2 } from "@ensnode/datasources";
3006
+ import {
3007
+ DatasourceNames as DatasourceNames3,
3008
+ ENSNamespaceIds as ENSNamespaceIds4,
3009
+ maybeGetDatasource as maybeGetDatasource3
3010
+ } from "@ensnode/datasources";
2266
3011
  function getEthnamesSubregistryId(namespace) {
2267
- const datasource = maybeGetDatasource2(namespace, DatasourceNames2.ENSRoot);
3012
+ const datasource = maybeGetDatasource3(namespace, DatasourceNames3.ENSRoot);
2268
3013
  if (!datasource) {
2269
- throw new Error(`Datasource not found for ${namespace} ${DatasourceNames2.ENSRoot}`);
3014
+ throw new Error(`Datasource not found for ${namespace} ${DatasourceNames3.ENSRoot}`);
2270
3015
  }
2271
3016
  const address = datasource.contracts.BaseRegistrar?.address;
2272
3017
  if (address === void 0 || Array.isArray(address)) {
@@ -2277,19 +3022,51 @@ function getEthnamesSubregistryId(namespace) {
2277
3022
  address
2278
3023
  };
2279
3024
  }
3025
+ function getEthnamesSubregistryManagedName(namespaceId) {
3026
+ switch (namespaceId) {
3027
+ case ENSNamespaceIds4.Mainnet:
3028
+ case ENSNamespaceIds4.Sepolia:
3029
+ case ENSNamespaceIds4.Holesky:
3030
+ case ENSNamespaceIds4.EnsTestEnv:
3031
+ return "eth";
3032
+ }
3033
+ }
2280
3034
 
2281
- // src/api/serialize.ts
2282
- function serializeIndexingStatusResponse(response) {
2283
- switch (response.responseCode) {
2284
- case IndexingStatusResponseCodes.Ok:
2285
- return {
2286
- responseCode: response.responseCode,
2287
- realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
2288
- };
2289
- case IndexingStatusResponseCodes.Error:
2290
- return response;
3035
+ // src/registrars/lineanames-subregistry.ts
3036
+ import {
3037
+ DatasourceNames as DatasourceNames4,
3038
+ ENSNamespaceIds as ENSNamespaceIds5,
3039
+ maybeGetDatasource as maybeGetDatasource4
3040
+ } from "@ensnode/datasources";
3041
+ function getLineanamesSubregistryId(namespace) {
3042
+ const datasource = maybeGetDatasource4(namespace, DatasourceNames4.Lineanames);
3043
+ if (!datasource) {
3044
+ throw new Error(`Datasource not found for ${namespace} ${DatasourceNames4.Lineanames}`);
3045
+ }
3046
+ const address = datasource.contracts.BaseRegistrar?.address;
3047
+ if (address === void 0 || Array.isArray(address)) {
3048
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
3049
+ }
3050
+ return {
3051
+ chainId: datasource.chain.id,
3052
+ address
3053
+ };
3054
+ }
3055
+ function getLineanamesSubregistryManagedName(namespaceId) {
3056
+ switch (namespaceId) {
3057
+ case ENSNamespaceIds5.Mainnet:
3058
+ return "linea.eth";
3059
+ case ENSNamespaceIds5.Sepolia:
3060
+ return "linea-sepolia.eth";
3061
+ case ENSNamespaceIds5.Holesky:
3062
+ case ENSNamespaceIds5.EnsTestEnv:
3063
+ throw new Error(
3064
+ `No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`
3065
+ );
2291
3066
  }
2292
3067
  }
3068
+
3069
+ // src/api/registrar-actions/serialize.ts
2293
3070
  function serializeNamedRegistrarAction({
2294
3071
  action,
2295
3072
  name
@@ -2304,13 +3081,61 @@ function serializeRegistrarActionsResponse(response) {
2304
3081
  case RegistrarActionsResponseCodes.Ok:
2305
3082
  return {
2306
3083
  responseCode: response.responseCode,
2307
- registrarActions: response.registrarActions.map(serializeNamedRegistrarAction)
3084
+ registrarActions: response.registrarActions.map(serializeNamedRegistrarAction),
3085
+ pageContext: response.pageContext
2308
3086
  };
2309
3087
  case RegistrarActionsResponseCodes.Error:
2310
3088
  return response;
2311
3089
  }
2312
3090
  }
2313
3091
 
3092
+ // src/api/shared/errors/deserialize.ts
3093
+ import { prettifyError as prettifyError9 } from "zod/v4";
3094
+ function deserializeErrorResponse(maybeErrorResponse) {
3095
+ const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
3096
+ if (parsed.error) {
3097
+ throw new Error(`Cannot deserialize ErrorResponse:
3098
+ ${prettifyError9(parsed.error)}
3099
+ `);
3100
+ }
3101
+ return parsed.data;
3102
+ }
3103
+
3104
+ // src/api/shared/pagination/build-page-context.ts
3105
+ function buildPageContext(page, recordsPerPage, totalRecords) {
3106
+ const totalPages = Math.max(1, Math.ceil(totalRecords / recordsPerPage));
3107
+ if (page > totalPages) {
3108
+ throw new Error(`Invalid page: page ${page} exceeds total pages ${totalPages}.`);
3109
+ }
3110
+ if (totalRecords === 0) {
3111
+ return {
3112
+ page,
3113
+ recordsPerPage,
3114
+ totalRecords: 0,
3115
+ totalPages: 1,
3116
+ hasNext: false,
3117
+ hasPrev: false,
3118
+ startIndex: void 0,
3119
+ endIndex: void 0
3120
+ };
3121
+ }
3122
+ const startIndex = (page - 1) * recordsPerPage;
3123
+ const maxTheoreticalIndexOnPage = startIndex + (recordsPerPage - 1);
3124
+ const endIndex = Math.min(maxTheoreticalIndexOnPage, totalRecords - 1);
3125
+ const hasNext = maxTheoreticalIndexOnPage < totalRecords - 1;
3126
+ const hasPrev = page > 1;
3127
+ return {
3128
+ page,
3129
+ recordsPerPage,
3130
+ totalRecords,
3131
+ totalPages,
3132
+ hasNext,
3133
+ hasPrev,
3134
+ startIndex,
3135
+ endIndex
3136
+ };
3137
+ }
3138
+
2314
3139
  // src/client-error.ts
2315
3140
  var ClientError = class _ClientError extends Error {
2316
3141
  details;
@@ -2325,10 +3150,10 @@ var ClientError = class _ClientError extends Error {
2325
3150
  };
2326
3151
 
2327
3152
  // src/ensanalytics/deserialize.ts
2328
- import { prettifyError as prettifyError5 } from "zod/v4";
3153
+ import { prettifyError as prettifyError10 } from "zod/v4";
2329
3154
 
2330
3155
  // src/ensanalytics/zod-schemas.ts
2331
- import z8 from "zod/v4";
3156
+ import z12 from "zod/v4";
2332
3157
 
2333
3158
  // src/ensanalytics/types.ts
2334
3159
  var ReferrerLeaderboardPageResponseCodes = {
@@ -2341,22 +3166,50 @@ var ReferrerLeaderboardPageResponseCodes = {
2341
3166
  */
2342
3167
  Error: "error"
2343
3168
  };
3169
+ var ReferrerDetailResponseCodes = {
3170
+ /**
3171
+ * Represents that the referrer detail data is available.
3172
+ */
3173
+ Ok: "ok",
3174
+ /**
3175
+ * Represents that an error occurred while fetching the data.
3176
+ */
3177
+ Error: "error"
3178
+ };
2344
3179
 
2345
3180
  // src/ensanalytics/zod-schemas.ts
2346
- var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => z8.object({
3181
+ var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => z12.object({
2347
3182
  totalAwardPoolValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.totalAwardPoolValue`),
2348
3183
  maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`),
2349
3184
  startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
2350
3185
  endTime: makeUnixTimestampSchema(`${valueLabel}.endTime`),
2351
3186
  subregistryId: makeAccountIdSchema(`${valueLabel}.subregistryId`)
2352
3187
  });
2353
- var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => z8.object({
3188
+ var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => z12.object({
2354
3189
  referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
2355
3190
  totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
2356
3191
  totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
2357
3192
  score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
2358
3193
  rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
2359
- isQualified: z8.boolean(),
3194
+ isQualified: z12.boolean(),
3195
+ finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
3196
+ 1,
3197
+ `${valueLabel}.finalScoreBoost must be <= 1`
3198
+ ),
3199
+ finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
3200
+ awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
3201
+ 1,
3202
+ `${valueLabel}.awardPoolShare must be <= 1`
3203
+ ),
3204
+ awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
3205
+ });
3206
+ var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics") => z12.object({
3207
+ referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
3208
+ totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
3209
+ totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
3210
+ score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
3211
+ rank: z12.null(),
3212
+ isQualified: z12.literal(false),
2360
3213
  finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
2361
3214
  1,
2362
3215
  `${valueLabel}.finalScoreBoost must be <= 1`
@@ -2368,7 +3221,7 @@ var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") =
2368
3221
  ),
2369
3222
  awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
2370
3223
  });
2371
- var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => z8.object({
3224
+ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => z12.object({
2372
3225
  grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
2373
3226
  grandTotalIncrementalDuration: makeDurationSchema(
2374
3227
  `${valueLabel}.grandTotalIncrementalDuration`
@@ -2380,41 +3233,69 @@ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetri
2380
3233
  `${valueLabel}.minFinalScoreToQualify`
2381
3234
  )
2382
3235
  });
2383
- var makeReferrerLeaderboardPaginationContextSchema = (valueLabel = "ReferrerLeaderboardPaginationContext") => z8.object({
3236
+ var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => z12.object({
2384
3237
  page: makePositiveIntegerSchema(`${valueLabel}.page`),
2385
- itemsPerPage: makePositiveIntegerSchema(`${valueLabel}.itemsPerPage`).max(
3238
+ recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
2386
3239
  REFERRERS_PER_LEADERBOARD_PAGE_MAX,
2387
- `${valueLabel}.itemsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
3240
+ `${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
2388
3241
  ),
2389
3242
  totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
2390
3243
  totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
2391
- hasNext: z8.boolean(),
2392
- hasPrev: z8.boolean(),
2393
- startIndex: z8.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
2394
- endIndex: z8.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
3244
+ hasNext: z12.boolean(),
3245
+ hasPrev: z12.boolean(),
3246
+ startIndex: z12.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
3247
+ endIndex: z12.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
2395
3248
  });
2396
- var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => z8.object({
3249
+ var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => z12.object({
2397
3250
  rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
2398
- referrers: z8.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[item]`)),
3251
+ referrers: z12.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[record]`)),
2399
3252
  aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
2400
- paginationContext: makeReferrerLeaderboardPaginationContextSchema(
2401
- `${valueLabel}.paginationContext`
2402
- ),
3253
+ pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
2403
3254
  accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2404
3255
  });
2405
- var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => z8.object({
2406
- responseCode: z8.literal(ReferrerLeaderboardPageResponseCodes.Ok),
3256
+ var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => z12.object({
3257
+ responseCode: z12.literal(ReferrerLeaderboardPageResponseCodes.Ok),
2407
3258
  data: makeReferrerLeaderboardPageSchema(`${valueLabel}.data`)
2408
3259
  });
2409
- var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => z8.object({
2410
- responseCode: z8.literal(ReferrerLeaderboardPageResponseCodes.Error),
2411
- error: z8.string(),
2412
- errorMessage: z8.string()
3260
+ var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => z12.object({
3261
+ responseCode: z12.literal(ReferrerLeaderboardPageResponseCodes.Error),
3262
+ error: z12.string(),
3263
+ errorMessage: z12.string()
2413
3264
  });
2414
- var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => z8.union([
3265
+ var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => z12.union([
2415
3266
  makeReferrerLeaderboardPageResponseOkSchema(valueLabel),
2416
3267
  makeReferrerLeaderboardPageResponseErrorSchema(valueLabel)
2417
3268
  ]);
3269
+ var makeReferrerDetailRankedSchema = (valueLabel = "ReferrerDetailRanked") => z12.object({
3270
+ type: z12.literal(ReferrerDetailTypeIds.Ranked),
3271
+ rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
3272
+ referrer: makeAwardedReferrerMetricsSchema(`${valueLabel}.referrer`),
3273
+ aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
3274
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
3275
+ });
3276
+ var makeReferrerDetailUnrankedSchema = (valueLabel = "ReferrerDetailUnranked") => z12.object({
3277
+ type: z12.literal(ReferrerDetailTypeIds.Unranked),
3278
+ rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
3279
+ referrer: makeUnrankedReferrerMetricsSchema(`${valueLabel}.referrer`),
3280
+ aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
3281
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
3282
+ });
3283
+ var makeReferrerDetailResponseOkSchema = (valueLabel = "ReferrerDetailResponse") => z12.object({
3284
+ responseCode: z12.literal(ReferrerDetailResponseCodes.Ok),
3285
+ data: z12.union([
3286
+ makeReferrerDetailRankedSchema(`${valueLabel}.data`),
3287
+ makeReferrerDetailUnrankedSchema(`${valueLabel}.data`)
3288
+ ])
3289
+ });
3290
+ var makeReferrerDetailResponseErrorSchema = (_valueLabel = "ReferrerDetailResponse") => z12.object({
3291
+ responseCode: z12.literal(ReferrerDetailResponseCodes.Error),
3292
+ error: z12.string(),
3293
+ errorMessage: z12.string()
3294
+ });
3295
+ var makeReferrerDetailResponseSchema = (valueLabel = "ReferrerDetailResponse") => z12.union([
3296
+ makeReferrerDetailResponseOkSchema(valueLabel),
3297
+ makeReferrerDetailResponseErrorSchema(valueLabel)
3298
+ ]);
2418
3299
 
2419
3300
  // src/ensanalytics/deserialize.ts
2420
3301
  function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
@@ -2423,12 +3304,22 @@ function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
2423
3304
  if (parsed.error) {
2424
3305
  throw new Error(
2425
3306
  `Cannot deserialize SerializedReferrerLeaderboardPageResponse:
2426
- ${prettifyError5(parsed.error)}
3307
+ ${prettifyError10(parsed.error)}
2427
3308
  `
2428
3309
  );
2429
3310
  }
2430
3311
  return parsed.data;
2431
3312
  }
3313
+ function deserializeReferrerDetailResponse(maybeResponse, valueLabel) {
3314
+ const schema = makeReferrerDetailResponseSchema(valueLabel);
3315
+ const parsed = schema.safeParse(maybeResponse);
3316
+ if (parsed.error) {
3317
+ throw new Error(`Cannot deserialize ReferrerDetailResponse:
3318
+ ${prettifyError10(parsed.error)}
3319
+ `);
3320
+ }
3321
+ return parsed.data;
3322
+ }
2432
3323
 
2433
3324
  // src/ensanalytics/serialize.ts
2434
3325
  function serializeReferrerLeaderboardPageResponse(response) {
@@ -2439,55 +3330,15 @@ function serializeReferrerLeaderboardPageResponse(response) {
2439
3330
  return response;
2440
3331
  }
2441
3332
  }
2442
-
2443
- // src/ensapi/config/deserialize.ts
2444
- import { prettifyError as prettifyError6, ZodError } from "zod/v4";
2445
-
2446
- // src/ensapi/config/zod-schemas.ts
2447
- import { z as z9 } from "zod/v4";
2448
- var TheGraphCannotFallbackReasonSchema = z9.enum({
2449
- NotSubgraphCompatible: "not-subgraph-compatible",
2450
- NoApiKey: "no-api-key",
2451
- NoSubgraphUrl: "no-subgraph-url"
2452
- });
2453
- var TheGraphFallbackSchema = z9.strictObject({
2454
- canFallback: z9.boolean(),
2455
- reason: TheGraphCannotFallbackReasonSchema.nullable()
2456
- });
2457
- function makeENSApiPublicConfigSchema(valueLabel) {
2458
- const label = valueLabel ?? "ENSApiPublicConfig";
2459
- return z9.strictObject({
2460
- version: z9.string().min(1, `${label}.version must be a non-empty string`),
2461
- theGraphFallback: TheGraphFallbackSchema,
2462
- ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
2463
- });
2464
- }
2465
-
2466
- // src/ensapi/config/deserialize.ts
2467
- function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
2468
- const schema = makeENSApiPublicConfigSchema(valueLabel);
2469
- try {
2470
- return schema.parse(maybeConfig);
2471
- } catch (error) {
2472
- if (error instanceof ZodError) {
2473
- throw new Error(`Cannot deserialize ENSApiPublicConfig:
2474
- ${prettifyError6(error)}
2475
- `);
2476
- }
2477
- throw error;
3333
+ function serializeReferrerDetailResponse(response) {
3334
+ switch (response.responseCode) {
3335
+ case ReferrerDetailResponseCodes.Ok:
3336
+ return response;
3337
+ case ReferrerDetailResponseCodes.Error:
3338
+ return response;
2478
3339
  }
2479
3340
  }
2480
3341
 
2481
- // src/ensapi/config/serialize.ts
2482
- function serializeENSApiPublicConfig(config) {
2483
- const { version, theGraphFallback, ensIndexerPublicConfig } = config;
2484
- return {
2485
- version,
2486
- theGraphFallback,
2487
- ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
2488
- };
2489
- }
2490
-
2491
3342
  // src/client.ts
2492
3343
  var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
2493
3344
  var ENSNodeClient = class _ENSNodeClient {
@@ -2691,7 +3542,7 @@ var ENSNodeClient = class _ENSNodeClient {
2691
3542
  const errorResponse = deserializeErrorResponse(responseData);
2692
3543
  throw new Error(`Fetching ENSNode Config Failed: ${errorResponse.message}`);
2693
3544
  }
2694
- return deserializeENSApiPublicConfig(responseData);
3545
+ return deserializeConfigResponse(responseData);
2695
3546
  }
2696
3547
  /**
2697
3548
  * Fetch ENSNode Indexing Status
@@ -2732,7 +3583,7 @@ var ENSNodeClient = class _ENSNodeClient {
2732
3583
  *
2733
3584
  * @param request - Pagination parameters
2734
3585
  * @param request.page - The page number to retrieve (1-indexed, default: 1)
2735
- * @param request.itemsPerPage - Number of items per page (default: 25, max: 100)
3586
+ * @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
2736
3587
  * @returns {ReferrerLeaderboardPageResponse}
2737
3588
  *
2738
3589
  * @throws if the ENSNode request fails
@@ -2741,34 +3592,34 @@ var ENSNodeClient = class _ENSNodeClient {
2741
3592
  *
2742
3593
  * @example
2743
3594
  * ```typescript
2744
- * // Get first page with default page size (25 items)
2745
- * const response = await client.getReferrerLeaderboard();
3595
+ * // Get first page with default page size (25 records)
3596
+ * const response = await client.getReferrerLeaderboardPage();
2746
3597
  * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
2747
3598
  * const {
2748
3599
  * aggregatedMetrics,
2749
3600
  * referrers,
2750
3601
  * rules,
2751
- * paginationContext,
3602
+ * pageContext,
2752
3603
  * updatedAt
2753
3604
  * } = response.data;
2754
3605
  * console.log(aggregatedMetrics);
2755
3606
  * console.log(referrers);
2756
3607
  * console.log(rules);
2757
3608
  * console.log(updatedAt);
2758
- * console.log(`Page ${paginationContext.page} of ${paginationContext.totalPages}`);
3609
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
2759
3610
  * }
2760
3611
  * ```
2761
3612
  *
2762
3613
  * @example
2763
3614
  * ```typescript
2764
- * // Get second page with 50 items per page
2765
- * const response = await client.getReferrerLeaderboard({ page: 2, itemsPerPage: 50 });
3615
+ * // Get second page with 50 records per page
3616
+ * const response = await client.getReferrerLeaderboardPage({ page: 2, recordsPerPage: 50 });
2766
3617
  * ```
2767
3618
  *
2768
3619
  * @example
2769
3620
  * ```typescript
2770
3621
  * // Handle error response, ie. when Referrer Leaderboard is not currently available.
2771
- * const response = await client.getReferrerLeaderboard();
3622
+ * const response = await client.getReferrerLeaderboardPage();
2772
3623
  *
2773
3624
  * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Error) {
2774
3625
  * console.error(response.error);
@@ -2776,11 +3627,11 @@ var ENSNodeClient = class _ENSNodeClient {
2776
3627
  * }
2777
3628
  * ```
2778
3629
  */
2779
- async getReferrerLeaderboard(request) {
3630
+ async getReferrerLeaderboardPage(request) {
2780
3631
  const url = new URL(`/ensanalytics/referrers`, this.options.url);
2781
3632
  if (request?.page) url.searchParams.set("page", request.page.toString());
2782
- if (request?.itemsPerPage)
2783
- url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
3633
+ if (request?.recordsPerPage)
3634
+ url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
2784
3635
  const response = await fetch(url);
2785
3636
  let responseData;
2786
3637
  try {
@@ -2792,14 +3643,106 @@ var ENSNodeClient = class _ENSNodeClient {
2792
3643
  responseData
2793
3644
  );
2794
3645
  }
3646
+ /**
3647
+ * Fetch Referrer Detail
3648
+ *
3649
+ * Retrieves detailed information about a specific referrer, whether they are on the
3650
+ * leaderboard or not.
3651
+ *
3652
+ * The response data is a discriminated union type with a `type` field:
3653
+ *
3654
+ * **For referrers on the leaderboard** (`ReferrerDetailRanked`):
3655
+ * - `type`: {@link ReferrerDetailTypeIds.Ranked}
3656
+ * - `referrer`: The `AwardedReferrerMetrics` from @namehash/ens-referrals
3657
+ * - `rules`: The referral program rules
3658
+ * - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
3659
+ * - `accurateAsOf`: Unix timestamp indicating when the data was last updated
3660
+ *
3661
+ * **For referrers NOT on the leaderboard** (`ReferrerDetailUnranked`):
3662
+ * - `type`: {@link ReferrerDetailTypeIds.Unranked}
3663
+ * - `referrer`: The `UnrankedReferrerMetrics` from @namehash/ens-referrals
3664
+ * - `rules`: The referral program rules
3665
+ * - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
3666
+ * - `accurateAsOf`: Unix timestamp indicating when the data was last updated
3667
+ *
3668
+ * @see {@link https://www.npmjs.com/package/@namehash/ens-referrals|@namehash/ens-referrals} for calculation details
3669
+ *
3670
+ * @param request The referrer address to query
3671
+ * @returns {ReferrerDetailResponse} Returns the referrer detail response
3672
+ *
3673
+ * @throws if the ENSNode request fails
3674
+ * @throws if the response data is malformed
3675
+ *
3676
+ * @example
3677
+ * ```typescript
3678
+ * // Get referrer detail for a specific address
3679
+ * const response = await client.getReferrerDetail({
3680
+ * referrer: "0x1234567890123456789012345678901234567890"
3681
+ * });
3682
+ * if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
3683
+ * const { type, referrer, rules, aggregatedMetrics, accurateAsOf } = response.data;
3684
+ * console.log(type); // ReferrerDetailTypeIds.Ranked or ReferrerDetailTypeIds.Unranked
3685
+ * console.log(referrer);
3686
+ * console.log(accurateAsOf);
3687
+ * }
3688
+ * ```
3689
+ *
3690
+ * @example
3691
+ * ```typescript
3692
+ * // Use discriminated union to check if referrer is ranked
3693
+ * const response = await client.getReferrerDetail({
3694
+ * referrer: "0x1234567890123456789012345678901234567890"
3695
+ * });
3696
+ * if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
3697
+ * if (response.data.type === ReferrerDetailTypeIds.Ranked) {
3698
+ * // TypeScript knows this is ReferrerDetailRanked
3699
+ * console.log(`Rank: ${response.data.referrer.rank}`);
3700
+ * console.log(`Qualified: ${response.data.referrer.isQualified}`);
3701
+ * console.log(`Award Pool Share: ${response.data.referrer.awardPoolShare * 100}%`);
3702
+ * } else {
3703
+ * // TypeScript knows this is ReferrerDetailUnranked
3704
+ * console.log("Referrer is not on the leaderboard (no referrals yet)");
3705
+ * }
3706
+ * }
3707
+ * ```
3708
+ *
3709
+ * @example
3710
+ * ```typescript
3711
+ * // Handle error response, ie. when Referrer Detail is not currently available.
3712
+ * const response = await client.getReferrerDetail({
3713
+ * referrer: "0x1234567890123456789012345678901234567890"
3714
+ * });
3715
+ *
3716
+ * if (response.responseCode === ReferrerDetailResponseCodes.Error) {
3717
+ * console.error(response.error);
3718
+ * console.error(response.errorMessage);
3719
+ * }
3720
+ * ```
3721
+ */
3722
+ async getReferrerDetail(request) {
3723
+ const url = new URL(
3724
+ `/api/ensanalytics/referrers/${encodeURIComponent(request.referrer)}`,
3725
+ this.options.url
3726
+ );
3727
+ const response = await fetch(url);
3728
+ let responseData;
3729
+ try {
3730
+ responseData = await response.json();
3731
+ } catch {
3732
+ throw new Error("Malformed response data: invalid JSON");
3733
+ }
3734
+ return deserializeReferrerDetailResponse(responseData);
3735
+ }
2795
3736
  /**
2796
3737
  * Fetch ENSNode Registrar Actions
2797
3738
  *
2798
- * @param {RegistrarActionsRequestFilter} request.filter is
2799
- * an optional request filter configuration.
2800
- * @param {number} request.limit sets the maximum count of results in the response.
2801
- * @param {RegistrarActionsRequestOrder} request.order sets the order of
2802
- * results in the response by field and direction.
3739
+ * Retrieves a paginated list of registrar actions with optional filters.
3740
+ *
3741
+ * @param request is a request configuration.
3742
+ * @param request.page sets the page number to retrieve (1-indexed, default: 1)
3743
+ * @param request.recordsPerPage sets the number of records per page (default: 10, max: 100)
3744
+ * @param request.filters is an optional request filter configuration.
3745
+ * @param request.order sets the order of results in the response by field and direction.
2803
3746
  * @returns {RegistrarActionsResponse}
2804
3747
  *
2805
3748
  * @throws if the ENSNode request fails
@@ -2809,23 +3752,25 @@ var ENSNodeClient = class _ENSNodeClient {
2809
3752
  * @example
2810
3753
  * ```ts
2811
3754
  * import {
2812
- * registrarActionsFilter,,
3755
+ * registrarActionsFilter,
2813
3756
  * ENSNodeClient,
2814
3757
  * } from "@ensnode/ensnode-sdk";
2815
3758
  * import { namehash } from "viem/ens";
2816
3759
  *
2817
3760
  * const client: ENSNodeClient;
2818
3761
  *
2819
- * // get latest registrar action records across all indexed subregistries
2820
- * // NOTE: when no `limit` value is passed,
2821
- * // the default RESPONSE_ITEMS_PER_PAGE_DEFAULT applies.
2822
- * const registrarActions = await client.registrarActions();
3762
+ * // Get first page with default page size (10 records)
3763
+ * const response = await client.registrarActions();
3764
+ * if (response.responseCode === RegistrarActionsResponseCodes.Ok) {
3765
+ * const { registrarActions, pageContext } = response;
3766
+ * console.log(registrarActions);
3767
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
3768
+ * }
2823
3769
  *
2824
- * // get latest 5 registrar action records across all indexed subregistries
2825
- * // NOTE: when a `limit` value is passed, it must be lower than or equal to
2826
- * // the RESPONSE_ITEMS_PER_PAGE_MAX value.
2827
- * const registrarActions = await client.registrarActions({
2828
- * limit: 5,
3770
+ * // Get second page with 25 records per page
3771
+ * const response = await client.registrarActions({
3772
+ * page: 2,
3773
+ * recordsPerPage: 25,
2829
3774
  * });
2830
3775
  *
2831
3776
  * // get latest registrar action records associated with
@@ -2839,11 +3784,16 @@ var ENSNodeClient = class _ENSNodeClient {
2839
3784
  * filters: [registrarActionsFilter.withReferral(true)],
2840
3785
  * });
2841
3786
  *
3787
+ * // get latest registrar action records for a specific decoded referrer
3788
+ * await client.registrarActions({
3789
+ * filters: [registrarActionsFilter.byDecodedReferrer("0x1234567890123456789012345678901234567890")],
3790
+ * });
3791
+ *
2842
3792
  * // get latest 10 registrar action records associated with
2843
3793
  * // subregistry managing `base.eth` name
2844
3794
  * await client.registrarActions({
2845
3795
  * filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
2846
- * limit: 10
3796
+ * recordsPerPage: 10
2847
3797
  * });
2848
3798
  * ```
2849
3799
  */
@@ -2860,6 +3810,12 @@ var ENSNodeClient = class _ENSNodeClient {
2860
3810
  );
2861
3811
  return withReferralFilter ? { key: "withReferral", value: "true" } : null;
2862
3812
  };
3813
+ const buildDecodedReferrerArg = (filters) => {
3814
+ const decodedReferrerFilter = filters?.find(
3815
+ (f) => f.filterType === RegistrarActionsFilterTypes.ByDecodedReferrer
3816
+ );
3817
+ return decodedReferrerFilter ? { key: "decodedReferrer", value: decodedReferrerFilter.value } : null;
3818
+ };
2863
3819
  const buildOrderArg = (order) => {
2864
3820
  switch (order) {
2865
3821
  case RegistrarActionsOrders.LatestRegistrarActions: {
@@ -2876,13 +3832,20 @@ var ENSNodeClient = class _ENSNodeClient {
2876
3832
  const orderArgs = buildOrderArg(request.order);
2877
3833
  url.searchParams.set(orderArgs.key, orderArgs.value);
2878
3834
  }
2879
- if (request.itemsPerPage) {
2880
- url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
3835
+ if (request.page) {
3836
+ url.searchParams.set("page", request.page.toString());
3837
+ }
3838
+ if (request.recordsPerPage) {
3839
+ url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
2881
3840
  }
2882
3841
  const referralArg = buildWithReferralArg(request.filters);
2883
3842
  if (referralArg) {
2884
3843
  url.searchParams.set(referralArg.key, referralArg.value);
2885
3844
  }
3845
+ const decodedReferrerArg = buildDecodedReferrerArg(request.filters);
3846
+ if (decodedReferrerArg) {
3847
+ url.searchParams.set(decodedReferrerArg.key, decodedReferrerArg.value);
3848
+ }
2886
3849
  const response = await fetch(url);
2887
3850
  let responseData;
2888
3851
  try {
@@ -2903,10 +3866,66 @@ var ENSNodeClient = class _ENSNodeClient {
2903
3866
  }
2904
3867
  return deserializeRegistrarActionsResponse(responseData);
2905
3868
  }
3869
+ /**
3870
+ * Fetch Name Tokens for requested name.
3871
+ *
3872
+ * @param request.name - Name for which Name Tokens will be fetched.
3873
+ * @returns {NameTokensResponse}
3874
+ *
3875
+ * @throws if the ENSNode request fails
3876
+ * @throws if the ENSNode API returns an error response
3877
+ * @throws if the ENSNode response breaks required invariants
3878
+ *
3879
+ * @example
3880
+ * ```ts
3881
+ * import {
3882
+ * ENSNodeClient,
3883
+ * } from "@ensnode/ensnode-sdk";
3884
+ * import { namehash } from "viem/ens";
3885
+ *
3886
+ * const client: ENSNodeClient;
3887
+ *
3888
+ * // get latest name token records from the indexed subregistry based on the requested name
3889
+ * const response = await client.nameTokens({
3890
+ * name: "vitalik.eth"
3891
+ * });
3892
+ *
3893
+ * const response = await client.nameTokens({
3894
+ * domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
3895
+ * })
3896
+ * ```
3897
+ */
3898
+ async nameTokens(request) {
3899
+ const url = new URL(`/api/name-tokens`, this.options.url);
3900
+ if (request.name !== void 0) {
3901
+ url.searchParams.set("name", request.name);
3902
+ } else {
3903
+ url.searchParams.set("domainId", request.domainId);
3904
+ }
3905
+ const response = await fetch(url);
3906
+ let responseData;
3907
+ try {
3908
+ responseData = await response.json();
3909
+ } catch {
3910
+ throw new Error("Malformed response data: invalid JSON");
3911
+ }
3912
+ if (!response.ok) {
3913
+ let errorResponse;
3914
+ try {
3915
+ errorResponse = deserializeErrorResponse(responseData);
3916
+ } catch {
3917
+ console.log("Name Tokens API: handling a known server error.");
3918
+ }
3919
+ if (typeof errorResponse !== "undefined") {
3920
+ throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
3921
+ }
3922
+ }
3923
+ return deserializedNameTokensResponse(responseData);
3924
+ }
2906
3925
  };
2907
3926
 
2908
3927
  // src/identity/identity.ts
2909
- import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
3928
+ import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
2910
3929
 
2911
3930
  // src/identity/types.ts
2912
3931
  var ResolutionStatusIds = {
@@ -2933,7 +3952,7 @@ var ResolutionStatusIds = {
2933
3952
  function buildUnresolvedIdentity(address, namespaceId, chainId) {
2934
3953
  return {
2935
3954
  resolutionStatus: ResolutionStatusIds.Unresolved,
2936
- chainId: chainId ?? getENSRootChainId3(namespaceId),
3955
+ chainId: chainId ?? getENSRootChainId2(namespaceId),
2937
3956
  address
2938
3957
  };
2939
3958
  }
@@ -2942,14 +3961,14 @@ function isResolvedIdentity(identity) {
2942
3961
  }
2943
3962
 
2944
3963
  // src/resolution/ensip19-chainid.ts
2945
- import { mainnet as mainnet2 } from "viem/chains";
2946
- import { getENSRootChainId as getENSRootChainId4 } from "@ensnode/datasources";
3964
+ import { mainnet } from "viem/chains";
3965
+ import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
2947
3966
  var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
2948
- const ensRootChainId = getENSRootChainId4(namespaceId);
2949
- return chainId === ensRootChainId ? mainnet2.id : chainId;
3967
+ const ensRootChainId = getENSRootChainId3(namespaceId);
3968
+ return chainId === ensRootChainId ? mainnet.id : chainId;
2950
3969
  };
2951
3970
  var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
2952
- return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId4(namespaceId) : chainId;
3971
+ return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId3(namespaceId) : chainId;
2953
3972
  };
2954
3973
 
2955
3974
  // src/resolution/resolver-records-selection.ts
@@ -2989,6 +4008,7 @@ export {
2989
4008
  ATTR_PROTOCOL_NAME,
2990
4009
  ATTR_PROTOCOL_STEP,
2991
4010
  ATTR_PROTOCOL_STEP_RESULT,
4011
+ AssetNamespaces,
2992
4012
  BASENAMES_NODE,
2993
4013
  ChainIndexingConfigTypeIds,
2994
4014
  ChainIndexingStatusIds,
@@ -2999,16 +4019,25 @@ export {
2999
4019
  DEFAULT_EVM_COIN_TYPE,
3000
4020
  ENSNamespaceIds,
3001
4021
  ENSNodeClient,
4022
+ ENS_ROOT,
3002
4023
  ETH_COIN_TYPE,
3003
4024
  ETH_NODE,
3004
4025
  ForwardResolutionProtocolStep,
3005
4026
  IndexingStatusResponseCodes,
3006
4027
  LINEANAMES_NODE,
3007
4028
  LruCache,
4029
+ NFTMintStatuses,
4030
+ NFTTransferTypes,
4031
+ NameTokenOwnershipTypes,
4032
+ NameTokensResponseCodes,
4033
+ NameTokensResponseErrorCodes,
3008
4034
  OmnichainIndexingStatusIds,
3009
4035
  PROTOCOL_ATTRIBUTE_PREFIX,
3010
4036
  PluginName,
4037
+ RECORDS_PER_PAGE_DEFAULT,
4038
+ RECORDS_PER_PAGE_MAX,
3011
4039
  ROOT_NODE,
4040
+ ReferrerDetailResponseCodes,
3012
4041
  ReferrerLeaderboardPageResponseCodes,
3013
4042
  RegistrarActionTypes,
3014
4043
  RegistrarActionsFilterTypes,
@@ -3030,9 +4059,11 @@ export {
3030
4059
  beautifyName,
3031
4060
  bigIntToNumber,
3032
4061
  bigintToCoinType,
4062
+ buildAssetId,
3033
4063
  buildEnsRainbowClientLabelSet,
3034
4064
  buildLabelSetId,
3035
4065
  buildLabelSetVersion,
4066
+ buildPageContext,
3036
4067
  buildUnresolvedIdentity,
3037
4068
  checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
3038
4069
  checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
@@ -3045,12 +4076,13 @@ export {
3045
4076
  decodeDNSEncodedLiteralName,
3046
4077
  decodeDNSEncodedName,
3047
4078
  decodeEncodedReferrer,
3048
- deserializeAccountId,
4079
+ deserializeAssetId,
3049
4080
  deserializeBlockNumber,
3050
4081
  deserializeBlockRef,
3051
4082
  deserializeBlockrange,
3052
4083
  deserializeChainId,
3053
4084
  deserializeChainIndexingStatusSnapshot,
4085
+ deserializeConfigResponse,
3054
4086
  deserializeCrossChainIndexingStatusSnapshot,
3055
4087
  deserializeDatetime,
3056
4088
  deserializeDuration,
@@ -3060,20 +4092,35 @@ export {
3060
4092
  deserializeIndexingStatusResponse,
3061
4093
  deserializeOmnichainIndexingStatusSnapshot,
3062
4094
  deserializeRealtimeIndexingStatusProjection,
4095
+ deserializeReferrerDetailResponse,
3063
4096
  deserializeReferrerLeaderboardPageResponse,
3064
4097
  deserializeRegistrarActionsResponse,
3065
4098
  deserializeUnixTimestamp,
3066
4099
  deserializeUrl,
4100
+ deserializedNameTokensResponse,
3067
4101
  durationBetween,
3068
4102
  encodeLabelHash,
3069
4103
  evmChainIdToCoinType,
4104
+ formatAccountId,
4105
+ formatAssetId,
4106
+ formatNFTTransferEventMetadata,
4107
+ getBasenamesSubregistryId,
4108
+ getBasenamesSubregistryManagedName,
3070
4109
  getCurrencyInfo,
4110
+ getDatasourceContract,
3071
4111
  getENSRootChainId,
3072
4112
  getEthnamesSubregistryId,
4113
+ getEthnamesSubregistryManagedName,
3073
4114
  getLatestIndexedBlockRef,
4115
+ getLineanamesSubregistryId,
4116
+ getLineanamesSubregistryManagedName,
4117
+ getNFTTransferType,
3074
4118
  getNameHierarchy,
4119
+ getNameTokenOwnership,
4120
+ getNameWrapperAccounts,
3075
4121
  getOmnichainIndexingCursor,
3076
4122
  getOmnichainIndexingStatus,
4123
+ getParentNameFQDN,
3077
4124
  getResolvePrimaryNameChainIdParam,
3078
4125
  getTimestampForHighestOmnichainKnownBlock,
3079
4126
  getTimestampForLowestOmnichainStartBlock,
@@ -3099,6 +4146,10 @@ export {
3099
4146
  literalLabelsToLiteralName,
3100
4147
  makeENSApiPublicConfigSchema,
3101
4148
  makeSubdomainNode,
4149
+ maybeGetDatasourceContract,
4150
+ nameTokensPrerequisites,
4151
+ parseAccountId,
4152
+ parseAssetId,
3102
4153
  parseNonNegativeInteger,
3103
4154
  parseReverseName,
3104
4155
  priceDai,
@@ -3107,26 +4158,30 @@ export {
3107
4158
  registrarActionsFilter,
3108
4159
  registrarActionsPrerequisites,
3109
4160
  reverseName,
3110
- serializeAccountId,
4161
+ serializeAssetId,
3111
4162
  serializeChainId,
3112
4163
  serializeChainIndexingSnapshots,
4164
+ serializeConfigResponse,
3113
4165
  serializeCrossChainIndexingStatusSnapshotOmnichain,
3114
4166
  serializeDatetime,
4167
+ serializeDomainAssetId,
3115
4168
  serializeENSApiPublicConfig,
3116
4169
  serializeENSIndexerPublicConfig,
3117
4170
  serializeIndexedChainIds,
3118
4171
  serializeIndexingStatusResponse,
4172
+ serializeNameToken,
4173
+ serializeNameTokensResponse,
3119
4174
  serializeNamedRegistrarAction,
3120
4175
  serializeOmnichainIndexingStatusSnapshot,
3121
4176
  serializePrice,
3122
4177
  serializePriceEth,
3123
4178
  serializeRealtimeIndexingStatusProjection,
4179
+ serializeReferrerDetailResponse,
3124
4180
  serializeReferrerLeaderboardPageResponse,
4181
+ serializeRegisteredNameTokens,
3125
4182
  serializeRegistrarAction,
3126
4183
  serializeRegistrarActionPricing,
3127
4184
  serializeRegistrarActionsResponse,
3128
- serializeRegistrationLifecycle,
3129
- serializeSubregistry,
3130
4185
  serializeUrl,
3131
4186
  sortChainStatusesByStartBlockAsc,
3132
4187
  stripNullBytes,