@ensnode/ensnode-sdk 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -45,6 +45,7 @@ __export(index_exports, {
45
45
  DEFAULT_EVM_COIN_TYPE: () => DEFAULT_EVM_COIN_TYPE,
46
46
  ENSNamespaceIds: () => import_datasources.ENSNamespaceIds,
47
47
  ENSNodeClient: () => ENSNodeClient,
48
+ ENS_ROOT: () => ENS_ROOT,
48
49
  ETH_COIN_TYPE: () => ETH_COIN_TYPE,
49
50
  ETH_NODE: () => ETH_NODE,
50
51
  ForwardResolutionProtocolStep: () => ForwardResolutionProtocolStep,
@@ -53,6 +54,9 @@ __export(index_exports, {
53
54
  LruCache: () => LruCache,
54
55
  NFTMintStatuses: () => NFTMintStatuses,
55
56
  NFTTransferTypes: () => NFTTransferTypes,
57
+ NameTokenOwnershipTypes: () => NameTokenOwnershipTypes,
58
+ NameTokensResponseCodes: () => NameTokensResponseCodes,
59
+ NameTokensResponseErrorCodes: () => NameTokensResponseErrorCodes,
56
60
  OmnichainIndexingStatusIds: () => OmnichainIndexingStatusIds,
57
61
  PROTOCOL_ATTRIBUTE_PREFIX: () => PROTOCOL_ATTRIBUTE_PREFIX,
58
62
  PluginName: () => PluginName,
@@ -85,6 +89,7 @@ __export(index_exports, {
85
89
  buildEnsRainbowClientLabelSet: () => buildEnsRainbowClientLabelSet,
86
90
  buildLabelSetId: () => buildLabelSetId,
87
91
  buildLabelSetVersion: () => buildLabelSetVersion,
92
+ buildPageContext: () => buildPageContext,
88
93
  buildUnresolvedIdentity: () => buildUnresolvedIdentity,
89
94
  checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
90
95
  checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
@@ -97,7 +102,7 @@ __export(index_exports, {
97
102
  decodeDNSEncodedLiteralName: () => decodeDNSEncodedLiteralName,
98
103
  decodeDNSEncodedName: () => decodeDNSEncodedName,
99
104
  decodeEncodedReferrer: () => decodeEncodedReferrer,
100
- deserializeAccountId: () => deserializeAccountId,
105
+ deserializeAssetId: () => deserializeAssetId,
101
106
  deserializeBlockNumber: () => deserializeBlockNumber,
102
107
  deserializeBlockRef: () => deserializeBlockRef,
103
108
  deserializeBlockrange: () => deserializeBlockrange,
@@ -118,18 +123,30 @@ __export(index_exports, {
118
123
  deserializeRegistrarActionsResponse: () => deserializeRegistrarActionsResponse,
119
124
  deserializeUnixTimestamp: () => deserializeUnixTimestamp,
120
125
  deserializeUrl: () => deserializeUrl,
126
+ deserializedNameTokensResponse: () => deserializedNameTokensResponse,
121
127
  durationBetween: () => durationBetween,
122
128
  encodeLabelHash: () => encodeLabelHash,
123
129
  evmChainIdToCoinType: () => evmChainIdToCoinType,
130
+ formatAccountId: () => formatAccountId,
131
+ formatAssetId: () => formatAssetId,
124
132
  formatNFTTransferEventMetadata: () => formatNFTTransferEventMetadata,
133
+ getBasenamesSubregistryId: () => getBasenamesSubregistryId,
134
+ getBasenamesSubregistryManagedName: () => getBasenamesSubregistryManagedName,
125
135
  getCurrencyInfo: () => getCurrencyInfo,
136
+ getDatasourceContract: () => getDatasourceContract,
126
137
  getENSRootChainId: () => import_datasources2.getENSRootChainId,
127
138
  getEthnamesSubregistryId: () => getEthnamesSubregistryId,
139
+ getEthnamesSubregistryManagedName: () => getEthnamesSubregistryManagedName,
128
140
  getLatestIndexedBlockRef: () => getLatestIndexedBlockRef,
141
+ getLineanamesSubregistryId: () => getLineanamesSubregistryId,
142
+ getLineanamesSubregistryManagedName: () => getLineanamesSubregistryManagedName,
129
143
  getNFTTransferType: () => getNFTTransferType,
130
144
  getNameHierarchy: () => getNameHierarchy,
145
+ getNameTokenOwnership: () => getNameTokenOwnership,
146
+ getNameWrapperAccounts: () => getNameWrapperAccounts,
131
147
  getOmnichainIndexingCursor: () => getOmnichainIndexingCursor,
132
148
  getOmnichainIndexingStatus: () => getOmnichainIndexingStatus,
149
+ getParentNameFQDN: () => getParentNameFQDN,
133
150
  getResolvePrimaryNameChainIdParam: () => getResolvePrimaryNameChainIdParam,
134
151
  getTimestampForHighestOmnichainKnownBlock: () => getTimestampForHighestOmnichainKnownBlock,
135
152
  getTimestampForLowestOmnichainStartBlock: () => getTimestampForLowestOmnichainStartBlock,
@@ -155,6 +172,10 @@ __export(index_exports, {
155
172
  literalLabelsToLiteralName: () => literalLabelsToLiteralName,
156
173
  makeENSApiPublicConfigSchema: () => makeENSApiPublicConfigSchema,
157
174
  makeSubdomainNode: () => makeSubdomainNode,
175
+ maybeGetDatasourceContract: () => maybeGetDatasourceContract,
176
+ nameTokensPrerequisites: () => nameTokensPrerequisites,
177
+ parseAccountId: () => parseAccountId,
178
+ parseAssetId: () => parseAssetId,
158
179
  parseNonNegativeInteger: () => parseNonNegativeInteger,
159
180
  parseReverseName: () => parseReverseName,
160
181
  priceDai: () => priceDai,
@@ -163,17 +184,19 @@ __export(index_exports, {
163
184
  registrarActionsFilter: () => registrarActionsFilter,
164
185
  registrarActionsPrerequisites: () => registrarActionsPrerequisites,
165
186
  reverseName: () => reverseName,
166
- serializeAccountId: () => serializeAccountId,
167
187
  serializeAssetId: () => serializeAssetId,
168
188
  serializeChainId: () => serializeChainId,
169
189
  serializeChainIndexingSnapshots: () => serializeChainIndexingSnapshots,
170
190
  serializeConfigResponse: () => serializeConfigResponse,
171
191
  serializeCrossChainIndexingStatusSnapshotOmnichain: () => serializeCrossChainIndexingStatusSnapshotOmnichain,
172
192
  serializeDatetime: () => serializeDatetime,
193
+ serializeDomainAssetId: () => serializeDomainAssetId,
173
194
  serializeENSApiPublicConfig: () => serializeENSApiPublicConfig,
174
195
  serializeENSIndexerPublicConfig: () => serializeENSIndexerPublicConfig,
175
196
  serializeIndexedChainIds: () => serializeIndexedChainIds,
176
197
  serializeIndexingStatusResponse: () => serializeIndexingStatusResponse,
198
+ serializeNameToken: () => serializeNameToken,
199
+ serializeNameTokensResponse: () => serializeNameTokensResponse,
177
200
  serializeNamedRegistrarAction: () => serializeNamedRegistrarAction,
178
201
  serializeOmnichainIndexingStatusSnapshot: () => serializeOmnichainIndexingStatusSnapshot,
179
202
  serializePrice: () => serializePrice,
@@ -181,11 +204,10 @@ __export(index_exports, {
181
204
  serializeRealtimeIndexingStatusProjection: () => serializeRealtimeIndexingStatusProjection,
182
205
  serializeReferrerDetailResponse: () => serializeReferrerDetailResponse,
183
206
  serializeReferrerLeaderboardPageResponse: () => serializeReferrerLeaderboardPageResponse,
207
+ serializeRegisteredNameTokens: () => serializeRegisteredNameTokens,
184
208
  serializeRegistrarAction: () => serializeRegistrarAction,
185
209
  serializeRegistrarActionPricing: () => serializeRegistrarActionPricing,
186
210
  serializeRegistrarActionsResponse: () => serializeRegistrarActionsResponse,
187
- serializeRegistrationLifecycle: () => serializeRegistrationLifecycle,
188
- serializeSubregistry: () => serializeSubregistry,
189
211
  serializeUrl: () => serializeUrl,
190
212
  sortChainStatusesByStartBlockAsc: () => sortChainStatusesByStartBlockAsc,
191
213
  stripNullBytes: () => stripNullBytes,
@@ -205,25 +227,6 @@ var import_v44 = require("zod/v4");
205
227
  // src/ensindexer/config/zod-schemas.ts
206
228
  var import_v43 = __toESM(require("zod/v4"), 1);
207
229
 
208
- // src/ens/is-normalized.ts
209
- var import_ens = require("viem/ens");
210
- function isNormalizedName(name) {
211
- try {
212
- return name === (0, import_ens.normalize)(name);
213
- } catch {
214
- return false;
215
- }
216
- }
217
- function isNormalizedLabel(label) {
218
- if (label === "") return false;
219
- if (label.includes(".")) return false;
220
- try {
221
- return label === (0, import_ens.normalize)(label);
222
- } catch {
223
- return false;
224
- }
225
- }
226
-
227
230
  // src/shared/account-id.ts
228
231
  var import_viem = require("viem");
229
232
  var accountIdEqual = (a, b) => {
@@ -374,9 +377,39 @@ function isEncodedLabelHash(maybeEncodedLabelHash) {
374
377
  return expectedFormatting && includesLabelHash;
375
378
  }
376
379
 
380
+ // src/ens/is-normalized.ts
381
+ var import_ens = require("viem/ens");
382
+ function isNormalizedName(name) {
383
+ try {
384
+ return name === (0, import_ens.normalize)(name);
385
+ } catch {
386
+ return false;
387
+ }
388
+ }
389
+ function isNormalizedLabel(label) {
390
+ if (label === "") return false;
391
+ if (label.includes(".")) return false;
392
+ try {
393
+ return label === (0, import_ens.normalize)(label);
394
+ } catch {
395
+ return false;
396
+ }
397
+ }
398
+
377
399
  // src/ens/names.ts
378
400
  var import_ens_normalize = require("@adraffy/ens-normalize");
401
+ var ENS_ROOT = "";
379
402
  var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
403
+ var getParentNameFQDN = (name) => {
404
+ if (name === ENS_ROOT) {
405
+ throw new Error("There is no parent name for ENS Root.");
406
+ }
407
+ const labels = name.split(".");
408
+ if (labels.length === 1) {
409
+ return ENS_ROOT;
410
+ }
411
+ return labels.slice(1).join(".");
412
+ };
380
413
  var beautifyName = (name) => {
381
414
  const beautifiedLabels = name.split(".").map((label) => {
382
415
  if (isNormalizedLabel(label)) {
@@ -619,7 +652,7 @@ var makeAccountIdSchema = (valueLabel = "AccountId") => import_v4.default.strict
619
652
  chainId: makeChainIdSchema(`${valueLabel} chain ID`),
620
653
  address: makeLowercaseAddressSchema(`${valueLabel} address`)
621
654
  });
622
- var makeSerializedAccountIdSchema = (valueLabel = "Account ID") => import_v4.default.coerce.string().transform((v) => {
655
+ var makeAccountIdStringSchema = (valueLabel = "Account ID String") => import_v4.default.coerce.string().transform((v) => {
623
656
  const result = new import_caip.AccountId(v);
624
657
  return {
625
658
  chainId: Number(result.chainId.reference),
@@ -631,7 +664,7 @@ var makeHexStringSchema = (options, valueLabel = "String representation of bytes
631
664
  ctx.issues.push({
632
665
  code: "custom",
633
666
  input: ctx.value,
634
- message: `${valueLabel} must start with '0x'.`
667
+ message: `${valueLabel} must be a hexadecimal value which starts with '0x'.`
635
668
  });
636
669
  }
637
670
  }).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
@@ -741,8 +774,8 @@ ${(0, import_v42.prettifyError)(parsed.error)}
741
774
  }
742
775
  return parsed.data;
743
776
  }
744
- function deserializeAccountId(maybeAccountId, valueLabel) {
745
- const schema = makeSerializedAccountIdSchema(valueLabel);
777
+ function parseAccountId(maybeAccountId, valueLabel) {
778
+ const schema = makeAccountIdStringSchema(valueLabel);
746
779
  const parsed = schema.safeParse(maybeAccountId);
747
780
  if (parsed.error) {
748
781
  throw new RangeError(`Cannot deserialize AccountId:
@@ -760,181 +793,65 @@ function addDuration(timestamp, duration) {
760
793
  return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
761
794
  }
762
795
 
763
- // src/shared/cache/background-revalidation-scheduler.ts
764
- var BackgroundRevalidationScheduler = class {
765
- activeSchedules = /* @__PURE__ */ new Map();
766
- /**
767
- * Schedule a revalidation function to run on a recurring interval.
768
- *
769
- * @param config Configuration object for the schedule
770
- * @returns The revalidate function that can be passed to `cancel()` to stop the schedule
771
- */
772
- schedule(config) {
773
- const { revalidate, interval, initialDelay = 0, onError } = config;
774
- if (this.activeSchedules.has(revalidate)) {
775
- return revalidate;
796
+ // src/shared/cache/swr-cache.ts
797
+ var SWRCache = class {
798
+ constructor(options) {
799
+ this.options = options;
800
+ if (options.proactiveRevalidationInterval) {
801
+ this.backgroundInterval = setInterval(
802
+ () => this.revalidate(),
803
+ (0, import_date_fns.secondsToMilliseconds)(options.proactiveRevalidationInterval)
804
+ );
776
805
  }
777
- const metadata = {
778
- config,
779
- timeoutId: null,
780
- inProgress: false
781
- };
782
- this.activeSchedules.set(revalidate, metadata);
783
- const executeRevalidation = async () => {
784
- if (metadata.inProgress) return;
785
- metadata.inProgress = true;
786
- try {
787
- await revalidate();
788
- } catch (error) {
789
- onError?.(error);
790
- } finally {
791
- metadata.inProgress = false;
792
- }
793
- };
794
- const scheduleNext = () => {
795
- if (!this.activeSchedules.has(revalidate)) return;
796
- metadata.timeoutId = setTimeout(() => {
797
- if (this.activeSchedules.has(revalidate)) {
798
- executeRevalidation().then(() => scheduleNext());
799
- }
800
- }, interval);
801
- };
802
- if (initialDelay > 0) {
803
- metadata.timeoutId = setTimeout(() => {
804
- if (this.activeSchedules.has(revalidate)) {
805
- executeRevalidation().then(() => scheduleNext());
806
+ if (options.proactivelyInitialize) this.revalidate();
807
+ }
808
+ cache = null;
809
+ inProgressRevalidate = null;
810
+ backgroundInterval = null;
811
+ async revalidate() {
812
+ if (!this.inProgressRevalidate) {
813
+ this.inProgressRevalidate = this.options.fn().then((result) => {
814
+ this.cache = {
815
+ result,
816
+ updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
817
+ };
818
+ }).catch((error) => {
819
+ if (!this.cache) {
820
+ this.cache = {
821
+ // ensure thrown value is always an Error instance
822
+ result: error instanceof Error ? error : new Error(String(error)),
823
+ updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
824
+ };
806
825
  }
807
- }, initialDelay);
808
- } else {
809
- scheduleNext();
826
+ }).finally(() => {
827
+ this.inProgressRevalidate = null;
828
+ });
810
829
  }
811
- return revalidate;
830
+ return this.inProgressRevalidate;
812
831
  }
813
832
  /**
814
- * Cancel a scheduled revalidation by its revalidate function.
833
+ * Read the most recently cached result from the `SWRCache`.
815
834
  *
816
- * @param revalidate The revalidation function returned from `schedule()`
817
- */
818
- cancel(revalidate) {
819
- const metadata = this.activeSchedules.get(revalidate);
820
- if (!metadata) return;
821
- if (metadata.timeoutId !== null) {
822
- clearTimeout(metadata.timeoutId);
823
- }
824
- this.activeSchedules.delete(revalidate);
825
- }
826
- /**
827
- * Cancel all active schedules.
835
+ * @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
836
+ * has never successfully returned.
828
837
  */
829
- cancelAll() {
830
- for (const [, metadata] of this.activeSchedules) {
831
- if (metadata.timeoutId !== null) {
832
- clearTimeout(metadata.timeoutId);
833
- }
838
+ async read() {
839
+ if (!this.cache) await this.revalidate();
840
+ if (!this.cache) throw new Error("never");
841
+ if (durationBetween(this.cache.updatedAt, (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())) > this.options.ttl) {
842
+ this.revalidate();
834
843
  }
835
- this.activeSchedules.clear();
844
+ return this.cache.result;
836
845
  }
837
846
  /**
838
- * Get the count of active schedules.
839
- * Useful for debugging and monitoring.
840
- *
841
- * @returns The number of currently active schedules
842
- */
843
- getActiveScheduleCount() {
844
- return this.activeSchedules.size;
845
- }
846
- };
847
-
848
- // src/shared/cache/swr-cache.ts
849
- var bgRevalidationScheduler = new BackgroundRevalidationScheduler();
850
- var SWRCache = class _SWRCache {
851
- options;
852
- cache;
853
- /**
854
- * Optional promise of the current in-progress attempt to revalidate the `cache`.
855
- *
856
- * If null, no revalidation attempt is currently in progress.
857
- * If not null, identifies the revalidation attempt that is currently in progress.
858
- *
859
- * Used to enforce no concurrent revalidation attempts.
860
- */
861
- inProgressRevalidate;
862
- /**
863
- * The callback function being managed by `BackgroundRevalidationScheduler`.
864
- *
865
- * If null, no background revalidation is scheduled.
866
- * If not null, identifies the background revalidation that is currently scheduled.
867
- *
868
- * Used to enforce no concurrent background revalidation attempts.
869
- */
870
- scheduledBackgroundRevalidate;
871
- constructor(options) {
872
- this.cache = null;
873
- this.inProgressRevalidate = null;
874
- this.scheduledBackgroundRevalidate = null;
875
- this.options = options;
876
- }
877
- /**
878
- * Asynchronously create a new `SWRCache` instance.
879
- *
880
- * @param options - The {@link SWRCacheOptions} for the SWR cache.
881
- * @returns a new `SWRCache` instance.
847
+ * Destroys the background revalidation interval, if exists.
882
848
  */
883
- static async create(options) {
884
- const cache = new _SWRCache(options);
885
- if (cache.options.proactivelyInitialize) {
886
- cache.readCache();
849
+ destroy() {
850
+ if (this.backgroundInterval) {
851
+ clearInterval(this.backgroundInterval);
852
+ this.backgroundInterval = null;
887
853
  }
888
- return cache;
889
854
  }
890
- revalidate = async () => {
891
- if (this.inProgressRevalidate) {
892
- return this.inProgressRevalidate;
893
- }
894
- return this.options.fn().then((value) => {
895
- this.cache = {
896
- value,
897
- updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
898
- };
899
- return this.cache;
900
- }).catch(() => {
901
- return null;
902
- }).finally(() => {
903
- this.inProgressRevalidate = null;
904
- if (this.options.revalidationInterval === void 0) {
905
- return;
906
- }
907
- if (this.scheduledBackgroundRevalidate) {
908
- bgRevalidationScheduler.cancel(this.scheduledBackgroundRevalidate);
909
- }
910
- const backgroundRevalidate = async () => {
911
- this.revalidate();
912
- };
913
- this.scheduledBackgroundRevalidate = bgRevalidationScheduler.schedule({
914
- revalidate: backgroundRevalidate,
915
- interval: (0, import_date_fns.secondsToMilliseconds)(this.options.revalidationInterval)
916
- });
917
- });
918
- };
919
- /**
920
- * Read the most recently cached `CachedValue` from the `SWRCache`.
921
- *
922
- * @returns a `CachedValue` holding a `value` of `ValueType` that was most recently successfully returned by `fn`
923
- * or `null` if `fn` has never successfully returned and has always thrown an error,
924
- */
925
- readCache = async () => {
926
- if (!this.cache) {
927
- this.inProgressRevalidate = this.revalidate();
928
- return this.inProgressRevalidate;
929
- }
930
- if (durationBetween(this.cache.updatedAt, (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())) <= this.options.ttl) {
931
- return this.cache;
932
- }
933
- if (!this.inProgressRevalidate) {
934
- this.inProgressRevalidate = this.revalidate();
935
- }
936
- return this.cache;
937
- };
938
855
  };
939
856
 
940
857
  // src/shared/cache/ttl-cache.ts
@@ -1005,6 +922,28 @@ var TtlCache = class {
1005
922
  // src/shared/collections.ts
1006
923
  var uniq = (arr) => [...new Set(arr)];
1007
924
 
925
+ // src/shared/datasource-contract.ts
926
+ var import_datasources3 = require("@ensnode/datasources");
927
+ var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
928
+ const datasource = (0, import_datasources3.maybeGetDatasource)(namespaceId, datasourceName);
929
+ if (!datasource) return void 0;
930
+ const address = datasource.contracts[contractName]?.address;
931
+ if (address === void 0 || Array.isArray(address)) return void 0;
932
+ return {
933
+ chainId: datasource.chain.id,
934
+ address
935
+ };
936
+ };
937
+ var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
938
+ const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
939
+ if (!contract) {
940
+ throw new Error(
941
+ `Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
942
+ );
943
+ }
944
+ return contract;
945
+ };
946
+
1008
947
  // src/shared/labelhash.ts
1009
948
  var import_viem9 = require("viem");
1010
949
  var labelhashLiteralLabel = (label) => (0, import_viem9.keccak256)((0, import_viem9.stringToBytes)(label));
@@ -1063,7 +1002,7 @@ function serializePrice(price) {
1063
1002
  function serializePriceEth(price) {
1064
1003
  return serializePrice(price);
1065
1004
  }
1066
- function serializeAccountId(accountId) {
1005
+ function formatAccountId(accountId) {
1067
1006
  return import_caip2.AccountId.format({
1068
1007
  chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
1069
1008
  address: accountId.address
@@ -1079,7 +1018,7 @@ function isWebSocketProtocol(url) {
1079
1018
  }
1080
1019
 
1081
1020
  // src/ensindexer/config/is-subgraph-compatible.ts
1082
- var import_datasources3 = require("@ensnode/datasources");
1021
+ var import_datasources4 = require("@ensnode/datasources");
1083
1022
 
1084
1023
  // src/ensindexer/config/types.ts
1085
1024
  var PluginName = /* @__PURE__ */ ((PluginName2) => {
@@ -1098,7 +1037,7 @@ function isSubgraphCompatible(config) {
1098
1037
  const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
1099
1038
  const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
1100
1039
  const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
1101
- const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === import_datasources3.ENSNamespaceIds.EnsTestEnv && isEnsTestEnvLabelSet;
1040
+ const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === import_datasources4.ENSNamespaceIds.EnsTestEnv && isEnsTestEnvLabelSet;
1102
1041
  return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
1103
1042
  }
1104
1043
 
@@ -2036,164 +1975,760 @@ function serializeConfigResponse(response) {
2036
1975
  }
2037
1976
 
2038
1977
  // src/api/indexing-status/deserialize.ts
2039
- var import_v416 = require("zod/v4");
1978
+ var import_v410 = require("zod/v4");
2040
1979
 
2041
1980
  // src/api/indexing-status/zod-schemas.ts
2042
- var import_v415 = __toESM(require("zod/v4"), 1);
2043
-
2044
- // src/api/registrar-actions/zod-schemas.ts
2045
- var import_ens5 = require("viem/ens");
2046
- var import_v410 = __toESM(require("zod/v4"), 1);
2047
-
2048
- // src/api/shared/errors/zod-schemas.ts
2049
1981
  var import_v49 = __toESM(require("zod/v4"), 1);
2050
- var ErrorResponseSchema = import_v49.default.object({
2051
- message: import_v49.default.string(),
2052
- details: import_v49.default.optional(import_v49.default.unknown())
2053
- });
2054
1982
 
2055
- // src/api/registrar-actions/response.ts
2056
- var RegistrarActionsResponseCodes = {
1983
+ // src/api/indexing-status/response.ts
1984
+ var IndexingStatusResponseCodes = {
2057
1985
  /**
2058
- * Represents that Registrar Actions are available.
1986
+ * Represents that the indexing status is available.
2059
1987
  */
2060
1988
  Ok: "ok",
2061
1989
  /**
2062
- * Represents that Registrar Actions are unavailable.
1990
+ * Represents that the indexing status is unavailable.
2063
1991
  */
2064
1992
  Error: "error"
2065
1993
  };
2066
1994
 
2067
- // src/api/registrar-actions/zod-schemas.ts
2068
- function invariant_registrationLifecycleNodeMatchesName(ctx) {
2069
- const { name, action } = ctx.value;
2070
- const expectedNode = action.registrationLifecycle.node;
2071
- const actualNode = (0, import_ens5.namehash)(name);
2072
- if (actualNode !== expectedNode) {
2073
- ctx.issues.push({
2074
- code: "custom",
2075
- input: ctx.value,
2076
- message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
2077
- });
2078
- }
2079
- }
2080
- var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => import_v410.default.object({
2081
- action: makeRegistrarActionSchema(valueLabel),
2082
- name: makeReinterpretedNameSchema(valueLabel)
2083
- }).check(invariant_registrationLifecycleNodeMatchesName);
2084
- var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => import_v410.default.strictObject({
2085
- responseCode: import_v410.default.literal(RegistrarActionsResponseCodes.Ok),
2086
- registrarActions: import_v410.default.array(makeNamedRegistrarActionSchema(valueLabel))
1995
+ // src/api/indexing-status/zod-schemas.ts
1996
+ var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => import_v49.default.strictObject({
1997
+ responseCode: import_v49.default.literal(IndexingStatusResponseCodes.Ok),
1998
+ realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
2087
1999
  });
2088
- var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => import_v410.default.strictObject({
2089
- responseCode: import_v410.default.literal(RegistrarActionsResponseCodes.Error),
2090
- error: ErrorResponseSchema
2000
+ var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => import_v49.default.strictObject({
2001
+ responseCode: import_v49.default.literal(IndexingStatusResponseCodes.Error)
2091
2002
  });
2092
- var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => import_v410.default.discriminatedUnion("responseCode", [
2093
- makeRegistrarActionsResponseOkSchema(valueLabel),
2094
- makeRegistrarActionsResponseErrorSchema(valueLabel)
2003
+ var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => import_v49.default.discriminatedUnion("responseCode", [
2004
+ makeIndexingStatusResponseOkSchema(valueLabel),
2005
+ makeIndexingStatusResponseErrorSchema(valueLabel)
2095
2006
  ]);
2096
2007
 
2097
- // src/api/shared/pagination/zod-schemas.ts
2098
- var import_v411 = __toESM(require("zod/v4"), 1);
2099
-
2100
- // src/api/shared/pagination/request.ts
2101
- var RECORDS_PER_PAGE_DEFAULT = 10;
2102
- var RECORDS_PER_PAGE_MAX = 100;
2103
-
2104
- // ../ens-referrals/src/address.ts
2105
- var import_viem11 = require("viem");
2106
-
2107
- // ../ens-referrals/src/encoding.ts
2108
- var import_viem12 = require("viem");
2109
- var ENCODED_REFERRER_BYTE_OFFSET = 12;
2110
- var ENCODED_REFERRER_BYTE_LENGTH = 32;
2111
- var EXPECTED_ENCODED_REFERRER_PADDING = (0, import_viem12.pad)("0x", {
2112
- size: ENCODED_REFERRER_BYTE_OFFSET,
2113
- dir: "left"
2114
- });
2115
- var ZERO_ENCODED_REFERRER = (0, import_viem12.pad)("0x", {
2116
- size: ENCODED_REFERRER_BYTE_LENGTH,
2117
- dir: "left"
2118
- });
2119
- function decodeEncodedReferrer(encodedReferrer) {
2120
- if ((0, import_viem12.size)(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
2121
- throw new Error(
2122
- `Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
2123
- );
2124
- }
2125
- const padding = (0, import_viem12.slice)(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
2126
- if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
2127
- return import_viem12.zeroAddress;
2008
+ // src/api/indexing-status/deserialize.ts
2009
+ function deserializeIndexingStatusResponse(maybeResponse) {
2010
+ const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
2011
+ if (parsed.error) {
2012
+ throw new Error(`Cannot deserialize IndexingStatusResponse:
2013
+ ${(0, import_v410.prettifyError)(parsed.error)}
2014
+ `);
2128
2015
  }
2129
- const decodedReferrer = (0, import_viem12.slice)(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
2130
- try {
2131
- return (0, import_viem12.getAddress)(decodedReferrer);
2132
- } catch {
2133
- throw new Error(`Decoded referrer value must be a valid EVM address.`);
2016
+ return parsed.data;
2017
+ }
2018
+
2019
+ // src/api/indexing-status/serialize.ts
2020
+ function serializeIndexingStatusResponse(response) {
2021
+ switch (response.responseCode) {
2022
+ case IndexingStatusResponseCodes.Ok:
2023
+ return {
2024
+ responseCode: response.responseCode,
2025
+ realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
2026
+ };
2027
+ case IndexingStatusResponseCodes.Error:
2028
+ return response;
2134
2029
  }
2135
2030
  }
2136
2031
 
2137
- // ../ens-referrals/src/leaderboard-page.ts
2138
- var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
2032
+ // src/api/name-tokens/deserialize.ts
2033
+ var import_v415 = require("zod/v4");
2139
2034
 
2140
- // ../ens-referrals/src/link.ts
2035
+ // src/api/name-tokens/zod-schemas.ts
2036
+ var import_viem14 = require("viem");
2037
+ var import_v414 = __toESM(require("zod/v4"), 1);
2038
+
2039
+ // src/tokenscope/assets.ts
2040
+ var import_caip4 = require("caip");
2141
2041
  var import_viem13 = require("viem");
2042
+ var import_v412 = require("zod/v4");
2142
2043
 
2143
- // ../ens-referrals/src/referrer-detail.ts
2144
- var ReferrerDetailTypeIds = {
2044
+ // src/tokenscope/zod-schemas.ts
2045
+ var import_caip3 = require("caip");
2046
+ var import_viem12 = require("viem");
2047
+ var import_v411 = __toESM(require("zod/v4"), 1);
2048
+
2049
+ // src/tokenscope/name-token.ts
2050
+ var import_viem11 = require("viem");
2051
+ var import_datasources5 = require("@ensnode/datasources");
2052
+ var NameTokenOwnershipTypes = {
2145
2053
  /**
2146
- * Represents a referrer who is ranked on the leaderboard.
2054
+ * Name Token is owned by NameWrapper account.
2147
2055
  */
2148
- Ranked: "ranked",
2056
+ NameWrapper: "namewrapper",
2149
2057
  /**
2150
- * Represents a referrer who is not ranked on the leaderboard.
2058
+ * Name Token is owned fully onchain.
2059
+ *
2060
+ * This ownership type can only apply to direct subnames of `.eth`
2151
2061
  */
2152
- Unranked: "unranked"
2062
+ FullyOnchain: "fully-onchain",
2063
+ /**
2064
+ * Name Token ownership has been transferred to the null address.
2065
+ */
2066
+ Burned: "burned",
2067
+ /**
2068
+ * Name Token ownership is unknown.
2069
+ */
2070
+ Unknown: "unknown"
2153
2071
  };
2154
-
2155
- // src/registrars/zod-schemas.ts
2156
- var import_v412 = __toESM(require("zod/v4"), 1);
2157
-
2158
- // src/registrars/subregistry.ts
2159
- function serializeSubregistry(subregistry) {
2072
+ function serializeNameToken(nameToken) {
2160
2073
  return {
2161
- subregistryId: serializeAccountId(subregistry.subregistryId),
2162
- node: subregistry.node
2074
+ token: serializeAssetId(nameToken.token),
2075
+ ownership: nameToken.ownership,
2076
+ mintStatus: nameToken.mintStatus
2163
2077
  };
2164
2078
  }
2165
-
2166
- // src/registrars/registration-lifecycle.ts
2167
- function serializeRegistrationLifecycle(registrationLifecycle) {
2079
+ function getNameWrapperAccounts(namespaceId) {
2080
+ const ethnamesNameWrapperAccount = getDatasourceContract(
2081
+ namespaceId,
2082
+ import_datasources5.DatasourceNames.ENSRoot,
2083
+ "NameWrapper"
2084
+ );
2085
+ const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
2086
+ namespaceId,
2087
+ import_datasources5.DatasourceNames.Lineanames,
2088
+ "NameWrapper"
2089
+ );
2090
+ const nameWrapperAccounts = [
2091
+ // NameWrapper for direct subnames of .eth is defined for all ENS namespaces
2092
+ ethnamesNameWrapperAccount
2093
+ ];
2094
+ if (lineanamesNameWrapperAccount) {
2095
+ nameWrapperAccounts.push(lineanamesNameWrapperAccount);
2096
+ }
2097
+ return nameWrapperAccounts;
2098
+ }
2099
+ function getNameTokenOwnership(namespaceId, name, owner) {
2100
+ const nameWrapperAccounts = getNameWrapperAccounts(namespaceId);
2101
+ const hasNameWrapperOwnership = nameWrapperAccounts.some(
2102
+ (nameWrapperAccount) => accountIdEqual(owner, nameWrapperAccount)
2103
+ );
2104
+ if (hasNameWrapperOwnership) {
2105
+ return {
2106
+ ownershipType: NameTokenOwnershipTypes.NameWrapper,
2107
+ owner
2108
+ };
2109
+ }
2110
+ if ((0, import_viem11.isAddressEqual)(owner.address, import_viem11.zeroAddress)) {
2111
+ return {
2112
+ ownershipType: NameTokenOwnershipTypes.Burned,
2113
+ owner
2114
+ };
2115
+ }
2116
+ const parentName = getParentNameFQDN(name);
2117
+ if (parentName === "eth") {
2118
+ return {
2119
+ ownershipType: NameTokenOwnershipTypes.FullyOnchain,
2120
+ owner
2121
+ };
2122
+ }
2168
2123
  return {
2169
- subregistry: serializeSubregistry(registrationLifecycle.subregistry),
2170
- node: registrationLifecycle.node,
2171
- expiresAt: registrationLifecycle.expiresAt
2124
+ ownershipType: NameTokenOwnershipTypes.Unknown,
2125
+ owner
2172
2126
  };
2173
2127
  }
2174
2128
 
2175
- // src/registrars/registrar-action.ts
2176
- var RegistrarActionTypes = {
2177
- Registration: "registration",
2178
- Renewal: "renewal"
2179
- };
2180
- function isRegistrarActionPricingAvailable(registrarActionPricing) {
2181
- const { baseCost, premium, total } = registrarActionPricing;
2182
- return baseCost !== null && premium !== null && total !== null;
2183
- }
2184
- function isRegistrarActionReferralAvailable(registrarActionReferral) {
2185
- const { encodedReferrer, decodedReferrer } = registrarActionReferral;
2186
- return encodedReferrer !== null && decodedReferrer !== null;
2187
- }
2188
- function serializeRegistrarActionPricing(pricing) {
2189
- if (isRegistrarActionPricingAvailable(pricing)) {
2129
+ // src/tokenscope/zod-schemas.ts
2130
+ var makeAssetIdSchema = (valueLabel = "Asset ID Schema") => import_v411.default.object({
2131
+ assetNamespace: import_v411.default.enum(AssetNamespaces),
2132
+ contract: makeAccountIdSchema(valueLabel),
2133
+ tokenId: import_v411.default.preprocess((v) => typeof v === "string" ? BigInt(v) : v, import_v411.default.bigint().positive())
2134
+ });
2135
+ var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => import_v411.default.preprocess((v) => {
2136
+ if (typeof v === "string") {
2137
+ const result = new import_caip3.AssetId(v);
2190
2138
  return {
2191
- baseCost: serializePriceEth(pricing.baseCost),
2192
- premium: serializePriceEth(pricing.premium),
2193
- total: serializePriceEth(pricing.total)
2139
+ assetNamespace: result.assetName.namespace,
2140
+ contract: {
2141
+ chainId: Number(result.chainId.reference),
2142
+ address: result.assetName.reference
2143
+ },
2144
+ tokenId: result.tokenId
2194
2145
  };
2195
2146
  }
2196
- return pricing;
2147
+ return v;
2148
+ }, makeAssetIdSchema(valueLabel));
2149
+ function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
2150
+ const ownership = ctx.value;
2151
+ if (ctx.value.owner.address === import_viem12.zeroAddress) {
2152
+ ctx.issues.push({
2153
+ code: "custom",
2154
+ input: ctx.value,
2155
+ message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' other than the zero address.`
2156
+ });
2157
+ }
2158
+ }
2159
+ var makeNameTokenOwnershipNameWrapperSchema = (valueLabel = "Name Token Ownership NameWrapper") => import_v411.default.object({
2160
+ ownershipType: import_v411.default.literal(NameTokenOwnershipTypes.NameWrapper),
2161
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2162
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2163
+ var makeNameTokenOwnershipFullyOnchainSchema = (valueLabel = "Name Token Ownership Fully Onchain") => import_v411.default.object({
2164
+ ownershipType: import_v411.default.literal(NameTokenOwnershipTypes.FullyOnchain),
2165
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2166
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2167
+ var makeNameTokenOwnershipBurnedSchema = (valueLabel = "Name Token Ownership Burned") => import_v411.default.object({
2168
+ ownershipType: import_v411.default.literal(NameTokenOwnershipTypes.Burned),
2169
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2170
+ }).check(invariant_nameTokenOwnershipHasZeroAddressOwner);
2171
+ var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Unknown") => import_v411.default.object({
2172
+ ownershipType: import_v411.default.literal(NameTokenOwnershipTypes.Unknown),
2173
+ owner: makeAccountIdSchema(`${valueLabel}.owner`)
2174
+ }).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
2175
+ function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
2176
+ const ownership = ctx.value;
2177
+ if (ctx.value.owner.address !== import_viem12.zeroAddress) {
2178
+ ctx.issues.push({
2179
+ code: "custom",
2180
+ input: ctx.value,
2181
+ message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' set to the zero address.`
2182
+ });
2183
+ }
2184
+ }
2185
+ var makeNameTokenOwnershipSchema = (valueLabel = "Name Token Ownership") => import_v411.default.discriminatedUnion("ownershipType", [
2186
+ makeNameTokenOwnershipNameWrapperSchema(valueLabel),
2187
+ makeNameTokenOwnershipFullyOnchainSchema(valueLabel),
2188
+ makeNameTokenOwnershipBurnedSchema(valueLabel),
2189
+ makeNameTokenOwnershipUnknownSchema(valueLabel)
2190
+ ]);
2191
+ var makeNameTokenSchema = (valueLabel = "Name Token Schema") => import_v411.default.object({
2192
+ token: makeAssetIdSchema(`${valueLabel}.token`),
2193
+ ownership: makeNameTokenOwnershipSchema(`${valueLabel}.ownership`),
2194
+ mintStatus: import_v411.default.enum(NFTMintStatuses)
2195
+ });
2196
+
2197
+ // src/tokenscope/assets.ts
2198
+ var AssetNamespaces = {
2199
+ ERC721: "erc721",
2200
+ ERC1155: "erc1155"
2201
+ };
2202
+ function serializeAssetId(assetId) {
2203
+ return {
2204
+ assetNamespace: assetId.assetNamespace,
2205
+ contract: assetId.contract,
2206
+ tokenId: uint256ToHex32(assetId.tokenId)
2207
+ };
2208
+ }
2209
+ function deserializeAssetId(maybeAssetId, valueLabel) {
2210
+ const schema = makeAssetIdSchema(valueLabel);
2211
+ const parsed = schema.safeParse(maybeAssetId);
2212
+ if (parsed.error) {
2213
+ throw new RangeError(`Cannot deserialize AssetId:
2214
+ ${(0, import_v412.prettifyError)(parsed.error)}
2215
+ `);
2216
+ }
2217
+ return parsed.data;
2218
+ }
2219
+ function formatAssetId(assetId) {
2220
+ const { assetNamespace, contract, tokenId } = serializeAssetId(assetId);
2221
+ return import_caip4.AssetId.format({
2222
+ chainId: { namespace: "eip155", reference: contract.chainId.toString() },
2223
+ assetName: { namespace: assetNamespace, reference: contract.address },
2224
+ tokenId
2225
+ }).toLowerCase();
2226
+ }
2227
+ function parseAssetId(maybeAssetId, valueLabel) {
2228
+ const schema = makeAssetIdStringSchema(valueLabel);
2229
+ const parsed = schema.safeParse(maybeAssetId);
2230
+ if (parsed.error) {
2231
+ throw new RangeError(`Cannot parse AssetId:
2232
+ ${(0, import_v412.prettifyError)(parsed.error)}
2233
+ `);
2234
+ }
2235
+ return parsed.data;
2236
+ }
2237
+ var buildAssetId = (contract, tokenId, assetNamespace) => {
2238
+ return {
2239
+ assetNamespace,
2240
+ contract,
2241
+ tokenId
2242
+ };
2243
+ };
2244
+ function serializeDomainAssetId(domainAsset) {
2245
+ return {
2246
+ ...serializeAssetId(domainAsset),
2247
+ domainId: domainAsset.domainId
2248
+ };
2249
+ }
2250
+ var NFTMintStatuses = {
2251
+ Minted: "minted",
2252
+ Burned: "burned"
2253
+ };
2254
+ var formatNFTTransferEventMetadata = (metadata) => {
2255
+ const serializedAssetId = serializeAssetId(metadata.nft);
2256
+ return [
2257
+ `Event: ${metadata.eventHandlerName}`,
2258
+ `Chain ID: ${metadata.chainId}`,
2259
+ `Block Number: ${metadata.blockNumber}`,
2260
+ `Transaction Hash: ${metadata.transactionHash}`,
2261
+ `NFT: ${serializedAssetId}`
2262
+ ].map((line) => ` - ${line}`).join("\n");
2263
+ };
2264
+ var NFTTransferTypes = {
2265
+ /**
2266
+ * Initial transfer from zeroAddress to a non-zeroAddress
2267
+ * Can happen at most once to a NFT AssetId
2268
+ *
2269
+ * Invariants:
2270
+ * - NFT is not indexed and therefore has no previous mint status or owner
2271
+ * - new NFT mint status is `minted`
2272
+ * - new NFT owner is a non-zeroAddress
2273
+ */
2274
+ Mint: "mint",
2275
+ /**
2276
+ * Subsequent transfer from zeroAddress to a non-zeroAddress
2277
+ * Can happen any number of times to a NFT AssetId as it passes in a cycle from
2278
+ * mint -> burn -> remint -> burn -> remint -> ...
2279
+ *
2280
+ * Invariants:
2281
+ * - NFT is indexed
2282
+ * - previous NFT mint status was `burned`
2283
+ * - previous NFT owner is the zeroAddress
2284
+ * - new NFT mint status is `minted`
2285
+ * - new NFT owner is a non-zeroAddress
2286
+ */
2287
+ Remint: "remint",
2288
+ /**
2289
+ * Special transfer type for improperly implemented NFT contracts that allow a NFT
2290
+ * that is currently minted to be reminted before an intermediate burn.
2291
+ *
2292
+ * Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
2293
+ * previously indexed nft had status `minted` with a non-zeroAddress owner.
2294
+ *
2295
+ * Invariants:
2296
+ * - NFT is indexed
2297
+ * - previous NFT mint status was `minted`
2298
+ * - previous NFT owner was a non-zeroAddress
2299
+ * - new NFT mint status is `minted`
2300
+ * - new NFT owner is a non-zeroAddress
2301
+ */
2302
+ MintedRemint: "minted-remint",
2303
+ /**
2304
+ * Transfer from a non-zeroAddress to zeroAddress
2305
+ *
2306
+ * Invariants:
2307
+ * - NFT is indexed
2308
+ * - previous NFT mint status was `minted`
2309
+ * - previous NFT owner is a non-zeroAddress
2310
+ * - new NFT mint status is `burned`
2311
+ * - new NFT owner is the zeroAddress
2312
+ */
2313
+ Burn: "burn",
2314
+ /**
2315
+ * Transfer from a non-zeroAddress to a distinct non-zeroAddress
2316
+ *
2317
+ * Invariants:
2318
+ * - NFT is indexed
2319
+ * - previous and new NFT mint status is `minted`
2320
+ * - previous and new NFT owner are distinct non-zeroAddress
2321
+ */
2322
+ Transfer: "transfer",
2323
+ /**
2324
+ * Transfer from a non-zeroAddress to the same non-zeroAddress
2325
+ *
2326
+ * Invariants:
2327
+ * - NFT is indexed
2328
+ * - previous and new NFT mint status is `minted`
2329
+ * - previous and new NFT owner are equivalent non-zeroAddress
2330
+ */
2331
+ SelfTransfer: "self-transfer",
2332
+ /**
2333
+ * Transfer from zeroAddress to zeroAddress for an indexed NFT
2334
+ *
2335
+ * Invariants:
2336
+ * - NFT is indexed
2337
+ * - previous and new NFT mint status is `burned`
2338
+ * - previous and new NFT owner are zeroAddress
2339
+ */
2340
+ RemintBurn: "remint-burn",
2341
+ /**
2342
+ * Special transfer type for improperly implemented NFT contracts that allow a NFT
2343
+ * that is currently minted to be reminted again before an intermediate burn.
2344
+ *
2345
+ * Transfer from zeroAddress to zeroAddress for an indexed NFT where the
2346
+ * previously indexed nft had status `minted` with a non-zeroAddress owner.
2347
+ *
2348
+ * Invariants:
2349
+ * - NFT is indexed
2350
+ * - previous NFT mint status was `minted`
2351
+ * - previous NFT owner was a non-zeroAddress
2352
+ * - new NFT mint status is `burned`
2353
+ * - new NFT owner is the zeroAddress
2354
+ */
2355
+ MintedRemintBurn: "minted-remint-burn",
2356
+ /**
2357
+ * Transfer from zeroAddress to zeroAddress for an unindexed NFT
2358
+ *
2359
+ * Invariants:
2360
+ * - NFT is not indexed and therefore has no previous mint status or owner
2361
+ * - NFT should remain unindexed and without any mint status or owner
2362
+ */
2363
+ MintBurn: "mint-burn"
2364
+ };
2365
+ var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
2366
+ const isIndexed = currentlyIndexedOwner !== void 0;
2367
+ const isIndexedAsMinted = isIndexed && !(0, import_viem13.isAddressEqual)(currentlyIndexedOwner, import_viem13.zeroAddress);
2368
+ const isMint = (0, import_viem13.isAddressEqual)(from, import_viem13.zeroAddress);
2369
+ const isBurn = (0, import_viem13.isAddressEqual)(to, import_viem13.zeroAddress);
2370
+ const isSelfTransfer = (0, import_viem13.isAddressEqual)(from, to);
2371
+ if (isIndexed && !(0, import_viem13.isAddressEqual)(currentlyIndexedOwner, from)) {
2372
+ if (isMint && allowMintedRemint) {
2373
+ } else {
2374
+ throw new Error(
2375
+ `Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
2376
+ ${formatNFTTransferEventMetadata(metadata)}`
2377
+ );
2378
+ }
2379
+ }
2380
+ if (isSelfTransfer) {
2381
+ if (isMint) {
2382
+ if (!isIndexed) {
2383
+ return NFTTransferTypes.MintBurn;
2384
+ } else if (!isIndexedAsMinted) {
2385
+ return NFTTransferTypes.RemintBurn;
2386
+ } else if (allowMintedRemint) {
2387
+ return NFTTransferTypes.MintedRemintBurn;
2388
+ } else {
2389
+ throw new Error(
2390
+ `Error: Invalid state transition from minted -> remint-burn
2391
+ ${formatNFTTransferEventMetadata(metadata)}`
2392
+ );
2393
+ }
2394
+ } else {
2395
+ if (!isIndexed) {
2396
+ throw new Error(
2397
+ `Error: Invalid state transition from unindexed -> self-transfer
2398
+ ${formatNFTTransferEventMetadata(metadata)}`
2399
+ );
2400
+ } else if (!isIndexedAsMinted) {
2401
+ throw new Error(
2402
+ `Error: invalid state transition from burned -> self-transfer
2403
+ ${formatNFTTransferEventMetadata(metadata)}`
2404
+ );
2405
+ } else {
2406
+ return NFTTransferTypes.SelfTransfer;
2407
+ }
2408
+ }
2409
+ } else if (isMint) {
2410
+ if (!isIndexed) {
2411
+ return NFTTransferTypes.Mint;
2412
+ } else if (!isIndexedAsMinted) {
2413
+ return NFTTransferTypes.Remint;
2414
+ } else if (allowMintedRemint) {
2415
+ return NFTTransferTypes.MintedRemint;
2416
+ } else {
2417
+ throw new Error(
2418
+ `Error: Invalid state transition from minted -> mint
2419
+ ${formatNFTTransferEventMetadata(metadata)}`
2420
+ );
2421
+ }
2422
+ } else if (isBurn) {
2423
+ if (!isIndexed) {
2424
+ throw new Error(
2425
+ `Error: Invalid state transition from unindexed -> burn
2426
+ ${formatNFTTransferEventMetadata(metadata)}`
2427
+ );
2428
+ } else if (!isIndexedAsMinted) {
2429
+ throw new Error(
2430
+ `Error: Invalid state transition from burned -> burn
2431
+ ${formatNFTTransferEventMetadata(metadata)}`
2432
+ );
2433
+ } else {
2434
+ return NFTTransferTypes.Burn;
2435
+ }
2436
+ } else {
2437
+ if (!isIndexed) {
2438
+ throw new Error(
2439
+ `Error: Invalid state transition from unindexed -> transfer
2440
+ ${formatNFTTransferEventMetadata(metadata)}`
2441
+ );
2442
+ } else if (!isIndexedAsMinted) {
2443
+ throw new Error(
2444
+ `Error: Invalid state transition from burned -> transfer
2445
+ ${formatNFTTransferEventMetadata(metadata)}`
2446
+ );
2447
+ } else {
2448
+ return NFTTransferTypes.Transfer;
2449
+ }
2450
+ }
2451
+ };
2452
+
2453
+ // src/api/shared/errors/zod-schemas.ts
2454
+ var import_v413 = __toESM(require("zod/v4"), 1);
2455
+ var ErrorResponseSchema = import_v413.default.object({
2456
+ message: import_v413.default.string(),
2457
+ details: import_v413.default.optional(import_v413.default.unknown())
2458
+ });
2459
+
2460
+ // src/api/name-tokens/response.ts
2461
+ var NameTokensResponseCodes = {
2462
+ /**
2463
+ * Represents a response when Name Tokens API can respond with requested data.
2464
+ */
2465
+ Ok: "ok",
2466
+ /**
2467
+ * Represents a response when Name Tokens API could not respond with requested data.
2468
+ */
2469
+ Error: "error"
2470
+ };
2471
+ var NameTokensResponseErrorCodes = {
2472
+ /**
2473
+ * Name tokens not indexed
2474
+ *
2475
+ * Represents an error when tokens for the requested name are not indexed by
2476
+ * the ENSNode instance's configuration.
2477
+ */
2478
+ NameTokensNotIndexed: "name-tokens-not-indexed",
2479
+ /**
2480
+ * Unsupported ENSIndexer Config
2481
+ *
2482
+ * Represents a prerequisites error when connected ENSIndexer config lacks
2483
+ * params required to enable Name Tokens API.
2484
+ */
2485
+ EnsIndexerConfigUnsupported: "unsupported-ensindexer-config",
2486
+ /**
2487
+ * Unsupported Indexing Status
2488
+ *
2489
+ * Represents a prerequisites error when Indexing Status has not yet reached
2490
+ * status required to enable Name Tokens API.
2491
+ */
2492
+ IndexingStatusUnsupported: "unsupported-indexing-status"
2493
+ };
2494
+
2495
+ // src/api/name-tokens/zod-schemas.ts
2496
+ function invariant_nameIsAssociatedWithDomainId(ctx) {
2497
+ const { name, domainId } = ctx.value;
2498
+ if ((0, import_viem14.namehash)(name) !== domainId) {
2499
+ ctx.issues.push({
2500
+ code: "custom",
2501
+ input: ctx.value,
2502
+ message: `'name' must be associated with 'domainId': ${domainId}`
2503
+ });
2504
+ }
2505
+ }
2506
+ function invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown(ctx) {
2507
+ const { tokens } = ctx.value;
2508
+ const containsOwnershipNameWrapper = tokens.some(
2509
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.NameWrapper
2510
+ );
2511
+ const containsOwnershipFullyOnchainOrUnknown = tokens.some(
2512
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain || t.ownership.ownershipType === NameTokenOwnershipTypes.Unknown
2513
+ );
2514
+ if (containsOwnershipNameWrapper && !containsOwnershipFullyOnchainOrUnknown) {
2515
+ ctx.issues.push({
2516
+ code: "custom",
2517
+ input: ctx.value,
2518
+ message: `'tokens' must contain name token with ownership type 'fully-onchain' or 'unknown' when name token with ownership type 'namewrapper' in listed`
2519
+ });
2520
+ }
2521
+ }
2522
+ function invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective(ctx) {
2523
+ const { tokens } = ctx.value;
2524
+ const tokensCountWithOwnershipFullyOnchain = tokens.filter(
2525
+ (t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain
2526
+ ).length;
2527
+ if (tokensCountWithOwnershipFullyOnchain > 1) {
2528
+ ctx.issues.push({
2529
+ code: "custom",
2530
+ input: ctx.value,
2531
+ message: `'tokens' must contain at most one name token with ownership type 'fully-onchain', current count: ${tokensCountWithOwnershipFullyOnchain}`
2532
+ });
2533
+ }
2534
+ }
2535
+ var makeRegisteredNameTokenSchema = (valueLabel = "Registered Name Token") => import_v414.default.object({
2536
+ domainId: makeNodeSchema(`${valueLabel}.domainId`),
2537
+ name: makeReinterpretedNameSchema(valueLabel),
2538
+ tokens: import_v414.default.array(makeNameTokenSchema(`${valueLabel}.tokens`)).nonempty(),
2539
+ expiresAt: makeUnixTimestampSchema(`${valueLabel}.expiresAt`),
2540
+ accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2541
+ }).check(invariant_nameIsAssociatedWithDomainId).check(invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective).check(invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown);
2542
+ var makeNameTokensResponseOkSchema = (valueLabel = "Name Tokens Response OK") => import_v414.default.strictObject({
2543
+ responseCode: import_v414.default.literal(NameTokensResponseCodes.Ok),
2544
+ registeredNameTokens: makeRegisteredNameTokenSchema(`${valueLabel}.nameTokens`)
2545
+ });
2546
+ var makeNameTokensResponseErrorNameTokensNotIndexedSchema = (_valueLabel = "Name Tokens Response Error Name Not Indexed") => import_v414.default.strictObject({
2547
+ responseCode: import_v414.default.literal(NameTokensResponseCodes.Error),
2548
+ errorCode: import_v414.default.literal(NameTokensResponseErrorCodes.NameTokensNotIndexed),
2549
+ error: ErrorResponseSchema
2550
+ });
2551
+ var makeNameTokensResponseErrorEnsIndexerConfigUnsupported = (_valueLabel = "Name Tokens Response Error ENSIndexer Config Unsupported") => import_v414.default.strictObject({
2552
+ responseCode: import_v414.default.literal(NameTokensResponseCodes.Error),
2553
+ errorCode: import_v414.default.literal(NameTokensResponseErrorCodes.EnsIndexerConfigUnsupported),
2554
+ error: ErrorResponseSchema
2555
+ });
2556
+ var makeNameTokensResponseErrorNameIndexingStatusUnsupported = (_valueLabel = "Name Tokens Response Error Indexing Status Unsupported") => import_v414.default.strictObject({
2557
+ responseCode: import_v414.default.literal(NameTokensResponseCodes.Error),
2558
+ errorCode: import_v414.default.literal(NameTokensResponseErrorCodes.IndexingStatusUnsupported),
2559
+ error: ErrorResponseSchema
2560
+ });
2561
+ var makeNameTokensResponseErrorSchema = (valueLabel = "Name Tokens Response Error") => import_v414.default.discriminatedUnion("errorCode", [
2562
+ makeNameTokensResponseErrorNameTokensNotIndexedSchema(valueLabel),
2563
+ makeNameTokensResponseErrorEnsIndexerConfigUnsupported(valueLabel),
2564
+ makeNameTokensResponseErrorNameIndexingStatusUnsupported(valueLabel)
2565
+ ]);
2566
+ var makeNameTokensResponseSchema = (valueLabel = "Name Tokens Response") => import_v414.default.discriminatedUnion("responseCode", [
2567
+ makeNameTokensResponseOkSchema(valueLabel),
2568
+ makeNameTokensResponseErrorSchema(valueLabel)
2569
+ ]);
2570
+
2571
+ // src/api/name-tokens/deserialize.ts
2572
+ function deserializedNameTokensResponse(maybeResponse) {
2573
+ const parsed = makeNameTokensResponseSchema().safeParse(maybeResponse);
2574
+ if (parsed.error) {
2575
+ throw new Error(`Cannot deserialize NameTokensResponse:
2576
+ ${(0, import_v415.prettifyError)(parsed.error)}
2577
+ `);
2578
+ }
2579
+ return parsed.data;
2580
+ }
2581
+
2582
+ // src/api/name-tokens/prerequisites.ts
2583
+ var nameTokensPrerequisites = Object.freeze({
2584
+ /**
2585
+ * Required plugins to enable Name Tokens API routes.
2586
+ *
2587
+ * 1. `registrars` plugin is required so that data in the `registrationLifecycles`
2588
+ * table is populated.
2589
+ * 2. `tokenscope` plugin is required so that data in the `nameTokens`
2590
+ * table is populated.
2591
+ */
2592
+ requiredPlugins: ["registrars" /* Registrars */, "tokenscope" /* TokenScope */],
2593
+ /**
2594
+ * Check if provided ENSApiPublicConfig supports the Name Tokens API.
2595
+ */
2596
+ hasEnsIndexerConfigSupport(config) {
2597
+ return nameTokensPrerequisites.requiredPlugins.every(
2598
+ (plugin) => config.plugins.includes(plugin)
2599
+ );
2600
+ },
2601
+ /**
2602
+ * Required Indexing Status IDs
2603
+ *
2604
+ * Database indexes are created by the time the omnichain indexing status
2605
+ * is either `completed` or `following`.
2606
+ */
2607
+ supportedIndexingStatusIds: [
2608
+ OmnichainIndexingStatusIds.Completed,
2609
+ OmnichainIndexingStatusIds.Following
2610
+ ],
2611
+ /**
2612
+ * Check if provided indexing status supports the Name Tokens API.
2613
+ */
2614
+ hasIndexingStatusSupport(omnichainIndexingStatusId) {
2615
+ return nameTokensPrerequisites.supportedIndexingStatusIds.some(
2616
+ (supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
2617
+ );
2618
+ }
2619
+ });
2620
+
2621
+ // src/api/name-tokens/serialize.ts
2622
+ function serializeRegisteredNameTokens({
2623
+ domainId,
2624
+ name,
2625
+ tokens,
2626
+ expiresAt,
2627
+ accurateAsOf
2628
+ }) {
2629
+ return {
2630
+ domainId,
2631
+ name,
2632
+ tokens: tokens.map(serializeNameToken),
2633
+ expiresAt,
2634
+ accurateAsOf
2635
+ };
2636
+ }
2637
+ function serializeNameTokensResponse(response) {
2638
+ switch (response.responseCode) {
2639
+ case NameTokensResponseCodes.Ok:
2640
+ return {
2641
+ responseCode: response.responseCode,
2642
+ registeredNameTokens: serializeRegisteredNameTokens(response.registeredNameTokens)
2643
+ };
2644
+ case NameTokensResponseCodes.Error:
2645
+ return response;
2646
+ }
2647
+ }
2648
+
2649
+ // src/api/registrar-actions/deserialize.ts
2650
+ var import_v419 = require("zod/v4");
2651
+
2652
+ // src/api/registrar-actions/zod-schemas.ts
2653
+ var import_ens7 = require("viem/ens");
2654
+ var import_v418 = __toESM(require("zod/v4"), 1);
2655
+
2656
+ // ../ens-referrals/src/address.ts
2657
+ var import_viem15 = require("viem");
2658
+
2659
+ // ../ens-referrals/src/encoding.ts
2660
+ var import_viem16 = require("viem");
2661
+ var ENCODED_REFERRER_BYTE_OFFSET = 12;
2662
+ var ENCODED_REFERRER_BYTE_LENGTH = 32;
2663
+ var EXPECTED_ENCODED_REFERRER_PADDING = (0, import_viem16.pad)("0x", {
2664
+ size: ENCODED_REFERRER_BYTE_OFFSET,
2665
+ dir: "left"
2666
+ });
2667
+ var ZERO_ENCODED_REFERRER = (0, import_viem16.pad)("0x", {
2668
+ size: ENCODED_REFERRER_BYTE_LENGTH,
2669
+ dir: "left"
2670
+ });
2671
+ function decodeEncodedReferrer(encodedReferrer) {
2672
+ if ((0, import_viem16.size)(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
2673
+ throw new Error(
2674
+ `Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
2675
+ );
2676
+ }
2677
+ const padding = (0, import_viem16.slice)(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
2678
+ if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
2679
+ return import_viem16.zeroAddress;
2680
+ }
2681
+ const decodedReferrer = (0, import_viem16.slice)(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
2682
+ try {
2683
+ return (0, import_viem16.getAddress)(decodedReferrer);
2684
+ } catch {
2685
+ throw new Error(`Decoded referrer value must be a valid EVM address.`);
2686
+ }
2687
+ }
2688
+
2689
+ // ../ens-referrals/src/leaderboard-page.ts
2690
+ var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
2691
+
2692
+ // ../ens-referrals/src/link.ts
2693
+ var import_viem17 = require("viem");
2694
+
2695
+ // ../ens-referrals/src/referrer-detail.ts
2696
+ var ReferrerDetailTypeIds = {
2697
+ /**
2698
+ * Represents a referrer who is ranked on the leaderboard.
2699
+ */
2700
+ Ranked: "ranked",
2701
+ /**
2702
+ * Represents a referrer who is not ranked on the leaderboard.
2703
+ */
2704
+ Unranked: "unranked"
2705
+ };
2706
+
2707
+ // src/registrars/zod-schemas.ts
2708
+ var import_v416 = __toESM(require("zod/v4"), 1);
2709
+
2710
+ // src/registrars/registrar-action.ts
2711
+ var RegistrarActionTypes = {
2712
+ Registration: "registration",
2713
+ Renewal: "renewal"
2714
+ };
2715
+ function isRegistrarActionPricingAvailable(registrarActionPricing) {
2716
+ const { baseCost, premium, total } = registrarActionPricing;
2717
+ return baseCost !== null && premium !== null && total !== null;
2718
+ }
2719
+ function isRegistrarActionReferralAvailable(registrarActionReferral) {
2720
+ const { encodedReferrer, decodedReferrer } = registrarActionReferral;
2721
+ return encodedReferrer !== null && decodedReferrer !== null;
2722
+ }
2723
+ function serializeRegistrarActionPricing(pricing) {
2724
+ if (isRegistrarActionPricingAvailable(pricing)) {
2725
+ return {
2726
+ baseCost: serializePriceEth(pricing.baseCost),
2727
+ premium: serializePriceEth(pricing.premium),
2728
+ total: serializePriceEth(pricing.total)
2729
+ };
2730
+ }
2731
+ return pricing;
2197
2732
  }
2198
2733
  function serializeRegistrarAction(registrarAction) {
2199
2734
  return {
@@ -2201,7 +2736,7 @@ function serializeRegistrarAction(registrarAction) {
2201
2736
  type: registrarAction.type,
2202
2737
  incrementalDuration: registrarAction.incrementalDuration,
2203
2738
  registrant: registrarAction.registrant,
2204
- registrationLifecycle: serializeRegistrationLifecycle(registrarAction.registrationLifecycle),
2739
+ registrationLifecycle: registrarAction.registrationLifecycle,
2205
2740
  pricing: serializeRegistrarActionPricing(registrarAction.pricing),
2206
2741
  referral: registrarAction.referral,
2207
2742
  block: registrarAction.block,
@@ -2211,11 +2746,11 @@ function serializeRegistrarAction(registrarAction) {
2211
2746
  }
2212
2747
 
2213
2748
  // src/registrars/zod-schemas.ts
2214
- var makeSubregistrySchema = (valueLabel = "Subregistry") => import_v412.default.object({
2215
- subregistryId: makeSerializedAccountIdSchema(`${valueLabel} Subregistry ID`),
2749
+ var makeSubregistrySchema = (valueLabel = "Subregistry") => import_v416.default.object({
2750
+ subregistryId: makeAccountIdSchema(`${valueLabel} Subregistry ID`),
2216
2751
  node: makeNodeSchema(`${valueLabel} Node`)
2217
2752
  });
2218
- var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => import_v412.default.object({
2753
+ var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => import_v416.default.object({
2219
2754
  subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
2220
2755
  node: makeNodeSchema(`${valueLabel} Node`),
2221
2756
  expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
@@ -2231,18 +2766,18 @@ function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
2231
2766
  });
2232
2767
  }
2233
2768
  }
2234
- var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => import_v412.default.union([
2769
+ var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => import_v416.default.union([
2235
2770
  // pricing available
2236
- import_v412.default.object({
2771
+ import_v416.default.object({
2237
2772
  baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
2238
2773
  premium: makePriceEthSchema(`${valueLabel} Premium`),
2239
2774
  total: makePriceEthSchema(`${valueLabel} Total`)
2240
2775
  }).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
2241
2776
  // pricing unknown
2242
- import_v412.default.object({
2243
- baseCost: import_v412.default.null(),
2244
- premium: import_v412.default.null(),
2245
- total: import_v412.default.null()
2777
+ import_v416.default.object({
2778
+ baseCost: import_v416.default.null(),
2779
+ premium: import_v416.default.null(),
2780
+ total: import_v416.default.null()
2246
2781
  }).transform((v) => v)
2247
2782
  ]);
2248
2783
  function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
@@ -2265,9 +2800,9 @@ function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
2265
2800
  });
2266
2801
  }
2267
2802
  }
2268
- var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => import_v412.default.union([
2803
+ var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => import_v416.default.union([
2269
2804
  // referral available
2270
- import_v412.default.object({
2805
+ import_v416.default.object({
2271
2806
  encodedReferrer: makeHexStringSchema(
2272
2807
  { bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
2273
2808
  `${valueLabel} Encoded Referrer`
@@ -2275,9 +2810,9 @@ var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral
2275
2810
  decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
2276
2811
  }).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
2277
2812
  // referral not applicable
2278
- import_v412.default.object({
2279
- encodedReferrer: import_v412.default.null(),
2280
- decodedReferrer: import_v412.default.null()
2813
+ import_v416.default.object({
2814
+ encodedReferrer: import_v416.default.null(),
2815
+ decodedReferrer: import_v416.default.null()
2281
2816
  })
2282
2817
  ]);
2283
2818
  function invariant_eventIdsInitialElementIsTheActionId(ctx) {
@@ -2290,9 +2825,9 @@ function invariant_eventIdsInitialElementIsTheActionId(ctx) {
2290
2825
  });
2291
2826
  }
2292
2827
  }
2293
- var EventIdSchema = import_v412.default.string().nonempty();
2294
- var EventIdsSchema = import_v412.default.array(EventIdSchema).min(1).transform((v) => v);
2295
- var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => import_v412.default.object({
2828
+ var EventIdSchema = import_v416.default.string().nonempty();
2829
+ var EventIdsSchema = import_v416.default.array(EventIdSchema).min(1).transform((v) => v);
2830
+ var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => import_v416.default.object({
2296
2831
  id: EventIdSchema,
2297
2832
  incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
2298
2833
  registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
@@ -2306,151 +2841,135 @@ var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => im
2306
2841
  eventIds: EventIdsSchema
2307
2842
  }).check(invariant_eventIdsInitialElementIsTheActionId);
2308
2843
  var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
2309
- type: import_v412.default.literal(RegistrarActionTypes.Registration)
2844
+ type: import_v416.default.literal(RegistrarActionTypes.Registration)
2310
2845
  });
2311
2846
  var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
2312
- type: import_v412.default.literal(RegistrarActionTypes.Renewal)
2847
+ type: import_v416.default.literal(RegistrarActionTypes.Renewal)
2313
2848
  });
2314
- var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => import_v412.default.discriminatedUnion("type", [
2849
+ var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => import_v416.default.discriminatedUnion("type", [
2315
2850
  makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
2316
2851
  makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
2317
2852
  ]);
2318
2853
 
2319
- // src/shared/config/build-rpc-urls.ts
2320
- var import_chains = require("viem/chains");
2854
+ // src/api/shared/pagination/zod-schemas.ts
2855
+ var import_v417 = __toESM(require("zod/v4"), 1);
2321
2856
 
2322
- // src/shared/config/rpc-configs-from-env.ts
2323
- var import_datasources4 = require("@ensnode/datasources");
2857
+ // src/api/shared/pagination/request.ts
2858
+ var RECORDS_PER_PAGE_DEFAULT = 10;
2859
+ var RECORDS_PER_PAGE_MAX = 100;
2324
2860
 
2325
- // src/shared/config/validatons.ts
2326
- var import_datasources5 = require("@ensnode/datasources");
2327
- function invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL(ctx) {
2328
- const endpoints = ctx.value;
2329
- const httpEndpoints = endpoints.filter(isHttpProtocol);
2330
- if (httpEndpoints.length < 1) {
2861
+ // src/api/shared/pagination/zod-schemas.ts
2862
+ var makeRequestPageParamsSchema = (valueLabel = "RequestPageParams") => import_v417.default.object({
2863
+ page: makePositiveIntegerSchema(`${valueLabel}.page`),
2864
+ recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
2865
+ RECORDS_PER_PAGE_MAX,
2866
+ `${valueLabel}.recordsPerPage must not exceed ${RECORDS_PER_PAGE_MAX}`
2867
+ )
2868
+ });
2869
+ var makeResponsePageContextSchemaWithNoRecords = (valueLabel = "ResponsePageContextWithNoRecords") => import_v417.default.object({
2870
+ totalRecords: import_v417.default.literal(0),
2871
+ totalPages: import_v417.default.literal(1),
2872
+ hasNext: import_v417.default.literal(false),
2873
+ hasPrev: import_v417.default.literal(false),
2874
+ startIndex: import_v417.default.undefined(),
2875
+ endIndex: import_v417.default.undefined()
2876
+ }).extend(makeRequestPageParamsSchema(valueLabel).shape);
2877
+ function invariant_responsePageWithRecordsIsCorrect(ctx) {
2878
+ const { hasNext, hasPrev, recordsPerPage, page, totalRecords, startIndex, endIndex } = ctx.value;
2879
+ const expectedHasNext = page * recordsPerPage < totalRecords;
2880
+ if (hasNext !== expectedHasNext) {
2331
2881
  ctx.issues.push({
2332
2882
  code: "custom",
2333
- input: endpoints,
2334
- message: `RPC endpoint configuration for a chain must include at least one http/https protocol URL.`
2883
+ input: ctx.value,
2884
+ message: `hasNext must be equal to '${expectedHasNext ? "true" : "false"}'`
2335
2885
  });
2336
2886
  }
2337
- }
2338
- function invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL(ctx) {
2339
- const endpoints = ctx.value;
2340
- const wsEndpoints = endpoints.filter(isWebSocketProtocol);
2341
- if (wsEndpoints.length > 1) {
2887
+ const expectedHasPrev = page > 1;
2888
+ if (hasPrev !== expectedHasPrev) {
2342
2889
  ctx.issues.push({
2343
2890
  code: "custom",
2344
- input: endpoints,
2345
- message: `RPC endpoint configuration for a chain must include at most one websocket (ws/wss) protocol URL.`
2891
+ input: ctx.value,
2892
+ message: `hasPrev must be equal to '${expectedHasPrev ? "true" : "false"}'`
2346
2893
  });
2347
2894
  }
2348
- }
2349
-
2350
- // src/shared/config/zod-schemas.ts
2351
- var import_v413 = require("zod/v4");
2352
- var import_datasources6 = require("@ensnode/datasources");
2353
- var DatabaseSchemaNameSchema = import_v413.z.string({
2354
- error: "DATABASE_SCHEMA is required."
2355
- }).trim().min(1, {
2356
- error: "DATABASE_SCHEMA is required and cannot be an empty string."
2357
- });
2358
- var RpcConfigSchema = import_v413.z.string().transform((val) => val.split(",")).pipe(import_v413.z.array(makeUrlSchema("RPC URL"))).check(invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL).check(invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL);
2359
- var RpcConfigsSchema = import_v413.z.record(makeChainIdStringSchema("RPC URL"), RpcConfigSchema, {
2360
- error: "Chains configuration must be an object mapping valid chain IDs to their configs."
2361
- }).transform((records) => {
2362
- const rpcConfigs = /* @__PURE__ */ new Map();
2363
- for (const [chainIdString, rpcConfig] of Object.entries(records)) {
2364
- const httpRPCs = rpcConfig.filter(isHttpProtocol);
2365
- const websocketRPC = rpcConfig.find(isWebSocketProtocol);
2366
- rpcConfigs.set(deserializeChainId(chainIdString), {
2367
- httpRPCs,
2368
- websocketRPC
2895
+ if (endIndex < startIndex) {
2896
+ ctx.issues.push({
2897
+ code: "custom",
2898
+ input: ctx.value,
2899
+ message: `endIndex must be greater than or equal to startIndex`
2369
2900
  });
2370
2901
  }
2371
- return rpcConfigs;
2372
- });
2373
- var EnsIndexerUrlSchema = makeUrlSchema("ENSINDEXER_URL");
2374
- var ENSNamespaceSchema = import_v413.z.enum(import_datasources6.ENSNamespaceIds, {
2375
- error: ({ input }) => `Invalid NAMESPACE. Got '${input}', but supported ENS namespaces are: ${Object.keys(import_datasources6.ENSNamespaceIds).join(", ")}`
2376
- });
2377
- var PortSchema = import_v413.z.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();
2378
- var TheGraphApiKeySchema = import_v413.z.string().optional();
2379
-
2380
- // src/shared/datasources-with-resolvers.ts
2381
- var import_datasources7 = require("@ensnode/datasources");
2382
- var DATASOURCE_NAMES_WITH_RESOLVERS = [
2383
- import_datasources7.DatasourceNames.ENSRoot,
2384
- import_datasources7.DatasourceNames.Basenames,
2385
- import_datasources7.DatasourceNames.Lineanames,
2386
- import_datasources7.DatasourceNames.ThreeDNSOptimism,
2387
- import_datasources7.DatasourceNames.ThreeDNSBase
2388
- ];
2389
-
2390
- // src/shared/log-level.ts
2391
- var import_v414 = require("zod/v4");
2392
- var LogLevelSchema = import_v414.z.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]);
2393
-
2394
- // src/shared/protocol-acceleration/interpret-record-values.ts
2395
- var import_viem14 = require("viem");
2902
+ if (endIndex >= totalRecords) {
2903
+ ctx.issues.push({
2904
+ code: "custom",
2905
+ input: ctx.value,
2906
+ message: `endIndex must be lower than totalRecords`
2907
+ });
2908
+ }
2909
+ }
2910
+ var makeResponsePageContextSchemaWithRecords = (valueLabel = "ResponsePageContextWithRecords") => import_v417.default.object({
2911
+ totalRecords: makePositiveIntegerSchema(`${valueLabel}.totalRecords`),
2912
+ totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
2913
+ hasNext: import_v417.default.boolean(),
2914
+ hasPrev: import_v417.default.boolean(),
2915
+ startIndex: makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`),
2916
+ endIndex: makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`)
2917
+ }).extend(makeRequestPageParamsSchema(valueLabel).shape).check(invariant_responsePageWithRecordsIsCorrect);
2918
+ var makeResponsePageContextSchema = (valueLabel = "ResponsePageContext") => import_v417.default.union([
2919
+ makeResponsePageContextSchemaWithNoRecords(valueLabel),
2920
+ makeResponsePageContextSchemaWithRecords(valueLabel)
2921
+ ]);
2396
2922
 
2397
- // src/api/indexing-status/response.ts
2398
- var IndexingStatusResponseCodes = {
2923
+ // src/api/registrar-actions/response.ts
2924
+ var RegistrarActionsResponseCodes = {
2399
2925
  /**
2400
- * Represents that the indexing status is available.
2926
+ * Represents that Registrar Actions are available.
2401
2927
  */
2402
2928
  Ok: "ok",
2403
2929
  /**
2404
- * Represents that the indexing status is unavailable.
2930
+ * Represents that Registrar Actions are unavailable.
2405
2931
  */
2406
2932
  Error: "error"
2407
2933
  };
2408
2934
 
2409
- // src/api/indexing-status/zod-schemas.ts
2410
- var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => import_v415.default.strictObject({
2411
- responseCode: import_v415.default.literal(IndexingStatusResponseCodes.Ok),
2412
- realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
2935
+ // src/api/registrar-actions/zod-schemas.ts
2936
+ function invariant_registrationLifecycleNodeMatchesName(ctx) {
2937
+ const { name, action } = ctx.value;
2938
+ const expectedNode = action.registrationLifecycle.node;
2939
+ const actualNode = (0, import_ens7.namehash)(name);
2940
+ if (actualNode !== expectedNode) {
2941
+ ctx.issues.push({
2942
+ code: "custom",
2943
+ input: ctx.value,
2944
+ message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
2945
+ });
2946
+ }
2947
+ }
2948
+ var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => import_v418.default.object({
2949
+ action: makeRegistrarActionSchema(valueLabel),
2950
+ name: makeReinterpretedNameSchema(valueLabel)
2951
+ }).check(invariant_registrationLifecycleNodeMatchesName);
2952
+ var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => import_v418.default.strictObject({
2953
+ responseCode: import_v418.default.literal(RegistrarActionsResponseCodes.Ok),
2954
+ registrarActions: import_v418.default.array(makeNamedRegistrarActionSchema(valueLabel)),
2955
+ pageContext: makeResponsePageContextSchema(`${valueLabel}.pageContext`)
2413
2956
  });
2414
- var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => import_v415.default.strictObject({
2415
- responseCode: import_v415.default.literal(IndexingStatusResponseCodes.Error)
2957
+ var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => import_v418.default.strictObject({
2958
+ responseCode: import_v418.default.literal(RegistrarActionsResponseCodes.Error),
2959
+ error: ErrorResponseSchema
2416
2960
  });
2417
- var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => import_v415.default.discriminatedUnion("responseCode", [
2418
- makeIndexingStatusResponseOkSchema(valueLabel),
2419
- makeIndexingStatusResponseErrorSchema(valueLabel)
2961
+ var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => import_v418.default.discriminatedUnion("responseCode", [
2962
+ makeRegistrarActionsResponseOkSchema(valueLabel),
2963
+ makeRegistrarActionsResponseErrorSchema(valueLabel)
2420
2964
  ]);
2421
2965
 
2422
- // src/api/indexing-status/deserialize.ts
2423
- function deserializeIndexingStatusResponse(maybeResponse) {
2424
- const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
2425
- if (parsed.error) {
2426
- throw new Error(`Cannot deserialize IndexingStatusResponse:
2427
- ${(0, import_v416.prettifyError)(parsed.error)}
2428
- `);
2429
- }
2430
- return parsed.data;
2431
- }
2432
-
2433
- // src/api/indexing-status/serialize.ts
2434
- function serializeIndexingStatusResponse(response) {
2435
- switch (response.responseCode) {
2436
- case IndexingStatusResponseCodes.Ok:
2437
- return {
2438
- responseCode: response.responseCode,
2439
- realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
2440
- };
2441
- case IndexingStatusResponseCodes.Error:
2442
- return response;
2443
- }
2444
- }
2445
-
2446
2966
  // src/api/registrar-actions/deserialize.ts
2447
- var import_v417 = require("zod/v4");
2448
2967
  function deserializeRegistrarActionsResponse(maybeResponse) {
2449
2968
  const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
2450
2969
  if (parsed.error) {
2451
2970
  throw new Error(
2452
2971
  `Cannot deserialize RegistrarActionsResponse:
2453
- ${(0, import_v417.prettifyError)(parsed.error)}
2972
+ ${(0, import_v419.prettifyError)(parsed.error)}
2454
2973
  `
2455
2974
  );
2456
2975
  }
@@ -2460,7 +2979,8 @@ ${(0, import_v417.prettifyError)(parsed.error)}
2460
2979
  // src/api/registrar-actions/request.ts
2461
2980
  var RegistrarActionsFilterTypes = {
2462
2981
  BySubregistryNode: "bySubregistryNode",
2463
- WithEncodedReferral: "withEncodedReferral"
2982
+ WithEncodedReferral: "withEncodedReferral",
2983
+ ByDecodedReferrer: "byDecodedReferrer"
2464
2984
  };
2465
2985
  var RegistrarActionsOrders = {
2466
2986
  LatestRegistrarActions: "orderBy[timestamp]=desc"
@@ -2484,9 +3004,19 @@ function withReferral(withReferral2) {
2484
3004
  filterType: RegistrarActionsFilterTypes.WithEncodedReferral
2485
3005
  };
2486
3006
  }
3007
+ function byDecodedReferrer(decodedReferrer) {
3008
+ if (typeof decodedReferrer === "undefined") {
3009
+ return void 0;
3010
+ }
3011
+ return {
3012
+ filterType: RegistrarActionsFilterTypes.ByDecodedReferrer,
3013
+ value: decodedReferrer
3014
+ };
3015
+ }
2487
3016
  var registrarActionsFilter = {
2488
3017
  byParentNode,
2489
- withReferral
3018
+ withReferral,
3019
+ byDecodedReferrer
2490
3020
  };
2491
3021
 
2492
3022
  // src/api/registrar-actions/prerequisites.ts
@@ -2539,12 +3069,68 @@ var registrarActionsPrerequisites = Object.freeze({
2539
3069
  }
2540
3070
  });
2541
3071
 
3072
+ // src/registrars/basenames-subregistry.ts
3073
+ var import_datasources6 = require("@ensnode/datasources");
3074
+ function getBasenamesSubregistryId(namespace) {
3075
+ const datasource = (0, import_datasources6.maybeGetDatasource)(namespace, import_datasources6.DatasourceNames.Basenames);
3076
+ if (!datasource) {
3077
+ throw new Error(`Datasource not found for ${namespace} ${import_datasources6.DatasourceNames.Basenames}`);
3078
+ }
3079
+ const address = datasource.contracts.BaseRegistrar?.address;
3080
+ if (address === void 0 || Array.isArray(address)) {
3081
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
3082
+ }
3083
+ return {
3084
+ chainId: datasource.chain.id,
3085
+ address
3086
+ };
3087
+ }
3088
+ function getBasenamesSubregistryManagedName(namespaceId) {
3089
+ switch (namespaceId) {
3090
+ case import_datasources6.ENSNamespaceIds.Mainnet:
3091
+ return "base.eth";
3092
+ case import_datasources6.ENSNamespaceIds.Sepolia:
3093
+ return "basetest.eth";
3094
+ case import_datasources6.ENSNamespaceIds.Holesky:
3095
+ case import_datasources6.ENSNamespaceIds.EnsTestEnv:
3096
+ throw new Error(
3097
+ `No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`
3098
+ );
3099
+ }
3100
+ }
3101
+
2542
3102
  // src/registrars/ethnames-subregistry.ts
2543
- var import_datasources8 = require("@ensnode/datasources");
3103
+ var import_datasources7 = require("@ensnode/datasources");
2544
3104
  function getEthnamesSubregistryId(namespace) {
2545
- const datasource = (0, import_datasources8.maybeGetDatasource)(namespace, import_datasources8.DatasourceNames.ENSRoot);
3105
+ const datasource = (0, import_datasources7.maybeGetDatasource)(namespace, import_datasources7.DatasourceNames.ENSRoot);
3106
+ if (!datasource) {
3107
+ throw new Error(`Datasource not found for ${namespace} ${import_datasources7.DatasourceNames.ENSRoot}`);
3108
+ }
3109
+ const address = datasource.contracts.BaseRegistrar?.address;
3110
+ if (address === void 0 || Array.isArray(address)) {
3111
+ throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
3112
+ }
3113
+ return {
3114
+ chainId: datasource.chain.id,
3115
+ address
3116
+ };
3117
+ }
3118
+ function getEthnamesSubregistryManagedName(namespaceId) {
3119
+ switch (namespaceId) {
3120
+ case import_datasources7.ENSNamespaceIds.Mainnet:
3121
+ case import_datasources7.ENSNamespaceIds.Sepolia:
3122
+ case import_datasources7.ENSNamespaceIds.Holesky:
3123
+ case import_datasources7.ENSNamespaceIds.EnsTestEnv:
3124
+ return "eth";
3125
+ }
3126
+ }
3127
+
3128
+ // src/registrars/lineanames-subregistry.ts
3129
+ var import_datasources8 = require("@ensnode/datasources");
3130
+ function getLineanamesSubregistryId(namespace) {
3131
+ const datasource = (0, import_datasources8.maybeGetDatasource)(namespace, import_datasources8.DatasourceNames.Lineanames);
2546
3132
  if (!datasource) {
2547
- throw new Error(`Datasource not found for ${namespace} ${import_datasources8.DatasourceNames.ENSRoot}`);
3133
+ throw new Error(`Datasource not found for ${namespace} ${import_datasources8.DatasourceNames.Lineanames}`);
2548
3134
  }
2549
3135
  const address = datasource.contracts.BaseRegistrar?.address;
2550
3136
  if (address === void 0 || Array.isArray(address)) {
@@ -2555,6 +3141,19 @@ function getEthnamesSubregistryId(namespace) {
2555
3141
  address
2556
3142
  };
2557
3143
  }
3144
+ function getLineanamesSubregistryManagedName(namespaceId) {
3145
+ switch (namespaceId) {
3146
+ case import_datasources8.ENSNamespaceIds.Mainnet:
3147
+ return "linea.eth";
3148
+ case import_datasources8.ENSNamespaceIds.Sepolia:
3149
+ return "linea-sepolia.eth";
3150
+ case import_datasources8.ENSNamespaceIds.Holesky:
3151
+ case import_datasources8.ENSNamespaceIds.EnsTestEnv:
3152
+ throw new Error(
3153
+ `No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`
3154
+ );
3155
+ }
3156
+ }
2558
3157
 
2559
3158
  // src/api/registrar-actions/serialize.ts
2560
3159
  function serializeNamedRegistrarAction({
@@ -2571,7 +3170,8 @@ function serializeRegistrarActionsResponse(response) {
2571
3170
  case RegistrarActionsResponseCodes.Ok:
2572
3171
  return {
2573
3172
  responseCode: response.responseCode,
2574
- registrarActions: response.registrarActions.map(serializeNamedRegistrarAction)
3173
+ registrarActions: response.registrarActions.map(serializeNamedRegistrarAction),
3174
+ pageContext: response.pageContext
2575
3175
  };
2576
3176
  case RegistrarActionsResponseCodes.Error:
2577
3177
  return response;
@@ -2579,17 +3179,52 @@ function serializeRegistrarActionsResponse(response) {
2579
3179
  }
2580
3180
 
2581
3181
  // src/api/shared/errors/deserialize.ts
2582
- var import_v418 = require("zod/v4");
3182
+ var import_v420 = require("zod/v4");
2583
3183
  function deserializeErrorResponse(maybeErrorResponse) {
2584
3184
  const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
2585
3185
  if (parsed.error) {
2586
3186
  throw new Error(`Cannot deserialize ErrorResponse:
2587
- ${(0, import_v418.prettifyError)(parsed.error)}
3187
+ ${(0, import_v420.prettifyError)(parsed.error)}
2588
3188
  `);
2589
3189
  }
2590
3190
  return parsed.data;
2591
3191
  }
2592
3192
 
3193
+ // src/api/shared/pagination/build-page-context.ts
3194
+ function buildPageContext(page, recordsPerPage, totalRecords) {
3195
+ const totalPages = Math.max(1, Math.ceil(totalRecords / recordsPerPage));
3196
+ if (page > totalPages) {
3197
+ throw new Error(`Invalid page: page ${page} exceeds total pages ${totalPages}.`);
3198
+ }
3199
+ if (totalRecords === 0) {
3200
+ return {
3201
+ page,
3202
+ recordsPerPage,
3203
+ totalRecords: 0,
3204
+ totalPages: 1,
3205
+ hasNext: false,
3206
+ hasPrev: false,
3207
+ startIndex: void 0,
3208
+ endIndex: void 0
3209
+ };
3210
+ }
3211
+ const startIndex = (page - 1) * recordsPerPage;
3212
+ const maxTheoreticalIndexOnPage = startIndex + (recordsPerPage - 1);
3213
+ const endIndex = Math.min(maxTheoreticalIndexOnPage, totalRecords - 1);
3214
+ const hasNext = maxTheoreticalIndexOnPage < totalRecords - 1;
3215
+ const hasPrev = page > 1;
3216
+ return {
3217
+ page,
3218
+ recordsPerPage,
3219
+ totalRecords,
3220
+ totalPages,
3221
+ hasNext,
3222
+ hasPrev,
3223
+ startIndex,
3224
+ endIndex
3225
+ };
3226
+ }
3227
+
2593
3228
  // src/client-error.ts
2594
3229
  var ClientError = class _ClientError extends Error {
2595
3230
  details;
@@ -2604,10 +3239,10 @@ var ClientError = class _ClientError extends Error {
2604
3239
  };
2605
3240
 
2606
3241
  // src/ensanalytics/deserialize.ts
2607
- var import_v420 = require("zod/v4");
3242
+ var import_v422 = require("zod/v4");
2608
3243
 
2609
3244
  // src/ensanalytics/zod-schemas.ts
2610
- var import_v419 = __toESM(require("zod/v4"), 1);
3245
+ var import_v421 = __toESM(require("zod/v4"), 1);
2611
3246
 
2612
3247
  // src/ensanalytics/types.ts
2613
3248
  var ReferrerLeaderboardPageResponseCodes = {
@@ -2632,20 +3267,20 @@ var ReferrerDetailResponseCodes = {
2632
3267
  };
2633
3268
 
2634
3269
  // src/ensanalytics/zod-schemas.ts
2635
- var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => import_v419.default.object({
3270
+ var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => import_v421.default.object({
2636
3271
  totalAwardPoolValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.totalAwardPoolValue`),
2637
3272
  maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`),
2638
3273
  startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
2639
3274
  endTime: makeUnixTimestampSchema(`${valueLabel}.endTime`),
2640
3275
  subregistryId: makeAccountIdSchema(`${valueLabel}.subregistryId`)
2641
3276
  });
2642
- var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => import_v419.default.object({
3277
+ var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => import_v421.default.object({
2643
3278
  referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
2644
3279
  totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
2645
3280
  totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
2646
3281
  score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
2647
3282
  rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
2648
- isQualified: import_v419.default.boolean(),
3283
+ isQualified: import_v421.default.boolean(),
2649
3284
  finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
2650
3285
  1,
2651
3286
  `${valueLabel}.finalScoreBoost must be <= 1`
@@ -2657,13 +3292,13 @@ var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") =
2657
3292
  ),
2658
3293
  awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
2659
3294
  });
2660
- var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics") => import_v419.default.object({
3295
+ var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics") => import_v421.default.object({
2661
3296
  referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
2662
3297
  totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
2663
3298
  totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
2664
3299
  score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
2665
- rank: import_v419.default.null(),
2666
- isQualified: import_v419.default.literal(false),
3300
+ rank: import_v421.default.null(),
3301
+ isQualified: import_v421.default.literal(false),
2667
3302
  finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
2668
3303
  1,
2669
3304
  `${valueLabel}.finalScoreBoost must be <= 1`
@@ -2675,7 +3310,7 @@ var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics")
2675
3310
  ),
2676
3311
  awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
2677
3312
  });
2678
- var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => import_v419.default.object({
3313
+ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => import_v421.default.object({
2679
3314
  grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
2680
3315
  grandTotalIncrementalDuration: makeDurationSchema(
2681
3316
  `${valueLabel}.grandTotalIncrementalDuration`
@@ -2687,66 +3322,66 @@ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetri
2687
3322
  `${valueLabel}.minFinalScoreToQualify`
2688
3323
  )
2689
3324
  });
2690
- var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => import_v419.default.object({
3325
+ var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => import_v421.default.object({
2691
3326
  page: makePositiveIntegerSchema(`${valueLabel}.page`),
2692
- itemsPerPage: makePositiveIntegerSchema(`${valueLabel}.itemsPerPage`).max(
3327
+ recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
2693
3328
  REFERRERS_PER_LEADERBOARD_PAGE_MAX,
2694
- `${valueLabel}.itemsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
3329
+ `${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
2695
3330
  ),
2696
3331
  totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
2697
3332
  totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
2698
- hasNext: import_v419.default.boolean(),
2699
- hasPrev: import_v419.default.boolean(),
2700
- startIndex: import_v419.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
2701
- endIndex: import_v419.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
3333
+ hasNext: import_v421.default.boolean(),
3334
+ hasPrev: import_v421.default.boolean(),
3335
+ startIndex: import_v421.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
3336
+ endIndex: import_v421.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
2702
3337
  });
2703
- var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => import_v419.default.object({
3338
+ var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => import_v421.default.object({
2704
3339
  rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
2705
- referrers: import_v419.default.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[item]`)),
3340
+ referrers: import_v421.default.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[record]`)),
2706
3341
  aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
2707
- paginationContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.paginationContext`),
3342
+ pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
2708
3343
  accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2709
3344
  });
2710
- var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => import_v419.default.object({
2711
- responseCode: import_v419.default.literal(ReferrerLeaderboardPageResponseCodes.Ok),
3345
+ var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => import_v421.default.object({
3346
+ responseCode: import_v421.default.literal(ReferrerLeaderboardPageResponseCodes.Ok),
2712
3347
  data: makeReferrerLeaderboardPageSchema(`${valueLabel}.data`)
2713
3348
  });
2714
- var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => import_v419.default.object({
2715
- responseCode: import_v419.default.literal(ReferrerLeaderboardPageResponseCodes.Error),
2716
- error: import_v419.default.string(),
2717
- errorMessage: import_v419.default.string()
3349
+ var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => import_v421.default.object({
3350
+ responseCode: import_v421.default.literal(ReferrerLeaderboardPageResponseCodes.Error),
3351
+ error: import_v421.default.string(),
3352
+ errorMessage: import_v421.default.string()
2718
3353
  });
2719
- var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => import_v419.default.union([
3354
+ var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => import_v421.default.union([
2720
3355
  makeReferrerLeaderboardPageResponseOkSchema(valueLabel),
2721
3356
  makeReferrerLeaderboardPageResponseErrorSchema(valueLabel)
2722
3357
  ]);
2723
- var makeReferrerDetailRankedSchema = (valueLabel = "ReferrerDetailRanked") => import_v419.default.object({
2724
- type: import_v419.default.literal(ReferrerDetailTypeIds.Ranked),
3358
+ var makeReferrerDetailRankedSchema = (valueLabel = "ReferrerDetailRanked") => import_v421.default.object({
3359
+ type: import_v421.default.literal(ReferrerDetailTypeIds.Ranked),
2725
3360
  rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
2726
3361
  referrer: makeAwardedReferrerMetricsSchema(`${valueLabel}.referrer`),
2727
3362
  aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
2728
3363
  accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2729
3364
  });
2730
- var makeReferrerDetailUnrankedSchema = (valueLabel = "ReferrerDetailUnranked") => import_v419.default.object({
2731
- type: import_v419.default.literal(ReferrerDetailTypeIds.Unranked),
3365
+ var makeReferrerDetailUnrankedSchema = (valueLabel = "ReferrerDetailUnranked") => import_v421.default.object({
3366
+ type: import_v421.default.literal(ReferrerDetailTypeIds.Unranked),
2732
3367
  rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
2733
3368
  referrer: makeUnrankedReferrerMetricsSchema(`${valueLabel}.referrer`),
2734
3369
  aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
2735
3370
  accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
2736
3371
  });
2737
- var makeReferrerDetailResponseOkSchema = (valueLabel = "ReferrerDetailResponse") => import_v419.default.object({
2738
- responseCode: import_v419.default.literal(ReferrerDetailResponseCodes.Ok),
2739
- data: import_v419.default.union([
3372
+ var makeReferrerDetailResponseOkSchema = (valueLabel = "ReferrerDetailResponse") => import_v421.default.object({
3373
+ responseCode: import_v421.default.literal(ReferrerDetailResponseCodes.Ok),
3374
+ data: import_v421.default.union([
2740
3375
  makeReferrerDetailRankedSchema(`${valueLabel}.data`),
2741
3376
  makeReferrerDetailUnrankedSchema(`${valueLabel}.data`)
2742
3377
  ])
2743
3378
  });
2744
- var makeReferrerDetailResponseErrorSchema = (_valueLabel = "ReferrerDetailResponse") => import_v419.default.object({
2745
- responseCode: import_v419.default.literal(ReferrerDetailResponseCodes.Error),
2746
- error: import_v419.default.string(),
2747
- errorMessage: import_v419.default.string()
3379
+ var makeReferrerDetailResponseErrorSchema = (_valueLabel = "ReferrerDetailResponse") => import_v421.default.object({
3380
+ responseCode: import_v421.default.literal(ReferrerDetailResponseCodes.Error),
3381
+ error: import_v421.default.string(),
3382
+ errorMessage: import_v421.default.string()
2748
3383
  });
2749
- var makeReferrerDetailResponseSchema = (valueLabel = "ReferrerDetailResponse") => import_v419.default.union([
3384
+ var makeReferrerDetailResponseSchema = (valueLabel = "ReferrerDetailResponse") => import_v421.default.union([
2750
3385
  makeReferrerDetailResponseOkSchema(valueLabel),
2751
3386
  makeReferrerDetailResponseErrorSchema(valueLabel)
2752
3387
  ]);
@@ -2758,7 +3393,7 @@ function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
2758
3393
  if (parsed.error) {
2759
3394
  throw new Error(
2760
3395
  `Cannot deserialize SerializedReferrerLeaderboardPageResponse:
2761
- ${(0, import_v420.prettifyError)(parsed.error)}
3396
+ ${(0, import_v422.prettifyError)(parsed.error)}
2762
3397
  `
2763
3398
  );
2764
3399
  }
@@ -2769,7 +3404,7 @@ function deserializeReferrerDetailResponse(maybeResponse, valueLabel) {
2769
3404
  const parsed = schema.safeParse(maybeResponse);
2770
3405
  if (parsed.error) {
2771
3406
  throw new Error(`Cannot deserialize ReferrerDetailResponse:
2772
- ${(0, import_v420.prettifyError)(parsed.error)}
3407
+ ${(0, import_v422.prettifyError)(parsed.error)}
2773
3408
  `);
2774
3409
  }
2775
3410
  return parsed.data;
@@ -3037,7 +3672,7 @@ var ENSNodeClient = class _ENSNodeClient {
3037
3672
  *
3038
3673
  * @param request - Pagination parameters
3039
3674
  * @param request.page - The page number to retrieve (1-indexed, default: 1)
3040
- * @param request.itemsPerPage - Number of items per page (default: 25, max: 100)
3675
+ * @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
3041
3676
  * @returns {ReferrerLeaderboardPageResponse}
3042
3677
  *
3043
3678
  * @throws if the ENSNode request fails
@@ -3046,28 +3681,28 @@ var ENSNodeClient = class _ENSNodeClient {
3046
3681
  *
3047
3682
  * @example
3048
3683
  * ```typescript
3049
- * // Get first page with default page size (25 items)
3684
+ * // Get first page with default page size (25 records)
3050
3685
  * const response = await client.getReferrerLeaderboardPage();
3051
3686
  * if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
3052
3687
  * const {
3053
3688
  * aggregatedMetrics,
3054
3689
  * referrers,
3055
3690
  * rules,
3056
- * paginationContext,
3691
+ * pageContext,
3057
3692
  * updatedAt
3058
3693
  * } = response.data;
3059
3694
  * console.log(aggregatedMetrics);
3060
3695
  * console.log(referrers);
3061
3696
  * console.log(rules);
3062
3697
  * console.log(updatedAt);
3063
- * console.log(`Page ${paginationContext.page} of ${paginationContext.totalPages}`);
3698
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
3064
3699
  * }
3065
3700
  * ```
3066
3701
  *
3067
3702
  * @example
3068
3703
  * ```typescript
3069
- * // Get second page with 50 items per page
3070
- * const response = await client.getReferrerLeaderboardPage({ page: 2, itemsPerPage: 50 });
3704
+ * // Get second page with 50 records per page
3705
+ * const response = await client.getReferrerLeaderboardPage({ page: 2, recordsPerPage: 50 });
3071
3706
  * ```
3072
3707
  *
3073
3708
  * @example
@@ -3084,8 +3719,8 @@ var ENSNodeClient = class _ENSNodeClient {
3084
3719
  async getReferrerLeaderboardPage(request) {
3085
3720
  const url = new URL(`/ensanalytics/referrers`, this.options.url);
3086
3721
  if (request?.page) url.searchParams.set("page", request.page.toString());
3087
- if (request?.itemsPerPage)
3088
- url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
3722
+ if (request?.recordsPerPage)
3723
+ url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
3089
3724
  const response = await fetch(url);
3090
3725
  let responseData;
3091
3726
  try {
@@ -3190,11 +3825,13 @@ var ENSNodeClient = class _ENSNodeClient {
3190
3825
  /**
3191
3826
  * Fetch ENSNode Registrar Actions
3192
3827
  *
3193
- * @param {RegistrarActionsRequestFilter} request.filter is
3194
- * an optional request filter configuration.
3195
- * @param {number} request.limit sets the maximum count of results in the response.
3196
- * @param {RegistrarActionsRequestOrder} request.order sets the order of
3197
- * results in the response by field and direction.
3828
+ * Retrieves a paginated list of registrar actions with optional filters.
3829
+ *
3830
+ * @param request is a request configuration.
3831
+ * @param request.page sets the page number to retrieve (1-indexed, default: 1)
3832
+ * @param request.recordsPerPage sets the number of records per page (default: 10, max: 100)
3833
+ * @param request.filters is an optional request filter configuration.
3834
+ * @param request.order sets the order of results in the response by field and direction.
3198
3835
  * @returns {RegistrarActionsResponse}
3199
3836
  *
3200
3837
  * @throws if the ENSNode request fails
@@ -3204,23 +3841,25 @@ var ENSNodeClient = class _ENSNodeClient {
3204
3841
  * @example
3205
3842
  * ```ts
3206
3843
  * import {
3207
- * registrarActionsFilter,,
3844
+ * registrarActionsFilter,
3208
3845
  * ENSNodeClient,
3209
3846
  * } from "@ensnode/ensnode-sdk";
3210
3847
  * import { namehash } from "viem/ens";
3211
3848
  *
3212
3849
  * const client: ENSNodeClient;
3213
3850
  *
3214
- * // get latest registrar action records across all indexed subregistries
3215
- * // NOTE: when no `limit` value is passed,
3216
- * // the default RESPONSE_ITEMS_PER_PAGE_DEFAULT applies.
3217
- * const registrarActions = await client.registrarActions();
3851
+ * // Get first page with default page size (10 records)
3852
+ * const response = await client.registrarActions();
3853
+ * if (response.responseCode === RegistrarActionsResponseCodes.Ok) {
3854
+ * const { registrarActions, pageContext } = response;
3855
+ * console.log(registrarActions);
3856
+ * console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
3857
+ * }
3218
3858
  *
3219
- * // get latest 5 registrar action records across all indexed subregistries
3220
- * // NOTE: when a `limit` value is passed, it must be lower than or equal to
3221
- * // the RESPONSE_ITEMS_PER_PAGE_MAX value.
3222
- * const registrarActions = await client.registrarActions({
3223
- * limit: 5,
3859
+ * // Get second page with 25 records per page
3860
+ * const response = await client.registrarActions({
3861
+ * page: 2,
3862
+ * recordsPerPage: 25,
3224
3863
  * });
3225
3864
  *
3226
3865
  * // get latest registrar action records associated with
@@ -3234,11 +3873,16 @@ var ENSNodeClient = class _ENSNodeClient {
3234
3873
  * filters: [registrarActionsFilter.withReferral(true)],
3235
3874
  * });
3236
3875
  *
3876
+ * // get latest registrar action records for a specific decoded referrer
3877
+ * await client.registrarActions({
3878
+ * filters: [registrarActionsFilter.byDecodedReferrer("0x1234567890123456789012345678901234567890")],
3879
+ * });
3880
+ *
3237
3881
  * // get latest 10 registrar action records associated with
3238
3882
  * // subregistry managing `base.eth` name
3239
3883
  * await client.registrarActions({
3240
3884
  * filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
3241
- * limit: 10
3885
+ * recordsPerPage: 10
3242
3886
  * });
3243
3887
  * ```
3244
3888
  */
@@ -3255,6 +3899,12 @@ var ENSNodeClient = class _ENSNodeClient {
3255
3899
  );
3256
3900
  return withReferralFilter ? { key: "withReferral", value: "true" } : null;
3257
3901
  };
3902
+ const buildDecodedReferrerArg = (filters) => {
3903
+ const decodedReferrerFilter = filters?.find(
3904
+ (f) => f.filterType === RegistrarActionsFilterTypes.ByDecodedReferrer
3905
+ );
3906
+ return decodedReferrerFilter ? { key: "decodedReferrer", value: decodedReferrerFilter.value } : null;
3907
+ };
3258
3908
  const buildOrderArg = (order) => {
3259
3909
  switch (order) {
3260
3910
  case RegistrarActionsOrders.LatestRegistrarActions: {
@@ -3271,12 +3921,75 @@ var ENSNodeClient = class _ENSNodeClient {
3271
3921
  const orderArgs = buildOrderArg(request.order);
3272
3922
  url.searchParams.set(orderArgs.key, orderArgs.value);
3273
3923
  }
3274
- if (request.itemsPerPage) {
3275
- url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
3924
+ if (request.page) {
3925
+ url.searchParams.set("page", request.page.toString());
3926
+ }
3927
+ if (request.recordsPerPage) {
3928
+ url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
3929
+ }
3930
+ const referralArg = buildWithReferralArg(request.filters);
3931
+ if (referralArg) {
3932
+ url.searchParams.set(referralArg.key, referralArg.value);
3933
+ }
3934
+ const decodedReferrerArg = buildDecodedReferrerArg(request.filters);
3935
+ if (decodedReferrerArg) {
3936
+ url.searchParams.set(decodedReferrerArg.key, decodedReferrerArg.value);
3937
+ }
3938
+ const response = await fetch(url);
3939
+ let responseData;
3940
+ try {
3941
+ responseData = await response.json();
3942
+ } catch {
3943
+ throw new Error("Malformed response data: invalid JSON");
3944
+ }
3945
+ if (!response.ok) {
3946
+ let errorResponse;
3947
+ try {
3948
+ errorResponse = deserializeErrorResponse(responseData);
3949
+ } catch {
3950
+ console.log("Registrar Actions API: handling a known server error.");
3951
+ }
3952
+ if (typeof errorResponse !== "undefined") {
3953
+ throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
3954
+ }
3276
3955
  }
3277
- const referralArg = buildWithReferralArg(request.filters);
3278
- if (referralArg) {
3279
- url.searchParams.set(referralArg.key, referralArg.value);
3956
+ return deserializeRegistrarActionsResponse(responseData);
3957
+ }
3958
+ /**
3959
+ * Fetch Name Tokens for requested name.
3960
+ *
3961
+ * @param request.name - Name for which Name Tokens will be fetched.
3962
+ * @returns {NameTokensResponse}
3963
+ *
3964
+ * @throws if the ENSNode request fails
3965
+ * @throws if the ENSNode API returns an error response
3966
+ * @throws if the ENSNode response breaks required invariants
3967
+ *
3968
+ * @example
3969
+ * ```ts
3970
+ * import {
3971
+ * ENSNodeClient,
3972
+ * } from "@ensnode/ensnode-sdk";
3973
+ * import { namehash } from "viem/ens";
3974
+ *
3975
+ * const client: ENSNodeClient;
3976
+ *
3977
+ * // get latest name token records from the indexed subregistry based on the requested name
3978
+ * const response = await client.nameTokens({
3979
+ * name: "vitalik.eth"
3980
+ * });
3981
+ *
3982
+ * const response = await client.nameTokens({
3983
+ * domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
3984
+ * })
3985
+ * ```
3986
+ */
3987
+ async nameTokens(request) {
3988
+ const url = new URL(`/api/name-tokens`, this.options.url);
3989
+ if (request.name !== void 0) {
3990
+ url.searchParams.set("name", request.name);
3991
+ } else {
3992
+ url.searchParams.set("domainId", request.domainId);
3280
3993
  }
3281
3994
  const response = await fetch(url);
3282
3995
  let responseData;
@@ -3290,13 +4003,13 @@ var ENSNodeClient = class _ENSNodeClient {
3290
4003
  try {
3291
4004
  errorResponse = deserializeErrorResponse(responseData);
3292
4005
  } catch {
3293
- console.log("Registrar Actions API: handling a known server error.");
4006
+ console.log("Name Tokens API: handling a known server error.");
3294
4007
  }
3295
4008
  if (typeof errorResponse !== "undefined") {
3296
- throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
4009
+ throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
3297
4010
  }
3298
4011
  }
3299
- return deserializeRegistrarActionsResponse(responseData);
4012
+ return deserializedNameTokensResponse(responseData);
3300
4013
  }
3301
4014
  };
3302
4015
 
@@ -3337,11 +4050,11 @@ function isResolvedIdentity(identity) {
3337
4050
  }
3338
4051
 
3339
4052
  // src/resolution/ensip19-chainid.ts
3340
- var import_chains2 = require("viem/chains");
4053
+ var import_chains = require("viem/chains");
3341
4054
  var import_datasources10 = require("@ensnode/datasources");
3342
4055
  var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
3343
4056
  const ensRootChainId = (0, import_datasources10.getENSRootChainId)(namespaceId);
3344
- return chainId === ensRootChainId ? import_chains2.mainnet.id : chainId;
4057
+ return chainId === ensRootChainId ? import_chains.mainnet.id : chainId;
3345
4058
  };
3346
4059
  var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
3347
4060
  return chainId === DEFAULT_EVM_CHAIN_ID ? (0, import_datasources10.getENSRootChainId)(namespaceId) : chainId;
@@ -3350,232 +4063,11 @@ var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
3350
4063
  // src/resolution/resolver-records-selection.ts
3351
4064
  var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
3352
4065
 
3353
- // src/tokenscope/assets.ts
3354
- var import_caip3 = require("caip");
3355
- var import_viem15 = require("viem");
3356
- var AssetNamespaces = {
3357
- ERC721: "erc721",
3358
- ERC1155: "erc1155"
3359
- };
3360
- function serializeAssetId(assetId) {
3361
- const { assetNamespace, contract, tokenId } = assetId;
3362
- return import_caip3.AssetId.format({
3363
- chainId: { namespace: "eip155", reference: contract.chainId.toString() },
3364
- assetName: { namespace: assetNamespace, reference: contract.address },
3365
- tokenId: uint256ToHex32(tokenId)
3366
- }).toLowerCase();
3367
- }
3368
- var buildAssetId = (contract, tokenId, assetNamespace) => {
3369
- return {
3370
- assetNamespace,
3371
- contract,
3372
- tokenId
3373
- };
3374
- };
3375
- var NFTMintStatuses = {
3376
- Minted: "minted",
3377
- Burned: "burned"
3378
- };
3379
- var formatNFTTransferEventMetadata = (metadata) => {
3380
- const serializedAssetId = serializeAssetId(metadata.nft);
3381
- return [
3382
- `Event: ${metadata.eventHandlerName}`,
3383
- `Chain ID: ${metadata.chainId}`,
3384
- `Block Number: ${metadata.blockNumber}`,
3385
- `Transaction Hash: ${metadata.transactionHash}`,
3386
- `NFT: ${serializedAssetId}`
3387
- ].map((line) => ` - ${line}`).join("\n");
3388
- };
3389
- var NFTTransferTypes = {
3390
- /**
3391
- * Initial transfer from zeroAddress to a non-zeroAddress
3392
- * Can happen at most once to a NFT AssetId
3393
- *
3394
- * Invariants:
3395
- * - NFT is not indexed and therefore has no previous mint status or owner
3396
- * - new NFT mint status is `minted`
3397
- * - new NFT owner is a non-zeroAddress
3398
- */
3399
- Mint: "mint",
3400
- /**
3401
- * Subsequent transfer from zeroAddress to a non-zeroAddress
3402
- * Can happen any number of times to a NFT AssetId as it passes in a cycle from
3403
- * mint -> burn -> remint -> burn -> remint -> ...
3404
- *
3405
- * Invariants:
3406
- * - NFT is indexed
3407
- * - previous NFT mint status was `burned`
3408
- * - previous NFT owner is the zeroAddress
3409
- * - new NFT mint status is `minted`
3410
- * - new NFT owner is a non-zeroAddress
3411
- */
3412
- Remint: "remint",
3413
- /**
3414
- * Special transfer type for improperly implemented NFT contracts that allow a NFT
3415
- * that is currently minted to be reminted before an intermediate burn.
3416
- *
3417
- * Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
3418
- * previously indexed nft had status `minted` with a non-zeroAddress owner.
3419
- *
3420
- * Invariants:
3421
- * - NFT is indexed
3422
- * - previous NFT mint status was `minted`
3423
- * - previous NFT owner was a non-zeroAddress
3424
- * - new NFT mint status is `minted`
3425
- * - new NFT owner is a non-zeroAddress
3426
- */
3427
- MintedRemint: "minted-remint",
3428
- /**
3429
- * Transfer from a non-zeroAddress to zeroAddress
3430
- *
3431
- * Invariants:
3432
- * - NFT is indexed
3433
- * - previous NFT mint status was `minted`
3434
- * - previous NFT owner is a non-zeroAddress
3435
- * - new NFT mint status is `burned`
3436
- * - new NFT owner is the zeroAddress
3437
- */
3438
- Burn: "burn",
3439
- /**
3440
- * Transfer from a non-zeroAddress to a distinct non-zeroAddress
3441
- *
3442
- * Invariants:
3443
- * - NFT is indexed
3444
- * - previous and new NFT mint status is `minted`
3445
- * - previous and new NFT owner are distinct non-zeroAddress
3446
- */
3447
- Transfer: "transfer",
3448
- /**
3449
- * Transfer from a non-zeroAddress to the same non-zeroAddress
3450
- *
3451
- * Invariants:
3452
- * - NFT is indexed
3453
- * - previous and new NFT mint status is `minted`
3454
- * - previous and new NFT owner are equivalent non-zeroAddress
3455
- */
3456
- SelfTransfer: "self-transfer",
3457
- /**
3458
- * Transfer from zeroAddress to zeroAddress for an indexed NFT
3459
- *
3460
- * Invariants:
3461
- * - NFT is indexed
3462
- * - previous and new NFT mint status is `burned`
3463
- * - previous and new NFT owner are zeroAddress
3464
- */
3465
- RemintBurn: "remint-burn",
3466
- /**
3467
- * Special transfer type for improperly implemented NFT contracts that allow a NFT
3468
- * that is currently minted to be reminted again before an intermediate burn.
3469
- *
3470
- * Transfer from zeroAddress to zeroAddress for an indexed NFT where the
3471
- * previously indexed nft had status `minted` with a non-zeroAddress owner.
3472
- *
3473
- * Invariants:
3474
- * - NFT is indexed
3475
- * - previous NFT mint status was `minted`
3476
- * - previous NFT owner was a non-zeroAddress
3477
- * - new NFT mint status is `burned`
3478
- * - new NFT owner is the zeroAddress
3479
- */
3480
- MintedRemintBurn: "minted-remint-burn",
3481
- /**
3482
- * Transfer from zeroAddress to zeroAddress for an unindexed NFT
3483
- *
3484
- * Invariants:
3485
- * - NFT is not indexed and therefore has no previous mint status or owner
3486
- * - NFT should remain unindexed and without any mint status or owner
3487
- */
3488
- MintBurn: "mint-burn"
3489
- };
3490
- var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
3491
- const isIndexed = currentlyIndexedOwner !== void 0;
3492
- const isIndexedAsMinted = isIndexed && !(0, import_viem15.isAddressEqual)(currentlyIndexedOwner, import_viem15.zeroAddress);
3493
- const isMint = (0, import_viem15.isAddressEqual)(from, import_viem15.zeroAddress);
3494
- const isBurn = (0, import_viem15.isAddressEqual)(to, import_viem15.zeroAddress);
3495
- const isSelfTransfer = (0, import_viem15.isAddressEqual)(from, to);
3496
- if (isIndexed && !(0, import_viem15.isAddressEqual)(currentlyIndexedOwner, from)) {
3497
- if (isMint && allowMintedRemint) {
3498
- } else {
3499
- throw new Error(
3500
- `Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
3501
- ${formatNFTTransferEventMetadata(metadata)}`
3502
- );
3503
- }
3504
- }
3505
- if (isSelfTransfer) {
3506
- if (isMint) {
3507
- if (!isIndexed) {
3508
- return NFTTransferTypes.MintBurn;
3509
- } else if (!isIndexedAsMinted) {
3510
- return NFTTransferTypes.RemintBurn;
3511
- } else if (allowMintedRemint) {
3512
- return NFTTransferTypes.MintedRemintBurn;
3513
- } else {
3514
- throw new Error(
3515
- `Error: Invalid state transition from minted -> remint-burn
3516
- ${formatNFTTransferEventMetadata(metadata)}`
3517
- );
3518
- }
3519
- } else {
3520
- if (!isIndexed) {
3521
- throw new Error(
3522
- `Error: Invalid state transition from unindexed -> self-transfer
3523
- ${formatNFTTransferEventMetadata(metadata)}`
3524
- );
3525
- } else if (!isIndexedAsMinted) {
3526
- throw new Error(
3527
- `Error: invalid state transition from burned -> self-transfer
3528
- ${formatNFTTransferEventMetadata(metadata)}`
3529
- );
3530
- } else {
3531
- return NFTTransferTypes.SelfTransfer;
3532
- }
3533
- }
3534
- } else if (isMint) {
3535
- if (!isIndexed) {
3536
- return NFTTransferTypes.Mint;
3537
- } else if (!isIndexedAsMinted) {
3538
- return NFTTransferTypes.Remint;
3539
- } else if (allowMintedRemint) {
3540
- return NFTTransferTypes.MintedRemint;
3541
- } else {
3542
- throw new Error(
3543
- `Error: Invalid state transition from minted -> mint
3544
- ${formatNFTTransferEventMetadata(metadata)}`
3545
- );
3546
- }
3547
- } else if (isBurn) {
3548
- if (!isIndexed) {
3549
- throw new Error(
3550
- `Error: Invalid state transition from unindexed -> burn
3551
- ${formatNFTTransferEventMetadata(metadata)}`
3552
- );
3553
- } else if (!isIndexedAsMinted) {
3554
- throw new Error(
3555
- `Error: Invalid state transition from burned -> burn
3556
- ${formatNFTTransferEventMetadata(metadata)}`
3557
- );
3558
- } else {
3559
- return NFTTransferTypes.Burn;
3560
- }
3561
- } else {
3562
- if (!isIndexed) {
3563
- throw new Error(
3564
- `Error: Invalid state transition from unindexed -> transfer
3565
- ${formatNFTTransferEventMetadata(metadata)}`
3566
- );
3567
- } else if (!isIndexedAsMinted) {
3568
- throw new Error(
3569
- `Error: Invalid state transition from burned -> transfer
3570
- ${formatNFTTransferEventMetadata(metadata)}`
3571
- );
3572
- } else {
3573
- return NFTTransferTypes.Transfer;
3574
- }
3575
- }
3576
- };
3577
-
3578
- // src/tracing/index.ts
4066
+ // src/tracing/ens-protocol-tracing.ts
4067
+ var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
4068
+ var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
4069
+ var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
4070
+ var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
3579
4071
  var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
3580
4072
  TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
3581
4073
  TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
@@ -3600,8 +4092,4 @@ var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolS
3600
4092
  ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
3601
4093
  return ReverseResolutionProtocolStep2;
3602
4094
  })(ReverseResolutionProtocolStep || {});
3603
- var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
3604
- var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
3605
- var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
3606
- var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
3607
4095
  //# sourceMappingURL=index.cjs.map