@ensnode/ensnode-react 0.35.0 → 1.0.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/README.md CHANGED
@@ -80,6 +80,7 @@ function DisplayPrimaryName() {
80
80
  const { data, isLoading, error } = usePrimaryName({
81
81
  address: "0x179A862703a4adfb29896552DF9e307980D19285",
82
82
  chainId: mainnet.id,
83
+ accelerate: true, // Attempt Protocol Acceleration
83
84
  });
84
85
 
85
86
  if (isLoading) return <div>Loading...</div>;
@@ -181,7 +182,7 @@ const { data, isLoading, error, refetch } = useRecords({
181
182
 
182
183
  ### `usePrimaryName`
183
184
 
184
- Hook that resolves the primary name of the provided `address` on the specified `chainId`, via ENSNode, which implements Protocol Acceleration for indexed names. If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to determine the `address`'s Default Name directly.
185
+ Hook that resolves the primary name of the provided `address` on the specified `chainId`, via ENSNode, which implements Protocol Acceleration for indexed names. If the chainId-specific Primary Name is not defined, but the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to determine the `address`'s Default Name directly.
185
186
 
186
187
  The returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name). If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.
187
188
 
@@ -199,12 +200,13 @@ The returned Primary Name, if set, is guaranteed to be a [Normalized Name](https
199
200
  const { data, isLoading, error, refetch } = usePrimaryName({
200
201
  address: "0x179A862703a4adfb29896552DF9e307980D19285",
201
202
  chainId: 10, // Optimism
203
+ accelerate: true, // Attempt Protocol Acceleration
202
204
  });
203
205
  ```
204
206
 
205
207
  ### `usePrimaryNames`
206
208
 
207
- Hook that resolves the primary names of the provided `address` on the specified chainIds, via ENSNode, which implements Protocol Acceleration for indexed names. If the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default Name will be returned for all chainIds for which there is not a chain-specific Primary Name. To avoid misuse, you _may not_ query the Default EVM Chain Id (`0`) directly, and should rely on the aforementioned per-chain defaulting behavior.
209
+ Hook that resolves the primary names of the provided `address` on the specified chainIds, via ENSNode, which implements Protocol Acceleration for indexed names. For each Primary Name, if the chainId-specific Primary Name is not defined, but the `address` specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default Name will be returned. You _may not_ query the Default EVM Chain Id (`0`) directly, and should rely on the aforementioned per-chain defaulting behavior.
208
210
 
209
211
  Each returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name). If the primary name set for the address on any chain is not normalized, `null` is returned for that chain as if no primary name was set.
210
212
 
@@ -284,7 +286,8 @@ const [address, setAddress] = useState("");
284
286
  // only executes when address is not null
285
287
  const { data } = usePrimaryName({
286
288
  address: address || null,
287
- chainId: 1
289
+ chainId: 1,
290
+ accelerate: true, // Attempt Protocol Acceleration
288
291
  });
289
292
  ```
290
293
 
@@ -297,6 +300,7 @@ const [showPrimaryName, setShowPrimaryName] = useState(false);
297
300
  const { data } = usePrimaryName({
298
301
  address: "0x179A862703a4adfb29896552DF9e307980D19285",
299
302
  chainId: 1,
303
+ accelerate: true, // Attempt Protocol Acceleration
300
304
  query: { enabled: showPrimaryName },
301
305
  });
302
306
  ```
package/dist/index.cjs CHANGED
@@ -20,104 +20,46 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ASSUME_IMMUTABLE_QUERY: () => ASSUME_IMMUTABLE_QUERY,
23
24
  ENSNodeContext: () => ENSNodeContext,
24
25
  ENSNodeProvider: () => ENSNodeProvider,
25
26
  createConfig: () => createConfig,
26
- useENSIndexerConfig: () => useENSIndexerConfig,
27
+ createConfigQueryOptions: () => createConfigQueryOptions,
28
+ createIndexingStatusQueryOptions: () => createIndexingStatusQueryOptions,
29
+ createPrimaryNameQueryOptions: () => createPrimaryNameQueryOptions,
30
+ createPrimaryNamesQueryOptions: () => createPrimaryNamesQueryOptions,
31
+ createRecordsQueryOptions: () => createRecordsQueryOptions,
32
+ createRegistrarActionsQueryOptions: () => createRegistrarActionsQueryOptions,
33
+ queryKeys: () => queryKeys,
27
34
  useENSNodeConfig: () => useENSNodeConfig,
35
+ useENSNodeSDKConfig: () => useENSNodeSDKConfig,
28
36
  useIndexingStatus: () => useIndexingStatus,
29
37
  usePrimaryName: () => usePrimaryName,
30
38
  usePrimaryNames: () => usePrimaryNames,
31
- useRecords: () => useRecords
39
+ useRecords: () => useRecords,
40
+ useRegistrarActions: () => useRegistrarActions,
41
+ useResolvedIdentity: () => useResolvedIdentity,
42
+ useSwrQuery: () => useSwrQuery
32
43
  });
33
44
  module.exports = __toCommonJS(index_exports);
34
45
 
35
- // src/provider.tsx
36
- var import_ensnode_sdk = require("@ensnode/ensnode-sdk");
37
- var import_react_query = require("@tanstack/react-query");
38
- var import_react2 = require("react");
39
-
40
46
  // src/context.ts
41
47
  var import_react = require("react");
42
48
  var ENSNodeContext = (0, import_react.createContext)(void 0);
43
49
  ENSNodeContext.displayName = "ENSNodeContext";
44
50
 
45
- // src/provider.tsx
46
- function ENSNodeInternalProvider({
47
- children,
48
- config
49
- }) {
50
- const memoizedConfig = (0, import_react2.useMemo)(() => config, [config]);
51
- return (0, import_react2.createElement)(ENSNodeContext.Provider, { value: memoizedConfig }, children);
52
- }
53
- function ENSNodeProvider(parameters) {
54
- const { children, config, queryClient, queryClientOptions } = parameters;
55
- let hasExistingQueryClient = false;
56
- try {
57
- hasExistingQueryClient = Boolean((0, import_react_query.useQueryClient)());
58
- } catch {
59
- hasExistingQueryClient = false;
60
- }
61
- if (queryClient) {
62
- if (!hasExistingQueryClient) {
63
- throw new Error(
64
- "When providing a custom queryClient, you must wrap your app with QueryClientProvider. Either remove the queryClient prop to use auto-managed setup, or wrap with QueryClientProvider."
65
- );
66
- }
67
- return (0, import_react2.createElement)(ENSNodeInternalProvider, { config, children });
68
- }
69
- if (hasExistingQueryClient) {
70
- return (0, import_react2.createElement)(ENSNodeInternalProvider, { config, children });
71
- }
72
- const defaultQueryClient = (0, import_react2.useMemo)(
73
- () => new import_react_query.QueryClient({
74
- defaultOptions: {
75
- queries: {
76
- retry: 3,
77
- staleTime: 1e3 * 60 * 5,
78
- // 5 minutes
79
- gcTime: 1e3 * 60 * 30
80
- // 30 minutes
81
- }
82
- },
83
- ...queryClientOptions
84
- }),
85
- [queryClientOptions]
86
- );
87
- return (0, import_react2.createElement)(
88
- import_react_query.QueryClientProvider,
89
- { client: defaultQueryClient },
90
- (0, import_react2.createElement)(ENSNodeInternalProvider, { config, children })
91
- );
92
- }
93
- function createConfig(options) {
94
- const url = options?.url ? new URL(options.url) : import_ensnode_sdk.ENSNodeClient.defaultOptions().url;
95
- return {
96
- client: {
97
- ...import_ensnode_sdk.ENSNodeClient.defaultOptions(),
98
- url
99
- }
100
- };
101
- }
102
-
103
51
  // src/hooks/useENSNodeConfig.ts
104
- var import_react3 = require("react");
105
- function useENSNodeConfig(config) {
106
- const contextConfig = (0, import_react3.useContext)(ENSNodeContext);
107
- const resolvedConfig = config ?? contextConfig;
108
- if (!resolvedConfig) {
109
- throw new Error(
110
- "useENSNodeConfig must be used within an ENSNodeProvider or you must pass a config parameter"
111
- );
112
- }
113
- return resolvedConfig;
114
- }
115
-
116
- // src/hooks/useRecords.ts
117
- var import_react_query2 = require("@tanstack/react-query");
52
+ var import_react_query = require("@tanstack/react-query");
118
53
 
119
54
  // src/utils/query.ts
120
- var import_ensnode_sdk2 = require("@ensnode/ensnode-sdk");
55
+ var import_ensnode_sdk = require("@ensnode/ensnode-sdk");
56
+ var ASSUME_IMMUTABLE_QUERY = {
57
+ staleTime: Infinity,
58
+ gcTime: Infinity,
59
+ refetchOnWindowFocus: false,
60
+ refetchOnReconnect: false,
61
+ refetchOnMount: false
62
+ };
121
63
  var queryKeys = {
122
64
  base: (url) => ["ensnode", url],
123
65
  resolve: (url) => [...queryKeys.base(url), "resolve"],
@@ -125,14 +67,15 @@ var queryKeys = {
125
67
  primaryName: (url, args) => [...queryKeys.resolve(url), "primary-name", args],
126
68
  primaryNames: (url, args) => [...queryKeys.resolve(url), "primary-names", args],
127
69
  config: (url) => [...queryKeys.base(url), "config"],
128
- indexingStatus: (url, args) => [...queryKeys.base(url), "config", args]
70
+ indexingStatus: (url) => [...queryKeys.base(url), "indexing-status"],
71
+ registrarActions: (url, args) => [...queryKeys.base(url), "registrar-actions", args]
129
72
  };
130
73
  function createRecordsQueryOptions(config, args) {
131
74
  return {
132
75
  enabled: true,
133
76
  queryKey: queryKeys.records(config.client.url.href, args),
134
77
  queryFn: async () => {
135
- const client = new import_ensnode_sdk2.ENSNodeClient(config.client);
78
+ const client = new import_ensnode_sdk.ENSNodeClient(config.client);
136
79
  return client.resolveRecords(args.name, args.selection, args);
137
80
  }
138
81
  };
@@ -142,7 +85,7 @@ function createPrimaryNameQueryOptions(config, args) {
142
85
  enabled: true,
143
86
  queryKey: queryKeys.primaryName(config.client.url.href, args),
144
87
  queryFn: async () => {
145
- const client = new import_ensnode_sdk2.ENSNodeClient(config.client);
88
+ const client = new import_ensnode_sdk.ENSNodeClient(config.client);
146
89
  return client.resolvePrimaryName(args.address, args.chainId, args);
147
90
  }
148
91
  };
@@ -152,42 +95,81 @@ function createPrimaryNamesQueryOptions(config, args) {
152
95
  enabled: true,
153
96
  queryKey: queryKeys.primaryNames(config.client.url.href, args),
154
97
  queryFn: async () => {
155
- const client = new import_ensnode_sdk2.ENSNodeClient(config.client);
98
+ const client = new import_ensnode_sdk.ENSNodeClient(config.client);
156
99
  return client.resolvePrimaryNames(args.address, args);
157
100
  }
158
101
  };
159
102
  }
160
- function createENSIndexerConfigQueryOptions(config) {
103
+ function createConfigQueryOptions(config) {
161
104
  return {
162
105
  enabled: true,
163
106
  queryKey: queryKeys.config(config.client.url.href),
164
107
  queryFn: async () => {
165
- const client = new import_ensnode_sdk2.ENSNodeClient(config.client);
108
+ const client = new import_ensnode_sdk.ENSNodeClient(config.client);
166
109
  return client.config();
167
110
  }
168
111
  };
169
112
  }
170
- function createIndexingStatusQueryOptions(config, args) {
113
+ function createIndexingStatusQueryOptions(config) {
171
114
  return {
172
115
  enabled: true,
173
- queryKey: queryKeys.indexingStatus(config.client.url.href, args),
116
+ queryKey: queryKeys.indexingStatus(config.client.url.href),
174
117
  queryFn: async () => {
175
- const client = new import_ensnode_sdk2.ENSNodeClient(config.client);
176
- return client.indexingStatus(args);
118
+ const client = new import_ensnode_sdk.ENSNodeClient(config.client);
119
+ return client.indexingStatus();
120
+ }
121
+ };
122
+ }
123
+ function createRegistrarActionsQueryOptions(config, args) {
124
+ return {
125
+ enabled: true,
126
+ queryKey: queryKeys.registrarActions(config.client.url.href, args),
127
+ queryFn: async () => {
128
+ const client = new import_ensnode_sdk.ENSNodeClient(config.client);
129
+ return client.registrarActions(args);
177
130
  }
178
131
  };
179
132
  }
180
133
 
181
- // src/hooks/useRecords.ts
182
- function useRecords(parameters) {
183
- const { config, query = {}, name, ...args } = parameters;
184
- const _config = useENSNodeConfig(config);
185
- const canEnable = name !== null;
186
- const queryOptions = canEnable ? createRecordsQueryOptions(_config, { ...args, name }) : { enabled: false, queryKey: ["disabled"] };
134
+ // src/hooks/useENSNodeSDKConfig.ts
135
+ var import_react2 = require("react");
136
+ function useENSNodeSDKConfig(config) {
137
+ const contextConfig = (0, import_react2.useContext)(ENSNodeContext);
138
+ const resolvedConfig = config ?? contextConfig;
139
+ if (!resolvedConfig) {
140
+ throw new Error(
141
+ "useENSNodeSDKConfig must be used within an ENSNodeProvider or you must pass a config parameter"
142
+ );
143
+ }
144
+ return resolvedConfig;
145
+ }
146
+
147
+ // src/hooks/useENSNodeConfig.ts
148
+ function useENSNodeConfig(parameters = {}) {
149
+ const { config, query = {} } = parameters;
150
+ const _config = useENSNodeSDKConfig(config);
151
+ const queryOptions = createConfigQueryOptions(_config);
187
152
  const options = {
188
153
  ...queryOptions,
154
+ ...ASSUME_IMMUTABLE_QUERY,
189
155
  ...query,
190
- enabled: canEnable && (query.enabled ?? queryOptions.enabled)
156
+ enabled: query.enabled ?? queryOptions.enabled
157
+ };
158
+ return (0, import_react_query.useQuery)(options);
159
+ }
160
+
161
+ // src/hooks/useIndexingStatus.ts
162
+ var import_react_query2 = require("@tanstack/react-query");
163
+ function useIndexingStatus(parameters = {}) {
164
+ const { config, query = {} } = parameters;
165
+ const _config = useENSNodeSDKConfig(config);
166
+ const queryOptions = createIndexingStatusQueryOptions(_config);
167
+ const options = {
168
+ ...queryOptions,
169
+ refetchInterval: 10 * 1e3,
170
+ // 10 seconds - indexing status changes frequently
171
+ ...query,
172
+ enabled: query.enabled ?? queryOptions.enabled
191
173
  };
192
174
  return (0, import_react_query2.useQuery)(options);
193
175
  }
@@ -196,7 +178,7 @@ function useRecords(parameters) {
196
178
  var import_react_query3 = require("@tanstack/react-query");
197
179
  function usePrimaryName(parameters) {
198
180
  const { config, query = {}, address, ...args } = parameters;
199
- const _config = useENSNodeConfig(config);
181
+ const _config = useENSNodeSDKConfig(config);
200
182
  const canEnable = address !== null;
201
183
  const queryOptions = canEnable ? createPrimaryNameQueryOptions(_config, { ...args, address }) : { enabled: false, queryKey: ["disabled"] };
202
184
  const options = {
@@ -211,7 +193,7 @@ function usePrimaryName(parameters) {
211
193
  var import_react_query4 = require("@tanstack/react-query");
212
194
  function usePrimaryNames(parameters) {
213
195
  const { config, query = {}, address, ...args } = parameters;
214
- const _config = useENSNodeConfig(config);
196
+ const _config = useENSNodeSDKConfig(config);
215
197
  const canEnable = address !== null;
216
198
  const queryOptions = canEnable ? createPrimaryNamesQueryOptions(_config, { ...args, address }) : { enabled: false, queryKey: ["disabled"] };
217
199
  const options = {
@@ -222,31 +204,178 @@ function usePrimaryNames(parameters) {
222
204
  return (0, import_react_query4.useQuery)(options);
223
205
  }
224
206
 
225
- // src/hooks/useENSIndexerConfig.ts
207
+ // src/hooks/useRecords.ts
226
208
  var import_react_query5 = require("@tanstack/react-query");
227
- function useENSIndexerConfig(parameters = {}) {
228
- const { config, query = {} } = parameters;
229
- const _config = useENSNodeConfig(config);
230
- const queryOptions = createENSIndexerConfigQueryOptions(_config);
209
+ function useRecords(parameters) {
210
+ const { config, query = {}, name, ...args } = parameters;
211
+ const _config = useENSNodeSDKConfig(config);
212
+ const canEnable = name !== null;
213
+ const queryOptions = canEnable ? createRecordsQueryOptions(_config, { ...args, name }) : { enabled: false, queryKey: ["disabled"] };
231
214
  const options = {
232
215
  ...queryOptions,
233
216
  ...query,
234
- enabled: query.enabled ?? queryOptions.enabled
217
+ enabled: canEnable && (query.enabled ?? queryOptions.enabled)
235
218
  };
236
219
  return (0, import_react_query5.useQuery)(options);
237
220
  }
238
221
 
239
- // src/hooks/useIndexingStatus.ts
222
+ // src/hooks/useRegistrarActions.ts
240
223
  var import_react_query6 = require("@tanstack/react-query");
241
- function useIndexingStatus(parameters = {}) {
242
- const { config, query = {}, ...args } = parameters;
243
- const _config = useENSNodeConfig(config);
244
- const queryOptions = createIndexingStatusQueryOptions(_config, { ...args });
224
+ function useRegistrarActions(parameters = {}) {
225
+ const { config, query = {} } = parameters;
226
+ const _config = useENSNodeSDKConfig(config);
227
+ const queryOptions = createRegistrarActionsQueryOptions(_config, parameters);
245
228
  const options = {
246
229
  ...queryOptions,
230
+ refetchInterval: 10 * 1e3,
231
+ // 10 seconds - latest registrar actions change frequently
247
232
  ...query,
248
233
  enabled: query.enabled ?? queryOptions.enabled
249
234
  };
250
235
  return (0, import_react_query6.useQuery)(options);
251
236
  }
237
+
238
+ // src/hooks/useResolvedIdentity.ts
239
+ var import_ensnode_sdk2 = require("@ensnode/ensnode-sdk");
240
+ function useResolvedIdentity(parameters) {
241
+ const { identity, namespaceId, accelerate, ...args } = parameters;
242
+ const {
243
+ data: primaryNameData,
244
+ status,
245
+ ...query
246
+ } = usePrimaryName({
247
+ address: identity.address,
248
+ chainId: (0, import_ensnode_sdk2.getResolvePrimaryNameChainIdParam)(identity.chainId, namespaceId),
249
+ accelerate,
250
+ ...args
251
+ });
252
+ let result;
253
+ if (status === "pending") {
254
+ result = identity;
255
+ } else if (status === "error") {
256
+ result = {
257
+ resolutionStatus: import_ensnode_sdk2.ResolutionStatusIds.Unknown,
258
+ chainId: identity.chainId,
259
+ address: identity.address
260
+ };
261
+ } else if (primaryNameData.name === null) {
262
+ result = {
263
+ resolutionStatus: import_ensnode_sdk2.ResolutionStatusIds.Unnamed,
264
+ chainId: identity.chainId,
265
+ address: identity.address,
266
+ name: null
267
+ };
268
+ } else {
269
+ result = {
270
+ resolutionStatus: import_ensnode_sdk2.ResolutionStatusIds.Named,
271
+ chainId: identity.chainId,
272
+ address: identity.address,
273
+ name: primaryNameData.name
274
+ };
275
+ }
276
+ return {
277
+ ...query,
278
+ identity: result
279
+ };
280
+ }
281
+
282
+ // src/hooks/useSwrQuery.ts
283
+ var import_react_query7 = require("@tanstack/react-query");
284
+ var import_react3 = require("react");
285
+ function useSwrQuery(options, queryClient) {
286
+ const queryClientFromContext = (0, import_react_query7.useQueryClient)();
287
+ const derivedQueryClient = queryClient ?? queryClientFromContext;
288
+ const cachedSuccessfulResult = derivedQueryClient.getQueryData(options.queryKey);
289
+ const queryResult = (0, import_react_query7.useQuery)(
290
+ {
291
+ ...options,
292
+ // cached result can never be stale
293
+ staleTime: cachedSuccessfulResult ? Infinity : void 0,
294
+ // cached result can never be removed by garbage collector
295
+ gcTime: cachedSuccessfulResult ? Infinity : void 0
296
+ },
297
+ queryClient
298
+ );
299
+ const memoizedQueryResult = (0, import_react3.useMemo)(() => {
300
+ if (queryResult.isError && cachedSuccessfulResult) {
301
+ return {
302
+ ...queryResult,
303
+ // set error props
304
+ isError: false,
305
+ error: null,
306
+ isRefetchError: false,
307
+ isLoadingError: false,
308
+ // st success props
309
+ isSuccess: true,
310
+ status: "success",
311
+ data: cachedSuccessfulResult
312
+ };
313
+ }
314
+ return queryResult;
315
+ }, [queryResult, cachedSuccessfulResult]);
316
+ return memoizedQueryResult;
317
+ }
318
+
319
+ // src/provider.tsx
320
+ var import_react_query8 = require("@tanstack/react-query");
321
+ var import_react4 = require("react");
322
+ var import_ensnode_sdk3 = require("@ensnode/ensnode-sdk");
323
+ function ENSNodeInternalProvider({
324
+ children,
325
+ config
326
+ }) {
327
+ const memoizedConfig = (0, import_react4.useMemo)(() => config, [config]);
328
+ return (0, import_react4.createElement)(ENSNodeContext.Provider, { value: memoizedConfig }, children);
329
+ }
330
+ function ENSNodeProvider(parameters) {
331
+ const { children, config, queryClient, queryClientOptions } = parameters;
332
+ let hasExistingQueryClient = false;
333
+ try {
334
+ hasExistingQueryClient = Boolean((0, import_react_query8.useQueryClient)());
335
+ } catch {
336
+ hasExistingQueryClient = false;
337
+ }
338
+ if (queryClient) {
339
+ if (!hasExistingQueryClient) {
340
+ throw new Error(
341
+ "When providing a custom queryClient, you must wrap your app with QueryClientProvider. Either remove the queryClient prop to use auto-managed setup, or wrap with QueryClientProvider."
342
+ );
343
+ }
344
+ return (0, import_react4.createElement)(ENSNodeInternalProvider, { config, children });
345
+ }
346
+ if (hasExistingQueryClient) {
347
+ return (0, import_react4.createElement)(ENSNodeInternalProvider, { config, children });
348
+ }
349
+ const defaultQueryClient = (0, import_react4.useMemo)(
350
+ () => new import_react_query8.QueryClient({
351
+ defaultOptions: {
352
+ queries: {
353
+ retry: 3,
354
+ staleTime: 1e3 * 60 * 5,
355
+ // 5 minutes
356
+ gcTime: 1e3 * 60 * 30,
357
+ // 30 minutes
358
+ refetchInterval: 1e3 * 10
359
+ // 10 seconds
360
+ }
361
+ },
362
+ ...queryClientOptions
363
+ }),
364
+ [queryClientOptions]
365
+ );
366
+ return (0, import_react4.createElement)(
367
+ import_react_query8.QueryClientProvider,
368
+ { client: defaultQueryClient },
369
+ (0, import_react4.createElement)(ENSNodeInternalProvider, { config, children })
370
+ );
371
+ }
372
+ function createConfig(options) {
373
+ const url = options?.url ? new URL(options.url) : import_ensnode_sdk3.ENSNodeClient.defaultOptions().url;
374
+ return {
375
+ client: {
376
+ ...import_ensnode_sdk3.ENSNodeClient.defaultOptions(),
377
+ url
378
+ }
379
+ };
380
+ }
252
381
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/provider.tsx","../src/context.ts","../src/hooks/useENSNodeConfig.ts","../src/hooks/useRecords.ts","../src/utils/query.ts","../src/hooks/usePrimaryName.ts","../src/hooks/usePrimaryNames.ts","../src/hooks/useENSIndexerConfig.ts","../src/hooks/useIndexingStatus.ts"],"sourcesContent":["export type { QueryClient } from \"@tanstack/react-query\";\n\nexport type { ResolverRecordsSelection } from \"@ensnode/ensnode-sdk\";\n\nexport * from \"./provider\";\nexport * from \"./context\";\nexport * from \"./hooks\";\nexport * from \"./types\";\n","\"use client\";\n\nimport { ENSNodeClient } from \"@ensnode/ensnode-sdk\";\nimport { QueryClient, QueryClientProvider, useQueryClient } from \"@tanstack/react-query\";\nimport { createElement, useMemo } from \"react\";\n\nimport { ENSNodeContext } from \"./context\";\nimport type { ENSNodeConfig } from \"./types\";\n\nexport interface ENSNodeProviderProps {\n /** ENSNode configuration */\n config: ENSNodeConfig;\n\n /**\n * Optional QueryClient instance. If provided, you must wrap your app with QueryClientProvider yourself.\n * If not provided, ENSNodeProvider will create and manage its own QueryClient internally.\n */\n queryClient?: QueryClient;\n\n /**\n * Custom query client options when auto-creating a QueryClient.\n * Only used when queryClient is not provided.\n */\n queryClientOptions?: ConstructorParameters<typeof QueryClient>[0];\n}\n\nfunction ENSNodeInternalProvider({\n children,\n config,\n}: {\n children: React.ReactNode;\n config: ENSNodeConfig;\n}) {\n // Memoize the config to prevent unnecessary re-renders\n const memoizedConfig = useMemo(() => config, [config]);\n\n return createElement(ENSNodeContext.Provider, { value: memoizedConfig }, children);\n}\n\nexport function ENSNodeProvider(parameters: React.PropsWithChildren<ENSNodeProviderProps>) {\n const { children, config, queryClient, queryClientOptions } = parameters;\n\n // Check if we're already inside a QueryClientProvider\n let hasExistingQueryClient = false;\n try {\n hasExistingQueryClient = Boolean(useQueryClient());\n } catch {\n // useQueryClient throws if not inside a QueryClientProvider\n hasExistingQueryClient = false;\n }\n\n // If user provided a queryClient, they must handle QueryClientProvider themselves\n if (queryClient) {\n if (!hasExistingQueryClient) {\n throw new Error(\n \"When providing a custom queryClient, you must wrap your app with QueryClientProvider. \" +\n \"Either remove the queryClient prop to use auto-managed setup, or wrap with QueryClientProvider.\",\n );\n }\n return createElement(ENSNodeInternalProvider, { config, children });\n }\n\n // If already inside a QueryClientProvider, just use that\n if (hasExistingQueryClient) {\n return createElement(ENSNodeInternalProvider, { config, children });\n }\n\n // Create our own QueryClient and QueryClientProvider\n const defaultQueryClient = useMemo(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n retry: 3,\n staleTime: 1000 * 60 * 5, // 5 minutes\n gcTime: 1000 * 60 * 30, // 30 minutes\n },\n },\n ...queryClientOptions,\n }),\n [queryClientOptions],\n );\n\n return createElement(\n QueryClientProvider,\n { client: defaultQueryClient },\n createElement(ENSNodeInternalProvider, { config, children }),\n );\n}\n\n/**\n * Helper function to create ENSNode configuration\n */\nexport function createConfig(options?: {\n url?: string | URL;\n}): ENSNodeConfig {\n const url = options?.url ? new URL(options.url) : ENSNodeClient.defaultOptions().url;\n\n return {\n client: {\n ...ENSNodeClient.defaultOptions(),\n url,\n },\n };\n}\n","import { createContext } from \"react\";\n\nimport type { ENSNodeConfig } from \"./types\";\n\n/**\n * React context for ENSNode configuration\n */\nexport const ENSNodeContext = createContext<ENSNodeConfig | undefined>(undefined);\n\n/**\n * Display name for debugging\n */\nENSNodeContext.displayName = \"ENSNodeContext\";\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport { ENSNodeContext } from \"../context\";\nimport type { ENSNodeConfig } from \"../types\";\n\n/**\n * Hook to access the ENSNode configuration from context or parameters\n *\n * @param parameters - Optional config parameter that overrides context\n * @returns The ENSNode configuration\n * @throws Error if no config is available in context or parameters\n */\nexport function useENSNodeConfig<TConfig extends ENSNodeConfig = ENSNodeConfig>(\n config: TConfig | undefined,\n): TConfig {\n const contextConfig = useContext(ENSNodeContext);\n\n // Use provided config or fall back to context\n const resolvedConfig = config ?? contextConfig;\n\n if (!resolvedConfig) {\n throw new Error(\n \"useENSNodeConfig must be used within an ENSNodeProvider or you must pass a config parameter\",\n );\n }\n\n return resolvedConfig as TConfig;\n}\n","\"use client\";\n\nimport type { ResolverRecordsSelection } from \"@ensnode/ensnode-sdk\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport type { ConfigParameter, UseRecordsParameters } from \"../types\";\nimport { createRecordsQueryOptions } from \"../utils/query\";\nimport { useENSNodeConfig } from \"./useENSNodeConfig\";\n\n/**\n * Resolves records for an ENS name (Forward Resolution).\n *\n * The returned `name` field, if set, is guaranteed to be a normalized name.\n * If the name record returned by the resolver is not normalized, `null` is returned as if no name record was set.\n *\n * @param parameters - Configuration for the ENS name resolution\n * @returns Query result with resolved records\n *\n * @example\n * ```typescript\n * import { useRecords } from \"@ensnode/ensnode-react\";\n *\n * function DisplayNameRecords() {\n * const { data, isLoading, error } = useRecords({\n * name: \"jesse.base.eth\",\n * selection: {\n * addresses: [60], // ETH CoinType\n * texts: [\"avatar\", \"com.twitter\"]\n * }\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * <h3>Resolved Records for vitalik.eth</h3>\n * {data.records.addresses && (\n * <p>ETH Address: {data.records.addresses[60]}</p>\n * )}\n * {data.records.texts && (\n * <div>\n * <p>Avatar: {data.records.texts.avatar}</p>\n * <p>Twitter: {data.records.texts[\"com.twitter\"]}</p>\n * </div>\n * )}\n * </div>\n * );\n * }\n * ```\n */\nexport function useRecords<SELECTION extends ResolverRecordsSelection>(\n parameters: UseRecordsParameters<SELECTION> & ConfigParameter,\n) {\n const { config, query = {}, name, ...args } = parameters;\n const _config = useENSNodeConfig(config);\n\n const canEnable = name !== null;\n\n const queryOptions = canEnable\n ? createRecordsQueryOptions(_config, { ...args, name })\n : { enabled: false, queryKey: [\"disabled\"] as const };\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: canEnable && (query.enabled ?? queryOptions.enabled),\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport {\n ENSNodeClient,\n IndexingStatusRequest,\n ResolvePrimaryNameRequest,\n ResolvePrimaryNamesRequest,\n ResolveRecordsRequest,\n ResolverRecordsSelection,\n} from \"@ensnode/ensnode-sdk\";\nimport type { ENSNodeConfig } from \"../types\";\n\n/**\n * Query keys for hooks. Simply keys by path and arguments.\n */\nexport const queryKeys = {\n base: (url: string) => [\"ensnode\", url] as const,\n\n resolve: (url: string) => [...queryKeys.base(url), \"resolve\"] as const,\n\n records: (url: string, args: ResolveRecordsRequest<any>) =>\n [...queryKeys.resolve(url), \"records\", args] as const,\n\n primaryName: (url: string, args: ResolvePrimaryNameRequest) =>\n [...queryKeys.resolve(url), \"primary-name\", args] as const,\n\n primaryNames: (url: string, args: ResolvePrimaryNamesRequest) =>\n [...queryKeys.resolve(url), \"primary-names\", args] as const,\n\n config: (url: string) => [...queryKeys.base(url), \"config\"] as const,\n\n indexingStatus: (url: string, args: IndexingStatusRequest) =>\n [...queryKeys.base(url), \"config\", args] as const,\n};\n\n/**\n * Creates query options for Records Resolution\n */\nexport function createRecordsQueryOptions<SELECTION extends ResolverRecordsSelection>(\n config: ENSNodeConfig,\n args: ResolveRecordsRequest<SELECTION>,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.records(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.resolveRecords(args.name, args.selection, args);\n },\n };\n}\n\n/**\n * Creates query options for Primary Name Resolution\n */\nexport function createPrimaryNameQueryOptions(\n config: ENSNodeConfig,\n args: ResolvePrimaryNameRequest,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.primaryName(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.resolvePrimaryName(args.address, args.chainId, args);\n },\n };\n}\n\n/**\n * Creates query options for Primary Name Resolution\n */\nexport function createPrimaryNamesQueryOptions(\n config: ENSNodeConfig,\n args: ResolvePrimaryNamesRequest,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.primaryNames(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.resolvePrimaryNames(args.address, args);\n },\n };\n}\n\n/**\n * Creates query options for ENSIndexer Config API\n */\nexport function createENSIndexerConfigQueryOptions(config: ENSNodeConfig) {\n return {\n enabled: true,\n queryKey: queryKeys.config(config.client.url.href),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.config();\n },\n };\n}\n\n/**\n * Creates query options for ENSIndexer Indexing Status API\n */\nexport function createIndexingStatusQueryOptions(\n config: ENSNodeConfig,\n args: IndexingStatusRequest,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.indexingStatus(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.indexingStatus(args);\n },\n };\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ConfigParameter, UsePrimaryNameParameters } from \"../types\";\nimport { createPrimaryNameQueryOptions } from \"../utils/query\";\nimport { useENSNodeConfig } from \"./useENSNodeConfig\";\n\n/**\n * Resolves the primary name of a specified address (Reverse Resolution).\n *\n * The returned Primary Name, if set, is guaranteed to be a normalized name.\n * If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.\n *\n * @param parameters - Configuration for the address resolution\n * @returns Query result with resolved primary name\n *\n * @example\n * ```typescript\n * import { usePrimaryName } from \"@ensnode/ensnode-react\";\n *\n * function DisplayPrimaryNameAndAvatar() {\n * const { data, isLoading, error } = usePrimaryName({\n * address: \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n * chainId: 1, // Ethereum Mainnet\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * <h3>Primary Name (for Mainnet)</h3>\n * <p>{data.name ?? \"No Primary Name\"}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePrimaryName(parameters: UsePrimaryNameParameters & ConfigParameter) {\n const { config, query = {}, address, ...args } = parameters;\n const _config = useENSNodeConfig(config);\n\n const canEnable = address !== null;\n\n const queryOptions = canEnable\n ? createPrimaryNameQueryOptions(_config, { ...args, address })\n : { enabled: false, queryKey: [\"disabled\"] as const };\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: canEnable && (query.enabled ?? queryOptions.enabled),\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ConfigParameter, UsePrimaryNamesParameters } from \"../types\";\nimport { createPrimaryNamesQueryOptions } from \"../utils/query\";\nimport { useENSNodeConfig } from \"./useENSNodeConfig\";\n\n/**\n * Resolves the primary names of a specified address across multiple chains.\n *\n * Each returned Primary Name, if set, is guaranteed to be a normalized name.\n * If the primary name set for the address on any chain is not normalized, `null` is returned for that chain as if no primary name was set.\n *\n * @param parameters - Configuration for the address resolution\n * @returns Query result with resolved primary names\n *\n * @example\n * ```typescript\n * import { usePrimaryNames } from \"@ensnode/ensnode-react\";\n *\n * function DisplayPrimaryNames() {\n * const { data, isLoading, error } = usePrimaryNames({\n * address: \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * {Object.entries(data.names).map(([chainId, name]) => (\n * <div key={chainId}>\n * <h3>Primary Name (Chain Id: {chainId})</h3>\n * <p>{name}</p>\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePrimaryNames(parameters: UsePrimaryNamesParameters & ConfigParameter) {\n const { config, query = {}, address, ...args } = parameters;\n const _config = useENSNodeConfig(config);\n\n const canEnable = address !== null;\n\n const queryOptions = canEnable\n ? createPrimaryNamesQueryOptions(_config, { ...args, address })\n : { enabled: false, queryKey: [\"disabled\"] as const };\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: canEnable && (query.enabled ?? queryOptions.enabled),\n };\n\n return useQuery(options);\n}\n","import { ConfigResponse } from \"@ensnode/ensnode-sdk\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ConfigParameter, QueryParameter } from \"../types\";\nimport { createENSIndexerConfigQueryOptions } from \"../utils/query\";\nimport { useENSNodeConfig } from \"./useENSNodeConfig\";\n\ntype UseENSIndexerConfigParameters = QueryParameter<ConfigResponse>;\n\nexport function useENSIndexerConfig(\n parameters: ConfigParameter & UseENSIndexerConfigParameters = {},\n) {\n const { config, query = {} } = parameters;\n const _config = useENSNodeConfig(config);\n\n const queryOptions = createENSIndexerConfigQueryOptions(_config);\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: query.enabled ?? queryOptions.enabled,\n };\n\n return useQuery(options);\n}\n","import { IndexingStatusRequest, IndexingStatusResponse } from \"@ensnode/ensnode-sdk\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ConfigParameter, QueryParameter } from \"../types\";\nimport { createIndexingStatusQueryOptions } from \"../utils/query\";\nimport { useENSNodeConfig } from \"./useENSNodeConfig\";\n\ninterface UseIndexingStatusParameters\n extends IndexingStatusRequest,\n QueryParameter<IndexingStatusResponse> {}\n\nexport function useIndexingStatus(parameters: ConfigParameter & UseIndexingStatusParameters = {}) {\n const { config, query = {}, ...args } = parameters;\n const _config = useENSNodeConfig(config);\n\n const queryOptions = createIndexingStatusQueryOptions(_config, { ...args });\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: query.enabled ?? queryOptions.enabled,\n };\n\n return useQuery(options);\n}\n"],"mappings":"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","names":["import_react","import_react","import_react_query","import_ensnode_sdk","import_react_query","import_react_query","import_react_query","import_react_query"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks/useENSNodeConfig.ts","../src/utils/query.ts","../src/hooks/useENSNodeSDKConfig.ts","../src/hooks/useIndexingStatus.ts","../src/hooks/usePrimaryName.ts","../src/hooks/usePrimaryNames.ts","../src/hooks/useRecords.ts","../src/hooks/useRegistrarActions.ts","../src/hooks/useResolvedIdentity.ts","../src/hooks/useSwrQuery.ts","../src/provider.tsx"],"sourcesContent":["export type { QueryClient } from \"@tanstack/react-query\";\n\nexport type { ResolverRecordsSelection } from \"@ensnode/ensnode-sdk\";\n\nexport * from \"./context\";\nexport * from \"./hooks\";\nexport * from \"./provider\";\nexport * from \"./types\";\nexport * from \"./utils/query\";\n","import { createContext } from \"react\";\n\nimport type { ENSNodeSDKConfig } from \"./types\";\n\n/**\n * React context for ENSNode configuration\n */\nexport const ENSNodeContext = createContext<ENSNodeSDKConfig | undefined>(undefined);\n\n/**\n * Display name for debugging\n */\nENSNodeContext.displayName = \"ENSNodeContext\";\n","import { useQuery } from \"@tanstack/react-query\";\n\nimport type { ConfigResponse } from \"@ensnode/ensnode-sdk\";\n\nimport type { QueryParameter, WithSDKConfigParameter } from \"../types\";\nimport { ASSUME_IMMUTABLE_QUERY, createConfigQueryOptions } from \"../utils/query\";\nimport { useENSNodeSDKConfig } from \"./useENSNodeSDKConfig\";\n\ntype UseENSNodeConfigParameters = QueryParameter<ConfigResponse>;\n\nexport function useENSNodeConfig(\n parameters: WithSDKConfigParameter & UseENSNodeConfigParameters = {},\n) {\n const { config, query = {} } = parameters;\n const _config = useENSNodeSDKConfig(config);\n\n const queryOptions = createConfigQueryOptions(_config);\n\n const options = {\n ...queryOptions,\n ...ASSUME_IMMUTABLE_QUERY,\n ...query,\n enabled: query.enabled ?? queryOptions.enabled,\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport type { UndefinedInitialDataOptions } from \"@tanstack/react-query\";\n\nimport {\n ENSNodeClient,\n type RegistrarActionsRequest,\n type ResolvePrimaryNameRequest,\n type ResolvePrimaryNamesRequest,\n type ResolveRecordsRequest,\n type ResolverRecordsSelection,\n} from \"@ensnode/ensnode-sdk\";\n\nimport type { ENSNodeSDKConfig } from \"../types\";\n\n/**\n * Immutable query options for data that is assumed to be immutable and should only be fetched once per full page refresh per unique key.\n * Similar to SWR's immutable: true API.\n *\n * Use this for data that is assumed not to change (e.g., records for a specific name) until the next full page refresh.\n *\n * @example\n * ```tsx\n * useRecords({\n * name: \"vitalik.eth\",\n * selection: { texts: [\"avatar\"] },\n * query: ASSUME_IMMUTABLE_QUERY\n * })\n * ```\n */\nexport const ASSUME_IMMUTABLE_QUERY = {\n staleTime: Infinity,\n gcTime: Infinity,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n refetchOnMount: false,\n} as const satisfies Partial<UndefinedInitialDataOptions>;\n\n/**\n * Query keys for hooks. Simply keys by path and arguments.\n */\nexport const queryKeys = {\n base: (url: string) => [\"ensnode\", url] as const,\n\n resolve: (url: string) => [...queryKeys.base(url), \"resolve\"] as const,\n\n records: (url: string, args: ResolveRecordsRequest<any>) =>\n [...queryKeys.resolve(url), \"records\", args] as const,\n\n primaryName: (url: string, args: ResolvePrimaryNameRequest) =>\n [...queryKeys.resolve(url), \"primary-name\", args] as const,\n\n primaryNames: (url: string, args: ResolvePrimaryNamesRequest) =>\n [...queryKeys.resolve(url), \"primary-names\", args] as const,\n\n config: (url: string) => [...queryKeys.base(url), \"config\"] as const,\n\n indexingStatus: (url: string) => [...queryKeys.base(url), \"indexing-status\"] as const,\n\n registrarActions: (url: string, args: RegistrarActionsRequest) =>\n [...queryKeys.base(url), \"registrar-actions\", args] as const,\n};\n\n/**\n * Creates query options for Records Resolution\n */\nexport function createRecordsQueryOptions<SELECTION extends ResolverRecordsSelection>(\n config: ENSNodeSDKConfig,\n args: ResolveRecordsRequest<SELECTION>,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.records(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.resolveRecords(args.name, args.selection, args);\n },\n };\n}\n\n/**\n * Creates query options for Primary Name Resolution\n */\nexport function createPrimaryNameQueryOptions(\n config: ENSNodeSDKConfig,\n args: ResolvePrimaryNameRequest,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.primaryName(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.resolvePrimaryName(args.address, args.chainId, args);\n },\n };\n}\n\n/**\n * Creates query options for Primary Name Resolution\n */\nexport function createPrimaryNamesQueryOptions(\n config: ENSNodeSDKConfig,\n args: ResolvePrimaryNamesRequest,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.primaryNames(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.resolvePrimaryNames(args.address, args);\n },\n };\n}\n\n/**\n * Creates query options for ENSNode Config API\n */\nexport function createConfigQueryOptions(config: ENSNodeSDKConfig) {\n return {\n enabled: true,\n queryKey: queryKeys.config(config.client.url.href),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.config();\n },\n };\n}\n\n/**\n * Creates query options for ENSNode Indexing Status API\n */\nexport function createIndexingStatusQueryOptions(config: ENSNodeSDKConfig) {\n return {\n enabled: true,\n queryKey: queryKeys.indexingStatus(config.client.url.href),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n return client.indexingStatus();\n },\n };\n}\n\n/**\n * Creates query options for ENSNode Registrar Actions API\n */\nexport function createRegistrarActionsQueryOptions(\n config: ENSNodeSDKConfig,\n args: RegistrarActionsRequest,\n) {\n return {\n enabled: true,\n queryKey: queryKeys.registrarActions(config.client.url.href, args),\n queryFn: async () => {\n const client = new ENSNodeClient(config.client);\n\n return client.registrarActions(args);\n },\n };\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\n\nimport { ENSNodeContext } from \"../context\";\nimport type { ENSNodeSDKConfig } from \"../types\";\n\n/**\n * Hook to access the ENSNodeSDKConfig from context or parameters.\n *\n * @param parameters - Optional config parameter that overrides context\n * @returns The ENSNode configuration\n * @throws Error if no config is available in context or parameters\n */\nexport function useENSNodeSDKConfig<TConfig extends ENSNodeSDKConfig = ENSNodeSDKConfig>(\n config: TConfig | undefined,\n): TConfig {\n const contextConfig = useContext(ENSNodeContext);\n\n // Use provided config or fall back to context\n const resolvedConfig = config ?? contextConfig;\n\n if (!resolvedConfig) {\n throw new Error(\n \"useENSNodeSDKConfig must be used within an ENSNodeProvider or you must pass a config parameter\",\n );\n }\n\n return resolvedConfig as TConfig;\n}\n","import { useQuery } from \"@tanstack/react-query\";\n\nimport type { IndexingStatusRequest, IndexingStatusResponse } from \"@ensnode/ensnode-sdk\";\n\nimport type { QueryParameter, WithSDKConfigParameter } from \"../types\";\nimport { createIndexingStatusQueryOptions } from \"../utils/query\";\nimport { useENSNodeSDKConfig } from \"./useENSNodeSDKConfig\";\n\ninterface UseIndexingStatusParameters\n extends IndexingStatusRequest,\n QueryParameter<IndexingStatusResponse> {}\n\nexport function useIndexingStatus(\n parameters: WithSDKConfigParameter & UseIndexingStatusParameters = {},\n) {\n const { config, query = {} } = parameters;\n const _config = useENSNodeSDKConfig(config);\n\n const queryOptions = createIndexingStatusQueryOptions(_config);\n\n const options = {\n ...queryOptions,\n refetchInterval: 10 * 1000, // 10 seconds - indexing status changes frequently\n ...query,\n enabled: query.enabled ?? queryOptions.enabled,\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport type { UsePrimaryNameParameters, WithSDKConfigParameter } from \"../types\";\nimport { createPrimaryNameQueryOptions } from \"../utils/query\";\nimport { useENSNodeSDKConfig } from \"./useENSNodeSDKConfig\";\n\n/**\n * Resolves the primary name of a specified address (Reverse Resolution).\n *\n * The returned Primary Name, if set, is guaranteed to be a normalized name.\n * If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.\n *\n * @param parameters - Configuration for the address resolution\n * @returns Query result with resolved primary name\n *\n * @example\n * ```typescript\n * import { usePrimaryName } from \"@ensnode/ensnode-react\";\n *\n * function DisplayPrimaryNameAndAvatar() {\n * const { data, isLoading, error } = usePrimaryName({\n * address: \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n * chainId: 1, // Ethereum Mainnet\n * accelerate: true, // Attempt Protocol Acceleration\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * <h3>Primary Name (for Mainnet)</h3>\n * <p>{data.name ?? \"No Primary Name\"}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function usePrimaryName(parameters: UsePrimaryNameParameters & WithSDKConfigParameter) {\n const { config, query = {}, address, ...args } = parameters;\n const _config = useENSNodeSDKConfig(config);\n\n const canEnable = address !== null;\n\n const queryOptions = canEnable\n ? createPrimaryNameQueryOptions(_config, { ...args, address })\n : { enabled: false, queryKey: [\"disabled\"] as const };\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: canEnable && (query.enabled ?? queryOptions.enabled),\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport type { UsePrimaryNamesParameters, WithSDKConfigParameter } from \"../types\";\nimport { createPrimaryNamesQueryOptions } from \"../utils/query\";\nimport { useENSNodeSDKConfig } from \"./useENSNodeSDKConfig\";\n\n/**\n * Resolves the primary names of a specified address across multiple chains.\n *\n * Each returned Primary Name, if set, is guaranteed to be a normalized name.\n * If the primary name set for the address on any chain is not normalized, `null` is returned for that chain as if no primary name was set.\n *\n * @param parameters - Configuration for the address resolution\n * @returns Query result with resolved primary names\n *\n * @example\n * ```typescript\n * import { usePrimaryNames } from \"@ensnode/ensnode-react\";\n *\n * function DisplayPrimaryNames() {\n * const { data, isLoading, error } = usePrimaryNames({\n * address: \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * {Object.entries(data.names).map(([chainId, name]) => (\n * <div key={chainId}>\n * <h3>Primary Name (Chain Id: {chainId})</h3>\n * <p>{name}</p>\n * </div>\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePrimaryNames(parameters: UsePrimaryNamesParameters & WithSDKConfigParameter) {\n const { config, query = {}, address, ...args } = parameters;\n const _config = useENSNodeSDKConfig(config);\n\n const canEnable = address !== null;\n\n const queryOptions = canEnable\n ? createPrimaryNamesQueryOptions(_config, { ...args, address })\n : { enabled: false, queryKey: [\"disabled\"] as const };\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: canEnable && (query.enabled ?? queryOptions.enabled),\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport type { ResolverRecordsSelection } from \"@ensnode/ensnode-sdk\";\n\nimport type { UseRecordsParameters, WithSDKConfigParameter } from \"../types\";\nimport { createRecordsQueryOptions } from \"../utils/query\";\nimport { useENSNodeSDKConfig } from \"./useENSNodeSDKConfig\";\n\n/**\n * Resolves records for an ENS name (Forward Resolution).\n *\n * The returned `name` field, if set, is guaranteed to be a normalized name.\n * If the name record returned by the resolver is not normalized, `null` is returned as if no name record was set.\n *\n * @param parameters - Configuration for the ENS name resolution\n * @returns Query result with resolved records\n *\n * @example\n * ```typescript\n * import { useRecords } from \"@ensnode/ensnode-react\";\n *\n * function DisplayNameRecords() {\n * const { data, isLoading, error } = useRecords({\n * name: \"jesse.base.eth\",\n * selection: {\n * addresses: [60], // ETH CoinType\n * texts: [\"avatar\", \"com.twitter\"]\n * }\n * });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * <h3>Resolved Records for vitalik.eth</h3>\n * {data.records.addresses && (\n * <p>ETH Address: {data.records.addresses[60]}</p>\n * )}\n * {data.records.texts && (\n * <div>\n * <p>Avatar: {data.records.texts.avatar}</p>\n * <p>Twitter: {data.records.texts[\"com.twitter\"]}</p>\n * </div>\n * )}\n * </div>\n * );\n * }\n * ```\n */\nexport function useRecords<SELECTION extends ResolverRecordsSelection>(\n parameters: UseRecordsParameters<SELECTION> & WithSDKConfigParameter,\n) {\n const { config, query = {}, name, ...args } = parameters;\n const _config = useENSNodeSDKConfig(config);\n\n const canEnable = name !== null;\n\n const queryOptions = canEnable\n ? createRecordsQueryOptions(_config, { ...args, name })\n : { enabled: false, queryKey: [\"disabled\"] as const };\n\n const options = {\n ...queryOptions,\n ...query,\n enabled: canEnable && (query.enabled ?? queryOptions.enabled),\n };\n\n return useQuery(options);\n}\n","import { useQuery } from \"@tanstack/react-query\";\n\nimport type { RegistrarActionsRequest, RegistrarActionsResponse } from \"@ensnode/ensnode-sdk\";\n\nimport type { QueryParameter, WithSDKConfigParameter } from \"../types\";\nimport { createRegistrarActionsQueryOptions } from \"../utils/query\";\nimport { useENSNodeSDKConfig } from \"./useENSNodeSDKConfig\";\n\ninterface UseRegistrarActionsParameters\n extends RegistrarActionsRequest,\n QueryParameter<RegistrarActionsResponse> {}\n\n/**\n * Use Registrar Actions hook\n *\n * Query ENSNode Registrar Actions API.\n */\nexport function useRegistrarActions(\n parameters: WithSDKConfigParameter & UseRegistrarActionsParameters = {},\n) {\n const { config, query = {} } = parameters;\n const _config = useENSNodeSDKConfig(config);\n\n const queryOptions = createRegistrarActionsQueryOptions(_config, parameters);\n\n const options = {\n ...queryOptions,\n refetchInterval: 10 * 1000, // 10 seconds - latest registrar actions change frequently\n ...query,\n enabled: query.enabled ?? queryOptions.enabled,\n };\n\n return useQuery(options);\n}\n","\"use client\";\n\nimport {\n type ENSNamespaceId,\n getResolvePrimaryNameChainIdParam,\n type Identity,\n type NamedIdentity,\n ResolutionStatusIds,\n ResolvedIdentity,\n type UnknownIdentity,\n type UnnamedIdentity,\n type UnresolvedIdentity,\n} from \"@ensnode/ensnode-sdk\";\n\nimport { usePrimaryName } from \"./usePrimaryName\";\n\n// TODO: `namespaceId` ideally would not be a parameter for this hook.\n// Ideally it should come from the active namespace context and be a nested hook within this hook.\n// However, currently this hook lives in ENSAdmin and not in `ensnode-react`.\n/**\n * Parameters for the useResolvedIdentity hook.\n */\nexport interface UseResolvedIdentityParameters {\n identity: UnresolvedIdentity;\n namespaceId: ENSNamespaceId;\n accelerate?: boolean;\n}\n\n/**\n * Hook to perform ENSIP-19 primary name resolution to resolve an\n * {@link UnresolvedIdentity} into a {@link ResolvedIdentity}.\n *\n * @param parameters - Configuration object for the hook\n * @param parameters.identity - An {@link UnresolvedIdentity} containing the {@link DefaultableChainId}\n * and {@link Address} to resolve.\n * @param parameters.namespaceId - The {@link ENSNamespaceId} that `identity.chainId` should be interpreted\n * through (via {@link getResolvePrimaryNameChainIdParam}) to determine the literal\n * chainId that should be used for ENSIP-19 primary name resolution.\n * @param parameters.accelerate - Whether to attempt Protocol Acceleration (default: false)\n * when resolving the primary name.\n *\n * @returns An object containing:\n * - `identity`: An {@link Identity} with one of four possible {@link ResolutionStatusIds}:\n * - {@link ResolutionStatusIds.Unresolved}: While the query is pending (loading state).\n * - {@link ResolutionStatusIds.Unknown}: If an error occurs during resolution.\n * - {@link ResolutionStatusIds.Unnamed}: If the resolution found no primary name.\n * - {@link ResolutionStatusIds.Named}: If a primary name is successfully resolved.\n * - All other properties from the underlying {@link usePrimaryName} query (e.g., `isLoading`, `error`, `refetch`, etc.)\n */\nexport function useResolvedIdentity(parameters: UseResolvedIdentityParameters) {\n const { identity, namespaceId, accelerate, ...args } = parameters;\n\n const {\n data: primaryNameData,\n status,\n ...query\n } = usePrimaryName({\n address: identity.address,\n chainId: getResolvePrimaryNameChainIdParam(identity.chainId, namespaceId),\n accelerate,\n ...args,\n });\n\n let result: Identity;\n\n if (status === \"pending\") {\n // loading state\n // return the `UnresolvedIdentity` to support loading state functionality.\n result = identity;\n } else if (status === \"error\") {\n result = {\n resolutionStatus: ResolutionStatusIds.Unknown,\n chainId: identity.chainId,\n address: identity.address,\n } satisfies UnknownIdentity;\n } else if (primaryNameData.name === null) {\n result = {\n resolutionStatus: ResolutionStatusIds.Unnamed,\n chainId: identity.chainId,\n address: identity.address,\n name: null,\n } satisfies UnnamedIdentity;\n } else {\n result = {\n resolutionStatus: ResolutionStatusIds.Named,\n chainId: identity.chainId,\n address: identity.address,\n name: primaryNameData.name,\n } satisfies NamedIdentity;\n }\n\n return {\n ...query,\n identity: result,\n };\n}\n","import {\n type DefaultError,\n type DefinedInitialDataOptions,\n type DefinedUseQueryResult,\n type QueryClient,\n type QueryKey,\n type QueryObserverSuccessResult,\n type UndefinedInitialDataOptions,\n type UseQueryOptions,\n type UseQueryResult,\n useQuery,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport { useMemo } from \"react\";\n\n/**\n * Use Stale-While-Revalidate Query\n *\n * This hooks is a proxy for {@link useQuery} with addition of the following\n * semantics:\n * - if the query has been resolved successfully just once,\n * the query result will always be success with data being the previously\n * cached result,\n * - the cached result can never go stale, or be garbage collected\n * - the cached result can be only overridden by the current result when\n * the query is successfully re-fetched (in other words,\n * the `options.queryFn` returns a resolved promise).\n *\n * Please note how there can be any number of failed queries before one\n * succeeds. In such case, no successful result has ever been cached and\n * the query fails (`isError: true`, `error` is available) until\n * the first successful resolution (`isSuccess: true`, `data` is available).\n *\n * @example\n * ```tsx\n * const swrQuery = useSwrQuery({\n * queryKey: ['data'],\n * queryFn: fetchData,\n * });\n *\n * if (swrQuery.isPending) {\n * // Show loading state while there's no cached successful result and\n * // no query attempt was finished yet.\n * return <>Loading...</>;\n * }\n *\n * if (swrQuery.isError) {\n * // Show error state when query attempt fails and\n * // no cached successful result is available.\n * return <>Error: {swrQuery.error.message}</>;\n * }\n *\n * // Otherwise, show data when the cached successful result is available.\n * return <>Data: {JSON.stringify(swrQuery.data)}</>;\n * ```\n */\nexport function useSwrQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): DefinedUseQueryResult<NoInfer<TData>, TError>;\nexport function useSwrQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError>;\nexport function useSwrQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError>;\nexport function useSwrQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n>(\n options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n queryClient?: QueryClient,\n): UseQueryResult<NoInfer<TData>, TError> {\n const queryClientFromContext = useQueryClient();\n const derivedQueryClient = queryClient ?? queryClientFromContext;\n\n // cacheResult, if available, is always the last successfully resolved query data\n const cachedSuccessfulResult = derivedQueryClient.getQueryData<TData>(options.queryKey);\n\n const queryResult = useQuery(\n {\n ...options,\n // cached result can never be stale\n staleTime: cachedSuccessfulResult ? Infinity : undefined,\n // cached result can never be removed by garbage collector\n gcTime: cachedSuccessfulResult ? Infinity : undefined,\n },\n queryClient,\n );\n\n // memoize query results to avoid unnecessary UI re-rendering\n const memoizedQueryResult = useMemo(() => {\n // If the query result is error\n // and the cachedSuccessfulResult is available\n // override the query result to be success, replacing the unsuccessful\n // result with the most recent cachedSuccessfulResult\n if (queryResult.isError && cachedSuccessfulResult) {\n return {\n ...queryResult,\n // set error props\n isError: false,\n error: null,\n isRefetchError: false,\n isLoadingError: false,\n // st success props\n isSuccess: true,\n status: \"success\",\n data: cachedSuccessfulResult,\n } satisfies QueryObserverSuccessResult<TData, TError>;\n }\n\n return queryResult;\n }, [queryResult, cachedSuccessfulResult]);\n\n return memoizedQueryResult;\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: conditional hooks used correctly here */\n\"use client\";\n\nimport { QueryClient, QueryClientProvider, useQueryClient } from \"@tanstack/react-query\";\nimport { createElement, useMemo } from \"react\";\n\nimport { ENSNodeClient } from \"@ensnode/ensnode-sdk\";\n\nimport { ENSNodeContext } from \"./context\";\nimport type { ENSNodeSDKConfig } from \"./types\";\n\nexport interface ENSNodeProviderProps {\n /** ENSNode configuration */\n config: ENSNodeSDKConfig;\n\n /**\n * Optional QueryClient instance. If provided, you must wrap your app with QueryClientProvider yourself.\n * If not provided, ENSNodeProvider will create and manage its own QueryClient internally.\n */\n queryClient?: QueryClient;\n\n /**\n * Custom query client options when auto-creating a QueryClient.\n * Only used when queryClient is not provided.\n */\n queryClientOptions?: ConstructorParameters<typeof QueryClient>[0];\n}\n\nfunction ENSNodeInternalProvider({\n children,\n config,\n}: {\n children?: React.ReactNode;\n config: ENSNodeSDKConfig;\n}) {\n // Memoize the config to prevent unnecessary re-renders\n const memoizedConfig = useMemo(() => config, [config]);\n\n return createElement(ENSNodeContext.Provider, { value: memoizedConfig }, children);\n}\n\nexport function ENSNodeProvider(parameters: React.PropsWithChildren<ENSNodeProviderProps>) {\n const { children, config, queryClient, queryClientOptions } = parameters;\n\n // Check if we're already inside a QueryClientProvider\n let hasExistingQueryClient = false;\n try {\n hasExistingQueryClient = Boolean(useQueryClient());\n } catch {\n // useQueryClient throws if not inside a QueryClientProvider\n hasExistingQueryClient = false;\n }\n\n // If user provided a queryClient, they must handle QueryClientProvider themselves\n if (queryClient) {\n if (!hasExistingQueryClient) {\n throw new Error(\n \"When providing a custom queryClient, you must wrap your app with QueryClientProvider. \" +\n \"Either remove the queryClient prop to use auto-managed setup, or wrap with QueryClientProvider.\",\n );\n }\n return createElement(ENSNodeInternalProvider, { config, children });\n }\n\n // If already inside a QueryClientProvider, just use that\n if (hasExistingQueryClient) {\n return createElement(ENSNodeInternalProvider, { config, children });\n }\n\n // Create our own QueryClient and QueryClientProvider\n const defaultQueryClient = useMemo(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n retry: 3,\n staleTime: 1000 * 60 * 5, // 5 minutes\n gcTime: 1000 * 60 * 30, // 30 minutes\n refetchInterval: 1000 * 10, // 10 seconds\n },\n },\n ...queryClientOptions,\n }),\n [queryClientOptions],\n );\n\n return createElement(\n QueryClientProvider,\n { client: defaultQueryClient },\n createElement(ENSNodeInternalProvider, { config, children }),\n );\n}\n\n/**\n * Helper function to create ENSNode configuration\n */\nexport function createConfig(options?: { url?: string | URL }): ENSNodeSDKConfig {\n const url = options?.url ? new URL(options.url) : ENSNodeClient.defaultOptions().url;\n\n return {\n client: {\n ...ENSNodeClient.defaultOptions(),\n url,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAA8B;AAOvB,IAAM,qBAAiB,4BAA4C,MAAS;AAKnF,eAAe,cAAc;;;ACZ7B,yBAAyB;;;ACIzB,yBAOO;AAmBA,IAAM,yBAAyB;AAAA,EACpC,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,gBAAgB;AAClB;AAKO,IAAM,YAAY;AAAA,EACvB,MAAM,CAAC,QAAgB,CAAC,WAAW,GAAG;AAAA,EAEtC,SAAS,CAAC,QAAgB,CAAC,GAAG,UAAU,KAAK,GAAG,GAAG,SAAS;AAAA,EAE5D,SAAS,CAAC,KAAa,SACrB,CAAC,GAAG,UAAU,QAAQ,GAAG,GAAG,WAAW,IAAI;AAAA,EAE7C,aAAa,CAAC,KAAa,SACzB,CAAC,GAAG,UAAU,QAAQ,GAAG,GAAG,gBAAgB,IAAI;AAAA,EAElD,cAAc,CAAC,KAAa,SAC1B,CAAC,GAAG,UAAU,QAAQ,GAAG,GAAG,iBAAiB,IAAI;AAAA,EAEnD,QAAQ,CAAC,QAAgB,CAAC,GAAG,UAAU,KAAK,GAAG,GAAG,QAAQ;AAAA,EAE1D,gBAAgB,CAAC,QAAgB,CAAC,GAAG,UAAU,KAAK,GAAG,GAAG,iBAAiB;AAAA,EAE3E,kBAAkB,CAAC,KAAa,SAC9B,CAAC,GAAG,UAAU,KAAK,GAAG,GAAG,qBAAqB,IAAI;AACtD;AAKO,SAAS,0BACd,QACA,MACA;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,UAAU,QAAQ,OAAO,OAAO,IAAI,MAAM,IAAI;AAAA,IACxD,SAAS,YAAY;AACnB,YAAM,SAAS,IAAI,iCAAc,OAAO,MAAM;AAC9C,aAAO,OAAO,eAAe,KAAK,MAAM,KAAK,WAAW,IAAI;AAAA,IAC9D;AAAA,EACF;AACF;AAKO,SAAS,8BACd,QACA,MACA;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,UAAU,YAAY,OAAO,OAAO,IAAI,MAAM,IAAI;AAAA,IAC5D,SAAS,YAAY;AACnB,YAAM,SAAS,IAAI,iCAAc,OAAO,MAAM;AAC9C,aAAO,OAAO,mBAAmB,KAAK,SAAS,KAAK,SAAS,IAAI;AAAA,IACnE;AAAA,EACF;AACF;AAKO,SAAS,+BACd,QACA,MACA;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,UAAU,aAAa,OAAO,OAAO,IAAI,MAAM,IAAI;AAAA,IAC7D,SAAS,YAAY;AACnB,YAAM,SAAS,IAAI,iCAAc,OAAO,MAAM;AAC9C,aAAO,OAAO,oBAAoB,KAAK,SAAS,IAAI;AAAA,IACtD;AAAA,EACF;AACF;AAKO,SAAS,yBAAyB,QAA0B;AACjE,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,UAAU,OAAO,OAAO,OAAO,IAAI,IAAI;AAAA,IACjD,SAAS,YAAY;AACnB,YAAM,SAAS,IAAI,iCAAc,OAAO,MAAM;AAC9C,aAAO,OAAO,OAAO;AAAA,IACvB;AAAA,EACF;AACF;AAKO,SAAS,iCAAiC,QAA0B;AACzE,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,UAAU,eAAe,OAAO,OAAO,IAAI,IAAI;AAAA,IACzD,SAAS,YAAY;AACnB,YAAM,SAAS,IAAI,iCAAc,OAAO,MAAM;AAC9C,aAAO,OAAO,eAAe;AAAA,IAC/B;AAAA,EACF;AACF;AAKO,SAAS,mCACd,QACA,MACA;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU,UAAU,iBAAiB,OAAO,OAAO,IAAI,MAAM,IAAI;AAAA,IACjE,SAAS,YAAY;AACnB,YAAM,SAAS,IAAI,iCAAc,OAAO,MAAM;AAE9C,aAAO,OAAO,iBAAiB,IAAI;AAAA,IACrC;AAAA,EACF;AACF;;;AC5JA,IAAAA,gBAA2B;AAYpB,SAAS,oBACd,QACS;AACT,QAAM,oBAAgB,0BAAW,cAAc;AAG/C,QAAM,iBAAiB,UAAU;AAEjC,MAAI,CAAC,gBAAgB;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AFnBO,SAAS,iBACd,aAAkE,CAAC,GACnE;AACA,QAAM,EAAE,QAAQ,QAAQ,CAAC,EAAE,IAAI;AAC/B,QAAM,UAAU,oBAAoB,MAAM;AAE1C,QAAM,eAAe,yBAAyB,OAAO;AAErD,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS,MAAM,WAAW,aAAa;AAAA,EACzC;AAEA,aAAO,6BAAS,OAAO;AACzB;;;AG1BA,IAAAC,sBAAyB;AAYlB,SAAS,kBACd,aAAmE,CAAC,GACpE;AACA,QAAM,EAAE,QAAQ,QAAQ,CAAC,EAAE,IAAI;AAC/B,QAAM,UAAU,oBAAoB,MAAM;AAE1C,QAAM,eAAe,iCAAiC,OAAO;AAE7D,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,iBAAiB,KAAK;AAAA;AAAA,IACtB,GAAG;AAAA,IACH,SAAS,MAAM,WAAW,aAAa;AAAA,EACzC;AAEA,aAAO,8BAAS,OAAO;AACzB;;;AC1BA,IAAAC,sBAAyB;AAsClB,SAAS,eAAe,YAA+D;AAC5F,QAAM,EAAE,QAAQ,QAAQ,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI;AACjD,QAAM,UAAU,oBAAoB,MAAM;AAE1C,QAAM,YAAY,YAAY;AAE9B,QAAM,eAAe,YACjB,8BAA8B,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,IAC3D,EAAE,SAAS,OAAO,UAAU,CAAC,UAAU,EAAW;AAEtD,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS,cAAc,MAAM,WAAW,aAAa;AAAA,EACvD;AAEA,aAAO,8BAAS,OAAO;AACzB;;;ACvDA,IAAAC,sBAAyB;AAwClB,SAAS,gBAAgB,YAAgE;AAC9F,QAAM,EAAE,QAAQ,QAAQ,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI;AACjD,QAAM,UAAU,oBAAoB,MAAM;AAE1C,QAAM,YAAY,YAAY;AAE9B,QAAM,eAAe,YACjB,+BAA+B,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,IAC5D,EAAE,SAAS,OAAO,UAAU,CAAC,UAAU,EAAW;AAEtD,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS,cAAc,MAAM,WAAW,aAAa;AAAA,EACvD;AAEA,aAAO,8BAAS,OAAO;AACzB;;;ACzDA,IAAAC,sBAAyB;AAkDlB,SAAS,WACd,YACA;AACA,QAAM,EAAE,QAAQ,QAAQ,CAAC,GAAG,MAAM,GAAG,KAAK,IAAI;AAC9C,QAAM,UAAU,oBAAoB,MAAM;AAE1C,QAAM,YAAY,SAAS;AAE3B,QAAM,eAAe,YACjB,0BAA0B,SAAS,EAAE,GAAG,MAAM,KAAK,CAAC,IACpD,EAAE,SAAS,OAAO,UAAU,CAAC,UAAU,EAAW;AAEtD,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS,cAAc,MAAM,WAAW,aAAa;AAAA,EACvD;AAEA,aAAO,8BAAS,OAAO;AACzB;;;ACvEA,IAAAC,sBAAyB;AAiBlB,SAAS,oBACd,aAAqE,CAAC,GACtE;AACA,QAAM,EAAE,QAAQ,QAAQ,CAAC,EAAE,IAAI;AAC/B,QAAM,UAAU,oBAAoB,MAAM;AAE1C,QAAM,eAAe,mCAAmC,SAAS,UAAU;AAE3E,QAAM,UAAU;AAAA,IACd,GAAG;AAAA,IACH,iBAAiB,KAAK;AAAA;AAAA,IACtB,GAAG;AAAA,IACH,SAAS,MAAM,WAAW,aAAa;AAAA,EACzC;AAEA,aAAO,8BAAS,OAAO;AACzB;;;AC/BA,IAAAC,sBAUO;AAqCA,SAAS,oBAAoB,YAA2C;AAC7E,QAAM,EAAE,UAAU,aAAa,YAAY,GAAG,KAAK,IAAI;AAEvD,QAAM;AAAA,IACJ,MAAM;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACL,IAAI,eAAe;AAAA,IACjB,SAAS,SAAS;AAAA,IAClB,aAAS,uDAAkC,SAAS,SAAS,WAAW;AAAA,IACxE;AAAA,IACA,GAAG;AAAA,EACL,CAAC;AAED,MAAI;AAEJ,MAAI,WAAW,WAAW;AAGxB,aAAS;AAAA,EACX,WAAW,WAAW,SAAS;AAC7B,aAAS;AAAA,MACP,kBAAkB,wCAAoB;AAAA,MACtC,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,IACpB;AAAA,EACF,WAAW,gBAAgB,SAAS,MAAM;AACxC,aAAS;AAAA,MACP,kBAAkB,wCAAoB;AAAA,MACtC,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,MAClB,MAAM;AAAA,IACR;AAAA,EACF,OAAO;AACL,aAAS;AAAA,MACP,kBAAkB,wCAAoB;AAAA,MACtC,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,MAClB,MAAM,gBAAgB;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU;AAAA,EACZ;AACF;;;AC/FA,IAAAC,sBAYO;AACP,IAAAC,gBAAwB;AAsEjB,SAAS,YAMd,SACA,aACwC;AACxC,QAAM,6BAAyB,oCAAe;AAC9C,QAAM,qBAAqB,eAAe;AAG1C,QAAM,yBAAyB,mBAAmB,aAAoB,QAAQ,QAAQ;AAEtF,QAAM,kBAAc;AAAA,IAClB;AAAA,MACE,GAAG;AAAA;AAAA,MAEH,WAAW,yBAAyB,WAAW;AAAA;AAAA,MAE/C,QAAQ,yBAAyB,WAAW;AAAA,IAC9C;AAAA,IACA;AAAA,EACF;AAGA,QAAM,0BAAsB,uBAAQ,MAAM;AAKxC,QAAI,YAAY,WAAW,wBAAwB;AACjD,aAAO;AAAA,QACL,GAAG;AAAA;AAAA,QAEH,SAAS;AAAA,QACT,OAAO;AAAA,QACP,gBAAgB;AAAA,QAChB,gBAAgB;AAAA;AAAA,QAEhB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,MAAM;AAAA,MACR;AAAA,IACF;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,aAAa,sBAAsB,CAAC;AAExC,SAAO;AACT;;;ACnIA,IAAAC,sBAAiE;AACjE,IAAAC,gBAAuC;AAEvC,IAAAC,sBAA8B;AAsB9B,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AACF,GAGG;AAED,QAAM,qBAAiB,uBAAQ,MAAM,QAAQ,CAAC,MAAM,CAAC;AAErD,aAAO,6BAAc,eAAe,UAAU,EAAE,OAAO,eAAe,GAAG,QAAQ;AACnF;AAEO,SAAS,gBAAgB,YAA2D;AACzF,QAAM,EAAE,UAAU,QAAQ,aAAa,mBAAmB,IAAI;AAG9D,MAAI,yBAAyB;AAC7B,MAAI;AACF,6BAAyB,YAAQ,oCAAe,CAAC;AAAA,EACnD,QAAQ;AAEN,6BAAyB;AAAA,EAC3B;AAGA,MAAI,aAAa;AACf,QAAI,CAAC,wBAAwB;AAC3B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,eAAO,6BAAc,yBAAyB,EAAE,QAAQ,SAAS,CAAC;AAAA,EACpE;AAGA,MAAI,wBAAwB;AAC1B,eAAO,6BAAc,yBAAyB,EAAE,QAAQ,SAAS,CAAC;AAAA,EACpE;AAGA,QAAM,yBAAqB;AAAA,IACzB,MACE,IAAI,gCAAY;AAAA,MACd,gBAAgB;AAAA,QACd,SAAS;AAAA,UACP,OAAO;AAAA,UACP,WAAW,MAAO,KAAK;AAAA;AAAA,UACvB,QAAQ,MAAO,KAAK;AAAA;AAAA,UACpB,iBAAiB,MAAO;AAAA;AAAA,QAC1B;AAAA,MACF;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,IACH,CAAC,kBAAkB;AAAA,EACrB;AAEA,aAAO;AAAA,IACL;AAAA,IACA,EAAE,QAAQ,mBAAmB;AAAA,QAC7B,6BAAc,yBAAyB,EAAE,QAAQ,SAAS,CAAC;AAAA,EAC7D;AACF;AAKO,SAAS,aAAa,SAAoD;AAC/E,QAAM,MAAM,SAAS,MAAM,IAAI,IAAI,QAAQ,GAAG,IAAI,kCAAc,eAAe,EAAE;AAEjF,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,GAAG,kCAAc,eAAe;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AACF;","names":["import_react","import_react_query","import_react_query","import_react_query","import_react_query","import_react_query","import_ensnode_sdk","import_react_query","import_react","import_react_query","import_react","import_ensnode_sdk"]}