@ensnode/ensnode-sdk 0.0.0-next-20260130145445 → 0.0.0-next-20260202030222
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 +1563 -1445
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1836 -1704
- package/dist/index.d.ts +1836 -1704
- package/dist/index.js +981 -863
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/ensapi/config/deserialize.ts
|
|
2
|
-
import { prettifyError
|
|
2
|
+
import { prettifyError, ZodError } from "zod/v4";
|
|
3
3
|
|
|
4
4
|
// src/ensapi/config/zod-schemas.ts
|
|
5
5
|
import { z as z4 } from "zod/v4";
|
|
@@ -7,72 +7,8 @@ import { z as z4 } from "zod/v4";
|
|
|
7
7
|
// src/ensindexer/config/zod-schemas.ts
|
|
8
8
|
import { z as z2 } from "zod/v4";
|
|
9
9
|
|
|
10
|
-
// src/shared/
|
|
11
|
-
|
|
12
|
-
var accountIdEqual = (a, b) => {
|
|
13
|
-
return a.chainId === b.chainId && isAddressEqual(a.address, b.address);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// src/shared/address.ts
|
|
17
|
-
function asLowerCaseAddress(address) {
|
|
18
|
-
return address.toLowerCase();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/shared/cache/lru-cache.ts
|
|
22
|
-
var LruCache = class {
|
|
23
|
-
_cache = /* @__PURE__ */ new Map();
|
|
24
|
-
_capacity;
|
|
25
|
-
/**
|
|
26
|
-
* Create a new LRU cache with the given capacity.
|
|
27
|
-
*
|
|
28
|
-
* @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
|
|
29
|
-
* @throws Error if capacity is not a non-negative integer.
|
|
30
|
-
*/
|
|
31
|
-
constructor(capacity) {
|
|
32
|
-
if (!Number.isInteger(capacity)) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
`LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
if (capacity < 0) {
|
|
38
|
-
throw new Error(
|
|
39
|
-
`LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
this._capacity = capacity;
|
|
43
|
-
}
|
|
44
|
-
set(key, value) {
|
|
45
|
-
this._cache.set(key, value);
|
|
46
|
-
if (this._cache.size > this._capacity) {
|
|
47
|
-
const oldestKey = this._cache.keys().next().value;
|
|
48
|
-
this._cache.delete(oldestKey);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
get(key) {
|
|
52
|
-
const value = this._cache.get(key);
|
|
53
|
-
if (value) {
|
|
54
|
-
this._cache.delete(key);
|
|
55
|
-
this._cache.set(key, value);
|
|
56
|
-
}
|
|
57
|
-
return value;
|
|
58
|
-
}
|
|
59
|
-
clear() {
|
|
60
|
-
this._cache.clear();
|
|
61
|
-
}
|
|
62
|
-
get size() {
|
|
63
|
-
return this._cache.size;
|
|
64
|
-
}
|
|
65
|
-
get capacity() {
|
|
66
|
-
return this._capacity;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// src/shared/cache/swr-cache.ts
|
|
71
|
-
import { secondsToMilliseconds } from "date-fns";
|
|
72
|
-
import { getUnixTime } from "date-fns/getUnixTime";
|
|
73
|
-
|
|
74
|
-
// src/shared/deserialize.ts
|
|
75
|
-
import { prettifyError } from "zod/v4";
|
|
10
|
+
// src/shared/collections.ts
|
|
11
|
+
var uniq = (arr) => [...new Set(arr)];
|
|
76
12
|
|
|
77
13
|
// src/shared/zod-schemas.ts
|
|
78
14
|
import { AccountId as CaipAccountId } from "caip";
|
|
@@ -212,6 +148,13 @@ var beautifyName = (name) => {
|
|
|
212
148
|
|
|
213
149
|
// src/ens/parse-reverse-name.ts
|
|
214
150
|
import { hexToBigInt, isAddress } from "viem";
|
|
151
|
+
|
|
152
|
+
// src/shared/address.ts
|
|
153
|
+
function asLowerCaseAddress(address) {
|
|
154
|
+
return address.toLowerCase();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/ens/parse-reverse-name.ts
|
|
215
158
|
var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
|
|
216
159
|
var parseAddressLabel = (addressLabel) => {
|
|
217
160
|
const maybeAddress = `0x${addressLabel}`;
|
|
@@ -267,6 +210,52 @@ var uint256ToHex32 = (num) => toHex(num, { size: 32 });
|
|
|
267
210
|
// src/ens/types.ts
|
|
268
211
|
import { ENSNamespaceIds } from "@ensnode/datasources";
|
|
269
212
|
|
|
213
|
+
// src/shared/currencies.ts
|
|
214
|
+
import { parseUnits } from "viem";
|
|
215
|
+
|
|
216
|
+
// src/shared/numbers.ts
|
|
217
|
+
function bigIntToNumber(n) {
|
|
218
|
+
if (n < Number.MIN_SAFE_INTEGER) {
|
|
219
|
+
throw new Error(
|
|
220
|
+
`The bigint '${n.toString()}' value is too low to be to converted into a number.'`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
if (n > Number.MAX_SAFE_INTEGER) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`The bigint '${n.toString()}' value is too high to be to converted into a number.'`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
return Number(n);
|
|
229
|
+
}
|
|
230
|
+
function scaleBigintByNumber(value, scaleFactor) {
|
|
231
|
+
if (value < 0n) {
|
|
232
|
+
throw new Error(`scaleBigintByNumber: value must be non-negative, got: ${value.toString()}`);
|
|
233
|
+
}
|
|
234
|
+
if (!Number.isFinite(scaleFactor)) {
|
|
235
|
+
throw new Error(
|
|
236
|
+
`scaleBigintByNumber: scaleFactor must be a finite number, got: ${scaleFactor}`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
if (scaleFactor < 0) {
|
|
240
|
+
throw new Error(`scaleBigintByNumber: scaleFactor must be non-negative, got: ${scaleFactor}`);
|
|
241
|
+
}
|
|
242
|
+
if (scaleFactor >= 1e21) {
|
|
243
|
+
throw new Error(`scaleBigintByNumber: scaleFactor must be less than 1e21, got: ${scaleFactor}`);
|
|
244
|
+
}
|
|
245
|
+
if (value === 0n || scaleFactor === 0) {
|
|
246
|
+
return 0n;
|
|
247
|
+
}
|
|
248
|
+
if (scaleFactor === 1) {
|
|
249
|
+
return value;
|
|
250
|
+
}
|
|
251
|
+
const fixedStr = scaleFactor.toFixed(20);
|
|
252
|
+
const [integerPart, decimalPart = ""] = fixedStr.split(".");
|
|
253
|
+
const trimmedDecimal = decimalPart.replace(/0+$/, "") || "0";
|
|
254
|
+
const numerator = BigInt(integerPart + trimmedDecimal);
|
|
255
|
+
const denominator = 10n ** BigInt(trimmedDecimal.length);
|
|
256
|
+
return value * numerator / denominator;
|
|
257
|
+
}
|
|
258
|
+
|
|
270
259
|
// src/shared/currencies.ts
|
|
271
260
|
var CurrencyIds = {
|
|
272
261
|
ETH: "ETH",
|
|
@@ -335,6 +324,43 @@ function addPrices(...prices) {
|
|
|
335
324
|
}
|
|
336
325
|
);
|
|
337
326
|
}
|
|
327
|
+
function scalePrice(price, scaleFactor) {
|
|
328
|
+
const scaledAmount = scaleBigintByNumber(price.amount, scaleFactor);
|
|
329
|
+
return {
|
|
330
|
+
...price,
|
|
331
|
+
amount: scaledAmount
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function validateAmountToParse(value) {
|
|
335
|
+
const trimmed = value.trim();
|
|
336
|
+
if (trimmed === "") {
|
|
337
|
+
throw new Error("amount must be a non-negative decimal string");
|
|
338
|
+
}
|
|
339
|
+
if (value !== trimmed) {
|
|
340
|
+
throw new Error("amount must not have leading or trailing whitespace");
|
|
341
|
+
}
|
|
342
|
+
if (trimmed.startsWith("-")) {
|
|
343
|
+
throw new Error("amount must be a non-negative decimal string");
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function parseEth(value) {
|
|
347
|
+
validateAmountToParse(value);
|
|
348
|
+
const currencyInfo2 = getCurrencyInfo(CurrencyIds.ETH);
|
|
349
|
+
const amount = parseUnits(value, currencyInfo2.decimals);
|
|
350
|
+
return priceEth(amount);
|
|
351
|
+
}
|
|
352
|
+
function parseUsdc(value) {
|
|
353
|
+
validateAmountToParse(value);
|
|
354
|
+
const currencyInfo2 = getCurrencyInfo(CurrencyIds.USDC);
|
|
355
|
+
const amount = parseUnits(value, currencyInfo2.decimals);
|
|
356
|
+
return priceUsdc(amount);
|
|
357
|
+
}
|
|
358
|
+
function parseDai(value) {
|
|
359
|
+
validateAmountToParse(value);
|
|
360
|
+
const currencyInfo2 = getCurrencyInfo(CurrencyIds.DAI);
|
|
361
|
+
const amount = parseUnits(value, currencyInfo2.decimals);
|
|
362
|
+
return priceDai(amount);
|
|
363
|
+
}
|
|
338
364
|
|
|
339
365
|
// src/shared/interpretation/reinterpretation.ts
|
|
340
366
|
import { labelhash as labelToLabelHash } from "viem";
|
|
@@ -430,6 +456,8 @@ var makePriceCurrencySchema = (currency, valueLabel = "Price Currency") => z.str
|
|
|
430
456
|
})
|
|
431
457
|
});
|
|
432
458
|
var makePriceEthSchema = (valueLabel = "Price ETH") => makePriceCurrencySchema(CurrencyIds.ETH, valueLabel).transform((v) => v);
|
|
459
|
+
var makePriceUsdcSchema = (valueLabel = "Price USDC") => makePriceCurrencySchema(CurrencyIds.USDC, valueLabel).transform((v) => v);
|
|
460
|
+
var makePriceDaiSchema = (valueLabel = "Price DAI") => makePriceCurrencySchema(CurrencyIds.DAI, valueLabel).transform((v) => v);
|
|
433
461
|
var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
|
|
434
462
|
chainId: makeChainIdSchema(`${valueLabel} chain ID`),
|
|
435
463
|
address: makeLowercaseAddressSchema(`${valueLabel} address`)
|
|
@@ -475,710 +503,405 @@ var makeReinterpretedNameSchema = (valueLabel = "Reinterpreted Name") => z.strin
|
|
|
475
503
|
}
|
|
476
504
|
}).transform(reinterpretName);
|
|
477
505
|
|
|
478
|
-
// src/
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
506
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
507
|
+
import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
|
|
508
|
+
|
|
509
|
+
// src/ensindexer/config/types.ts
|
|
510
|
+
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
511
|
+
PluginName2["Subgraph"] = "subgraph";
|
|
512
|
+
PluginName2["Basenames"] = "basenames";
|
|
513
|
+
PluginName2["Lineanames"] = "lineanames";
|
|
514
|
+
PluginName2["ThreeDNS"] = "threedns";
|
|
515
|
+
PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
|
|
516
|
+
PluginName2["Registrars"] = "registrars";
|
|
517
|
+
PluginName2["TokenScope"] = "tokenscope";
|
|
518
|
+
PluginName2["ENSv2"] = "ensv2";
|
|
519
|
+
return PluginName2;
|
|
520
|
+
})(PluginName || {});
|
|
521
|
+
|
|
522
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
523
|
+
function isSubgraphCompatible(config) {
|
|
524
|
+
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
525
|
+
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
526
|
+
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
527
|
+
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
528
|
+
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
498
529
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
530
|
+
|
|
531
|
+
// src/ensindexer/config/validations.ts
|
|
532
|
+
function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
|
|
533
|
+
const versionInfo = ctx.value;
|
|
534
|
+
if (versionInfo.ensDb !== versionInfo.ensIndexer) {
|
|
535
|
+
ctx.issues.push({
|
|
536
|
+
code: "custom",
|
|
537
|
+
input: versionInfo,
|
|
538
|
+
message: "`ensDb` version must be same as `ensIndexer` version"
|
|
539
|
+
});
|
|
506
540
|
}
|
|
507
|
-
return parsed.data;
|
|
508
541
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
542
|
+
|
|
543
|
+
// src/ensindexer/config/zod-schemas.ts
|
|
544
|
+
var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
|
|
545
|
+
error: `${valueLabel} must be an array.`
|
|
546
|
+
}).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
|
|
547
|
+
var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(z2.string(), {
|
|
548
|
+
error: `${valueLabel} must be a list of strings.`
|
|
549
|
+
}).min(1, {
|
|
550
|
+
error: `${valueLabel} must be a list of strings with at least one string value`
|
|
551
|
+
}).refine((arr) => arr.length === uniq(arr).length, {
|
|
552
|
+
error: `${valueLabel} cannot contain duplicate values.`
|
|
553
|
+
});
|
|
554
|
+
var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
|
|
555
|
+
error: `${valueLabel} is required and must be a non-empty string.`
|
|
556
|
+
});
|
|
557
|
+
var makeLabelSetIdSchema = (valueLabel) => {
|
|
558
|
+
return z2.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
|
|
559
|
+
error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
|
|
560
|
+
});
|
|
561
|
+
};
|
|
562
|
+
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
563
|
+
return z2.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
564
|
+
};
|
|
565
|
+
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
566
|
+
let valueLabelLabelSetId = valueLabel;
|
|
567
|
+
let valueLabelLabelSetVersion = valueLabel;
|
|
568
|
+
if (valueLabel === "LABEL_SET") {
|
|
569
|
+
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
570
|
+
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
571
|
+
} else {
|
|
572
|
+
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
573
|
+
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
516
574
|
}
|
|
517
|
-
return
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
575
|
+
return z2.object({
|
|
576
|
+
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
577
|
+
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
581
|
+
var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z2.strictObject(
|
|
582
|
+
{
|
|
583
|
+
nodejs: makeNonEmptyStringSchema(),
|
|
584
|
+
ponder: makeNonEmptyStringSchema(),
|
|
585
|
+
ensDb: makeNonEmptyStringSchema(),
|
|
586
|
+
ensIndexer: makeNonEmptyStringSchema(),
|
|
587
|
+
ensNormalize: makeNonEmptyStringSchema(),
|
|
588
|
+
ensRainbow: makeNonEmptyStringSchema(),
|
|
589
|
+
ensRainbowSchema: makePositiveIntegerSchema()
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
|
|
526
593
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
${
|
|
535
|
-
|
|
594
|
+
).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
|
|
595
|
+
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
596
|
+
const { value: config } = ctx;
|
|
597
|
+
if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
|
|
598
|
+
ctx.issues.push({
|
|
599
|
+
code: "custom",
|
|
600
|
+
input: config,
|
|
601
|
+
message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
|
|
602
|
+
});
|
|
536
603
|
}
|
|
537
|
-
return parsed.data;
|
|
538
604
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
`)
|
|
546
|
-
}
|
|
547
|
-
|
|
605
|
+
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
|
|
606
|
+
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
607
|
+
indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
|
|
608
|
+
isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
609
|
+
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
610
|
+
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
611
|
+
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
612
|
+
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
613
|
+
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
614
|
+
|
|
615
|
+
// src/shared/config/thegraph.ts
|
|
616
|
+
import { z as z3 } from "zod/v4";
|
|
617
|
+
var TheGraphCannotFallbackReasonSchema = z3.enum({
|
|
618
|
+
NotSubgraphCompatible: "not-subgraph-compatible",
|
|
619
|
+
NoApiKey: "no-api-key",
|
|
620
|
+
NoSubgraphUrl: "no-subgraph-url"
|
|
621
|
+
});
|
|
622
|
+
var TheGraphFallbackSchema = z3.discriminatedUnion("canFallback", [
|
|
623
|
+
z3.strictObject({
|
|
624
|
+
canFallback: z3.literal(true),
|
|
625
|
+
url: z3.string()
|
|
626
|
+
}),
|
|
627
|
+
z3.strictObject({
|
|
628
|
+
canFallback: z3.literal(false),
|
|
629
|
+
reason: TheGraphCannotFallbackReasonSchema
|
|
630
|
+
})
|
|
631
|
+
]);
|
|
632
|
+
|
|
633
|
+
// src/ensapi/config/zod-schemas.ts
|
|
634
|
+
function makeENSApiPublicConfigSchema(valueLabel) {
|
|
635
|
+
const label = valueLabel ?? "ENSApiPublicConfig";
|
|
636
|
+
return z4.strictObject({
|
|
637
|
+
version: z4.string().min(1, `${label}.version must be a non-empty string`),
|
|
638
|
+
theGraphFallback: TheGraphFallbackSchema,
|
|
639
|
+
ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
|
|
640
|
+
});
|
|
548
641
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
642
|
+
|
|
643
|
+
// src/ensapi/config/deserialize.ts
|
|
644
|
+
function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
|
|
645
|
+
const schema = makeENSApiPublicConfigSchema(valueLabel);
|
|
646
|
+
try {
|
|
647
|
+
return schema.parse(maybeConfig);
|
|
648
|
+
} catch (error) {
|
|
649
|
+
if (error instanceof ZodError) {
|
|
650
|
+
throw new Error(`Cannot deserialize ENSApiPublicConfig:
|
|
651
|
+
${prettifyError(error)}
|
|
555
652
|
`);
|
|
653
|
+
}
|
|
654
|
+
throw error;
|
|
556
655
|
}
|
|
557
|
-
return parsed.data;
|
|
558
656
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
657
|
+
|
|
658
|
+
// src/ensindexer/config/deserialize.ts
|
|
659
|
+
import { prettifyError as prettifyError2 } from "zod/v4";
|
|
660
|
+
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
661
|
+
const schema = makeENSIndexerPublicConfigSchema(valueLabel);
|
|
662
|
+
const parsed = schema.safeParse(maybeConfig);
|
|
562
663
|
if (parsed.error) {
|
|
563
|
-
throw new
|
|
564
|
-
${
|
|
664
|
+
throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
|
|
665
|
+
${prettifyError2(parsed.error)}
|
|
565
666
|
`);
|
|
566
667
|
}
|
|
567
668
|
return parsed.data;
|
|
568
669
|
}
|
|
569
670
|
|
|
570
|
-
// src/
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// src/shared/cache/swr-cache.ts
|
|
579
|
-
var SWRCache = class {
|
|
580
|
-
constructor(options) {
|
|
581
|
-
this.options = options;
|
|
582
|
-
if (options.proactiveRevalidationInterval) {
|
|
583
|
-
this.backgroundInterval = setInterval(
|
|
584
|
-
() => this.revalidate(),
|
|
585
|
-
secondsToMilliseconds(options.proactiveRevalidationInterval)
|
|
586
|
-
);
|
|
671
|
+
// src/ensindexer/config/label-utils.ts
|
|
672
|
+
import { hexToBytes as hexToBytes2 } from "viem";
|
|
673
|
+
function labelHashToBytes(labelHash) {
|
|
674
|
+
try {
|
|
675
|
+
if (labelHash.length !== 66) {
|
|
676
|
+
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
587
677
|
}
|
|
588
|
-
if (
|
|
589
|
-
|
|
590
|
-
cache = null;
|
|
591
|
-
inProgressRevalidate = null;
|
|
592
|
-
backgroundInterval = null;
|
|
593
|
-
async revalidate() {
|
|
594
|
-
if (!this.inProgressRevalidate) {
|
|
595
|
-
this.inProgressRevalidate = this.options.fn().then((result) => {
|
|
596
|
-
this.cache = {
|
|
597
|
-
result,
|
|
598
|
-
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
599
|
-
};
|
|
600
|
-
}).catch((error) => {
|
|
601
|
-
if (!this.cache) {
|
|
602
|
-
this.cache = {
|
|
603
|
-
// ensure thrown value is always an Error instance
|
|
604
|
-
result: error instanceof Error ? error : new Error(String(error)),
|
|
605
|
-
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
}).finally(() => {
|
|
609
|
-
this.inProgressRevalidate = null;
|
|
610
|
-
});
|
|
678
|
+
if (labelHash !== labelHash.toLowerCase()) {
|
|
679
|
+
throw new Error("Labelhash must be in lowercase");
|
|
611
680
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* Read the most recently cached result from the `SWRCache`.
|
|
616
|
-
*
|
|
617
|
-
* @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
|
|
618
|
-
* has never successfully returned.
|
|
619
|
-
*/
|
|
620
|
-
async read() {
|
|
621
|
-
if (!this.cache) await this.revalidate();
|
|
622
|
-
if (!this.cache) throw new Error("never");
|
|
623
|
-
if (durationBetween(this.cache.updatedAt, getUnixTime(/* @__PURE__ */ new Date())) > this.options.ttl) {
|
|
624
|
-
this.revalidate();
|
|
681
|
+
if (!labelHash.startsWith("0x")) {
|
|
682
|
+
throw new Error("Labelhash must be 0x-prefixed");
|
|
625
683
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (
|
|
633
|
-
|
|
634
|
-
this.backgroundInterval = null;
|
|
684
|
+
const bytes = hexToBytes2(labelHash);
|
|
685
|
+
if (bytes.length !== 32) {
|
|
686
|
+
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
687
|
+
}
|
|
688
|
+
return bytes;
|
|
689
|
+
} catch (e) {
|
|
690
|
+
if (e instanceof Error) {
|
|
691
|
+
throw e;
|
|
635
692
|
}
|
|
693
|
+
throw new Error("Invalid hex format");
|
|
636
694
|
}
|
|
637
|
-
}
|
|
695
|
+
}
|
|
638
696
|
|
|
639
|
-
// src/
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
constructor(ttl) {
|
|
650
|
-
this._ttl = ttl;
|
|
697
|
+
// src/ensindexer/config/labelset-utils.ts
|
|
698
|
+
function buildLabelSetId(maybeLabelSetId) {
|
|
699
|
+
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
700
|
+
}
|
|
701
|
+
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
702
|
+
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
703
|
+
}
|
|
704
|
+
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
705
|
+
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
706
|
+
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
651
707
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
}
|
|
708
|
+
return { labelSetId, labelSetVersion };
|
|
709
|
+
}
|
|
710
|
+
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
711
|
+
if (clientSet.labelSetId === void 0) {
|
|
712
|
+
return;
|
|
659
713
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
714
|
+
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
715
|
+
throw new Error(
|
|
716
|
+
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
717
|
+
);
|
|
664
718
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
return void 0;
|
|
670
|
-
}
|
|
671
|
-
if (entry.expiresAt <= getUnixTime2(/* @__PURE__ */ new Date())) {
|
|
672
|
-
this._cache.delete(key);
|
|
673
|
-
return void 0;
|
|
674
|
-
}
|
|
675
|
-
return entry.value;
|
|
719
|
+
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
720
|
+
throw new Error(
|
|
721
|
+
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
722
|
+
);
|
|
676
723
|
}
|
|
677
|
-
|
|
678
|
-
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// src/ensindexer/config/parsing.ts
|
|
727
|
+
function parseNonNegativeInteger(maybeNumber) {
|
|
728
|
+
const trimmed = maybeNumber.trim();
|
|
729
|
+
if (!trimmed) {
|
|
730
|
+
throw new Error("Input cannot be empty");
|
|
679
731
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
return this._cache.size;
|
|
732
|
+
if (trimmed === "-0") {
|
|
733
|
+
throw new Error("Negative zero is not a valid non-negative integer");
|
|
683
734
|
}
|
|
684
|
-
|
|
685
|
-
|
|
735
|
+
const num = Number(maybeNumber);
|
|
736
|
+
if (Number.isNaN(num)) {
|
|
737
|
+
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
686
738
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
const entry = this._cache.get(key);
|
|
690
|
-
if (!entry) {
|
|
691
|
-
return false;
|
|
692
|
-
}
|
|
693
|
-
if (entry.expiresAt <= getUnixTime2(/* @__PURE__ */ new Date())) {
|
|
694
|
-
this._cache.delete(key);
|
|
695
|
-
return false;
|
|
696
|
-
}
|
|
697
|
-
return true;
|
|
739
|
+
if (!Number.isFinite(num)) {
|
|
740
|
+
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
698
741
|
}
|
|
699
|
-
|
|
700
|
-
|
|
742
|
+
if (!Number.isInteger(num)) {
|
|
743
|
+
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
701
744
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
745
|
+
if (num < 0) {
|
|
746
|
+
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
747
|
+
}
|
|
748
|
+
return num;
|
|
749
|
+
}
|
|
706
750
|
|
|
707
|
-
// src/
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
const
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
751
|
+
// src/ensindexer/config/serialize.ts
|
|
752
|
+
function serializeIndexedChainIds(indexedChainIds) {
|
|
753
|
+
return Array.from(indexedChainIds);
|
|
754
|
+
}
|
|
755
|
+
function serializeENSIndexerPublicConfig(config) {
|
|
756
|
+
const {
|
|
757
|
+
labelSet,
|
|
758
|
+
indexedChainIds,
|
|
759
|
+
databaseSchemaName,
|
|
760
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
761
|
+
namespace,
|
|
762
|
+
plugins,
|
|
763
|
+
versionInfo
|
|
764
|
+
} = config;
|
|
716
765
|
return {
|
|
717
|
-
|
|
718
|
-
|
|
766
|
+
labelSet,
|
|
767
|
+
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
768
|
+
databaseSchemaName,
|
|
769
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
770
|
+
namespace,
|
|
771
|
+
plugins,
|
|
772
|
+
versionInfo
|
|
719
773
|
};
|
|
720
|
-
};
|
|
721
|
-
var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
722
|
-
const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
|
|
723
|
-
if (!contract) {
|
|
724
|
-
throw new Error(
|
|
725
|
-
`Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
|
|
726
|
-
);
|
|
727
|
-
}
|
|
728
|
-
return contract;
|
|
729
|
-
};
|
|
730
|
-
var makeContractMatcher = (namespace, b) => (datasourceName, contractName) => {
|
|
731
|
-
const a = maybeGetDatasourceContract(namespace, datasourceName, contractName);
|
|
732
|
-
return a && accountIdEqual(a, b);
|
|
733
|
-
};
|
|
734
|
-
|
|
735
|
-
// src/shared/interpretation/interpret-address.ts
|
|
736
|
-
import { isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
|
|
737
|
-
var interpretAddress = (owner) => isAddressEqual2(zeroAddress, owner) ? null : owner;
|
|
738
|
-
|
|
739
|
-
// src/shared/interpretation/interpret-record-values.ts
|
|
740
|
-
import { isAddress as isAddress3, isAddressEqual as isAddressEqual3, zeroAddress as zeroAddress2 } from "viem";
|
|
741
|
-
|
|
742
|
-
// src/shared/null-bytes.ts
|
|
743
|
-
var hasNullByte = (value) => value.indexOf("\0") !== -1;
|
|
744
|
-
var stripNullBytes = (value) => value.replaceAll("\0", "");
|
|
745
|
-
|
|
746
|
-
// src/shared/interpretation/interpret-record-values.ts
|
|
747
|
-
function interpretNameRecordValue(value) {
|
|
748
|
-
if (value === "") return null;
|
|
749
|
-
if (!isNormalizedName(value)) return null;
|
|
750
|
-
return value;
|
|
751
|
-
}
|
|
752
|
-
function interpretAddressRecordValue(value) {
|
|
753
|
-
if (hasNullByte(value)) return null;
|
|
754
|
-
if (value === "") return null;
|
|
755
|
-
if (value === "0x") return null;
|
|
756
|
-
if (!isAddress3(value)) return value;
|
|
757
|
-
if (isAddressEqual3(value, zeroAddress2)) return null;
|
|
758
|
-
return asLowerCaseAddress(value);
|
|
759
|
-
}
|
|
760
|
-
function interpretTextRecordKey(key) {
|
|
761
|
-
if (hasNullByte(key)) return null;
|
|
762
|
-
if (key === "") return null;
|
|
763
|
-
return key;
|
|
764
|
-
}
|
|
765
|
-
function interpretTextRecordValue(value) {
|
|
766
|
-
if (hasNullByte(value)) return null;
|
|
767
|
-
if (value === "") return null;
|
|
768
|
-
return value;
|
|
769
774
|
}
|
|
770
775
|
|
|
771
|
-
// src/
|
|
772
|
-
|
|
773
|
-
var interpretTokenIdAsNode = (tokenId) => uint256ToHex32(tokenId);
|
|
774
|
-
|
|
775
|
-
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
776
|
-
import { isHex as isHex3 } from "viem";
|
|
777
|
-
import { labelhash } from "viem/ens";
|
|
776
|
+
// src/ensindexer/indexing-status/deserialize.ts
|
|
777
|
+
import { prettifyError as prettifyError4 } from "zod/v4";
|
|
778
778
|
|
|
779
|
-
// src/
|
|
780
|
-
import {
|
|
781
|
-
var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
|
|
779
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
780
|
+
import { z as z5 } from "zod/v4";
|
|
782
781
|
|
|
783
|
-
// src/shared/
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
function literalLabelsToLiteralName(labels) {
|
|
795
|
-
return labels.join(".");
|
|
782
|
+
// src/shared/deserialize.ts
|
|
783
|
+
import { prettifyError as prettifyError3 } from "zod/v4";
|
|
784
|
+
function deserializeChainId(maybeChainId, valueLabel) {
|
|
785
|
+
const schema = makeChainIdStringSchema(valueLabel);
|
|
786
|
+
const parsed = schema.safeParse(maybeChainId);
|
|
787
|
+
if (parsed.error) {
|
|
788
|
+
throw new Error(`Cannot deserialize ChainId:
|
|
789
|
+
${prettifyError3(parsed.error)}
|
|
790
|
+
`);
|
|
791
|
+
}
|
|
792
|
+
return parsed.data;
|
|
796
793
|
}
|
|
797
|
-
function
|
|
798
|
-
|
|
794
|
+
function deserializeDatetime(maybeDatetime, valueLabel) {
|
|
795
|
+
const schema = makeDatetimeSchema(valueLabel);
|
|
796
|
+
const parsed = schema.safeParse(maybeDatetime);
|
|
797
|
+
if (parsed.error) {
|
|
798
|
+
throw new Error(`Cannot deserialize Datetime:
|
|
799
|
+
${prettifyError3(parsed.error)}
|
|
800
|
+
`);
|
|
801
|
+
}
|
|
802
|
+
return parsed.data;
|
|
799
803
|
}
|
|
800
|
-
function
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
804
|
+
function deserializeUnixTimestamp(maybeTimestamp, valueLabel) {
|
|
805
|
+
const schema = makeUnixTimestampSchema(valueLabel);
|
|
806
|
+
const parsed = schema.safeParse(maybeTimestamp);
|
|
807
|
+
if (parsed.error) {
|
|
808
|
+
throw new Error(`Cannot deserialize Unix Timestamp:
|
|
809
|
+
${prettifyError3(parsed.error)}
|
|
810
|
+
`);
|
|
811
|
+
}
|
|
812
|
+
return parsed.data;
|
|
807
813
|
}
|
|
808
|
-
function
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
814
|
+
function deserializeUrl(maybeUrl, valueLabel) {
|
|
815
|
+
const schema = makeUrlSchema(valueLabel);
|
|
816
|
+
const parsed = schema.safeParse(maybeUrl);
|
|
817
|
+
if (parsed.error) {
|
|
818
|
+
throw new Error(`Cannot deserialize URL:
|
|
819
|
+
${prettifyError3(parsed.error)}
|
|
820
|
+
`);
|
|
812
821
|
}
|
|
813
|
-
return
|
|
822
|
+
return parsed.data;
|
|
814
823
|
}
|
|
815
|
-
function
|
|
816
|
-
|
|
824
|
+
function deserializeBlockNumber(maybeBlockNumber, valueLabel) {
|
|
825
|
+
const schema = makeBlockNumberSchema(valueLabel);
|
|
826
|
+
const parsed = schema.safeParse(maybeBlockNumber);
|
|
827
|
+
if (parsed.error) {
|
|
828
|
+
throw new Error(`Cannot deserialize BlockNumber:
|
|
829
|
+
${prettifyError3(parsed.error)}
|
|
830
|
+
`);
|
|
831
|
+
}
|
|
832
|
+
return parsed.data;
|
|
817
833
|
}
|
|
818
|
-
function
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
return labelhash(label);
|
|
828
|
-
}).toReversed();
|
|
834
|
+
function deserializeBlockrange(maybeBlockrange, valueLabel) {
|
|
835
|
+
const schema = makeBlockrangeSchema(valueLabel);
|
|
836
|
+
const parsed = schema.safeParse(maybeBlockrange);
|
|
837
|
+
if (parsed.error) {
|
|
838
|
+
throw new Error(`Cannot deserialize Blockrange:
|
|
839
|
+
${prettifyError3(parsed.error)}
|
|
840
|
+
`);
|
|
841
|
+
}
|
|
842
|
+
return parsed.data;
|
|
829
843
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
if (
|
|
834
|
-
throw new Error(
|
|
835
|
-
|
|
836
|
-
|
|
844
|
+
function deserializeBlockRef(maybeBlockRef, valueLabel) {
|
|
845
|
+
const schema = makeBlockRefSchema(valueLabel);
|
|
846
|
+
const parsed = schema.safeParse(maybeBlockRef);
|
|
847
|
+
if (parsed.error) {
|
|
848
|
+
throw new Error(`Cannot deserialize BlockRef:
|
|
849
|
+
${prettifyError3(parsed.error)}
|
|
850
|
+
`);
|
|
837
851
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
852
|
+
return parsed.data;
|
|
853
|
+
}
|
|
854
|
+
function deserializeDuration(maybeDuration, valueLabel) {
|
|
855
|
+
const schema = makeDurationSchema(valueLabel);
|
|
856
|
+
const parsed = schema.safeParse(maybeDuration);
|
|
857
|
+
if (parsed.error) {
|
|
858
|
+
throw new RangeError(`Cannot deserialize Duration:
|
|
859
|
+
${prettifyError3(parsed.error)}
|
|
860
|
+
`);
|
|
842
861
|
}
|
|
843
|
-
return
|
|
862
|
+
return parsed.data;
|
|
844
863
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
// src/shared/serialize.ts
|
|
855
|
-
import { AccountId as CaipAccountId2, AssetId as CaipAssetId } from "caip";
|
|
856
|
-
function serializeChainId(chainId) {
|
|
857
|
-
return chainId.toString();
|
|
864
|
+
function parseAccountId(maybeAccountId, valueLabel) {
|
|
865
|
+
const schema = makeAccountIdStringSchema(valueLabel);
|
|
866
|
+
const parsed = schema.safeParse(maybeAccountId);
|
|
867
|
+
if (parsed.error) {
|
|
868
|
+
throw new RangeError(`Cannot deserialize AccountId:
|
|
869
|
+
${prettifyError3(parsed.error)}
|
|
870
|
+
`);
|
|
871
|
+
}
|
|
872
|
+
return parsed.data;
|
|
858
873
|
}
|
|
859
|
-
function
|
|
860
|
-
|
|
874
|
+
function deserializePriceEth(maybePrice, valueLabel) {
|
|
875
|
+
const schema = makePriceEthSchema(valueLabel);
|
|
876
|
+
const parsed = schema.safeParse(maybePrice);
|
|
877
|
+
if (parsed.error) {
|
|
878
|
+
throw new Error(`Cannot deserialize PriceEth:
|
|
879
|
+
${prettifyError3(parsed.error)}
|
|
880
|
+
`);
|
|
881
|
+
}
|
|
882
|
+
return parsed.data;
|
|
861
883
|
}
|
|
862
|
-
function
|
|
863
|
-
|
|
884
|
+
function deserializePriceUsdc(maybePrice, valueLabel) {
|
|
885
|
+
const schema = makePriceUsdcSchema(valueLabel);
|
|
886
|
+
const parsed = schema.safeParse(maybePrice);
|
|
887
|
+
if (parsed.error) {
|
|
888
|
+
throw new Error(`Cannot deserialize PriceUsdc:
|
|
889
|
+
${prettifyError3(parsed.error)}
|
|
890
|
+
`);
|
|
891
|
+
}
|
|
892
|
+
return parsed.data;
|
|
864
893
|
}
|
|
865
|
-
function
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
function formatAccountId(accountId) {
|
|
875
|
-
return CaipAccountId2.format({
|
|
876
|
-
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
877
|
-
address: accountId.address
|
|
878
|
-
}).toLowerCase();
|
|
879
|
-
}
|
|
880
|
-
function formatAssetId({
|
|
881
|
-
assetNamespace,
|
|
882
|
-
contract: { chainId, address },
|
|
883
|
-
tokenId
|
|
884
|
-
}) {
|
|
885
|
-
return CaipAssetId.format({
|
|
886
|
-
chainId: { namespace: "eip155", reference: chainId.toString() },
|
|
887
|
-
assetName: { namespace: assetNamespace, reference: address },
|
|
888
|
-
tokenId: uint256ToHex32(tokenId)
|
|
889
|
-
}).toLowerCase();
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
// src/shared/types.ts
|
|
893
|
-
var AssetNamespaces = {
|
|
894
|
-
ERC721: "erc721",
|
|
895
|
-
ERC1155: "erc1155"
|
|
896
|
-
};
|
|
897
|
-
|
|
898
|
-
// src/shared/url.ts
|
|
899
|
-
function isHttpProtocol(url) {
|
|
900
|
-
return ["http:", "https:"].includes(url.protocol);
|
|
901
|
-
}
|
|
902
|
-
function isWebSocketProtocol(url) {
|
|
903
|
-
return ["ws:", "wss:"].includes(url.protocol);
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
907
|
-
import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
|
|
908
|
-
|
|
909
|
-
// src/ensindexer/config/types.ts
|
|
910
|
-
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
911
|
-
PluginName2["Subgraph"] = "subgraph";
|
|
912
|
-
PluginName2["Basenames"] = "basenames";
|
|
913
|
-
PluginName2["Lineanames"] = "lineanames";
|
|
914
|
-
PluginName2["ThreeDNS"] = "threedns";
|
|
915
|
-
PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
|
|
916
|
-
PluginName2["Registrars"] = "registrars";
|
|
917
|
-
PluginName2["TokenScope"] = "tokenscope";
|
|
918
|
-
PluginName2["ENSv2"] = "ensv2";
|
|
919
|
-
return PluginName2;
|
|
920
|
-
})(PluginName || {});
|
|
921
|
-
|
|
922
|
-
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
923
|
-
function isSubgraphCompatible(config) {
|
|
924
|
-
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
925
|
-
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
926
|
-
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
927
|
-
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
928
|
-
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
// src/ensindexer/config/validations.ts
|
|
932
|
-
function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
|
|
933
|
-
const versionInfo = ctx.value;
|
|
934
|
-
if (versionInfo.ensDb !== versionInfo.ensIndexer) {
|
|
935
|
-
ctx.issues.push({
|
|
936
|
-
code: "custom",
|
|
937
|
-
input: versionInfo,
|
|
938
|
-
message: "`ensDb` version must be same as `ensIndexer` version"
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
// src/ensindexer/config/zod-schemas.ts
|
|
944
|
-
var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
|
|
945
|
-
error: `${valueLabel} must be an array.`
|
|
946
|
-
}).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
|
|
947
|
-
var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(z2.string(), {
|
|
948
|
-
error: `${valueLabel} must be a list of strings.`
|
|
949
|
-
}).min(1, {
|
|
950
|
-
error: `${valueLabel} must be a list of strings with at least one string value`
|
|
951
|
-
}).refine((arr) => arr.length === uniq(arr).length, {
|
|
952
|
-
error: `${valueLabel} cannot contain duplicate values.`
|
|
953
|
-
});
|
|
954
|
-
var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
|
|
955
|
-
error: `${valueLabel} is required and must be a non-empty string.`
|
|
956
|
-
});
|
|
957
|
-
var makeLabelSetIdSchema = (valueLabel) => {
|
|
958
|
-
return z2.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
|
|
959
|
-
error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
|
|
960
|
-
});
|
|
961
|
-
};
|
|
962
|
-
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
963
|
-
return z2.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
964
|
-
};
|
|
965
|
-
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
966
|
-
let valueLabelLabelSetId = valueLabel;
|
|
967
|
-
let valueLabelLabelSetVersion = valueLabel;
|
|
968
|
-
if (valueLabel === "LABEL_SET") {
|
|
969
|
-
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
970
|
-
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
971
|
-
} else {
|
|
972
|
-
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
973
|
-
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
974
|
-
}
|
|
975
|
-
return z2.object({
|
|
976
|
-
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
977
|
-
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
978
|
-
});
|
|
979
|
-
};
|
|
980
|
-
var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
981
|
-
var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z2.strictObject(
|
|
982
|
-
{
|
|
983
|
-
nodejs: makeNonEmptyStringSchema(),
|
|
984
|
-
ponder: makeNonEmptyStringSchema(),
|
|
985
|
-
ensDb: makeNonEmptyStringSchema(),
|
|
986
|
-
ensIndexer: makeNonEmptyStringSchema(),
|
|
987
|
-
ensNormalize: makeNonEmptyStringSchema(),
|
|
988
|
-
ensRainbow: makeNonEmptyStringSchema(),
|
|
989
|
-
ensRainbowSchema: makePositiveIntegerSchema()
|
|
990
|
-
},
|
|
991
|
-
{
|
|
992
|
-
error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
|
|
993
|
-
}
|
|
994
|
-
).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
|
|
995
|
-
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
996
|
-
const { value: config } = ctx;
|
|
997
|
-
if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
|
|
998
|
-
ctx.issues.push({
|
|
999
|
-
code: "custom",
|
|
1000
|
-
input: config,
|
|
1001
|
-
message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
|
|
1002
|
-
});
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
|
|
1006
|
-
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
1007
|
-
indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
|
|
1008
|
-
isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
1009
|
-
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
1010
|
-
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
1011
|
-
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
1012
|
-
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
1013
|
-
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
1014
|
-
|
|
1015
|
-
// src/shared/config/thegraph.ts
|
|
1016
|
-
import { z as z3 } from "zod/v4";
|
|
1017
|
-
var TheGraphCannotFallbackReasonSchema = z3.enum({
|
|
1018
|
-
NotSubgraphCompatible: "not-subgraph-compatible",
|
|
1019
|
-
NoApiKey: "no-api-key",
|
|
1020
|
-
NoSubgraphUrl: "no-subgraph-url"
|
|
1021
|
-
});
|
|
1022
|
-
var TheGraphFallbackSchema = z3.discriminatedUnion("canFallback", [
|
|
1023
|
-
z3.strictObject({
|
|
1024
|
-
canFallback: z3.literal(true),
|
|
1025
|
-
url: z3.string()
|
|
1026
|
-
}),
|
|
1027
|
-
z3.strictObject({
|
|
1028
|
-
canFallback: z3.literal(false),
|
|
1029
|
-
reason: TheGraphCannotFallbackReasonSchema
|
|
1030
|
-
})
|
|
1031
|
-
]);
|
|
1032
|
-
|
|
1033
|
-
// src/ensapi/config/zod-schemas.ts
|
|
1034
|
-
function makeENSApiPublicConfigSchema(valueLabel) {
|
|
1035
|
-
const label = valueLabel ?? "ENSApiPublicConfig";
|
|
1036
|
-
return z4.strictObject({
|
|
1037
|
-
version: z4.string().min(1, `${label}.version must be a non-empty string`),
|
|
1038
|
-
theGraphFallback: TheGraphFallbackSchema,
|
|
1039
|
-
ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
// src/ensapi/config/deserialize.ts
|
|
1044
|
-
function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
|
|
1045
|
-
const schema = makeENSApiPublicConfigSchema(valueLabel);
|
|
1046
|
-
try {
|
|
1047
|
-
return schema.parse(maybeConfig);
|
|
1048
|
-
} catch (error) {
|
|
1049
|
-
if (error instanceof ZodError) {
|
|
1050
|
-
throw new Error(`Cannot deserialize ENSApiPublicConfig:
|
|
1051
|
-
${prettifyError2(error)}
|
|
1052
|
-
`);
|
|
1053
|
-
}
|
|
1054
|
-
throw error;
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
// src/ensindexer/config/deserialize.ts
|
|
1059
|
-
import { prettifyError as prettifyError3 } from "zod/v4";
|
|
1060
|
-
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
1061
|
-
const schema = makeENSIndexerPublicConfigSchema(valueLabel);
|
|
1062
|
-
const parsed = schema.safeParse(maybeConfig);
|
|
1063
|
-
if (parsed.error) {
|
|
1064
|
-
throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
|
|
1065
|
-
${prettifyError3(parsed.error)}
|
|
1066
|
-
`);
|
|
1067
|
-
}
|
|
1068
|
-
return parsed.data;
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
// src/ensindexer/config/label-utils.ts
|
|
1072
|
-
import { hexToBytes as hexToBytes2 } from "viem";
|
|
1073
|
-
function labelHashToBytes(labelHash) {
|
|
1074
|
-
try {
|
|
1075
|
-
if (labelHash.length !== 66) {
|
|
1076
|
-
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
1077
|
-
}
|
|
1078
|
-
if (labelHash !== labelHash.toLowerCase()) {
|
|
1079
|
-
throw new Error("Labelhash must be in lowercase");
|
|
1080
|
-
}
|
|
1081
|
-
if (!labelHash.startsWith("0x")) {
|
|
1082
|
-
throw new Error("Labelhash must be 0x-prefixed");
|
|
1083
|
-
}
|
|
1084
|
-
const bytes = hexToBytes2(labelHash);
|
|
1085
|
-
if (bytes.length !== 32) {
|
|
1086
|
-
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
1087
|
-
}
|
|
1088
|
-
return bytes;
|
|
1089
|
-
} catch (e) {
|
|
1090
|
-
if (e instanceof Error) {
|
|
1091
|
-
throw e;
|
|
1092
|
-
}
|
|
1093
|
-
throw new Error("Invalid hex format");
|
|
1094
|
-
}
|
|
894
|
+
function deserializePriceDai(maybePrice, valueLabel) {
|
|
895
|
+
const schema = makePriceDaiSchema(valueLabel);
|
|
896
|
+
const parsed = schema.safeParse(maybePrice);
|
|
897
|
+
if (parsed.error) {
|
|
898
|
+
throw new Error(`Cannot deserialize PriceDai:
|
|
899
|
+
${prettifyError3(parsed.error)}
|
|
900
|
+
`);
|
|
901
|
+
}
|
|
902
|
+
return parsed.data;
|
|
1095
903
|
}
|
|
1096
904
|
|
|
1097
|
-
// src/ensindexer/config/labelset-utils.ts
|
|
1098
|
-
function buildLabelSetId(maybeLabelSetId) {
|
|
1099
|
-
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
1100
|
-
}
|
|
1101
|
-
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
1102
|
-
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
1103
|
-
}
|
|
1104
|
-
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
1105
|
-
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
1106
|
-
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
1107
|
-
}
|
|
1108
|
-
return { labelSetId, labelSetVersion };
|
|
1109
|
-
}
|
|
1110
|
-
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
1111
|
-
if (clientSet.labelSetId === void 0) {
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
1115
|
-
throw new Error(
|
|
1116
|
-
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
1117
|
-
);
|
|
1118
|
-
}
|
|
1119
|
-
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
1120
|
-
throw new Error(
|
|
1121
|
-
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
1122
|
-
);
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
// src/ensindexer/config/parsing.ts
|
|
1127
|
-
function parseNonNegativeInteger(maybeNumber) {
|
|
1128
|
-
const trimmed = maybeNumber.trim();
|
|
1129
|
-
if (!trimmed) {
|
|
1130
|
-
throw new Error("Input cannot be empty");
|
|
1131
|
-
}
|
|
1132
|
-
if (trimmed === "-0") {
|
|
1133
|
-
throw new Error("Negative zero is not a valid non-negative integer");
|
|
1134
|
-
}
|
|
1135
|
-
const num = Number(maybeNumber);
|
|
1136
|
-
if (Number.isNaN(num)) {
|
|
1137
|
-
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
1138
|
-
}
|
|
1139
|
-
if (!Number.isFinite(num)) {
|
|
1140
|
-
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
1141
|
-
}
|
|
1142
|
-
if (!Number.isInteger(num)) {
|
|
1143
|
-
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
1144
|
-
}
|
|
1145
|
-
if (num < 0) {
|
|
1146
|
-
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
1147
|
-
}
|
|
1148
|
-
return num;
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
// src/ensindexer/config/serialize.ts
|
|
1152
|
-
function serializeIndexedChainIds(indexedChainIds) {
|
|
1153
|
-
return Array.from(indexedChainIds);
|
|
1154
|
-
}
|
|
1155
|
-
function serializeENSIndexerPublicConfig(config) {
|
|
1156
|
-
const {
|
|
1157
|
-
labelSet,
|
|
1158
|
-
indexedChainIds,
|
|
1159
|
-
databaseSchemaName,
|
|
1160
|
-
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1161
|
-
namespace,
|
|
1162
|
-
plugins,
|
|
1163
|
-
versionInfo
|
|
1164
|
-
} = config;
|
|
1165
|
-
return {
|
|
1166
|
-
labelSet,
|
|
1167
|
-
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
1168
|
-
databaseSchemaName,
|
|
1169
|
-
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1170
|
-
namespace,
|
|
1171
|
-
plugins,
|
|
1172
|
-
versionInfo
|
|
1173
|
-
};
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
// src/ensindexer/indexing-status/deserialize.ts
|
|
1177
|
-
import { prettifyError as prettifyError4 } from "zod/v4";
|
|
1178
|
-
|
|
1179
|
-
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1180
|
-
import { z as z5 } from "zod/v4";
|
|
1181
|
-
|
|
1182
905
|
// src/ensindexer/indexing-status/types.ts
|
|
1183
906
|
var ChainIndexingConfigTypeIds = {
|
|
1184
907
|
/**
|
|
@@ -1792,6 +1515,50 @@ function createRealtimeIndexingStatusProjection(snapshot, now) {
|
|
|
1792
1515
|
};
|
|
1793
1516
|
}
|
|
1794
1517
|
|
|
1518
|
+
// src/shared/serialize.ts
|
|
1519
|
+
import { AccountId as CaipAccountId2, AssetId as CaipAssetId } from "caip";
|
|
1520
|
+
function serializeChainId(chainId) {
|
|
1521
|
+
return chainId.toString();
|
|
1522
|
+
}
|
|
1523
|
+
function serializeDatetime(datetime) {
|
|
1524
|
+
return datetime.toISOString();
|
|
1525
|
+
}
|
|
1526
|
+
function serializeUrl(url) {
|
|
1527
|
+
return url.toString();
|
|
1528
|
+
}
|
|
1529
|
+
function serializePrice(price) {
|
|
1530
|
+
return {
|
|
1531
|
+
currency: price.currency,
|
|
1532
|
+
amount: price.amount.toString()
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
function serializePriceEth(price) {
|
|
1536
|
+
return serializePrice(price);
|
|
1537
|
+
}
|
|
1538
|
+
function serializePriceUsdc(price) {
|
|
1539
|
+
return serializePrice(price);
|
|
1540
|
+
}
|
|
1541
|
+
function serializePriceDai(price) {
|
|
1542
|
+
return serializePrice(price);
|
|
1543
|
+
}
|
|
1544
|
+
function formatAccountId(accountId) {
|
|
1545
|
+
return CaipAccountId2.format({
|
|
1546
|
+
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
1547
|
+
address: accountId.address
|
|
1548
|
+
}).toLowerCase();
|
|
1549
|
+
}
|
|
1550
|
+
function formatAssetId({
|
|
1551
|
+
assetNamespace,
|
|
1552
|
+
contract: { chainId, address },
|
|
1553
|
+
tokenId
|
|
1554
|
+
}) {
|
|
1555
|
+
return CaipAssetId.format({
|
|
1556
|
+
chainId: { namespace: "eip155", reference: chainId.toString() },
|
|
1557
|
+
assetName: { namespace: assetNamespace, reference: address },
|
|
1558
|
+
tokenId: uint256ToHex32(tokenId)
|
|
1559
|
+
}).toLowerCase();
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1795
1562
|
// src/ensindexer/indexing-status/serialize.ts
|
|
1796
1563
|
function serializeCrossChainIndexingStatusSnapshotOmnichain({
|
|
1797
1564
|
strategy,
|
|
@@ -1933,17 +1700,59 @@ import { namehash as namehash2 } from "viem";
|
|
|
1933
1700
|
import { z as z9 } from "zod/v4";
|
|
1934
1701
|
|
|
1935
1702
|
// src/tokenscope/assets.ts
|
|
1936
|
-
import { isAddressEqual as
|
|
1703
|
+
import { isAddressEqual as isAddressEqual3, zeroAddress as zeroAddress3 } from "viem";
|
|
1937
1704
|
import { prettifyError as prettifyError6 } from "zod/v4";
|
|
1938
1705
|
|
|
1939
1706
|
// src/tokenscope/zod-schemas.ts
|
|
1940
1707
|
import { AssetId as CaipAssetId2 } from "caip";
|
|
1941
|
-
import { zeroAddress as
|
|
1708
|
+
import { zeroAddress as zeroAddress2 } from "viem";
|
|
1942
1709
|
import { z as z7 } from "zod/v4";
|
|
1943
1710
|
|
|
1711
|
+
// src/shared/types.ts
|
|
1712
|
+
var AssetNamespaces = {
|
|
1713
|
+
ERC721: "erc721",
|
|
1714
|
+
ERC1155: "erc1155"
|
|
1715
|
+
};
|
|
1716
|
+
|
|
1717
|
+
// src/tokenscope/name-token.ts
|
|
1718
|
+
import { isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
|
|
1719
|
+
import { DatasourceNames } from "@ensnode/datasources";
|
|
1720
|
+
|
|
1721
|
+
// src/shared/account-id.ts
|
|
1722
|
+
import { isAddressEqual } from "viem";
|
|
1723
|
+
var accountIdEqual = (a, b) => {
|
|
1724
|
+
return a.chainId === b.chainId && isAddressEqual(a.address, b.address);
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1727
|
+
// src/shared/datasource-contract.ts
|
|
1728
|
+
import {
|
|
1729
|
+
maybeGetDatasource
|
|
1730
|
+
} from "@ensnode/datasources";
|
|
1731
|
+
var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
1732
|
+
const datasource = maybeGetDatasource(namespaceId, datasourceName);
|
|
1733
|
+
if (!datasource) return void 0;
|
|
1734
|
+
const address = datasource.contracts[contractName]?.address;
|
|
1735
|
+
if (address === void 0 || Array.isArray(address)) return void 0;
|
|
1736
|
+
return {
|
|
1737
|
+
chainId: datasource.chain.id,
|
|
1738
|
+
address
|
|
1739
|
+
};
|
|
1740
|
+
};
|
|
1741
|
+
var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
1742
|
+
const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
|
|
1743
|
+
if (!contract) {
|
|
1744
|
+
throw new Error(
|
|
1745
|
+
`Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
return contract;
|
|
1749
|
+
};
|
|
1750
|
+
var makeContractMatcher = (namespace, b) => (datasourceName, contractName) => {
|
|
1751
|
+
const a = maybeGetDatasourceContract(namespace, datasourceName, contractName);
|
|
1752
|
+
return a && accountIdEqual(a, b);
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1944
1755
|
// src/tokenscope/name-token.ts
|
|
1945
|
-
import { isAddressEqual as isAddressEqual4, zeroAddress as zeroAddress3 } from "viem";
|
|
1946
|
-
import { DatasourceNames as DatasourceNames2 } from "@ensnode/datasources";
|
|
1947
1756
|
var NameTokenOwnershipTypes = {
|
|
1948
1757
|
/**
|
|
1949
1758
|
* Name Token is owned by NameWrapper account.
|
|
@@ -1974,12 +1783,12 @@ function serializeNameToken(nameToken) {
|
|
|
1974
1783
|
function getNameWrapperAccounts(namespaceId) {
|
|
1975
1784
|
const ethnamesNameWrapperAccount = getDatasourceContract(
|
|
1976
1785
|
namespaceId,
|
|
1977
|
-
|
|
1786
|
+
DatasourceNames.ENSRoot,
|
|
1978
1787
|
"NameWrapper"
|
|
1979
1788
|
);
|
|
1980
1789
|
const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
|
|
1981
1790
|
namespaceId,
|
|
1982
|
-
|
|
1791
|
+
DatasourceNames.Lineanames,
|
|
1983
1792
|
"NameWrapper"
|
|
1984
1793
|
);
|
|
1985
1794
|
const nameWrapperAccounts = [
|
|
@@ -2002,7 +1811,7 @@ function getNameTokenOwnership(namespaceId, name, owner) {
|
|
|
2002
1811
|
owner
|
|
2003
1812
|
};
|
|
2004
1813
|
}
|
|
2005
|
-
if (
|
|
1814
|
+
if (isAddressEqual2(owner.address, zeroAddress)) {
|
|
2006
1815
|
return {
|
|
2007
1816
|
ownershipType: NameTokenOwnershipTypes.Burned,
|
|
2008
1817
|
owner
|
|
@@ -2057,7 +1866,7 @@ var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => z7.prep
|
|
|
2057
1866
|
}, makeAssetIdSchema(valueLabel));
|
|
2058
1867
|
function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
|
|
2059
1868
|
const ownership = ctx.value;
|
|
2060
|
-
if (ctx.value.owner.address ===
|
|
1869
|
+
if (ctx.value.owner.address === zeroAddress2) {
|
|
2061
1870
|
ctx.issues.push({
|
|
2062
1871
|
code: "custom",
|
|
2063
1872
|
input: ctx.value,
|
|
@@ -2083,7 +1892,7 @@ var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Un
|
|
|
2083
1892
|
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
2084
1893
|
function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
|
|
2085
1894
|
const ownership = ctx.value;
|
|
2086
|
-
if (ctx.value.owner.address !==
|
|
1895
|
+
if (ctx.value.owner.address !== zeroAddress2) {
|
|
2087
1896
|
ctx.issues.push({
|
|
2088
1897
|
code: "custom",
|
|
2089
1898
|
input: ctx.value,
|
|
@@ -2261,11 +2070,11 @@ var NFTTransferTypes = {
|
|
|
2261
2070
|
};
|
|
2262
2071
|
var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
|
|
2263
2072
|
const isIndexed = currentlyIndexedOwner !== void 0;
|
|
2264
|
-
const isIndexedAsMinted = isIndexed && !
|
|
2265
|
-
const isMint =
|
|
2266
|
-
const isBurn =
|
|
2267
|
-
const isSelfTransfer =
|
|
2268
|
-
if (isIndexed && !
|
|
2073
|
+
const isIndexedAsMinted = isIndexed && !isAddressEqual3(currentlyIndexedOwner, zeroAddress3);
|
|
2074
|
+
const isMint = isAddressEqual3(from, zeroAddress3);
|
|
2075
|
+
const isBurn = isAddressEqual3(to, zeroAddress3);
|
|
2076
|
+
const isSelfTransfer = isAddressEqual3(from, to);
|
|
2077
|
+
if (isIndexed && !isAddressEqual3(currentlyIndexedOwner, from)) {
|
|
2269
2078
|
if (isMint && allowMintedRemint) {
|
|
2270
2079
|
} else {
|
|
2271
2080
|
throw new Error(
|
|
@@ -2557,7 +2366,7 @@ import { z as z12 } from "zod/v4";
|
|
|
2557
2366
|
import { z as z10 } from "zod/v4";
|
|
2558
2367
|
|
|
2559
2368
|
// src/registrars/encoded-referrer.ts
|
|
2560
|
-
import { getAddress, pad, size as size2, slice, zeroAddress as
|
|
2369
|
+
import { getAddress, pad, size as size2, slice, zeroAddress as zeroAddress4 } from "viem";
|
|
2561
2370
|
var ENCODED_REFERRER_BYTE_OFFSET = 12;
|
|
2562
2371
|
var ENCODED_REFERRER_BYTE_LENGTH = 32;
|
|
2563
2372
|
var EXPECTED_ENCODED_REFERRER_PADDING = pad("0x", {
|
|
@@ -2580,7 +2389,7 @@ function decodeEncodedReferrer(encodedReferrer) {
|
|
|
2580
2389
|
}
|
|
2581
2390
|
const padding = slice(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
|
|
2582
2391
|
if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
|
|
2583
|
-
return
|
|
2392
|
+
return zeroAddress4;
|
|
2584
2393
|
}
|
|
2585
2394
|
const decodedReferrer = slice(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
|
|
2586
2395
|
try {
|
|
@@ -2977,14 +2786,14 @@ var registrarActionsPrerequisites = Object.freeze({
|
|
|
2977
2786
|
|
|
2978
2787
|
// src/registrars/basenames-subregistry.ts
|
|
2979
2788
|
import {
|
|
2980
|
-
DatasourceNames as
|
|
2789
|
+
DatasourceNames as DatasourceNames2,
|
|
2981
2790
|
ENSNamespaceIds as ENSNamespaceIds3,
|
|
2982
2791
|
maybeGetDatasource as maybeGetDatasource2
|
|
2983
2792
|
} from "@ensnode/datasources";
|
|
2984
2793
|
function getBasenamesSubregistryId(namespace) {
|
|
2985
|
-
const datasource = maybeGetDatasource2(namespace,
|
|
2794
|
+
const datasource = maybeGetDatasource2(namespace, DatasourceNames2.Basenames);
|
|
2986
2795
|
if (!datasource) {
|
|
2987
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
2796
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames2.Basenames}`);
|
|
2988
2797
|
}
|
|
2989
2798
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2990
2799
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -3011,14 +2820,14 @@ function getBasenamesSubregistryManagedName(namespaceId) {
|
|
|
3011
2820
|
|
|
3012
2821
|
// src/registrars/ethnames-subregistry.ts
|
|
3013
2822
|
import {
|
|
3014
|
-
DatasourceNames as
|
|
2823
|
+
DatasourceNames as DatasourceNames3,
|
|
3015
2824
|
ENSNamespaceIds as ENSNamespaceIds4,
|
|
3016
2825
|
maybeGetDatasource as maybeGetDatasource3
|
|
3017
2826
|
} from "@ensnode/datasources";
|
|
3018
2827
|
function getEthnamesSubregistryId(namespace) {
|
|
3019
|
-
const datasource = maybeGetDatasource3(namespace,
|
|
2828
|
+
const datasource = maybeGetDatasource3(namespace, DatasourceNames3.ENSRoot);
|
|
3020
2829
|
if (!datasource) {
|
|
3021
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
2830
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames3.ENSRoot}`);
|
|
3022
2831
|
}
|
|
3023
2832
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
3024
2833
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -3041,14 +2850,14 @@ function getEthnamesSubregistryManagedName(namespaceId) {
|
|
|
3041
2850
|
|
|
3042
2851
|
// src/registrars/lineanames-subregistry.ts
|
|
3043
2852
|
import {
|
|
3044
|
-
DatasourceNames as
|
|
2853
|
+
DatasourceNames as DatasourceNames4,
|
|
3045
2854
|
ENSNamespaceIds as ENSNamespaceIds5,
|
|
3046
2855
|
maybeGetDatasource as maybeGetDatasource4
|
|
3047
2856
|
} from "@ensnode/datasources";
|
|
3048
2857
|
function getLineanamesSubregistryId(namespace) {
|
|
3049
|
-
const datasource = maybeGetDatasource4(namespace,
|
|
2858
|
+
const datasource = maybeGetDatasource4(namespace, DatasourceNames4.Lineanames);
|
|
3050
2859
|
if (!datasource) {
|
|
3051
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
2860
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames4.Lineanames}`);
|
|
3052
2861
|
}
|
|
3053
2862
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
3054
2863
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -3591,145 +3400,444 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3591
3400
|
try {
|
|
3592
3401
|
errorResponse = deserializeErrorResponse(responseData);
|
|
3593
3402
|
} catch {
|
|
3594
|
-
console.log("Registrar Actions API: handling a known server error.");
|
|
3403
|
+
console.log("Registrar Actions API: handling a known server error.");
|
|
3404
|
+
}
|
|
3405
|
+
if (typeof errorResponse !== "undefined") {
|
|
3406
|
+
throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
return deserializeRegistrarActionsResponse(responseData);
|
|
3410
|
+
}
|
|
3411
|
+
/**
|
|
3412
|
+
* Fetch Name Tokens for requested name.
|
|
3413
|
+
*
|
|
3414
|
+
* @param request.name - Name for which Name Tokens will be fetched.
|
|
3415
|
+
* @returns {NameTokensResponse}
|
|
3416
|
+
*
|
|
3417
|
+
* @throws if the ENSNode request fails
|
|
3418
|
+
* @throws if the ENSNode API returns an error response
|
|
3419
|
+
* @throws if the ENSNode response breaks required invariants
|
|
3420
|
+
*
|
|
3421
|
+
* @example
|
|
3422
|
+
* ```ts
|
|
3423
|
+
* import {
|
|
3424
|
+
* ENSNodeClient,
|
|
3425
|
+
* } from "@ensnode/ensnode-sdk";
|
|
3426
|
+
* import { namehash } from "viem/ens";
|
|
3427
|
+
*
|
|
3428
|
+
* const client: ENSNodeClient;
|
|
3429
|
+
*
|
|
3430
|
+
* // get latest name token records from the indexed subregistry based on the requested name
|
|
3431
|
+
* const response = await client.nameTokens({
|
|
3432
|
+
* name: "vitalik.eth"
|
|
3433
|
+
* });
|
|
3434
|
+
*
|
|
3435
|
+
* const response = await client.nameTokens({
|
|
3436
|
+
* domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
|
|
3437
|
+
* })
|
|
3438
|
+
* ```
|
|
3439
|
+
*/
|
|
3440
|
+
async nameTokens(request) {
|
|
3441
|
+
const url = new URL(`/api/name-tokens`, this.options.url);
|
|
3442
|
+
if (request.name !== void 0) {
|
|
3443
|
+
url.searchParams.set("name", request.name);
|
|
3444
|
+
} else if (request.domainId !== void 0) {
|
|
3445
|
+
url.searchParams.set("domainId", request.domainId);
|
|
3446
|
+
}
|
|
3447
|
+
const response = await fetch(url);
|
|
3448
|
+
let responseData;
|
|
3449
|
+
try {
|
|
3450
|
+
responseData = await response.json();
|
|
3451
|
+
} catch {
|
|
3452
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
3453
|
+
}
|
|
3454
|
+
if (!response.ok) {
|
|
3455
|
+
let errorResponse;
|
|
3456
|
+
try {
|
|
3457
|
+
errorResponse = deserializeErrorResponse(responseData);
|
|
3458
|
+
} catch {
|
|
3459
|
+
console.log("Name Tokens API: handling a known server error.");
|
|
3595
3460
|
}
|
|
3596
3461
|
if (typeof errorResponse !== "undefined") {
|
|
3597
|
-
throw new Error(`Fetching ENSNode
|
|
3462
|
+
throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
return deserializedNameTokensResponse(responseData);
|
|
3466
|
+
}
|
|
3467
|
+
};
|
|
3468
|
+
|
|
3469
|
+
// src/ensv2/ids-lib.ts
|
|
3470
|
+
import { hexToBigInt as hexToBigInt2 } from "viem";
|
|
3471
|
+
var makeRegistryId = (accountId) => formatAccountId(accountId);
|
|
3472
|
+
var makeENSv1DomainId = (node) => node;
|
|
3473
|
+
var makeENSv2DomainId = (registry, canonicalId) => formatAssetId({
|
|
3474
|
+
assetNamespace: AssetNamespaces.ERC1155,
|
|
3475
|
+
contract: registry,
|
|
3476
|
+
tokenId: canonicalId
|
|
3477
|
+
});
|
|
3478
|
+
var maskLower32Bits = (num) => num ^ num & 0xffffffffn;
|
|
3479
|
+
var getCanonicalId = (input) => {
|
|
3480
|
+
if (typeof input === "bigint") return maskLower32Bits(input);
|
|
3481
|
+
return getCanonicalId(hexToBigInt2(input));
|
|
3482
|
+
};
|
|
3483
|
+
var makePermissionsId = (contract) => formatAccountId(contract);
|
|
3484
|
+
var makePermissionsResourceId = (contract, resource) => `${makePermissionsId(contract)}/${resource}`;
|
|
3485
|
+
var makePermissionsUserId = (contract, resource, user) => `${makePermissionsId(contract)}/${resource}/${user}`;
|
|
3486
|
+
var makeResolverId = (contract) => formatAccountId(contract);
|
|
3487
|
+
var makeResolverRecordsId = (resolver, node) => `${makeResolverId(resolver)}/${node}`;
|
|
3488
|
+
var makeLatestRegistrationId = (domainId) => `${domainId}/latest`;
|
|
3489
|
+
var makeRegistrationId = (domainId, index = 0) => `${domainId}/${index}`;
|
|
3490
|
+
var makeLatestRenewalId = (domainId, registrationIndex) => `${makeRegistrationId(domainId, registrationIndex)}/latest`;
|
|
3491
|
+
var makeRenewalId = (domainId, registrationIndex, index = 0) => `${makeRegistrationId(domainId, registrationIndex)}/${index}`;
|
|
3492
|
+
|
|
3493
|
+
// src/identity/identity.ts
|
|
3494
|
+
import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
|
|
3495
|
+
|
|
3496
|
+
// src/identity/types.ts
|
|
3497
|
+
var ResolutionStatusIds = {
|
|
3498
|
+
/**
|
|
3499
|
+
* Represents that the `Identity` is not resolved yet.
|
|
3500
|
+
*/
|
|
3501
|
+
Unresolved: "unresolved",
|
|
3502
|
+
/**
|
|
3503
|
+
* Represents that resolution of the `Identity` resulted in a named identity.
|
|
3504
|
+
*/
|
|
3505
|
+
Named: "named",
|
|
3506
|
+
/**
|
|
3507
|
+
* Represents that resolution of the `Identity` resulted in an unnamed identity.
|
|
3508
|
+
*/
|
|
3509
|
+
Unnamed: "unnamed",
|
|
3510
|
+
/**
|
|
3511
|
+
* Represents that attempted resolution of the `Identity` resulted in an error
|
|
3512
|
+
* and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
|
|
3513
|
+
*/
|
|
3514
|
+
Unknown: "unknown"
|
|
3515
|
+
};
|
|
3516
|
+
|
|
3517
|
+
// src/identity/identity.ts
|
|
3518
|
+
function buildUnresolvedIdentity(address, namespaceId, chainId) {
|
|
3519
|
+
return {
|
|
3520
|
+
resolutionStatus: ResolutionStatusIds.Unresolved,
|
|
3521
|
+
chainId: chainId ?? getENSRootChainId2(namespaceId),
|
|
3522
|
+
address
|
|
3523
|
+
};
|
|
3524
|
+
}
|
|
3525
|
+
function isResolvedIdentity(identity) {
|
|
3526
|
+
return identity.resolutionStatus !== ResolutionStatusIds.Unresolved;
|
|
3527
|
+
}
|
|
3528
|
+
|
|
3529
|
+
// src/resolution/ensip19-chainid.ts
|
|
3530
|
+
import { mainnet } from "viem/chains";
|
|
3531
|
+
import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
|
|
3532
|
+
var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
|
|
3533
|
+
const ensRootChainId = getENSRootChainId3(namespaceId);
|
|
3534
|
+
return chainId === ensRootChainId ? mainnet.id : chainId;
|
|
3535
|
+
};
|
|
3536
|
+
var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
|
|
3537
|
+
return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId3(namespaceId) : chainId;
|
|
3538
|
+
};
|
|
3539
|
+
|
|
3540
|
+
// src/resolution/resolver-records-selection.ts
|
|
3541
|
+
var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
|
|
3542
|
+
|
|
3543
|
+
// src/shared/cache/lru-cache.ts
|
|
3544
|
+
var LruCache = class {
|
|
3545
|
+
_cache = /* @__PURE__ */ new Map();
|
|
3546
|
+
_capacity;
|
|
3547
|
+
/**
|
|
3548
|
+
* Create a new LRU cache with the given capacity.
|
|
3549
|
+
*
|
|
3550
|
+
* @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
|
|
3551
|
+
* @throws Error if capacity is not a non-negative integer.
|
|
3552
|
+
*/
|
|
3553
|
+
constructor(capacity) {
|
|
3554
|
+
if (!Number.isInteger(capacity)) {
|
|
3555
|
+
throw new Error(
|
|
3556
|
+
`LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
|
|
3557
|
+
);
|
|
3558
|
+
}
|
|
3559
|
+
if (capacity < 0) {
|
|
3560
|
+
throw new Error(
|
|
3561
|
+
`LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
|
|
3562
|
+
);
|
|
3563
|
+
}
|
|
3564
|
+
this._capacity = capacity;
|
|
3565
|
+
}
|
|
3566
|
+
set(key, value) {
|
|
3567
|
+
this._cache.set(key, value);
|
|
3568
|
+
if (this._cache.size > this._capacity) {
|
|
3569
|
+
const oldestKey = this._cache.keys().next().value;
|
|
3570
|
+
this._cache.delete(oldestKey);
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
get(key) {
|
|
3574
|
+
const value = this._cache.get(key);
|
|
3575
|
+
if (value) {
|
|
3576
|
+
this._cache.delete(key);
|
|
3577
|
+
this._cache.set(key, value);
|
|
3578
|
+
}
|
|
3579
|
+
return value;
|
|
3580
|
+
}
|
|
3581
|
+
clear() {
|
|
3582
|
+
this._cache.clear();
|
|
3583
|
+
}
|
|
3584
|
+
get size() {
|
|
3585
|
+
return this._cache.size;
|
|
3586
|
+
}
|
|
3587
|
+
get capacity() {
|
|
3588
|
+
return this._capacity;
|
|
3589
|
+
}
|
|
3590
|
+
};
|
|
3591
|
+
|
|
3592
|
+
// src/shared/cache/swr-cache.ts
|
|
3593
|
+
import { secondsToMilliseconds } from "date-fns";
|
|
3594
|
+
import { getUnixTime } from "date-fns/getUnixTime";
|
|
3595
|
+
|
|
3596
|
+
// src/shared/datetime.ts
|
|
3597
|
+
function durationBetween(start, end) {
|
|
3598
|
+
return deserializeDuration(end - start, "Duration");
|
|
3599
|
+
}
|
|
3600
|
+
function addDuration(timestamp, duration) {
|
|
3601
|
+
return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3604
|
+
// src/shared/cache/swr-cache.ts
|
|
3605
|
+
var SWRCache = class {
|
|
3606
|
+
constructor(options) {
|
|
3607
|
+
this.options = options;
|
|
3608
|
+
if (options.proactiveRevalidationInterval) {
|
|
3609
|
+
this.backgroundInterval = setInterval(
|
|
3610
|
+
() => this.revalidate(),
|
|
3611
|
+
secondsToMilliseconds(options.proactiveRevalidationInterval)
|
|
3612
|
+
);
|
|
3613
|
+
}
|
|
3614
|
+
if (options.proactivelyInitialize) this.revalidate();
|
|
3615
|
+
}
|
|
3616
|
+
cache = null;
|
|
3617
|
+
inProgressRevalidate = null;
|
|
3618
|
+
backgroundInterval = null;
|
|
3619
|
+
async revalidate() {
|
|
3620
|
+
if (!this.inProgressRevalidate) {
|
|
3621
|
+
this.inProgressRevalidate = this.options.fn().then((result) => {
|
|
3622
|
+
this.cache = {
|
|
3623
|
+
result,
|
|
3624
|
+
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
3625
|
+
};
|
|
3626
|
+
}).catch((error) => {
|
|
3627
|
+
if (!this.cache) {
|
|
3628
|
+
this.cache = {
|
|
3629
|
+
// ensure thrown value is always an Error instance
|
|
3630
|
+
result: error instanceof Error ? error : new Error(String(error)),
|
|
3631
|
+
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
3632
|
+
};
|
|
3633
|
+
}
|
|
3634
|
+
}).finally(() => {
|
|
3635
|
+
this.inProgressRevalidate = null;
|
|
3636
|
+
});
|
|
3637
|
+
}
|
|
3638
|
+
return this.inProgressRevalidate;
|
|
3639
|
+
}
|
|
3640
|
+
/**
|
|
3641
|
+
* Read the most recently cached result from the `SWRCache`.
|
|
3642
|
+
*
|
|
3643
|
+
* @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
|
|
3644
|
+
* has never successfully returned.
|
|
3645
|
+
*/
|
|
3646
|
+
async read() {
|
|
3647
|
+
if (!this.cache) await this.revalidate();
|
|
3648
|
+
if (!this.cache) throw new Error("never");
|
|
3649
|
+
if (durationBetween(this.cache.updatedAt, getUnixTime(/* @__PURE__ */ new Date())) > this.options.ttl) {
|
|
3650
|
+
this.revalidate();
|
|
3651
|
+
}
|
|
3652
|
+
return this.cache.result;
|
|
3653
|
+
}
|
|
3654
|
+
/**
|
|
3655
|
+
* Destroys the background revalidation interval, if exists.
|
|
3656
|
+
*/
|
|
3657
|
+
destroy() {
|
|
3658
|
+
if (this.backgroundInterval) {
|
|
3659
|
+
clearInterval(this.backgroundInterval);
|
|
3660
|
+
this.backgroundInterval = null;
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
};
|
|
3664
|
+
|
|
3665
|
+
// src/shared/cache/ttl-cache.ts
|
|
3666
|
+
import { getUnixTime as getUnixTime2 } from "date-fns/getUnixTime";
|
|
3667
|
+
var TtlCache = class {
|
|
3668
|
+
_cache = /* @__PURE__ */ new Map();
|
|
3669
|
+
_ttl;
|
|
3670
|
+
/**
|
|
3671
|
+
* Create a new TTL cache with the given TTL.
|
|
3672
|
+
*
|
|
3673
|
+
* @param ttl Time-to-live duration in seconds. Items expire after this duration.
|
|
3674
|
+
*/
|
|
3675
|
+
constructor(ttl) {
|
|
3676
|
+
this._ttl = ttl;
|
|
3677
|
+
}
|
|
3678
|
+
_cleanup() {
|
|
3679
|
+
const now = getUnixTime2(/* @__PURE__ */ new Date());
|
|
3680
|
+
for (const [key, entry] of this._cache.entries()) {
|
|
3681
|
+
if (entry.expiresAt <= now) {
|
|
3682
|
+
this._cache.delete(key);
|
|
3598
3683
|
}
|
|
3599
3684
|
}
|
|
3600
|
-
return deserializeRegistrarActionsResponse(responseData);
|
|
3601
3685
|
}
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
* @example
|
|
3613
|
-
* ```ts
|
|
3614
|
-
* import {
|
|
3615
|
-
* ENSNodeClient,
|
|
3616
|
-
* } from "@ensnode/ensnode-sdk";
|
|
3617
|
-
* import { namehash } from "viem/ens";
|
|
3618
|
-
*
|
|
3619
|
-
* const client: ENSNodeClient;
|
|
3620
|
-
*
|
|
3621
|
-
* // get latest name token records from the indexed subregistry based on the requested name
|
|
3622
|
-
* const response = await client.nameTokens({
|
|
3623
|
-
* name: "vitalik.eth"
|
|
3624
|
-
* });
|
|
3625
|
-
*
|
|
3626
|
-
* const response = await client.nameTokens({
|
|
3627
|
-
* domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
|
|
3628
|
-
* })
|
|
3629
|
-
* ```
|
|
3630
|
-
*/
|
|
3631
|
-
async nameTokens(request) {
|
|
3632
|
-
const url = new URL(`/api/name-tokens`, this.options.url);
|
|
3633
|
-
if (request.name !== void 0) {
|
|
3634
|
-
url.searchParams.set("name", request.name);
|
|
3635
|
-
} else if (request.domainId !== void 0) {
|
|
3636
|
-
url.searchParams.set("domainId", request.domainId);
|
|
3686
|
+
set(key, value) {
|
|
3687
|
+
this._cleanup();
|
|
3688
|
+
const expiresAt = addDuration(getUnixTime2(/* @__PURE__ */ new Date()), this._ttl);
|
|
3689
|
+
this._cache.set(key, { value, expiresAt });
|
|
3690
|
+
}
|
|
3691
|
+
get(key) {
|
|
3692
|
+
this._cleanup();
|
|
3693
|
+
const entry = this._cache.get(key);
|
|
3694
|
+
if (!entry) {
|
|
3695
|
+
return void 0;
|
|
3637
3696
|
}
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
responseData = await response.json();
|
|
3642
|
-
} catch {
|
|
3643
|
-
throw new Error("Malformed response data: invalid JSON");
|
|
3697
|
+
if (entry.expiresAt <= getUnixTime2(/* @__PURE__ */ new Date())) {
|
|
3698
|
+
this._cache.delete(key);
|
|
3699
|
+
return void 0;
|
|
3644
3700
|
}
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3701
|
+
return entry.value;
|
|
3702
|
+
}
|
|
3703
|
+
clear() {
|
|
3704
|
+
this._cache.clear();
|
|
3705
|
+
}
|
|
3706
|
+
get size() {
|
|
3707
|
+
this._cleanup();
|
|
3708
|
+
return this._cache.size;
|
|
3709
|
+
}
|
|
3710
|
+
get capacity() {
|
|
3711
|
+
return Number.MAX_SAFE_INTEGER;
|
|
3712
|
+
}
|
|
3713
|
+
has(key) {
|
|
3714
|
+
this._cleanup();
|
|
3715
|
+
const entry = this._cache.get(key);
|
|
3716
|
+
if (!entry) {
|
|
3717
|
+
return false;
|
|
3655
3718
|
}
|
|
3656
|
-
|
|
3719
|
+
if (entry.expiresAt <= getUnixTime2(/* @__PURE__ */ new Date())) {
|
|
3720
|
+
this._cache.delete(key);
|
|
3721
|
+
return false;
|
|
3722
|
+
}
|
|
3723
|
+
return true;
|
|
3724
|
+
}
|
|
3725
|
+
delete(key) {
|
|
3726
|
+
return this._cache.delete(key);
|
|
3657
3727
|
}
|
|
3658
3728
|
};
|
|
3659
3729
|
|
|
3660
|
-
// src/
|
|
3661
|
-
import {
|
|
3662
|
-
var
|
|
3663
|
-
var makeENSv1DomainId = (node) => node;
|
|
3664
|
-
var makeENSv2DomainId = (registry, canonicalId) => formatAssetId({
|
|
3665
|
-
assetNamespace: AssetNamespaces.ERC1155,
|
|
3666
|
-
contract: registry,
|
|
3667
|
-
tokenId: canonicalId
|
|
3668
|
-
});
|
|
3669
|
-
var maskLower32Bits = (num) => num ^ num & 0xffffffffn;
|
|
3670
|
-
var getCanonicalId = (input) => {
|
|
3671
|
-
if (typeof input === "bigint") return maskLower32Bits(input);
|
|
3672
|
-
return getCanonicalId(hexToBigInt2(input));
|
|
3673
|
-
};
|
|
3674
|
-
var makePermissionsId = (contract) => formatAccountId(contract);
|
|
3675
|
-
var makePermissionsResourceId = (contract, resource) => `${makePermissionsId(contract)}/${resource}`;
|
|
3676
|
-
var makePermissionsUserId = (contract, resource, user) => `${makePermissionsId(contract)}/${resource}/${user}`;
|
|
3677
|
-
var makeResolverId = (contract) => formatAccountId(contract);
|
|
3678
|
-
var makeResolverRecordsId = (resolver, node) => `${makeResolverId(resolver)}/${node}`;
|
|
3679
|
-
var makeLatestRegistrationId = (domainId) => `${domainId}/latest`;
|
|
3680
|
-
var makeRegistrationId = (domainId, index = 0) => `${domainId}/${index}`;
|
|
3681
|
-
var makeLatestRenewalId = (domainId, registrationIndex) => `${makeRegistrationId(domainId, registrationIndex)}/latest`;
|
|
3682
|
-
var makeRenewalId = (domainId, registrationIndex, index = 0) => `${makeRegistrationId(domainId, registrationIndex)}/${index}`;
|
|
3730
|
+
// src/shared/interpretation/interpret-address.ts
|
|
3731
|
+
import { isAddressEqual as isAddressEqual4, zeroAddress as zeroAddress5 } from "viem";
|
|
3732
|
+
var interpretAddress = (owner) => isAddressEqual4(zeroAddress5, owner) ? null : owner;
|
|
3683
3733
|
|
|
3684
|
-
// src/
|
|
3685
|
-
import {
|
|
3734
|
+
// src/shared/interpretation/interpret-record-values.ts
|
|
3735
|
+
import { isAddress as isAddress3, isAddressEqual as isAddressEqual5, zeroAddress as zeroAddress6 } from "viem";
|
|
3686
3736
|
|
|
3687
|
-
// src/
|
|
3688
|
-
var
|
|
3689
|
-
|
|
3690
|
-
* Represents that the `Identity` is not resolved yet.
|
|
3691
|
-
*/
|
|
3692
|
-
Unresolved: "unresolved",
|
|
3693
|
-
/**
|
|
3694
|
-
* Represents that resolution of the `Identity` resulted in a named identity.
|
|
3695
|
-
*/
|
|
3696
|
-
Named: "named",
|
|
3697
|
-
/**
|
|
3698
|
-
* Represents that resolution of the `Identity` resulted in an unnamed identity.
|
|
3699
|
-
*/
|
|
3700
|
-
Unnamed: "unnamed",
|
|
3701
|
-
/**
|
|
3702
|
-
* Represents that attempted resolution of the `Identity` resulted in an error
|
|
3703
|
-
* and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
|
|
3704
|
-
*/
|
|
3705
|
-
Unknown: "unknown"
|
|
3706
|
-
};
|
|
3737
|
+
// src/shared/null-bytes.ts
|
|
3738
|
+
var hasNullByte = (value) => value.indexOf("\0") !== -1;
|
|
3739
|
+
var stripNullBytes = (value) => value.replaceAll("\0", "");
|
|
3707
3740
|
|
|
3708
|
-
// src/
|
|
3709
|
-
function
|
|
3710
|
-
return
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
address
|
|
3714
|
-
};
|
|
3741
|
+
// src/shared/interpretation/interpret-record-values.ts
|
|
3742
|
+
function interpretNameRecordValue(value) {
|
|
3743
|
+
if (value === "") return null;
|
|
3744
|
+
if (!isNormalizedName(value)) return null;
|
|
3745
|
+
return value;
|
|
3715
3746
|
}
|
|
3716
|
-
function
|
|
3717
|
-
|
|
3747
|
+
function interpretAddressRecordValue(value) {
|
|
3748
|
+
if (hasNullByte(value)) return null;
|
|
3749
|
+
if (value === "") return null;
|
|
3750
|
+
if (value === "0x") return null;
|
|
3751
|
+
if (!isAddress3(value)) return value;
|
|
3752
|
+
if (isAddressEqual5(value, zeroAddress6)) return null;
|
|
3753
|
+
return asLowerCaseAddress(value);
|
|
3754
|
+
}
|
|
3755
|
+
function interpretTextRecordKey(key) {
|
|
3756
|
+
if (hasNullByte(key)) return null;
|
|
3757
|
+
if (key === "") return null;
|
|
3758
|
+
return key;
|
|
3759
|
+
}
|
|
3760
|
+
function interpretTextRecordValue(value) {
|
|
3761
|
+
if (hasNullByte(value)) return null;
|
|
3762
|
+
if (value === "") return null;
|
|
3763
|
+
return value;
|
|
3718
3764
|
}
|
|
3719
3765
|
|
|
3720
|
-
// src/
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
|
|
3724
|
-
const ensRootChainId = getENSRootChainId3(namespaceId);
|
|
3725
|
-
return chainId === ensRootChainId ? mainnet.id : chainId;
|
|
3726
|
-
};
|
|
3727
|
-
var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
|
|
3728
|
-
return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId3(namespaceId) : chainId;
|
|
3729
|
-
};
|
|
3766
|
+
// src/shared/interpretation/interpret-tokenid.ts
|
|
3767
|
+
var interpretTokenIdAsLabelHash = (tokenId) => uint256ToHex32(tokenId);
|
|
3768
|
+
var interpretTokenIdAsNode = (tokenId) => uint256ToHex32(tokenId);
|
|
3730
3769
|
|
|
3731
|
-
// src/
|
|
3732
|
-
|
|
3770
|
+
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
3771
|
+
import { isHex as isHex3 } from "viem";
|
|
3772
|
+
import { labelhash } from "viem/ens";
|
|
3773
|
+
|
|
3774
|
+
// src/shared/labelhash.ts
|
|
3775
|
+
import { keccak256 as keccak2562, stringToBytes } from "viem";
|
|
3776
|
+
var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
|
|
3777
|
+
|
|
3778
|
+
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
3779
|
+
function literalLabelToInterpretedLabel(label) {
|
|
3780
|
+
if (isNormalizedLabel(label)) return label;
|
|
3781
|
+
return encodeLabelHash(labelhashLiteralLabel(label));
|
|
3782
|
+
}
|
|
3783
|
+
function literalLabelsToInterpretedName(labels) {
|
|
3784
|
+
return labels.map(literalLabelToInterpretedLabel).join(".");
|
|
3785
|
+
}
|
|
3786
|
+
function interpretedLabelsToInterpretedName(labels) {
|
|
3787
|
+
return labels.join(".");
|
|
3788
|
+
}
|
|
3789
|
+
function literalLabelsToLiteralName(labels) {
|
|
3790
|
+
return labels.join(".");
|
|
3791
|
+
}
|
|
3792
|
+
function interpretedNameToInterpretedLabels(name) {
|
|
3793
|
+
return name.split(".");
|
|
3794
|
+
}
|
|
3795
|
+
function encodedLabelToLabelhash(label) {
|
|
3796
|
+
if (label.length !== 66) return null;
|
|
3797
|
+
if (label.indexOf("[") !== 0) return null;
|
|
3798
|
+
if (label.indexOf("]") !== 65) return null;
|
|
3799
|
+
const hash = `0x${label.slice(1, 65)}`;
|
|
3800
|
+
if (!isHex3(hash)) return null;
|
|
3801
|
+
return hash;
|
|
3802
|
+
}
|
|
3803
|
+
function isInterpetedLabel(label) {
|
|
3804
|
+
if (label.startsWith("[")) {
|
|
3805
|
+
const labelHash = encodedLabelToLabelhash(label);
|
|
3806
|
+
if (labelHash === null) return false;
|
|
3807
|
+
}
|
|
3808
|
+
return isNormalizedLabel(label);
|
|
3809
|
+
}
|
|
3810
|
+
function isInterpretedName(name) {
|
|
3811
|
+
return name.split(".").every(isInterpetedLabel);
|
|
3812
|
+
}
|
|
3813
|
+
function interpretedNameToLabelHashPath(name) {
|
|
3814
|
+
return interpretedNameToInterpretedLabels(name).map((label) => {
|
|
3815
|
+
if (!isInterpetedLabel(label)) {
|
|
3816
|
+
throw new Error(
|
|
3817
|
+
`Invariant(interpretedNameToLabelHashPath): Expected InterpretedLabel, received '${label}'.`
|
|
3818
|
+
);
|
|
3819
|
+
}
|
|
3820
|
+
const maybeLabelHash = encodedLabelToLabelhash(label);
|
|
3821
|
+
if (maybeLabelHash !== null) return maybeLabelHash;
|
|
3822
|
+
return labelhash(label);
|
|
3823
|
+
}).toReversed();
|
|
3824
|
+
}
|
|
3825
|
+
|
|
3826
|
+
// src/shared/root-registry.ts
|
|
3827
|
+
import { DatasourceNames as DatasourceNames5 } from "@ensnode/datasources";
|
|
3828
|
+
var getENSv1Registry = (namespace) => getDatasourceContract(namespace, DatasourceNames5.ENSRoot, "ENSv1Registry");
|
|
3829
|
+
var isENSv1Registry = (namespace, contract) => accountIdEqual(getENSv1Registry(namespace), contract);
|
|
3830
|
+
var getENSv2RootRegistry = (namespace) => getDatasourceContract(namespace, DatasourceNames5.ENSv2Root, "RootRegistry");
|
|
3831
|
+
var getENSv2RootRegistryId = (namespace) => makeRegistryId(getENSv2RootRegistry(namespace));
|
|
3832
|
+
var isENSv2RootRegistry = (namespace, contract) => accountIdEqual(getENSv2RootRegistry(namespace), contract);
|
|
3833
|
+
|
|
3834
|
+
// src/shared/url.ts
|
|
3835
|
+
function isHttpProtocol(url) {
|
|
3836
|
+
return ["http:", "https:"].includes(url.protocol);
|
|
3837
|
+
}
|
|
3838
|
+
function isWebSocketProtocol(url) {
|
|
3839
|
+
return ["ws:", "wss:"].includes(url.protocol);
|
|
3840
|
+
}
|
|
3733
3841
|
|
|
3734
3842
|
// src/tracing/ens-protocol-tracing.ts
|
|
3735
3843
|
var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|
|
@@ -3854,6 +3962,9 @@ export {
|
|
|
3854
3962
|
deserializeErrorResponse,
|
|
3855
3963
|
deserializeIndexingStatusResponse,
|
|
3856
3964
|
deserializeOmnichainIndexingStatusSnapshot,
|
|
3965
|
+
deserializePriceDai,
|
|
3966
|
+
deserializePriceEth,
|
|
3967
|
+
deserializePriceUsdc,
|
|
3857
3968
|
deserializeRealtimeIndexingStatusProjection,
|
|
3858
3969
|
deserializeRegistrarActionsResponse,
|
|
3859
3970
|
deserializeUnixTimestamp,
|
|
@@ -3947,14 +4058,19 @@ export {
|
|
|
3947
4058
|
nameTokensPrerequisites,
|
|
3948
4059
|
parseAccountId,
|
|
3949
4060
|
parseAssetId,
|
|
4061
|
+
parseDai,
|
|
4062
|
+
parseEth,
|
|
3950
4063
|
parseNonNegativeInteger,
|
|
3951
4064
|
parseReverseName,
|
|
4065
|
+
parseUsdc,
|
|
3952
4066
|
priceDai,
|
|
3953
4067
|
priceEth,
|
|
3954
4068
|
priceUsdc,
|
|
3955
4069
|
registrarActionsFilter,
|
|
3956
4070
|
registrarActionsPrerequisites,
|
|
3957
4071
|
reverseName,
|
|
4072
|
+
scaleBigintByNumber,
|
|
4073
|
+
scalePrice,
|
|
3958
4074
|
serializeAssetId,
|
|
3959
4075
|
serializeChainId,
|
|
3960
4076
|
serializeChainIndexingSnapshots,
|
|
@@ -3971,7 +4087,9 @@ export {
|
|
|
3971
4087
|
serializeNamedRegistrarAction,
|
|
3972
4088
|
serializeOmnichainIndexingStatusSnapshot,
|
|
3973
4089
|
serializePrice,
|
|
4090
|
+
serializePriceDai,
|
|
3974
4091
|
serializePriceEth,
|
|
4092
|
+
serializePriceUsdc,
|
|
3975
4093
|
serializeRealtimeIndexingStatusProjection,
|
|
3976
4094
|
serializeRegisteredNameTokens,
|
|
3977
4095
|
serializeRegistrarAction,
|