@ensnode/ensnode-sdk 0.33.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/dist/index.d.ts +385 -39
- package/dist/index.js +364 -46
- 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
|
{
|
|
@@ -393,7 +427,7 @@ function invariant_reverseResolversPluginNeedsResolverRecords(ctx) {
|
|
|
393
427
|
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
394
428
|
const { value: config } = ctx;
|
|
395
429
|
if (config.isSubgraphCompatible !== isSubgraphCompatible(config)) {
|
|
396
|
-
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'`;
|
|
397
431
|
ctx.issues.push({
|
|
398
432
|
code: "custom",
|
|
399
433
|
input: config,
|
|
@@ -404,6 +438,7 @@ function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
|
404
438
|
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
|
|
405
439
|
ensAdminUrl: makeUrlSchema(`${valueLabel}.ensAdminUrl`),
|
|
406
440
|
ensNodePublicUrl: makeUrlSchema(`${valueLabel}.ensNodePublicUrl`),
|
|
441
|
+
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
407
442
|
healReverseAddresses: z2.boolean({ error: `${valueLabel}.healReverseAddresses` }),
|
|
408
443
|
indexAdditionalResolverRecords: z2.boolean({
|
|
409
444
|
error: `${valueLabel}.indexAdditionalResolverRecords`
|
|
@@ -436,6 +471,7 @@ function serializeENSIndexerPublicConfig(config) {
|
|
|
436
471
|
const {
|
|
437
472
|
ensAdminUrl,
|
|
438
473
|
ensNodePublicUrl,
|
|
474
|
+
labelSet,
|
|
439
475
|
indexedChainIds,
|
|
440
476
|
databaseSchemaName,
|
|
441
477
|
healReverseAddresses,
|
|
@@ -448,6 +484,7 @@ function serializeENSIndexerPublicConfig(config) {
|
|
|
448
484
|
return {
|
|
449
485
|
ensAdminUrl: serializeUrl(ensAdminUrl),
|
|
450
486
|
ensNodePublicUrl: serializeUrl(ensNodePublicUrl),
|
|
487
|
+
labelSet,
|
|
451
488
|
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
452
489
|
databaseSchemaName,
|
|
453
490
|
healReverseAddresses,
|
|
@@ -459,6 +496,86 @@ function serializeENSIndexerPublicConfig(config) {
|
|
|
459
496
|
};
|
|
460
497
|
}
|
|
461
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
|
+
|
|
462
579
|
// src/ensindexer/indexing-status/deserialize.ts
|
|
463
580
|
import { prettifyError as prettifyError3 } from "zod/v4";
|
|
464
581
|
|
|
@@ -520,6 +637,34 @@ function getOverallApproxRealtimeDistance(chains) {
|
|
|
520
637
|
const approxRealtimeDistance = Math.max(...chainApproxRealtimeDistances);
|
|
521
638
|
return approxRealtimeDistance;
|
|
522
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
|
+
}
|
|
523
668
|
function getOmnichainIndexingCursor(chains) {
|
|
524
669
|
return Math.min(...chains.map((chain) => chain.latestIndexedBlock.timestamp));
|
|
525
670
|
}
|
|
@@ -571,6 +716,12 @@ function checkChainIndexingStatusesForFollowingOverallStatus(chains) {
|
|
|
571
716
|
);
|
|
572
717
|
return allChainsHaveValidStatuses;
|
|
573
718
|
}
|
|
719
|
+
function sortAscChainStatusesByStartBlock(chains) {
|
|
720
|
+
chains.sort(
|
|
721
|
+
([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
|
|
722
|
+
);
|
|
723
|
+
return chains;
|
|
724
|
+
}
|
|
574
725
|
|
|
575
726
|
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
576
727
|
var makeChainIndexingConfigSchema = (valueLabel = "Value") => z3.discriminatedUnion("strategy", [
|
|
@@ -598,6 +749,7 @@ var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictO
|
|
|
598
749
|
status: z3.literal(ChainIndexingStatusIds.Backfill),
|
|
599
750
|
config: makeChainIndexingConfigSchema(valueLabel),
|
|
600
751
|
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
752
|
+
latestSyncedBlock: makeBlockRefSchema(valueLabel),
|
|
601
753
|
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
602
754
|
}).refine(
|
|
603
755
|
({ config, latestIndexedBlock }) => isBeforeOrEqualTo(config.startBlock, latestIndexedBlock),
|
|
@@ -605,9 +757,14 @@ var makeChainIndexingBackfillStatusSchema = (valueLabel = "Value") => z3.strictO
|
|
|
605
757
|
error: `config.startBlock must be before or same as latestIndexedBlock.`
|
|
606
758
|
}
|
|
607
759
|
).refine(
|
|
608
|
-
({ latestIndexedBlock,
|
|
760
|
+
({ latestIndexedBlock, latestSyncedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, latestSyncedBlock),
|
|
761
|
+
{
|
|
762
|
+
error: `latestIndexedBlock must be before or same as latestSyncedBlock.`
|
|
763
|
+
}
|
|
764
|
+
).refine(
|
|
765
|
+
({ latestSyncedBlock, backfillEndBlock }) => isBeforeOrEqualTo(latestSyncedBlock, backfillEndBlock),
|
|
609
766
|
{
|
|
610
|
-
error: `
|
|
767
|
+
error: `latestSyncedBlock must be before or same as backfillEndBlock.`
|
|
611
768
|
}
|
|
612
769
|
).refine(
|
|
613
770
|
({ config, backfillEndBlock }) => config.endBlock === null || isEqualTo(backfillEndBlock, config.endBlock),
|
|
@@ -649,9 +806,9 @@ var makeChainIndexingCompletedStatusSchema = (valueLabel = "Value") => z3.strict
|
|
|
649
806
|
error: `config.startBlock must be before or same as latestIndexedBlock.`
|
|
650
807
|
}
|
|
651
808
|
).refine(
|
|
652
|
-
({ config, latestIndexedBlock }) =>
|
|
809
|
+
({ config, latestIndexedBlock }) => isBeforeOrEqualTo(latestIndexedBlock, config.endBlock),
|
|
653
810
|
{
|
|
654
|
-
error: `latestIndexedBlock must be
|
|
811
|
+
error: `latestIndexedBlock must be before or same as config.endBlock.`
|
|
655
812
|
}
|
|
656
813
|
);
|
|
657
814
|
var makeChainIndexingStatusSchema = (valueLabel = "Value") => z3.discriminatedUnion("status", [
|
|
@@ -839,7 +996,7 @@ var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
|
|
|
839
996
|
return TraceableENSProtocol2;
|
|
840
997
|
})(TraceableENSProtocol || {});
|
|
841
998
|
var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
|
|
842
|
-
ForwardResolutionProtocolStep2["Operation"] = "
|
|
999
|
+
ForwardResolutionProtocolStep2["Operation"] = "forward-resolution";
|
|
843
1000
|
ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
|
|
844
1001
|
ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
|
|
845
1002
|
ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
|
|
@@ -850,7 +1007,7 @@ var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolS
|
|
|
850
1007
|
return ForwardResolutionProtocolStep2;
|
|
851
1008
|
})(ForwardResolutionProtocolStep || {});
|
|
852
1009
|
var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
|
|
853
|
-
ReverseResolutionProtocolStep2["Operation"] = "
|
|
1010
|
+
ReverseResolutionProtocolStep2["Operation"] = "reverse-resolution";
|
|
854
1011
|
ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
|
|
855
1012
|
ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
|
|
856
1013
|
ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
|
|
@@ -861,26 +1018,47 @@ var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|
|
|
861
1018
|
var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
|
|
862
1019
|
var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
|
|
863
1020
|
var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
duration: hrTimeToMicroseconds(span.duration),
|
|
874
|
-
// only export `ens.*` attributes to avoid leaking internal details
|
|
875
|
-
attributes: Object.fromEntries(
|
|
876
|
-
Object.entries(span.attributes).filter(
|
|
877
|
-
([key]) => key.startsWith(`${PROTOCOL_ATTRIBUTE_PREFIX}.`)
|
|
878
|
-
)
|
|
879
|
-
),
|
|
880
|
-
status: span.status,
|
|
881
|
-
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())
|
|
882
1030
|
});
|
|
883
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
|
+
|
|
884
1062
|
// src/client.ts
|
|
885
1063
|
var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
|
|
886
1064
|
var ENSNodeClient = class _ENSNodeClient {
|
|
@@ -947,7 +1125,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
947
1125
|
const response = await fetch(url);
|
|
948
1126
|
if (!response.ok) {
|
|
949
1127
|
const error = await response.json();
|
|
950
|
-
throw
|
|
1128
|
+
throw ClientError.fromErrorResponse(error);
|
|
951
1129
|
}
|
|
952
1130
|
const data = await response.json();
|
|
953
1131
|
return data;
|
|
@@ -989,7 +1167,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
989
1167
|
const response = await fetch(url);
|
|
990
1168
|
if (!response.ok) {
|
|
991
1169
|
const error = await response.json();
|
|
992
|
-
throw
|
|
1170
|
+
throw ClientError.fromErrorResponse(error);
|
|
993
1171
|
}
|
|
994
1172
|
const data = await response.json();
|
|
995
1173
|
return data;
|
|
@@ -1044,51 +1222,176 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
1044
1222
|
const response = await fetch(url);
|
|
1045
1223
|
if (!response.ok) {
|
|
1046
1224
|
const error = await response.json();
|
|
1047
|
-
throw
|
|
1225
|
+
throw ClientError.fromErrorResponse(error);
|
|
1048
1226
|
}
|
|
1049
1227
|
const data = await response.json();
|
|
1050
1228
|
return data;
|
|
1051
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
|
+
}
|
|
1052
1314
|
};
|
|
1053
1315
|
|
|
1054
1316
|
// src/resolution/resolver-records-selection.ts
|
|
1055
|
-
var DEFAULT_RECORDS_SELECTION = {
|
|
1056
|
-
addresses: [ETH_COIN_TYPE],
|
|
1057
|
-
texts: [
|
|
1058
|
-
"url",
|
|
1059
|
-
"avatar",
|
|
1060
|
-
"header",
|
|
1061
|
-
"description",
|
|
1062
|
-
"email",
|
|
1063
|
-
"com.twitter",
|
|
1064
|
-
"com.farcaster",
|
|
1065
|
-
"com.github"
|
|
1066
|
-
]
|
|
1067
|
-
};
|
|
1068
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
|
+
};
|
|
1069
1362
|
export {
|
|
1070
1363
|
ATTR_PROTOCOL_NAME,
|
|
1071
1364
|
ATTR_PROTOCOL_STEP,
|
|
1072
1365
|
ATTR_PROTOCOL_STEP_RESULT,
|
|
1366
|
+
BASENAMES_NODE,
|
|
1073
1367
|
ChainIndexingStatusIds,
|
|
1074
1368
|
ChainIndexingStrategyIds,
|
|
1369
|
+
ClientError,
|
|
1075
1370
|
DEFAULT_ENSNODE_API_URL,
|
|
1076
1371
|
DEFAULT_EVM_CHAIN_ID,
|
|
1077
1372
|
DEFAULT_EVM_COIN_TYPE,
|
|
1078
|
-
|
|
1373
|
+
DefaultRecordsSelection,
|
|
1079
1374
|
ENSNamespaceIds,
|
|
1080
1375
|
ENSNodeClient,
|
|
1081
1376
|
ETH_COIN_TYPE,
|
|
1377
|
+
ETH_NODE,
|
|
1082
1378
|
ForwardResolutionProtocolStep,
|
|
1379
|
+
IndexingStatusResponseCodes,
|
|
1380
|
+
LINEANAMES_NODE,
|
|
1083
1381
|
LruCache,
|
|
1084
1382
|
OverallIndexingStatusIds,
|
|
1383
|
+
PROTOCOL_ATTRIBUTE_PREFIX,
|
|
1085
1384
|
PluginName,
|
|
1086
1385
|
REVERSE_ROOT_NODES,
|
|
1087
1386
|
ROOT_NODE,
|
|
1088
1387
|
ReverseResolutionProtocolStep,
|
|
1089
1388
|
TraceableENSProtocol,
|
|
1389
|
+
accountIdEqual,
|
|
1090
1390
|
addrReverseLabel,
|
|
1091
1391
|
bigintToCoinType,
|
|
1392
|
+
buildEnsRainbowClientLabelSet,
|
|
1393
|
+
buildLabelSetId,
|
|
1394
|
+
buildLabelSetVersion,
|
|
1092
1395
|
checkChainIndexingStatusesForBackfillOverallStatus,
|
|
1093
1396
|
checkChainIndexingStatusesForCompletedOverallStatus,
|
|
1094
1397
|
checkChainIndexingStatusesForFollowingOverallStatus,
|
|
@@ -1104,6 +1407,7 @@ export {
|
|
|
1104
1407
|
deserializeDuration,
|
|
1105
1408
|
deserializeENSIndexerIndexingStatus,
|
|
1106
1409
|
deserializeENSIndexerPublicConfig,
|
|
1410
|
+
deserializeErrorResponse,
|
|
1107
1411
|
deserializeUrl,
|
|
1108
1412
|
evmChainIdToCoinType,
|
|
1109
1413
|
getActiveChains,
|
|
@@ -1112,15 +1416,27 @@ export {
|
|
|
1112
1416
|
getOverallApproxRealtimeDistance,
|
|
1113
1417
|
getOverallIndexingStatus,
|
|
1114
1418
|
getStandbyChains,
|
|
1115
|
-
|
|
1419
|
+
getTimestampForHighestOmnichainKnownBlock,
|
|
1420
|
+
getTimestampForLowestOmnichainStartBlock,
|
|
1421
|
+
invariant_isSubgraphCompatibleRequirements,
|
|
1422
|
+
invariant_reverseResolversPluginNeedsResolverRecords,
|
|
1116
1423
|
isLabelIndexable,
|
|
1117
1424
|
isNormalized,
|
|
1118
1425
|
isSelectionEmpty,
|
|
1119
1426
|
isSubgraphCompatible,
|
|
1427
|
+
labelHashToBytes,
|
|
1428
|
+
makeDatabaseSchemaNameSchema,
|
|
1429
|
+
makeDependencyInfoSchema,
|
|
1430
|
+
makeENSIndexerPublicConfigSchema,
|
|
1431
|
+
makeFullyPinnedLabelSetSchema,
|
|
1432
|
+
makeIndexedChainIdsSchema,
|
|
1433
|
+
makeLabelSetIdSchema,
|
|
1434
|
+
makeLabelSetVersionSchema,
|
|
1435
|
+
makePluginsListSchema,
|
|
1120
1436
|
makeSubdomainNode,
|
|
1121
1437
|
maybeHealLabelByReverseAddress,
|
|
1438
|
+
parseNonNegativeInteger,
|
|
1122
1439
|
parseReverseName,
|
|
1123
|
-
readableSpanToProtocolSpan,
|
|
1124
1440
|
reverseName,
|
|
1125
1441
|
serializeChainId,
|
|
1126
1442
|
serializeChainIndexingStatuses,
|
|
@@ -1129,7 +1445,9 @@ export {
|
|
|
1129
1445
|
serializeENSIndexerPublicConfig,
|
|
1130
1446
|
serializeIndexedChainIds,
|
|
1131
1447
|
serializeUrl,
|
|
1448
|
+
sortAscChainStatusesByStartBlock,
|
|
1132
1449
|
uint256ToHex32,
|
|
1133
|
-
uniq
|
|
1450
|
+
uniq,
|
|
1451
|
+
validateSupportedLabelSetAndVersion
|
|
1134
1452
|
};
|
|
1135
1453
|
//# sourceMappingURL=index.js.map
|