@ensnode/ensnode-sdk 0.32.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.d.ts +387 -45
- package/dist/index.js +370 -66
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// src/ens/constants.ts
|
|
2
2
|
import { namehash } from "viem";
|
|
3
3
|
var ROOT_NODE = namehash("");
|
|
4
|
+
var ETH_NODE = namehash("eth");
|
|
5
|
+
var BASENAMES_NODE = namehash("base.eth");
|
|
6
|
+
var LINEANAMES_NODE = namehash("linea.eth");
|
|
4
7
|
var REVERSE_ROOT_NODES = /* @__PURE__ */ new Set([namehash("addr.reverse")]);
|
|
5
8
|
|
|
6
9
|
// src/ens/subname-helpers.ts
|
|
@@ -329,6 +332,12 @@ function isNormalized(name) {
|
|
|
329
332
|
}
|
|
330
333
|
}
|
|
331
334
|
|
|
335
|
+
// src/shared/account-id.ts
|
|
336
|
+
import { isAddressEqual } from "viem";
|
|
337
|
+
var accountIdEqual = (a, b) => {
|
|
338
|
+
return a.chainId === b.chainId && isAddressEqual(a.address, b.address);
|
|
339
|
+
};
|
|
340
|
+
|
|
332
341
|
// src/ensindexer/config/types.ts
|
|
333
342
|
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
334
343
|
PluginName2["Subgraph"] = "subgraph";
|
|
@@ -337,6 +346,7 @@ var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
|
337
346
|
PluginName2["ThreeDNS"] = "threedns";
|
|
338
347
|
PluginName2["ReverseResolvers"] = "reverse-resolvers";
|
|
339
348
|
PluginName2["Referrals"] = "referrals";
|
|
349
|
+
PluginName2["TokenScope"] = "tokenscope";
|
|
340
350
|
return PluginName2;
|
|
341
351
|
})(PluginName || {});
|
|
342
352
|
|
|
@@ -344,7 +354,8 @@ var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
|
344
354
|
function isSubgraphCompatible(config) {
|
|
345
355
|
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
346
356
|
const indexingBehaviorIsSubgraphCompatible = !config.healReverseAddresses && !config.indexAdditionalResolverRecords;
|
|
347
|
-
|
|
357
|
+
const labelSetIsSubgraphCompatible = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
358
|
+
return onlySubgraphPluginActivated && indexingBehaviorIsSubgraphCompatible && labelSetIsSubgraphCompatible;
|
|
348
359
|
}
|
|
349
360
|
|
|
350
361
|
// src/ensindexer/config/zod-schemas.ts
|
|
@@ -367,6 +378,29 @@ var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(
|
|
|
367
378
|
var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
|
|
368
379
|
error: `${valueLabel} is required and must be a non-empty string.`
|
|
369
380
|
});
|
|
381
|
+
var makeLabelSetIdSchema = (valueLabel) => {
|
|
382
|
+
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-]+$/, {
|
|
383
|
+
error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
|
|
384
|
+
});
|
|
385
|
+
};
|
|
386
|
+
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
387
|
+
return z2.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
388
|
+
};
|
|
389
|
+
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
390
|
+
let valueLabelLabelSetId = valueLabel;
|
|
391
|
+
let valueLabelLabelSetVersion = valueLabel;
|
|
392
|
+
if (valueLabel == "LABEL_SET") {
|
|
393
|
+
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
394
|
+
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
395
|
+
} else {
|
|
396
|
+
valueLabelLabelSetId = valueLabel + ".labelSetId";
|
|
397
|
+
valueLabelLabelSetVersion = valueLabel + ".labelSetVersion";
|
|
398
|
+
}
|
|
399
|
+
return z2.object({
|
|
400
|
+
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
401
|
+
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
402
|
+
});
|
|
403
|
+
};
|
|
370
404
|
var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
371
405
|
var makeDependencyInfoSchema = (valueLabel = "Value") => z2.strictObject(
|
|
372
406
|
{
|
|
@@ -390,21 +424,10 @@ function invariant_reverseResolversPluginNeedsResolverRecords(ctx) {
|
|
|
390
424
|
});
|
|
391
425
|
}
|
|
392
426
|
}
|
|
393
|
-
function invariant_experimentalResolutionNeedsReverseResolversPlugin(ctx) {
|
|
394
|
-
const { value: config } = ctx;
|
|
395
|
-
const reverseResolversPluginActive = config.plugins.includes("reverse-resolvers" /* ReverseResolvers */);
|
|
396
|
-
if (config.experimentalResolution && !reverseResolversPluginActive) {
|
|
397
|
-
ctx.issues.push({
|
|
398
|
-
code: "custom",
|
|
399
|
-
input: config,
|
|
400
|
-
message: `'reverseResolversPluginActive' requires the ${"reverse-resolvers" /* ReverseResolvers */} plugin to be active.`
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
427
|
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
405
428
|
const { value: config } = ctx;
|
|
406
429
|
if (config.isSubgraphCompatible !== isSubgraphCompatible(config)) {
|
|
407
|
-
const message = config.isSubgraphCompatible ? `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active
|
|
430
|
+
const message = config.isSubgraphCompatible ? `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active, both 'indexAdditionalResolverRecords' and 'healReverseAddresses' must be set to 'false', and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}` : `Both 'indexAdditionalResolverRecords' and 'healReverseAddresses' were set to 'false', the only active plugin was the '${"subgraph" /* Subgraph */}' plugin, and labelSet was {labelSetId: "subgraph", labelSetVersion: 0}. The 'isSubgraphCompatible' must be set to 'true'`;
|
|
408
431
|
ctx.issues.push({
|
|
409
432
|
code: "custom",
|
|
410
433
|
input: config,
|
|
@@ -415,7 +438,7 @@ function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
|
415
438
|
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
|
|
416
439
|
ensAdminUrl: makeUrlSchema(`${valueLabel}.ensAdminUrl`),
|
|
417
440
|
ensNodePublicUrl: makeUrlSchema(`${valueLabel}.ensNodePublicUrl`),
|
|
418
|
-
|
|
441
|
+
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
419
442
|
healReverseAddresses: z2.boolean({ error: `${valueLabel}.healReverseAddresses` }),
|
|
420
443
|
indexAdditionalResolverRecords: z2.boolean({
|
|
421
444
|
error: `${valueLabel}.indexAdditionalResolverRecords`
|
|
@@ -426,7 +449,7 @@ var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") =
|
|
|
426
449
|
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
427
450
|
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
428
451
|
dependencyInfo: makeDependencyInfoSchema(`${valueLabel}.dependencyInfo`)
|
|
429
|
-
}).check(invariant_reverseResolversPluginNeedsResolverRecords).check(
|
|
452
|
+
}).check(invariant_reverseResolversPluginNeedsResolverRecords).check(invariant_isSubgraphCompatibleRequirements);
|
|
430
453
|
|
|
431
454
|
// src/ensindexer/config/deserialize.ts
|
|
432
455
|
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
@@ -448,9 +471,9 @@ function serializeENSIndexerPublicConfig(config) {
|
|
|
448
471
|
const {
|
|
449
472
|
ensAdminUrl,
|
|
450
473
|
ensNodePublicUrl,
|
|
474
|
+
labelSet,
|
|
451
475
|
indexedChainIds,
|
|
452
476
|
databaseSchemaName,
|
|
453
|
-
experimentalResolution,
|
|
454
477
|
healReverseAddresses,
|
|
455
478
|
indexAdditionalResolverRecords,
|
|
456
479
|
isSubgraphCompatible: isSubgraphCompatible2,
|
|
@@ -461,9 +484,9 @@ function serializeENSIndexerPublicConfig(config) {
|
|
|
461
484
|
return {
|
|
462
485
|
ensAdminUrl: serializeUrl(ensAdminUrl),
|
|
463
486
|
ensNodePublicUrl: serializeUrl(ensNodePublicUrl),
|
|
487
|
+
labelSet,
|
|
464
488
|
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
465
489
|
databaseSchemaName,
|
|
466
|
-
experimentalResolution,
|
|
467
490
|
healReverseAddresses,
|
|
468
491
|
indexAdditionalResolverRecords,
|
|
469
492
|
isSubgraphCompatible: isSubgraphCompatible2,
|
|
@@ -473,6 +496,86 @@ function serializeENSIndexerPublicConfig(config) {
|
|
|
473
496
|
};
|
|
474
497
|
}
|
|
475
498
|
|
|
499
|
+
// src/ensindexer/config/labelset-utils.ts
|
|
500
|
+
function buildLabelSetId(maybeLabelSetId) {
|
|
501
|
+
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
502
|
+
}
|
|
503
|
+
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
504
|
+
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
505
|
+
}
|
|
506
|
+
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
507
|
+
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
508
|
+
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
509
|
+
}
|
|
510
|
+
return { labelSetId, labelSetVersion };
|
|
511
|
+
}
|
|
512
|
+
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
513
|
+
if (clientSet.labelSetId === void 0) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
517
|
+
throw new Error(
|
|
518
|
+
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
522
|
+
throw new Error(
|
|
523
|
+
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// src/ensindexer/config/label-utils.ts
|
|
529
|
+
import { hexToBytes } from "viem";
|
|
530
|
+
function labelHashToBytes(labelHash) {
|
|
531
|
+
try {
|
|
532
|
+
if (labelHash.length !== 66) {
|
|
533
|
+
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
534
|
+
}
|
|
535
|
+
if (labelHash !== labelHash.toLowerCase()) {
|
|
536
|
+
throw new Error("Labelhash must be in lowercase");
|
|
537
|
+
}
|
|
538
|
+
if (!labelHash.startsWith("0x")) {
|
|
539
|
+
throw new Error("Labelhash must be 0x-prefixed");
|
|
540
|
+
}
|
|
541
|
+
const bytes = hexToBytes(labelHash);
|
|
542
|
+
if (bytes.length !== 32) {
|
|
543
|
+
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
544
|
+
}
|
|
545
|
+
return bytes;
|
|
546
|
+
} catch (e) {
|
|
547
|
+
if (e instanceof Error) {
|
|
548
|
+
throw e;
|
|
549
|
+
}
|
|
550
|
+
throw new Error("Invalid hex format");
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// src/ensindexer/config/parsing.ts
|
|
555
|
+
function parseNonNegativeInteger(maybeNumber) {
|
|
556
|
+
const trimmed = maybeNumber.trim();
|
|
557
|
+
if (!trimmed) {
|
|
558
|
+
throw new Error("Input cannot be empty");
|
|
559
|
+
}
|
|
560
|
+
if (trimmed === "-0") {
|
|
561
|
+
throw new Error("Negative zero is not a valid non-negative integer");
|
|
562
|
+
}
|
|
563
|
+
const num = Number(maybeNumber);
|
|
564
|
+
if (Number.isNaN(num)) {
|
|
565
|
+
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
566
|
+
}
|
|
567
|
+
if (!Number.isFinite(num)) {
|
|
568
|
+
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
569
|
+
}
|
|
570
|
+
if (!Number.isInteger(num)) {
|
|
571
|
+
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
572
|
+
}
|
|
573
|
+
if (num < 0) {
|
|
574
|
+
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
575
|
+
}
|
|
576
|
+
return num;
|
|
577
|
+
}
|
|
578
|
+
|
|
476
579
|
// src/ensindexer/indexing-status/deserialize.ts
|
|
477
580
|
import { prettifyError as prettifyError3 } from "zod/v4";
|
|
478
581
|
|
|
@@ -534,6 +637,34 @@ function getOverallApproxRealtimeDistance(chains) {
|
|
|
534
637
|
const approxRealtimeDistance = Math.max(...chainApproxRealtimeDistances);
|
|
535
638
|
return approxRealtimeDistance;
|
|
536
639
|
}
|
|
640
|
+
function getTimestampForLowestOmnichainStartBlock(chains) {
|
|
641
|
+
const earliestKnownBlockTimestamps = chains.map(
|
|
642
|
+
(chain) => chain.config.startBlock.timestamp
|
|
643
|
+
);
|
|
644
|
+
return Math.min(...earliestKnownBlockTimestamps);
|
|
645
|
+
}
|
|
646
|
+
function getTimestampForHighestOmnichainKnownBlock(chains) {
|
|
647
|
+
const latestKnownBlockTimestamps = [];
|
|
648
|
+
for (const chain of chains) {
|
|
649
|
+
switch (chain.status) {
|
|
650
|
+
case ChainIndexingStatusIds.Unstarted:
|
|
651
|
+
if (chain.config.endBlock) {
|
|
652
|
+
latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
|
|
653
|
+
}
|
|
654
|
+
break;
|
|
655
|
+
case ChainIndexingStatusIds.Backfill:
|
|
656
|
+
latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
|
|
657
|
+
break;
|
|
658
|
+
case ChainIndexingStatusIds.Completed:
|
|
659
|
+
latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
|
|
660
|
+
break;
|
|
661
|
+
case ChainIndexingStatusIds.Following:
|
|
662
|
+
latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
return Math.max(...latestKnownBlockTimestamps);
|
|
667
|
+
}
|
|
537
668
|
function getOmnichainIndexingCursor(chains) {
|
|
538
669
|
return Math.min(...chains.map((chain) => chain.latestIndexedBlock.timestamp));
|
|
539
670
|
}
|
|
@@ -585,6 +716,12 @@ function checkChainIndexingStatusesForFollowingOverallStatus(chains) {
|
|
|
585
716
|
);
|
|
586
717
|
return allChainsHaveValidStatuses;
|
|
587
718
|
}
|
|
719
|
+
function sortAscChainStatusesByStartBlock(chains) {
|
|
720
|
+
chains.sort(
|
|
721
|
+
([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
|
|
722
|
+
);
|
|
723
|
+
return chains;
|
|
724
|
+
}
|
|
588
725
|
|
|
589
726
|
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
590
727
|
var makeChainIndexingConfigSchema = (valueLabel = "Value") => z3.discriminatedUnion("strategy", [
|
|
@@ -612,6 +749,7 @@ var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictO
|
|
|
612
749
|
status: z3.literal(ChainIndexingStatusIds.Backfill),
|
|
613
750
|
config: makeChainIndexingConfigSchema(valueLabel),
|
|
614
751
|
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
752
|
+
latestSyncedBlock: makeBlockRefSchema(valueLabel),
|
|
615
753
|
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
616
754
|
}).refine(
|
|
617
755
|
({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
|
|
@@ -619,9 +757,14 @@ var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictO
|
|
|
619
757
|
error: `config.startBlock must be before or same as latestIndexedBlock.`
|
|
620
758
|
}
|
|
621
759
|
).refine(
|
|
622
|
-
({ latestIndexedBlock,
|
|
760
|
+
({ latestIndexedBlock, latestSyncedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestSyncedBlock),
|
|
623
761
|
{
|
|
624
|
-
error: `latestIndexedBlock must be before or same as
|
|
762
|
+
error: `latestIndexedBlock must be before or same as latestSyncedBlock.`
|
|
763
|
+
}
|
|
764
|
+
).refine(
|
|
765
|
+
({ latestSyncedBlock, backfillEndBlock }) => isBeforeOrEqualTo(latestSyncedBlock, backfillEndBlock),
|
|
766
|
+
{
|
|
767
|
+
error: `latestSyncedBlock must be before or same as backfillEndBlock.`
|
|
625
768
|
}
|
|
626
769
|
).refine(
|
|
627
770
|
({ config, backfillEndBlock }) => config.endBlock === null || isEqualTo(backfillEndBlock, config.endBlock),
|
|
@@ -663,9 +806,9 @@ var makeChainIndexingCompletedStatusSchema = (valueLabel = "Value") => z3.strict
|
|
|
663
806
|
error: `config.startBlock must be before or same as latestIndexedBlock.`
|
|
664
807
|
}
|
|
665
808
|
).refine(
|
|
666
|
-
({ config, latestIndexedBlock }) =>
|
|
809
|
+
({ config, latestIndexedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, config.endBlock),
|
|
667
810
|
{
|
|
668
|
-
error: `latestIndexedBlock must be
|
|
811
|
+
error: `latestIndexedBlock must be before or same as config.endBlock.`
|
|
669
812
|
}
|
|
670
813
|
);
|
|
671
814
|
var makeChainIndexingStatusSchema = (valueLabel = "Value") => z3.discriminatedUnion("status", [
|
|
@@ -853,7 +996,7 @@ var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
|
|
|
853
996
|
return TraceableENSProtocol2;
|
|
854
997
|
})(TraceableENSProtocol || {});
|
|
855
998
|
var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
|
|
856
|
-
ForwardResolutionProtocolStep2["Operation"] = "
|
|
999
|
+
ForwardResolutionProtocolStep2["Operation"] = "forward-resolution";
|
|
857
1000
|
ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
|
|
858
1001
|
ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
|
|
859
1002
|
ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
|
|
@@ -864,7 +1007,7 @@ var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolS
|
|
|
864
1007
|
return ForwardResolutionProtocolStep2;
|
|
865
1008
|
})(ForwardResolutionProtocolStep || {});
|
|
866
1009
|
var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
|
|
867
|
-
ReverseResolutionProtocolStep2["Operation"] = "
|
|
1010
|
+
ReverseResolutionProtocolStep2["Operation"] = "reverse-resolution";
|
|
868
1011
|
ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
|
|
869
1012
|
ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
|
|
870
1013
|
ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
|
|
@@ -875,26 +1018,47 @@ var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|
|
|
875
1018
|
var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
|
|
876
1019
|
var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
|
|
877
1020
|
var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
duration: hrTimeToMicroseconds(span.duration),
|
|
888
|
-
// only export `ens.*` attributes to avoid leaking internal details
|
|
889
|
-
attributes: Object.fromEntries(
|
|
890
|
-
Object.entries(span.attributes).filter(
|
|
891
|
-
([key]) => key.startsWith(`${PROTOCOL_ATTRIBUTE_PREFIX}.`)
|
|
892
|
-
)
|
|
893
|
-
),
|
|
894
|
-
status: span.status,
|
|
895
|
-
events: span.events
|
|
1021
|
+
|
|
1022
|
+
// src/api/helpers.ts
|
|
1023
|
+
import { prettifyError as prettifyError4 } from "zod/v4";
|
|
1024
|
+
|
|
1025
|
+
// src/api/zod-schemas.ts
|
|
1026
|
+
import z4 from "zod/v4";
|
|
1027
|
+
var ErrorResponseSchema = z4.object({
|
|
1028
|
+
message: z4.string(),
|
|
1029
|
+
details: z4.optional(z4.unknown())
|
|
896
1030
|
});
|
|
897
1031
|
|
|
1032
|
+
// src/api/helpers.ts
|
|
1033
|
+
function deserializeErrorResponse(maybeErrorResponse) {
|
|
1034
|
+
const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
|
|
1035
|
+
if (parsed.error) {
|
|
1036
|
+
throw new Error(`Cannot deserialize ErrorResponse:
|
|
1037
|
+
${prettifyError4(parsed.error)}
|
|
1038
|
+
`);
|
|
1039
|
+
}
|
|
1040
|
+
return parsed.data;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// src/api/types.ts
|
|
1044
|
+
var IndexingStatusResponseCodes = {
|
|
1045
|
+
IndexerError: 512,
|
|
1046
|
+
RequestedDistanceNotAchievedError: 513
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
// src/client-error.ts
|
|
1050
|
+
var ClientError = class _ClientError extends Error {
|
|
1051
|
+
details;
|
|
1052
|
+
constructor(message, details) {
|
|
1053
|
+
super(message);
|
|
1054
|
+
this.name = "ClientError";
|
|
1055
|
+
this.details = details;
|
|
1056
|
+
}
|
|
1057
|
+
static fromErrorResponse({ message, details }) {
|
|
1058
|
+
return new _ClientError(message, details);
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
|
|
898
1062
|
// src/client.ts
|
|
899
1063
|
var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
|
|
900
1064
|
var ENSNodeClient = class _ENSNodeClient {
|
|
@@ -921,7 +1085,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
921
1085
|
* @param name The ENS Name whose records to resolve
|
|
922
1086
|
* @param selection selection of Resolver records
|
|
923
1087
|
* @param options additional options
|
|
924
|
-
* @param options.accelerate whether to attempt Protocol Acceleration (default
|
|
1088
|
+
* @param options.accelerate whether to attempt Protocol Acceleration (default false)
|
|
925
1089
|
* @param options.trace whether to include a trace in the response (default false)
|
|
926
1090
|
* @returns ResolveRecordsResponse<SELECTION>
|
|
927
1091
|
* @throws If the request fails or the ENSNode API returns an error response
|
|
@@ -957,11 +1121,11 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
957
1121
|
url.searchParams.set("texts", selection.texts.join(","));
|
|
958
1122
|
}
|
|
959
1123
|
if (options?.trace) url.searchParams.set("trace", "true");
|
|
960
|
-
if (options?.accelerate
|
|
1124
|
+
if (options?.accelerate) url.searchParams.set("accelerate", "true");
|
|
961
1125
|
const response = await fetch(url);
|
|
962
1126
|
if (!response.ok) {
|
|
963
1127
|
const error = await response.json();
|
|
964
|
-
throw
|
|
1128
|
+
throw ClientError.fromErrorResponse(error);
|
|
965
1129
|
}
|
|
966
1130
|
const data = await response.json();
|
|
967
1131
|
return data;
|
|
@@ -976,7 +1140,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
976
1140
|
* @param address The Address whose Primary Name to resolve
|
|
977
1141
|
* @param chainId The chain id within which to query the address' ENSIP-19 Multichain Primary Name
|
|
978
1142
|
* @param options additional options
|
|
979
|
-
* @param options.accelerate whether to attempt Protocol Acceleration (default
|
|
1143
|
+
* @param options.accelerate whether to attempt Protocol Acceleration (default false)
|
|
980
1144
|
* @param options.trace whether to include a trace in the response (default false)
|
|
981
1145
|
* @returns ResolvePrimaryNameResponse
|
|
982
1146
|
* @throws If the request fails or the ENSNode API returns an error response
|
|
@@ -999,11 +1163,11 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
999
1163
|
async resolvePrimaryName(address, chainId, options) {
|
|
1000
1164
|
const url = new URL(`/api/resolve/primary-name/${address}/${chainId}`, this.options.url);
|
|
1001
1165
|
if (options?.trace) url.searchParams.set("trace", "true");
|
|
1002
|
-
if (options?.accelerate
|
|
1166
|
+
if (options?.accelerate) url.searchParams.set("accelerate", "true");
|
|
1003
1167
|
const response = await fetch(url);
|
|
1004
1168
|
if (!response.ok) {
|
|
1005
1169
|
const error = await response.json();
|
|
1006
|
-
throw
|
|
1170
|
+
throw ClientError.fromErrorResponse(error);
|
|
1007
1171
|
}
|
|
1008
1172
|
const data = await response.json();
|
|
1009
1173
|
return data;
|
|
@@ -1054,55 +1218,180 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
1054
1218
|
const url = new URL(`/api/resolve/primary-names/${address}`, this.options.url);
|
|
1055
1219
|
if (options?.chainIds) url.searchParams.set("chainIds", options.chainIds.join(","));
|
|
1056
1220
|
if (options?.trace) url.searchParams.set("trace", "true");
|
|
1057
|
-
if (options?.accelerate
|
|
1221
|
+
if (options?.accelerate) url.searchParams.set("accelerate", "true");
|
|
1058
1222
|
const response = await fetch(url);
|
|
1059
1223
|
if (!response.ok) {
|
|
1060
1224
|
const error = await response.json();
|
|
1061
|
-
throw
|
|
1225
|
+
throw ClientError.fromErrorResponse(error);
|
|
1062
1226
|
}
|
|
1063
1227
|
const data = await response.json();
|
|
1064
1228
|
return data;
|
|
1065
1229
|
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Fetch ENSNode Config
|
|
1232
|
+
*
|
|
1233
|
+
* Fetch the ENSNode's configuration.
|
|
1234
|
+
*
|
|
1235
|
+
* @returns {ConfigResponse}
|
|
1236
|
+
*
|
|
1237
|
+
* @throws if the ENSNode request fails
|
|
1238
|
+
* @throws if the ENSNode API returns an error response
|
|
1239
|
+
* @throws if the ENSNode response breaks required invariants
|
|
1240
|
+
*/
|
|
1241
|
+
async config() {
|
|
1242
|
+
const url = new URL(`/api/config`, this.options.url);
|
|
1243
|
+
const response = await fetch(url);
|
|
1244
|
+
let responseData;
|
|
1245
|
+
try {
|
|
1246
|
+
responseData = await response.json();
|
|
1247
|
+
} catch {
|
|
1248
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
1249
|
+
}
|
|
1250
|
+
if (!response.ok) {
|
|
1251
|
+
const errorResponse = deserializeErrorResponse(responseData);
|
|
1252
|
+
throw new Error(`Fetching ENSNode Config Failed: ${errorResponse.message}`);
|
|
1253
|
+
}
|
|
1254
|
+
return deserializeENSIndexerPublicConfig(responseData);
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Fetch ENSNode Indexing Status
|
|
1258
|
+
*
|
|
1259
|
+
* Fetch the ENSNode's multichain indexing status.
|
|
1260
|
+
*
|
|
1261
|
+
* @param options additional options
|
|
1262
|
+
* @param options.maxRealtimeDistance the max allowed distance between the
|
|
1263
|
+
* latest indexed block of each chain and the "tip" of all indexed chains.
|
|
1264
|
+
* Setting this parameter influences the HTTP response code as follows:
|
|
1265
|
+
* - Success (200 OK): The latest indexed block of each chain is within the
|
|
1266
|
+
* requested distance from realtime.
|
|
1267
|
+
* - Service Unavailable (503): The latest indexed block of each chain is NOT
|
|
1268
|
+
* within the requested distance from realtime.
|
|
1269
|
+
*
|
|
1270
|
+
* @returns {IndexingStatusResponse}
|
|
1271
|
+
*
|
|
1272
|
+
* @throws if the ENSNode request fails
|
|
1273
|
+
* @throws if the ENSNode API returns an error response
|
|
1274
|
+
* @throws if the ENSNode response breaks required invariants
|
|
1275
|
+
*/
|
|
1276
|
+
async indexingStatus(options) {
|
|
1277
|
+
const url = new URL(`/api/indexing-status`, this.options.url);
|
|
1278
|
+
if (typeof options?.maxRealtimeDistance !== "undefined") {
|
|
1279
|
+
url.searchParams.set("maxRealtimeDistance", `${options.maxRealtimeDistance}`);
|
|
1280
|
+
}
|
|
1281
|
+
const response = await fetch(url);
|
|
1282
|
+
let responseData;
|
|
1283
|
+
try {
|
|
1284
|
+
responseData = await response.json();
|
|
1285
|
+
} catch {
|
|
1286
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
1287
|
+
}
|
|
1288
|
+
if (!response.ok) {
|
|
1289
|
+
switch (response.status) {
|
|
1290
|
+
case IndexingStatusResponseCodes.IndexerError: {
|
|
1291
|
+
console.error("Indexing Status API: indexer error");
|
|
1292
|
+
return deserializeENSIndexerIndexingStatus(
|
|
1293
|
+
responseData
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
case IndexingStatusResponseCodes.RequestedDistanceNotAchievedError: {
|
|
1297
|
+
console.error(
|
|
1298
|
+
"Indexing Status API: Requested realtime indexing distance not achieved error"
|
|
1299
|
+
);
|
|
1300
|
+
return deserializeENSIndexerIndexingStatus(
|
|
1301
|
+
responseData
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
default: {
|
|
1305
|
+
const errorResponse = deserializeErrorResponse(responseData);
|
|
1306
|
+
throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
return deserializeENSIndexerIndexingStatus(
|
|
1311
|
+
responseData
|
|
1312
|
+
);
|
|
1313
|
+
}
|
|
1066
1314
|
};
|
|
1067
1315
|
|
|
1068
1316
|
// src/resolution/resolver-records-selection.ts
|
|
1069
|
-
var DEFAULT_RECORDS_SELECTION = {
|
|
1070
|
-
addresses: [ETH_COIN_TYPE],
|
|
1071
|
-
texts: [
|
|
1072
|
-
"url",
|
|
1073
|
-
"avatar",
|
|
1074
|
-
"header",
|
|
1075
|
-
"description",
|
|
1076
|
-
"email",
|
|
1077
|
-
"com.twitter",
|
|
1078
|
-
"com.farcaster",
|
|
1079
|
-
"com.github"
|
|
1080
|
-
]
|
|
1081
|
-
};
|
|
1082
1317
|
var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
|
|
1318
|
+
|
|
1319
|
+
// src/resolution/default-records-selection.ts
|
|
1320
|
+
import {
|
|
1321
|
+
DatasourceNames,
|
|
1322
|
+
ENSNamespaceIds as ENSNamespaceIds2,
|
|
1323
|
+
maybeGetDatasource
|
|
1324
|
+
} from "@ensnode/datasources";
|
|
1325
|
+
var getENSIP19SupportedCoinTypes = (namespace) => uniq(
|
|
1326
|
+
[
|
|
1327
|
+
maybeGetDatasource(namespace, DatasourceNames.ReverseResolverBase),
|
|
1328
|
+
maybeGetDatasource(namespace, DatasourceNames.ReverseResolverLinea),
|
|
1329
|
+
maybeGetDatasource(namespace, DatasourceNames.ReverseResolverOptimism),
|
|
1330
|
+
maybeGetDatasource(namespace, DatasourceNames.ReverseResolverArbitrum),
|
|
1331
|
+
maybeGetDatasource(namespace, DatasourceNames.ReverseResolverScroll)
|
|
1332
|
+
].filter((ds) => ds !== void 0).map((ds) => ds.chain.id)
|
|
1333
|
+
).map(evmChainIdToCoinType);
|
|
1334
|
+
var TEXTS = [
|
|
1335
|
+
"url",
|
|
1336
|
+
"avatar",
|
|
1337
|
+
"header",
|
|
1338
|
+
"description",
|
|
1339
|
+
"email",
|
|
1340
|
+
"com.twitter",
|
|
1341
|
+
"com.farcaster",
|
|
1342
|
+
"com.github"
|
|
1343
|
+
];
|
|
1344
|
+
var DefaultRecordsSelection = {
|
|
1345
|
+
[ENSNamespaceIds2.Mainnet]: {
|
|
1346
|
+
addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Mainnet)],
|
|
1347
|
+
texts: TEXTS
|
|
1348
|
+
},
|
|
1349
|
+
[ENSNamespaceIds2.Sepolia]: {
|
|
1350
|
+
addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Sepolia)],
|
|
1351
|
+
texts: TEXTS
|
|
1352
|
+
},
|
|
1353
|
+
[ENSNamespaceIds2.Holesky]: {
|
|
1354
|
+
addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.Holesky)],
|
|
1355
|
+
texts: TEXTS
|
|
1356
|
+
},
|
|
1357
|
+
[ENSNamespaceIds2.EnsTestEnv]: {
|
|
1358
|
+
addresses: [ETH_COIN_TYPE, ...getENSIP19SupportedCoinTypes(ENSNamespaceIds2.EnsTestEnv)],
|
|
1359
|
+
texts: TEXTS
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1083
1362
|
export {
|
|
1084
1363
|
ATTR_PROTOCOL_NAME,
|
|
1085
1364
|
ATTR_PROTOCOL_STEP,
|
|
1086
1365
|
ATTR_PROTOCOL_STEP_RESULT,
|
|
1366
|
+
BASENAMES_NODE,
|
|
1087
1367
|
ChainIndexingStatusIds,
|
|
1088
1368
|
ChainIndexingStrategyIds,
|
|
1369
|
+
ClientError,
|
|
1089
1370
|
DEFAULT_ENSNODE_API_URL,
|
|
1090
1371
|
DEFAULT_EVM_CHAIN_ID,
|
|
1091
1372
|
DEFAULT_EVM_COIN_TYPE,
|
|
1092
|
-
|
|
1373
|
+
DefaultRecordsSelection,
|
|
1093
1374
|
ENSNamespaceIds,
|
|
1094
1375
|
ENSNodeClient,
|
|
1095
1376
|
ETH_COIN_TYPE,
|
|
1377
|
+
ETH_NODE,
|
|
1096
1378
|
ForwardResolutionProtocolStep,
|
|
1379
|
+
IndexingStatusResponseCodes,
|
|
1380
|
+
LINEANAMES_NODE,
|
|
1097
1381
|
LruCache,
|
|
1098
1382
|
OverallIndexingStatusIds,
|
|
1383
|
+
PROTOCOL_ATTRIBUTE_PREFIX,
|
|
1099
1384
|
PluginName,
|
|
1100
1385
|
REVERSE_ROOT_NODES,
|
|
1101
1386
|
ROOT_NODE,
|
|
1102
1387
|
ReverseResolutionProtocolStep,
|
|
1103
1388
|
TraceableENSProtocol,
|
|
1389
|
+
accountIdEqual,
|
|
1104
1390
|
addrReverseLabel,
|
|
1105
1391
|
bigintToCoinType,
|
|
1392
|
+
buildEnsRainbowClientLabelSet,
|
|
1393
|
+
buildLabelSetId,
|
|
1394
|
+
buildLabelSetVersion,
|
|
1106
1395
|
checkChainIndexingStatusesForBackfillOverallStatus,
|
|
1107
1396
|
checkChainIndexingStatusesForCompletedOverallStatus,
|
|
1108
1397
|
checkChainIndexingStatusesForFollowingOverallStatus,
|
|
@@ -1118,6 +1407,7 @@ export {
|
|
|
1118
1407
|
deserializeDuration,
|
|
1119
1408
|
deserializeENSIndexerIndexingStatus,
|
|
1120
1409
|
deserializeENSIndexerPublicConfig,
|
|
1410
|
+
deserializeErrorResponse,
|
|
1121
1411
|
deserializeUrl,
|
|
1122
1412
|
evmChainIdToCoinType,
|
|
1123
1413
|
getActiveChains,
|
|
@@ -1126,15 +1416,27 @@ export {
|
|
|
1126
1416
|
getOverallApproxRealtimeDistance,
|
|
1127
1417
|
getOverallIndexingStatus,
|
|
1128
1418
|
getStandbyChains,
|
|
1129
|
-
|
|
1419
|
+
getTimestampForHighestOmnichainKnownBlock,
|
|
1420
|
+
getTimestampForLowestOmnichainStartBlock,
|
|
1421
|
+
invariant_isSubgraphCompatibleRequirements,
|
|
1422
|
+
invariant_reverseResolversPluginNeedsResolverRecords,
|
|
1130
1423
|
isLabelIndexable,
|
|
1131
1424
|
isNormalized,
|
|
1132
1425
|
isSelectionEmpty,
|
|
1133
1426
|
isSubgraphCompatible,
|
|
1427
|
+
labelHashToBytes,
|
|
1428
|
+
makeDatabaseSchemaNameSchema,
|
|
1429
|
+
makeDependencyInfoSchema,
|
|
1430
|
+
makeENSIndexerPublicConfigSchema,
|
|
1431
|
+
makeFullyPinnedLabelSetSchema,
|
|
1432
|
+
makeIndexedChainIdsSchema,
|
|
1433
|
+
makeLabelSetIdSchema,
|
|
1434
|
+
makeLabelSetVersionSchema,
|
|
1435
|
+
makePluginsListSchema,
|
|
1134
1436
|
makeSubdomainNode,
|
|
1135
1437
|
maybeHealLabelByReverseAddress,
|
|
1438
|
+
parseNonNegativeInteger,
|
|
1136
1439
|
parseReverseName,
|
|
1137
|
-
readableSpanToProtocolSpan,
|
|
1138
1440
|
reverseName,
|
|
1139
1441
|
serializeChainId,
|
|
1140
1442
|
serializeChainIndexingStatuses,
|
|
@@ -1143,7 +1445,9 @@ export {
|
|
|
1143
1445
|
serializeENSIndexerPublicConfig,
|
|
1144
1446
|
serializeIndexedChainIds,
|
|
1145
1447
|
serializeUrl,
|
|
1448
|
+
sortAscChainStatusesByStartBlock,
|
|
1146
1449
|
uint256ToHex32,
|
|
1147
|
-
uniq
|
|
1450
|
+
uniq,
|
|
1451
|
+
validateSupportedLabelSetAndVersion
|
|
1148
1452
|
};
|
|
1149
1453
|
//# sourceMappingURL=index.js.map
|