@ensnode/ensnode-sdk 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1237 -749
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1059 -595
- package/dist/index.d.ts +1059 -595
- package/dist/index.js +1212 -729
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -7,25 +7,6 @@ import { z as z3 } from "zod/v4";
|
|
|
7
7
|
// src/ensindexer/config/zod-schemas.ts
|
|
8
8
|
import z2 from "zod/v4";
|
|
9
9
|
|
|
10
|
-
// src/ens/is-normalized.ts
|
|
11
|
-
import { normalize } from "viem/ens";
|
|
12
|
-
function isNormalizedName(name) {
|
|
13
|
-
try {
|
|
14
|
-
return name === normalize(name);
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function isNormalizedLabel(label) {
|
|
20
|
-
if (label === "") return false;
|
|
21
|
-
if (label.includes(".")) return false;
|
|
22
|
-
try {
|
|
23
|
-
return label === normalize(label);
|
|
24
|
-
} catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
10
|
// src/shared/account-id.ts
|
|
30
11
|
import { isAddressEqual } from "viem";
|
|
31
12
|
var accountIdEqual = (a, b) => {
|
|
@@ -179,9 +160,39 @@ function isEncodedLabelHash(maybeEncodedLabelHash) {
|
|
|
179
160
|
return expectedFormatting && includesLabelHash;
|
|
180
161
|
}
|
|
181
162
|
|
|
163
|
+
// src/ens/is-normalized.ts
|
|
164
|
+
import { normalize } from "viem/ens";
|
|
165
|
+
function isNormalizedName(name) {
|
|
166
|
+
try {
|
|
167
|
+
return name === normalize(name);
|
|
168
|
+
} catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function isNormalizedLabel(label) {
|
|
173
|
+
if (label === "") return false;
|
|
174
|
+
if (label.includes(".")) return false;
|
|
175
|
+
try {
|
|
176
|
+
return label === normalize(label);
|
|
177
|
+
} catch {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
182
|
// src/ens/names.ts
|
|
183
183
|
import { ens_beautify } from "@adraffy/ens-normalize";
|
|
184
|
+
var ENS_ROOT = "";
|
|
184
185
|
var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
|
|
186
|
+
var getParentNameFQDN = (name) => {
|
|
187
|
+
if (name === ENS_ROOT) {
|
|
188
|
+
throw new Error("There is no parent name for ENS Root.");
|
|
189
|
+
}
|
|
190
|
+
const labels = name.split(".");
|
|
191
|
+
if (labels.length === 1) {
|
|
192
|
+
return ENS_ROOT;
|
|
193
|
+
}
|
|
194
|
+
return labels.slice(1).join(".");
|
|
195
|
+
};
|
|
185
196
|
var beautifyName = (name) => {
|
|
186
197
|
const beautifiedLabels = name.split(".").map((label) => {
|
|
187
198
|
if (isNormalizedLabel(label)) {
|
|
@@ -424,7 +435,7 @@ var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
|
|
|
424
435
|
chainId: makeChainIdSchema(`${valueLabel} chain ID`),
|
|
425
436
|
address: makeLowercaseAddressSchema(`${valueLabel} address`)
|
|
426
437
|
});
|
|
427
|
-
var
|
|
438
|
+
var makeAccountIdStringSchema = (valueLabel = "Account ID String") => z.coerce.string().transform((v) => {
|
|
428
439
|
const result = new CaipAccountId(v);
|
|
429
440
|
return {
|
|
430
441
|
chainId: Number(result.chainId.reference),
|
|
@@ -436,7 +447,7 @@ var makeHexStringSchema = (options, valueLabel = "String representation of bytes
|
|
|
436
447
|
ctx.issues.push({
|
|
437
448
|
code: "custom",
|
|
438
449
|
input: ctx.value,
|
|
439
|
-
message: `${valueLabel} must
|
|
450
|
+
message: `${valueLabel} must be a hexadecimal value which starts with '0x'.`
|
|
440
451
|
});
|
|
441
452
|
}
|
|
442
453
|
}).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
|
|
@@ -546,8 +557,8 @@ ${prettifyError(parsed.error)}
|
|
|
546
557
|
}
|
|
547
558
|
return parsed.data;
|
|
548
559
|
}
|
|
549
|
-
function
|
|
550
|
-
const schema =
|
|
560
|
+
function parseAccountId(maybeAccountId, valueLabel) {
|
|
561
|
+
const schema = makeAccountIdStringSchema(valueLabel);
|
|
551
562
|
const parsed = schema.safeParse(maybeAccountId);
|
|
552
563
|
if (parsed.error) {
|
|
553
564
|
throw new RangeError(`Cannot deserialize AccountId:
|
|
@@ -565,181 +576,65 @@ function addDuration(timestamp, duration) {
|
|
|
565
576
|
return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
|
|
566
577
|
}
|
|
567
578
|
|
|
568
|
-
// src/shared/cache/
|
|
569
|
-
var
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
schedule(config) {
|
|
578
|
-
const { revalidate, interval, initialDelay = 0, onError } = config;
|
|
579
|
-
if (this.activeSchedules.has(revalidate)) {
|
|
580
|
-
return revalidate;
|
|
579
|
+
// src/shared/cache/swr-cache.ts
|
|
580
|
+
var SWRCache = class {
|
|
581
|
+
constructor(options) {
|
|
582
|
+
this.options = options;
|
|
583
|
+
if (options.proactiveRevalidationInterval) {
|
|
584
|
+
this.backgroundInterval = setInterval(
|
|
585
|
+
() => this.revalidate(),
|
|
586
|
+
secondsToMilliseconds(options.proactiveRevalidationInterval)
|
|
587
|
+
);
|
|
581
588
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
metadata.timeoutId = setTimeout(() => {
|
|
602
|
-
if (this.activeSchedules.has(revalidate)) {
|
|
603
|
-
executeRevalidation().then(() => scheduleNext());
|
|
604
|
-
}
|
|
605
|
-
}, interval);
|
|
606
|
-
};
|
|
607
|
-
if (initialDelay > 0) {
|
|
608
|
-
metadata.timeoutId = setTimeout(() => {
|
|
609
|
-
if (this.activeSchedules.has(revalidate)) {
|
|
610
|
-
executeRevalidation().then(() => scheduleNext());
|
|
589
|
+
if (options.proactivelyInitialize) this.revalidate();
|
|
590
|
+
}
|
|
591
|
+
cache = null;
|
|
592
|
+
inProgressRevalidate = null;
|
|
593
|
+
backgroundInterval = null;
|
|
594
|
+
async revalidate() {
|
|
595
|
+
if (!this.inProgressRevalidate) {
|
|
596
|
+
this.inProgressRevalidate = this.options.fn().then((result) => {
|
|
597
|
+
this.cache = {
|
|
598
|
+
result,
|
|
599
|
+
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
600
|
+
};
|
|
601
|
+
}).catch((error) => {
|
|
602
|
+
if (!this.cache) {
|
|
603
|
+
this.cache = {
|
|
604
|
+
// ensure thrown value is always an Error instance
|
|
605
|
+
result: error instanceof Error ? error : new Error(String(error)),
|
|
606
|
+
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
607
|
+
};
|
|
611
608
|
}
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
|
|
609
|
+
}).finally(() => {
|
|
610
|
+
this.inProgressRevalidate = null;
|
|
611
|
+
});
|
|
615
612
|
}
|
|
616
|
-
return
|
|
613
|
+
return this.inProgressRevalidate;
|
|
617
614
|
}
|
|
618
615
|
/**
|
|
619
|
-
*
|
|
616
|
+
* Read the most recently cached result from the `SWRCache`.
|
|
620
617
|
*
|
|
621
|
-
* @
|
|
622
|
-
|
|
623
|
-
cancel(revalidate) {
|
|
624
|
-
const metadata = this.activeSchedules.get(revalidate);
|
|
625
|
-
if (!metadata) return;
|
|
626
|
-
if (metadata.timeoutId !== null) {
|
|
627
|
-
clearTimeout(metadata.timeoutId);
|
|
628
|
-
}
|
|
629
|
-
this.activeSchedules.delete(revalidate);
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Cancel all active schedules.
|
|
618
|
+
* @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
|
|
619
|
+
* has never successfully returned.
|
|
633
620
|
*/
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
621
|
+
async read() {
|
|
622
|
+
if (!this.cache) await this.revalidate();
|
|
623
|
+
if (!this.cache) throw new Error("never");
|
|
624
|
+
if (durationBetween(this.cache.updatedAt, getUnixTime(/* @__PURE__ */ new Date())) > this.options.ttl) {
|
|
625
|
+
this.revalidate();
|
|
639
626
|
}
|
|
640
|
-
this.
|
|
627
|
+
return this.cache.result;
|
|
641
628
|
}
|
|
642
629
|
/**
|
|
643
|
-
*
|
|
644
|
-
* Useful for debugging and monitoring.
|
|
645
|
-
*
|
|
646
|
-
* @returns The number of currently active schedules
|
|
647
|
-
*/
|
|
648
|
-
getActiveScheduleCount() {
|
|
649
|
-
return this.activeSchedules.size;
|
|
650
|
-
}
|
|
651
|
-
};
|
|
652
|
-
|
|
653
|
-
// src/shared/cache/swr-cache.ts
|
|
654
|
-
var bgRevalidationScheduler = new BackgroundRevalidationScheduler();
|
|
655
|
-
var SWRCache = class _SWRCache {
|
|
656
|
-
options;
|
|
657
|
-
cache;
|
|
658
|
-
/**
|
|
659
|
-
* Optional promise of the current in-progress attempt to revalidate the `cache`.
|
|
660
|
-
*
|
|
661
|
-
* If null, no revalidation attempt is currently in progress.
|
|
662
|
-
* If not null, identifies the revalidation attempt that is currently in progress.
|
|
663
|
-
*
|
|
664
|
-
* Used to enforce no concurrent revalidation attempts.
|
|
665
|
-
*/
|
|
666
|
-
inProgressRevalidate;
|
|
667
|
-
/**
|
|
668
|
-
* The callback function being managed by `BackgroundRevalidationScheduler`.
|
|
669
|
-
*
|
|
670
|
-
* If null, no background revalidation is scheduled.
|
|
671
|
-
* If not null, identifies the background revalidation that is currently scheduled.
|
|
672
|
-
*
|
|
673
|
-
* Used to enforce no concurrent background revalidation attempts.
|
|
674
|
-
*/
|
|
675
|
-
scheduledBackgroundRevalidate;
|
|
676
|
-
constructor(options) {
|
|
677
|
-
this.cache = null;
|
|
678
|
-
this.inProgressRevalidate = null;
|
|
679
|
-
this.scheduledBackgroundRevalidate = null;
|
|
680
|
-
this.options = options;
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
* Asynchronously create a new `SWRCache` instance.
|
|
684
|
-
*
|
|
685
|
-
* @param options - The {@link SWRCacheOptions} for the SWR cache.
|
|
686
|
-
* @returns a new `SWRCache` instance.
|
|
630
|
+
* Destroys the background revalidation interval, if exists.
|
|
687
631
|
*/
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
632
|
+
destroy() {
|
|
633
|
+
if (this.backgroundInterval) {
|
|
634
|
+
clearInterval(this.backgroundInterval);
|
|
635
|
+
this.backgroundInterval = null;
|
|
692
636
|
}
|
|
693
|
-
return cache;
|
|
694
637
|
}
|
|
695
|
-
revalidate = async () => {
|
|
696
|
-
if (this.inProgressRevalidate) {
|
|
697
|
-
return this.inProgressRevalidate;
|
|
698
|
-
}
|
|
699
|
-
return this.options.fn().then((value) => {
|
|
700
|
-
this.cache = {
|
|
701
|
-
value,
|
|
702
|
-
updatedAt: getUnixTime(/* @__PURE__ */ new Date())
|
|
703
|
-
};
|
|
704
|
-
return this.cache;
|
|
705
|
-
}).catch(() => {
|
|
706
|
-
return null;
|
|
707
|
-
}).finally(() => {
|
|
708
|
-
this.inProgressRevalidate = null;
|
|
709
|
-
if (this.options.revalidationInterval === void 0) {
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
if (this.scheduledBackgroundRevalidate) {
|
|
713
|
-
bgRevalidationScheduler.cancel(this.scheduledBackgroundRevalidate);
|
|
714
|
-
}
|
|
715
|
-
const backgroundRevalidate = async () => {
|
|
716
|
-
this.revalidate();
|
|
717
|
-
};
|
|
718
|
-
this.scheduledBackgroundRevalidate = bgRevalidationScheduler.schedule({
|
|
719
|
-
revalidate: backgroundRevalidate,
|
|
720
|
-
interval: secondsToMilliseconds(this.options.revalidationInterval)
|
|
721
|
-
});
|
|
722
|
-
});
|
|
723
|
-
};
|
|
724
|
-
/**
|
|
725
|
-
* Read the most recently cached `CachedValue` from the `SWRCache`.
|
|
726
|
-
*
|
|
727
|
-
* @returns a `CachedValue` holding a `value` of `ValueType` that was most recently successfully returned by `fn`
|
|
728
|
-
* or `null` if `fn` has never successfully returned and has always thrown an error,
|
|
729
|
-
*/
|
|
730
|
-
readCache = async () => {
|
|
731
|
-
if (!this.cache) {
|
|
732
|
-
this.inProgressRevalidate = this.revalidate();
|
|
733
|
-
return this.inProgressRevalidate;
|
|
734
|
-
}
|
|
735
|
-
if (durationBetween(this.cache.updatedAt, getUnixTime(/* @__PURE__ */ new Date())) <= this.options.ttl) {
|
|
736
|
-
return this.cache;
|
|
737
|
-
}
|
|
738
|
-
if (!this.inProgressRevalidate) {
|
|
739
|
-
this.inProgressRevalidate = this.revalidate();
|
|
740
|
-
}
|
|
741
|
-
return this.cache;
|
|
742
|
-
};
|
|
743
638
|
};
|
|
744
639
|
|
|
745
640
|
// src/shared/cache/ttl-cache.ts
|
|
@@ -810,6 +705,28 @@ var TtlCache = class {
|
|
|
810
705
|
// src/shared/collections.ts
|
|
811
706
|
var uniq = (arr) => [...new Set(arr)];
|
|
812
707
|
|
|
708
|
+
// src/shared/datasource-contract.ts
|
|
709
|
+
import { maybeGetDatasource } from "@ensnode/datasources";
|
|
710
|
+
var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
711
|
+
const datasource = maybeGetDatasource(namespaceId, datasourceName);
|
|
712
|
+
if (!datasource) return void 0;
|
|
713
|
+
const address = datasource.contracts[contractName]?.address;
|
|
714
|
+
if (address === void 0 || Array.isArray(address)) return void 0;
|
|
715
|
+
return {
|
|
716
|
+
chainId: datasource.chain.id,
|
|
717
|
+
address
|
|
718
|
+
};
|
|
719
|
+
};
|
|
720
|
+
var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
721
|
+
const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
|
|
722
|
+
if (!contract) {
|
|
723
|
+
throw new Error(
|
|
724
|
+
`Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
|
|
725
|
+
);
|
|
726
|
+
}
|
|
727
|
+
return contract;
|
|
728
|
+
};
|
|
729
|
+
|
|
813
730
|
// src/shared/labelhash.ts
|
|
814
731
|
import { keccak256 as keccak2562, stringToBytes } from "viem";
|
|
815
732
|
var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
|
|
@@ -868,7 +785,7 @@ function serializePrice(price) {
|
|
|
868
785
|
function serializePriceEth(price) {
|
|
869
786
|
return serializePrice(price);
|
|
870
787
|
}
|
|
871
|
-
function
|
|
788
|
+
function formatAccountId(accountId) {
|
|
872
789
|
return CaipAccountId2.format({
|
|
873
790
|
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
874
791
|
address: accountId.address
|
|
@@ -1844,152 +1761,748 @@ function serializeConfigResponse(response) {
|
|
|
1844
1761
|
import { prettifyError as prettifyError5 } from "zod/v4";
|
|
1845
1762
|
|
|
1846
1763
|
// src/api/indexing-status/zod-schemas.ts
|
|
1847
|
-
import z11 from "zod/v4";
|
|
1848
|
-
|
|
1849
|
-
// src/api/registrar-actions/zod-schemas.ts
|
|
1850
|
-
import { namehash as namehash2 } from "viem/ens";
|
|
1851
|
-
import z6 from "zod/v4";
|
|
1852
|
-
|
|
1853
|
-
// src/api/shared/errors/zod-schemas.ts
|
|
1854
1764
|
import z5 from "zod/v4";
|
|
1855
|
-
var ErrorResponseSchema = z5.object({
|
|
1856
|
-
message: z5.string(),
|
|
1857
|
-
details: z5.optional(z5.unknown())
|
|
1858
|
-
});
|
|
1859
1765
|
|
|
1860
|
-
// src/api/
|
|
1861
|
-
var
|
|
1766
|
+
// src/api/indexing-status/response.ts
|
|
1767
|
+
var IndexingStatusResponseCodes = {
|
|
1862
1768
|
/**
|
|
1863
|
-
* Represents that
|
|
1769
|
+
* Represents that the indexing status is available.
|
|
1864
1770
|
*/
|
|
1865
1771
|
Ok: "ok",
|
|
1866
1772
|
/**
|
|
1867
|
-
* Represents that
|
|
1773
|
+
* Represents that the indexing status is unavailable.
|
|
1868
1774
|
*/
|
|
1869
1775
|
Error: "error"
|
|
1870
1776
|
};
|
|
1871
1777
|
|
|
1872
|
-
// src/api/
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
const actualNode = namehash2(name);
|
|
1877
|
-
if (actualNode !== expectedNode) {
|
|
1878
|
-
ctx.issues.push({
|
|
1879
|
-
code: "custom",
|
|
1880
|
-
input: ctx.value,
|
|
1881
|
-
message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
|
|
1882
|
-
});
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z6.object({
|
|
1886
|
-
action: makeRegistrarActionSchema(valueLabel),
|
|
1887
|
-
name: makeReinterpretedNameSchema(valueLabel)
|
|
1888
|
-
}).check(invariant_registrationLifecycleNodeMatchesName);
|
|
1889
|
-
var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z6.strictObject({
|
|
1890
|
-
responseCode: z6.literal(RegistrarActionsResponseCodes.Ok),
|
|
1891
|
-
registrarActions: z6.array(makeNamedRegistrarActionSchema(valueLabel))
|
|
1778
|
+
// src/api/indexing-status/zod-schemas.ts
|
|
1779
|
+
var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z5.strictObject({
|
|
1780
|
+
responseCode: z5.literal(IndexingStatusResponseCodes.Ok),
|
|
1781
|
+
realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
|
|
1892
1782
|
});
|
|
1893
|
-
var
|
|
1894
|
-
responseCode:
|
|
1895
|
-
error: ErrorResponseSchema
|
|
1783
|
+
var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => z5.strictObject({
|
|
1784
|
+
responseCode: z5.literal(IndexingStatusResponseCodes.Error)
|
|
1896
1785
|
});
|
|
1897
|
-
var
|
|
1898
|
-
|
|
1899
|
-
|
|
1786
|
+
var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z5.discriminatedUnion("responseCode", [
|
|
1787
|
+
makeIndexingStatusResponseOkSchema(valueLabel),
|
|
1788
|
+
makeIndexingStatusResponseErrorSchema(valueLabel)
|
|
1900
1789
|
]);
|
|
1901
1790
|
|
|
1902
|
-
// src/api/
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
// ../ens-referrals/src/address.ts
|
|
1910
|
-
import { isAddress as isAddress3 } from "viem";
|
|
1911
|
-
|
|
1912
|
-
// ../ens-referrals/src/encoding.ts
|
|
1913
|
-
import { getAddress, pad, size as size2, slice, zeroAddress } from "viem";
|
|
1914
|
-
var ENCODED_REFERRER_BYTE_OFFSET = 12;
|
|
1915
|
-
var ENCODED_REFERRER_BYTE_LENGTH = 32;
|
|
1916
|
-
var EXPECTED_ENCODED_REFERRER_PADDING = pad("0x", {
|
|
1917
|
-
size: ENCODED_REFERRER_BYTE_OFFSET,
|
|
1918
|
-
dir: "left"
|
|
1919
|
-
});
|
|
1920
|
-
var ZERO_ENCODED_REFERRER = pad("0x", {
|
|
1921
|
-
size: ENCODED_REFERRER_BYTE_LENGTH,
|
|
1922
|
-
dir: "left"
|
|
1923
|
-
});
|
|
1924
|
-
function decodeEncodedReferrer(encodedReferrer) {
|
|
1925
|
-
if (size2(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
|
|
1926
|
-
throw new Error(
|
|
1927
|
-
`Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
|
|
1928
|
-
);
|
|
1929
|
-
}
|
|
1930
|
-
const padding = slice(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
|
|
1931
|
-
if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
|
|
1932
|
-
return zeroAddress;
|
|
1791
|
+
// src/api/indexing-status/deserialize.ts
|
|
1792
|
+
function deserializeIndexingStatusResponse(maybeResponse) {
|
|
1793
|
+
const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
|
|
1794
|
+
if (parsed.error) {
|
|
1795
|
+
throw new Error(`Cannot deserialize IndexingStatusResponse:
|
|
1796
|
+
${prettifyError5(parsed.error)}
|
|
1797
|
+
`);
|
|
1933
1798
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1799
|
+
return parsed.data;
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
// src/api/indexing-status/serialize.ts
|
|
1803
|
+
function serializeIndexingStatusResponse(response) {
|
|
1804
|
+
switch (response.responseCode) {
|
|
1805
|
+
case IndexingStatusResponseCodes.Ok:
|
|
1806
|
+
return {
|
|
1807
|
+
responseCode: response.responseCode,
|
|
1808
|
+
realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
|
|
1809
|
+
};
|
|
1810
|
+
case IndexingStatusResponseCodes.Error:
|
|
1811
|
+
return response;
|
|
1939
1812
|
}
|
|
1940
1813
|
}
|
|
1941
1814
|
|
|
1942
|
-
//
|
|
1943
|
-
|
|
1815
|
+
// src/api/name-tokens/deserialize.ts
|
|
1816
|
+
import { prettifyError as prettifyError7 } from "zod/v4";
|
|
1944
1817
|
|
|
1945
|
-
//
|
|
1946
|
-
import {
|
|
1818
|
+
// src/api/name-tokens/zod-schemas.ts
|
|
1819
|
+
import { namehash as namehash2 } from "viem";
|
|
1820
|
+
import z8 from "zod/v4";
|
|
1947
1821
|
|
|
1948
|
-
//
|
|
1949
|
-
|
|
1822
|
+
// src/tokenscope/assets.ts
|
|
1823
|
+
import { AssetId as CaipAssetId2 } from "caip";
|
|
1824
|
+
import { isAddressEqual as isAddressEqual3, zeroAddress as zeroAddress3 } from "viem";
|
|
1825
|
+
import { prettifyError as prettifyError6 } from "zod/v4";
|
|
1826
|
+
|
|
1827
|
+
// src/tokenscope/zod-schemas.ts
|
|
1828
|
+
import { AssetId as CaipAssetId } from "caip";
|
|
1829
|
+
import { zeroAddress as zeroAddress2 } from "viem";
|
|
1830
|
+
import z6 from "zod/v4";
|
|
1831
|
+
|
|
1832
|
+
// src/tokenscope/name-token.ts
|
|
1833
|
+
import { isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
|
|
1834
|
+
import { DatasourceNames } from "@ensnode/datasources";
|
|
1835
|
+
var NameTokenOwnershipTypes = {
|
|
1950
1836
|
/**
|
|
1951
|
-
*
|
|
1837
|
+
* Name Token is owned by NameWrapper account.
|
|
1952
1838
|
*/
|
|
1953
|
-
|
|
1839
|
+
NameWrapper: "namewrapper",
|
|
1954
1840
|
/**
|
|
1955
|
-
*
|
|
1841
|
+
* Name Token is owned fully onchain.
|
|
1842
|
+
*
|
|
1843
|
+
* This ownership type can only apply to direct subnames of `.eth`
|
|
1956
1844
|
*/
|
|
1957
|
-
|
|
1845
|
+
FullyOnchain: "fully-onchain",
|
|
1846
|
+
/**
|
|
1847
|
+
* Name Token ownership has been transferred to the null address.
|
|
1848
|
+
*/
|
|
1849
|
+
Burned: "burned",
|
|
1850
|
+
/**
|
|
1851
|
+
* Name Token ownership is unknown.
|
|
1852
|
+
*/
|
|
1853
|
+
Unknown: "unknown"
|
|
1958
1854
|
};
|
|
1959
|
-
|
|
1960
|
-
// src/registrars/zod-schemas.ts
|
|
1961
|
-
import z8 from "zod/v4";
|
|
1962
|
-
|
|
1963
|
-
// src/registrars/subregistry.ts
|
|
1964
|
-
function serializeSubregistry(subregistry) {
|
|
1855
|
+
function serializeNameToken(nameToken) {
|
|
1965
1856
|
return {
|
|
1966
|
-
|
|
1967
|
-
|
|
1857
|
+
token: serializeAssetId(nameToken.token),
|
|
1858
|
+
ownership: nameToken.ownership,
|
|
1859
|
+
mintStatus: nameToken.mintStatus
|
|
1968
1860
|
};
|
|
1969
1861
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1862
|
+
function getNameWrapperAccounts(namespaceId) {
|
|
1863
|
+
const ethnamesNameWrapperAccount = getDatasourceContract(
|
|
1864
|
+
namespaceId,
|
|
1865
|
+
DatasourceNames.ENSRoot,
|
|
1866
|
+
"NameWrapper"
|
|
1867
|
+
);
|
|
1868
|
+
const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
|
|
1869
|
+
namespaceId,
|
|
1870
|
+
DatasourceNames.Lineanames,
|
|
1871
|
+
"NameWrapper"
|
|
1872
|
+
);
|
|
1873
|
+
const nameWrapperAccounts = [
|
|
1874
|
+
// NameWrapper for direct subnames of .eth is defined for all ENS namespaces
|
|
1875
|
+
ethnamesNameWrapperAccount
|
|
1876
|
+
];
|
|
1877
|
+
if (lineanamesNameWrapperAccount) {
|
|
1878
|
+
nameWrapperAccounts.push(lineanamesNameWrapperAccount);
|
|
1879
|
+
}
|
|
1880
|
+
return nameWrapperAccounts;
|
|
1881
|
+
}
|
|
1882
|
+
function getNameTokenOwnership(namespaceId, name, owner) {
|
|
1883
|
+
const nameWrapperAccounts = getNameWrapperAccounts(namespaceId);
|
|
1884
|
+
const hasNameWrapperOwnership = nameWrapperAccounts.some(
|
|
1885
|
+
(nameWrapperAccount) => accountIdEqual(owner, nameWrapperAccount)
|
|
1886
|
+
);
|
|
1887
|
+
if (hasNameWrapperOwnership) {
|
|
1888
|
+
return {
|
|
1889
|
+
ownershipType: NameTokenOwnershipTypes.NameWrapper,
|
|
1890
|
+
owner
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
if (isAddressEqual2(owner.address, zeroAddress)) {
|
|
1894
|
+
return {
|
|
1895
|
+
ownershipType: NameTokenOwnershipTypes.Burned,
|
|
1896
|
+
owner
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
const parentName = getParentNameFQDN(name);
|
|
1900
|
+
if (parentName === "eth") {
|
|
1901
|
+
return {
|
|
1902
|
+
ownershipType: NameTokenOwnershipTypes.FullyOnchain,
|
|
1903
|
+
owner
|
|
1904
|
+
};
|
|
1905
|
+
}
|
|
1973
1906
|
return {
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
expiresAt: registrationLifecycle.expiresAt
|
|
1907
|
+
ownershipType: NameTokenOwnershipTypes.Unknown,
|
|
1908
|
+
owner
|
|
1977
1909
|
};
|
|
1978
1910
|
}
|
|
1979
1911
|
|
|
1980
|
-
// src/
|
|
1981
|
-
var
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1912
|
+
// src/tokenscope/zod-schemas.ts
|
|
1913
|
+
var makeAssetIdSchema = (valueLabel = "Asset ID Schema") => z6.object({
|
|
1914
|
+
assetNamespace: z6.enum(AssetNamespaces),
|
|
1915
|
+
contract: makeAccountIdSchema(valueLabel),
|
|
1916
|
+
tokenId: z6.preprocess((v) => typeof v === "string" ? BigInt(v) : v, z6.bigint().positive())
|
|
1917
|
+
});
|
|
1918
|
+
var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => z6.preprocess((v) => {
|
|
1919
|
+
if (typeof v === "string") {
|
|
1920
|
+
const result = new CaipAssetId(v);
|
|
1921
|
+
return {
|
|
1922
|
+
assetNamespace: result.assetName.namespace,
|
|
1923
|
+
contract: {
|
|
1924
|
+
chainId: Number(result.chainId.reference),
|
|
1925
|
+
address: result.assetName.reference
|
|
1926
|
+
},
|
|
1927
|
+
tokenId: result.tokenId
|
|
1928
|
+
};
|
|
1929
|
+
}
|
|
1930
|
+
return v;
|
|
1931
|
+
}, makeAssetIdSchema(valueLabel));
|
|
1932
|
+
function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
|
|
1933
|
+
const ownership = ctx.value;
|
|
1934
|
+
if (ctx.value.owner.address === zeroAddress2) {
|
|
1935
|
+
ctx.issues.push({
|
|
1936
|
+
code: "custom",
|
|
1937
|
+
input: ctx.value,
|
|
1938
|
+
message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' other than the zero address.`
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
var makeNameTokenOwnershipNameWrapperSchema = (valueLabel = "Name Token Ownership NameWrapper") => z6.object({
|
|
1943
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.NameWrapper),
|
|
1944
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
1945
|
+
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
1946
|
+
var makeNameTokenOwnershipFullyOnchainSchema = (valueLabel = "Name Token Ownership Fully Onchain") => z6.object({
|
|
1947
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.FullyOnchain),
|
|
1948
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
1949
|
+
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
1950
|
+
var makeNameTokenOwnershipBurnedSchema = (valueLabel = "Name Token Ownership Burned") => z6.object({
|
|
1951
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.Burned),
|
|
1952
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
1953
|
+
}).check(invariant_nameTokenOwnershipHasZeroAddressOwner);
|
|
1954
|
+
var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Unknown") => z6.object({
|
|
1955
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.Unknown),
|
|
1956
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
1957
|
+
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
1958
|
+
function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
|
|
1959
|
+
const ownership = ctx.value;
|
|
1960
|
+
if (ctx.value.owner.address !== zeroAddress2) {
|
|
1961
|
+
ctx.issues.push({
|
|
1962
|
+
code: "custom",
|
|
1963
|
+
input: ctx.value,
|
|
1964
|
+
message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' set to the zero address.`
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
var makeNameTokenOwnershipSchema = (valueLabel = "Name Token Ownership") => z6.discriminatedUnion("ownershipType", [
|
|
1969
|
+
makeNameTokenOwnershipNameWrapperSchema(valueLabel),
|
|
1970
|
+
makeNameTokenOwnershipFullyOnchainSchema(valueLabel),
|
|
1971
|
+
makeNameTokenOwnershipBurnedSchema(valueLabel),
|
|
1972
|
+
makeNameTokenOwnershipUnknownSchema(valueLabel)
|
|
1973
|
+
]);
|
|
1974
|
+
var makeNameTokenSchema = (valueLabel = "Name Token Schema") => z6.object({
|
|
1975
|
+
token: makeAssetIdSchema(`${valueLabel}.token`),
|
|
1976
|
+
ownership: makeNameTokenOwnershipSchema(`${valueLabel}.ownership`),
|
|
1977
|
+
mintStatus: z6.enum(NFTMintStatuses)
|
|
1978
|
+
});
|
|
1979
|
+
|
|
1980
|
+
// src/tokenscope/assets.ts
|
|
1981
|
+
var AssetNamespaces = {
|
|
1982
|
+
ERC721: "erc721",
|
|
1983
|
+
ERC1155: "erc1155"
|
|
1984
|
+
};
|
|
1985
|
+
function serializeAssetId(assetId) {
|
|
1986
|
+
return {
|
|
1987
|
+
assetNamespace: assetId.assetNamespace,
|
|
1988
|
+
contract: assetId.contract,
|
|
1989
|
+
tokenId: uint256ToHex32(assetId.tokenId)
|
|
1990
|
+
};
|
|
1991
|
+
}
|
|
1992
|
+
function deserializeAssetId(maybeAssetId, valueLabel) {
|
|
1993
|
+
const schema = makeAssetIdSchema(valueLabel);
|
|
1994
|
+
const parsed = schema.safeParse(maybeAssetId);
|
|
1995
|
+
if (parsed.error) {
|
|
1996
|
+
throw new RangeError(`Cannot deserialize AssetId:
|
|
1997
|
+
${prettifyError6(parsed.error)}
|
|
1998
|
+
`);
|
|
1999
|
+
}
|
|
2000
|
+
return parsed.data;
|
|
2001
|
+
}
|
|
2002
|
+
function formatAssetId(assetId) {
|
|
2003
|
+
const { assetNamespace, contract, tokenId } = serializeAssetId(assetId);
|
|
2004
|
+
return CaipAssetId2.format({
|
|
2005
|
+
chainId: { namespace: "eip155", reference: contract.chainId.toString() },
|
|
2006
|
+
assetName: { namespace: assetNamespace, reference: contract.address },
|
|
2007
|
+
tokenId
|
|
2008
|
+
}).toLowerCase();
|
|
2009
|
+
}
|
|
2010
|
+
function parseAssetId(maybeAssetId, valueLabel) {
|
|
2011
|
+
const schema = makeAssetIdStringSchema(valueLabel);
|
|
2012
|
+
const parsed = schema.safeParse(maybeAssetId);
|
|
2013
|
+
if (parsed.error) {
|
|
2014
|
+
throw new RangeError(`Cannot parse AssetId:
|
|
2015
|
+
${prettifyError6(parsed.error)}
|
|
2016
|
+
`);
|
|
2017
|
+
}
|
|
2018
|
+
return parsed.data;
|
|
2019
|
+
}
|
|
2020
|
+
var buildAssetId = (contract, tokenId, assetNamespace) => {
|
|
2021
|
+
return {
|
|
2022
|
+
assetNamespace,
|
|
2023
|
+
contract,
|
|
2024
|
+
tokenId
|
|
2025
|
+
};
|
|
2026
|
+
};
|
|
2027
|
+
function serializeDomainAssetId(domainAsset) {
|
|
2028
|
+
return {
|
|
2029
|
+
...serializeAssetId(domainAsset),
|
|
2030
|
+
domainId: domainAsset.domainId
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
2033
|
+
var NFTMintStatuses = {
|
|
2034
|
+
Minted: "minted",
|
|
2035
|
+
Burned: "burned"
|
|
2036
|
+
};
|
|
2037
|
+
var formatNFTTransferEventMetadata = (metadata) => {
|
|
2038
|
+
const serializedAssetId = serializeAssetId(metadata.nft);
|
|
2039
|
+
return [
|
|
2040
|
+
`Event: ${metadata.eventHandlerName}`,
|
|
2041
|
+
`Chain ID: ${metadata.chainId}`,
|
|
2042
|
+
`Block Number: ${metadata.blockNumber}`,
|
|
2043
|
+
`Transaction Hash: ${metadata.transactionHash}`,
|
|
2044
|
+
`NFT: ${serializedAssetId}`
|
|
2045
|
+
].map((line) => ` - ${line}`).join("\n");
|
|
2046
|
+
};
|
|
2047
|
+
var NFTTransferTypes = {
|
|
2048
|
+
/**
|
|
2049
|
+
* Initial transfer from zeroAddress to a non-zeroAddress
|
|
2050
|
+
* Can happen at most once to a NFT AssetId
|
|
2051
|
+
*
|
|
2052
|
+
* Invariants:
|
|
2053
|
+
* - NFT is not indexed and therefore has no previous mint status or owner
|
|
2054
|
+
* - new NFT mint status is `minted`
|
|
2055
|
+
* - new NFT owner is a non-zeroAddress
|
|
2056
|
+
*/
|
|
2057
|
+
Mint: "mint",
|
|
2058
|
+
/**
|
|
2059
|
+
* Subsequent transfer from zeroAddress to a non-zeroAddress
|
|
2060
|
+
* Can happen any number of times to a NFT AssetId as it passes in a cycle from
|
|
2061
|
+
* mint -> burn -> remint -> burn -> remint -> ...
|
|
2062
|
+
*
|
|
2063
|
+
* Invariants:
|
|
2064
|
+
* - NFT is indexed
|
|
2065
|
+
* - previous NFT mint status was `burned`
|
|
2066
|
+
* - previous NFT owner is the zeroAddress
|
|
2067
|
+
* - new NFT mint status is `minted`
|
|
2068
|
+
* - new NFT owner is a non-zeroAddress
|
|
2069
|
+
*/
|
|
2070
|
+
Remint: "remint",
|
|
2071
|
+
/**
|
|
2072
|
+
* Special transfer type for improperly implemented NFT contracts that allow a NFT
|
|
2073
|
+
* that is currently minted to be reminted before an intermediate burn.
|
|
2074
|
+
*
|
|
2075
|
+
* Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
|
|
2076
|
+
* previously indexed nft had status `minted` with a non-zeroAddress owner.
|
|
2077
|
+
*
|
|
2078
|
+
* Invariants:
|
|
2079
|
+
* - NFT is indexed
|
|
2080
|
+
* - previous NFT mint status was `minted`
|
|
2081
|
+
* - previous NFT owner was a non-zeroAddress
|
|
2082
|
+
* - new NFT mint status is `minted`
|
|
2083
|
+
* - new NFT owner is a non-zeroAddress
|
|
2084
|
+
*/
|
|
2085
|
+
MintedRemint: "minted-remint",
|
|
2086
|
+
/**
|
|
2087
|
+
* Transfer from a non-zeroAddress to zeroAddress
|
|
2088
|
+
*
|
|
2089
|
+
* Invariants:
|
|
2090
|
+
* - NFT is indexed
|
|
2091
|
+
* - previous NFT mint status was `minted`
|
|
2092
|
+
* - previous NFT owner is a non-zeroAddress
|
|
2093
|
+
* - new NFT mint status is `burned`
|
|
2094
|
+
* - new NFT owner is the zeroAddress
|
|
2095
|
+
*/
|
|
2096
|
+
Burn: "burn",
|
|
2097
|
+
/**
|
|
2098
|
+
* Transfer from a non-zeroAddress to a distinct non-zeroAddress
|
|
2099
|
+
*
|
|
2100
|
+
* Invariants:
|
|
2101
|
+
* - NFT is indexed
|
|
2102
|
+
* - previous and new NFT mint status is `minted`
|
|
2103
|
+
* - previous and new NFT owner are distinct non-zeroAddress
|
|
2104
|
+
*/
|
|
2105
|
+
Transfer: "transfer",
|
|
2106
|
+
/**
|
|
2107
|
+
* Transfer from a non-zeroAddress to the same non-zeroAddress
|
|
2108
|
+
*
|
|
2109
|
+
* Invariants:
|
|
2110
|
+
* - NFT is indexed
|
|
2111
|
+
* - previous and new NFT mint status is `minted`
|
|
2112
|
+
* - previous and new NFT owner are equivalent non-zeroAddress
|
|
2113
|
+
*/
|
|
2114
|
+
SelfTransfer: "self-transfer",
|
|
2115
|
+
/**
|
|
2116
|
+
* Transfer from zeroAddress to zeroAddress for an indexed NFT
|
|
2117
|
+
*
|
|
2118
|
+
* Invariants:
|
|
2119
|
+
* - NFT is indexed
|
|
2120
|
+
* - previous and new NFT mint status is `burned`
|
|
2121
|
+
* - previous and new NFT owner are zeroAddress
|
|
2122
|
+
*/
|
|
2123
|
+
RemintBurn: "remint-burn",
|
|
2124
|
+
/**
|
|
2125
|
+
* Special transfer type for improperly implemented NFT contracts that allow a NFT
|
|
2126
|
+
* that is currently minted to be reminted again before an intermediate burn.
|
|
2127
|
+
*
|
|
2128
|
+
* Transfer from zeroAddress to zeroAddress for an indexed NFT where the
|
|
2129
|
+
* previously indexed nft had status `minted` with a non-zeroAddress owner.
|
|
2130
|
+
*
|
|
2131
|
+
* Invariants:
|
|
2132
|
+
* - NFT is indexed
|
|
2133
|
+
* - previous NFT mint status was `minted`
|
|
2134
|
+
* - previous NFT owner was a non-zeroAddress
|
|
2135
|
+
* - new NFT mint status is `burned`
|
|
2136
|
+
* - new NFT owner is the zeroAddress
|
|
2137
|
+
*/
|
|
2138
|
+
MintedRemintBurn: "minted-remint-burn",
|
|
2139
|
+
/**
|
|
2140
|
+
* Transfer from zeroAddress to zeroAddress for an unindexed NFT
|
|
2141
|
+
*
|
|
2142
|
+
* Invariants:
|
|
2143
|
+
* - NFT is not indexed and therefore has no previous mint status or owner
|
|
2144
|
+
* - NFT should remain unindexed and without any mint status or owner
|
|
2145
|
+
*/
|
|
2146
|
+
MintBurn: "mint-burn"
|
|
2147
|
+
};
|
|
2148
|
+
var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
|
|
2149
|
+
const isIndexed = currentlyIndexedOwner !== void 0;
|
|
2150
|
+
const isIndexedAsMinted = isIndexed && !isAddressEqual3(currentlyIndexedOwner, zeroAddress3);
|
|
2151
|
+
const isMint = isAddressEqual3(from, zeroAddress3);
|
|
2152
|
+
const isBurn = isAddressEqual3(to, zeroAddress3);
|
|
2153
|
+
const isSelfTransfer = isAddressEqual3(from, to);
|
|
2154
|
+
if (isIndexed && !isAddressEqual3(currentlyIndexedOwner, from)) {
|
|
2155
|
+
if (isMint && allowMintedRemint) {
|
|
2156
|
+
} else {
|
|
2157
|
+
throw new Error(
|
|
2158
|
+
`Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
|
|
2159
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2160
|
+
);
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
if (isSelfTransfer) {
|
|
2164
|
+
if (isMint) {
|
|
2165
|
+
if (!isIndexed) {
|
|
2166
|
+
return NFTTransferTypes.MintBurn;
|
|
2167
|
+
} else if (!isIndexedAsMinted) {
|
|
2168
|
+
return NFTTransferTypes.RemintBurn;
|
|
2169
|
+
} else if (allowMintedRemint) {
|
|
2170
|
+
return NFTTransferTypes.MintedRemintBurn;
|
|
2171
|
+
} else {
|
|
2172
|
+
throw new Error(
|
|
2173
|
+
`Error: Invalid state transition from minted -> remint-burn
|
|
2174
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2175
|
+
);
|
|
2176
|
+
}
|
|
2177
|
+
} else {
|
|
2178
|
+
if (!isIndexed) {
|
|
2179
|
+
throw new Error(
|
|
2180
|
+
`Error: Invalid state transition from unindexed -> self-transfer
|
|
2181
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2182
|
+
);
|
|
2183
|
+
} else if (!isIndexedAsMinted) {
|
|
2184
|
+
throw new Error(
|
|
2185
|
+
`Error: invalid state transition from burned -> self-transfer
|
|
2186
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2187
|
+
);
|
|
2188
|
+
} else {
|
|
2189
|
+
return NFTTransferTypes.SelfTransfer;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
} else if (isMint) {
|
|
2193
|
+
if (!isIndexed) {
|
|
2194
|
+
return NFTTransferTypes.Mint;
|
|
2195
|
+
} else if (!isIndexedAsMinted) {
|
|
2196
|
+
return NFTTransferTypes.Remint;
|
|
2197
|
+
} else if (allowMintedRemint) {
|
|
2198
|
+
return NFTTransferTypes.MintedRemint;
|
|
2199
|
+
} else {
|
|
2200
|
+
throw new Error(
|
|
2201
|
+
`Error: Invalid state transition from minted -> mint
|
|
2202
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2205
|
+
} else if (isBurn) {
|
|
2206
|
+
if (!isIndexed) {
|
|
2207
|
+
throw new Error(
|
|
2208
|
+
`Error: Invalid state transition from unindexed -> burn
|
|
2209
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2210
|
+
);
|
|
2211
|
+
} else if (!isIndexedAsMinted) {
|
|
2212
|
+
throw new Error(
|
|
2213
|
+
`Error: Invalid state transition from burned -> burn
|
|
2214
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2215
|
+
);
|
|
2216
|
+
} else {
|
|
2217
|
+
return NFTTransferTypes.Burn;
|
|
2218
|
+
}
|
|
2219
|
+
} else {
|
|
2220
|
+
if (!isIndexed) {
|
|
2221
|
+
throw new Error(
|
|
2222
|
+
`Error: Invalid state transition from unindexed -> transfer
|
|
2223
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2224
|
+
);
|
|
2225
|
+
} else if (!isIndexedAsMinted) {
|
|
2226
|
+
throw new Error(
|
|
2227
|
+
`Error: Invalid state transition from burned -> transfer
|
|
2228
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2229
|
+
);
|
|
2230
|
+
} else {
|
|
2231
|
+
return NFTTransferTypes.Transfer;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
};
|
|
2235
|
+
|
|
2236
|
+
// src/api/shared/errors/zod-schemas.ts
|
|
2237
|
+
import z7 from "zod/v4";
|
|
2238
|
+
var ErrorResponseSchema = z7.object({
|
|
2239
|
+
message: z7.string(),
|
|
2240
|
+
details: z7.optional(z7.unknown())
|
|
2241
|
+
});
|
|
2242
|
+
|
|
2243
|
+
// src/api/name-tokens/response.ts
|
|
2244
|
+
var NameTokensResponseCodes = {
|
|
2245
|
+
/**
|
|
2246
|
+
* Represents a response when Name Tokens API can respond with requested data.
|
|
2247
|
+
*/
|
|
2248
|
+
Ok: "ok",
|
|
2249
|
+
/**
|
|
2250
|
+
* Represents a response when Name Tokens API could not respond with requested data.
|
|
2251
|
+
*/
|
|
2252
|
+
Error: "error"
|
|
2253
|
+
};
|
|
2254
|
+
var NameTokensResponseErrorCodes = {
|
|
2255
|
+
/**
|
|
2256
|
+
* Name tokens not indexed
|
|
2257
|
+
*
|
|
2258
|
+
* Represents an error when tokens for the requested name are not indexed by
|
|
2259
|
+
* the ENSNode instance's configuration.
|
|
2260
|
+
*/
|
|
2261
|
+
NameTokensNotIndexed: "name-tokens-not-indexed",
|
|
2262
|
+
/**
|
|
2263
|
+
* Unsupported ENSIndexer Config
|
|
2264
|
+
*
|
|
2265
|
+
* Represents a prerequisites error when connected ENSIndexer config lacks
|
|
2266
|
+
* params required to enable Name Tokens API.
|
|
2267
|
+
*/
|
|
2268
|
+
EnsIndexerConfigUnsupported: "unsupported-ensindexer-config",
|
|
2269
|
+
/**
|
|
2270
|
+
* Unsupported Indexing Status
|
|
2271
|
+
*
|
|
2272
|
+
* Represents a prerequisites error when Indexing Status has not yet reached
|
|
2273
|
+
* status required to enable Name Tokens API.
|
|
2274
|
+
*/
|
|
2275
|
+
IndexingStatusUnsupported: "unsupported-indexing-status"
|
|
2276
|
+
};
|
|
2277
|
+
|
|
2278
|
+
// src/api/name-tokens/zod-schemas.ts
|
|
2279
|
+
function invariant_nameIsAssociatedWithDomainId(ctx) {
|
|
2280
|
+
const { name, domainId } = ctx.value;
|
|
2281
|
+
if (namehash2(name) !== domainId) {
|
|
2282
|
+
ctx.issues.push({
|
|
2283
|
+
code: "custom",
|
|
2284
|
+
input: ctx.value,
|
|
2285
|
+
message: `'name' must be associated with 'domainId': ${domainId}`
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
function invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown(ctx) {
|
|
2290
|
+
const { tokens } = ctx.value;
|
|
2291
|
+
const containsOwnershipNameWrapper = tokens.some(
|
|
2292
|
+
(t) => t.ownership.ownershipType === NameTokenOwnershipTypes.NameWrapper
|
|
2293
|
+
);
|
|
2294
|
+
const containsOwnershipFullyOnchainOrUnknown = tokens.some(
|
|
2295
|
+
(t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain || t.ownership.ownershipType === NameTokenOwnershipTypes.Unknown
|
|
2296
|
+
);
|
|
2297
|
+
if (containsOwnershipNameWrapper && !containsOwnershipFullyOnchainOrUnknown) {
|
|
2298
|
+
ctx.issues.push({
|
|
2299
|
+
code: "custom",
|
|
2300
|
+
input: ctx.value,
|
|
2301
|
+
message: `'tokens' must contain name token with ownership type 'fully-onchain' or 'unknown' when name token with ownership type 'namewrapper' in listed`
|
|
2302
|
+
});
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
function invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective(ctx) {
|
|
2306
|
+
const { tokens } = ctx.value;
|
|
2307
|
+
const tokensCountWithOwnershipFullyOnchain = tokens.filter(
|
|
2308
|
+
(t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain
|
|
2309
|
+
).length;
|
|
2310
|
+
if (tokensCountWithOwnershipFullyOnchain > 1) {
|
|
2311
|
+
ctx.issues.push({
|
|
2312
|
+
code: "custom",
|
|
2313
|
+
input: ctx.value,
|
|
2314
|
+
message: `'tokens' must contain at most one name token with ownership type 'fully-onchain', current count: ${tokensCountWithOwnershipFullyOnchain}`
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
var makeRegisteredNameTokenSchema = (valueLabel = "Registered Name Token") => z8.object({
|
|
2319
|
+
domainId: makeNodeSchema(`${valueLabel}.domainId`),
|
|
2320
|
+
name: makeReinterpretedNameSchema(valueLabel),
|
|
2321
|
+
tokens: z8.array(makeNameTokenSchema(`${valueLabel}.tokens`)).nonempty(),
|
|
2322
|
+
expiresAt: makeUnixTimestampSchema(`${valueLabel}.expiresAt`),
|
|
2323
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
2324
|
+
}).check(invariant_nameIsAssociatedWithDomainId).check(invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective).check(invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown);
|
|
2325
|
+
var makeNameTokensResponseOkSchema = (valueLabel = "Name Tokens Response OK") => z8.strictObject({
|
|
2326
|
+
responseCode: z8.literal(NameTokensResponseCodes.Ok),
|
|
2327
|
+
registeredNameTokens: makeRegisteredNameTokenSchema(`${valueLabel}.nameTokens`)
|
|
2328
|
+
});
|
|
2329
|
+
var makeNameTokensResponseErrorNameTokensNotIndexedSchema = (_valueLabel = "Name Tokens Response Error Name Not Indexed") => z8.strictObject({
|
|
2330
|
+
responseCode: z8.literal(NameTokensResponseCodes.Error),
|
|
2331
|
+
errorCode: z8.literal(NameTokensResponseErrorCodes.NameTokensNotIndexed),
|
|
2332
|
+
error: ErrorResponseSchema
|
|
2333
|
+
});
|
|
2334
|
+
var makeNameTokensResponseErrorEnsIndexerConfigUnsupported = (_valueLabel = "Name Tokens Response Error ENSIndexer Config Unsupported") => z8.strictObject({
|
|
2335
|
+
responseCode: z8.literal(NameTokensResponseCodes.Error),
|
|
2336
|
+
errorCode: z8.literal(NameTokensResponseErrorCodes.EnsIndexerConfigUnsupported),
|
|
2337
|
+
error: ErrorResponseSchema
|
|
2338
|
+
});
|
|
2339
|
+
var makeNameTokensResponseErrorNameIndexingStatusUnsupported = (_valueLabel = "Name Tokens Response Error Indexing Status Unsupported") => z8.strictObject({
|
|
2340
|
+
responseCode: z8.literal(NameTokensResponseCodes.Error),
|
|
2341
|
+
errorCode: z8.literal(NameTokensResponseErrorCodes.IndexingStatusUnsupported),
|
|
2342
|
+
error: ErrorResponseSchema
|
|
2343
|
+
});
|
|
2344
|
+
var makeNameTokensResponseErrorSchema = (valueLabel = "Name Tokens Response Error") => z8.discriminatedUnion("errorCode", [
|
|
2345
|
+
makeNameTokensResponseErrorNameTokensNotIndexedSchema(valueLabel),
|
|
2346
|
+
makeNameTokensResponseErrorEnsIndexerConfigUnsupported(valueLabel),
|
|
2347
|
+
makeNameTokensResponseErrorNameIndexingStatusUnsupported(valueLabel)
|
|
2348
|
+
]);
|
|
2349
|
+
var makeNameTokensResponseSchema = (valueLabel = "Name Tokens Response") => z8.discriminatedUnion("responseCode", [
|
|
2350
|
+
makeNameTokensResponseOkSchema(valueLabel),
|
|
2351
|
+
makeNameTokensResponseErrorSchema(valueLabel)
|
|
2352
|
+
]);
|
|
2353
|
+
|
|
2354
|
+
// src/api/name-tokens/deserialize.ts
|
|
2355
|
+
function deserializedNameTokensResponse(maybeResponse) {
|
|
2356
|
+
const parsed = makeNameTokensResponseSchema().safeParse(maybeResponse);
|
|
2357
|
+
if (parsed.error) {
|
|
2358
|
+
throw new Error(`Cannot deserialize NameTokensResponse:
|
|
2359
|
+
${prettifyError7(parsed.error)}
|
|
2360
|
+
`);
|
|
2361
|
+
}
|
|
2362
|
+
return parsed.data;
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
// src/api/name-tokens/prerequisites.ts
|
|
2366
|
+
var nameTokensPrerequisites = Object.freeze({
|
|
2367
|
+
/**
|
|
2368
|
+
* Required plugins to enable Name Tokens API routes.
|
|
2369
|
+
*
|
|
2370
|
+
* 1. `registrars` plugin is required so that data in the `registrationLifecycles`
|
|
2371
|
+
* table is populated.
|
|
2372
|
+
* 2. `tokenscope` plugin is required so that data in the `nameTokens`
|
|
2373
|
+
* table is populated.
|
|
2374
|
+
*/
|
|
2375
|
+
requiredPlugins: ["registrars" /* Registrars */, "tokenscope" /* TokenScope */],
|
|
2376
|
+
/**
|
|
2377
|
+
* Check if provided ENSApiPublicConfig supports the Name Tokens API.
|
|
2378
|
+
*/
|
|
2379
|
+
hasEnsIndexerConfigSupport(config) {
|
|
2380
|
+
return nameTokensPrerequisites.requiredPlugins.every(
|
|
2381
|
+
(plugin) => config.plugins.includes(plugin)
|
|
2382
|
+
);
|
|
2383
|
+
},
|
|
2384
|
+
/**
|
|
2385
|
+
* Required Indexing Status IDs
|
|
2386
|
+
*
|
|
2387
|
+
* Database indexes are created by the time the omnichain indexing status
|
|
2388
|
+
* is either `completed` or `following`.
|
|
2389
|
+
*/
|
|
2390
|
+
supportedIndexingStatusIds: [
|
|
2391
|
+
OmnichainIndexingStatusIds.Completed,
|
|
2392
|
+
OmnichainIndexingStatusIds.Following
|
|
2393
|
+
],
|
|
2394
|
+
/**
|
|
2395
|
+
* Check if provided indexing status supports the Name Tokens API.
|
|
2396
|
+
*/
|
|
2397
|
+
hasIndexingStatusSupport(omnichainIndexingStatusId) {
|
|
2398
|
+
return nameTokensPrerequisites.supportedIndexingStatusIds.some(
|
|
2399
|
+
(supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
|
|
2400
|
+
);
|
|
2401
|
+
}
|
|
2402
|
+
});
|
|
2403
|
+
|
|
2404
|
+
// src/api/name-tokens/serialize.ts
|
|
2405
|
+
function serializeRegisteredNameTokens({
|
|
2406
|
+
domainId,
|
|
2407
|
+
name,
|
|
2408
|
+
tokens,
|
|
2409
|
+
expiresAt,
|
|
2410
|
+
accurateAsOf
|
|
2411
|
+
}) {
|
|
2412
|
+
return {
|
|
2413
|
+
domainId,
|
|
2414
|
+
name,
|
|
2415
|
+
tokens: tokens.map(serializeNameToken),
|
|
2416
|
+
expiresAt,
|
|
2417
|
+
accurateAsOf
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
function serializeNameTokensResponse(response) {
|
|
2421
|
+
switch (response.responseCode) {
|
|
2422
|
+
case NameTokensResponseCodes.Ok:
|
|
2423
|
+
return {
|
|
2424
|
+
responseCode: response.responseCode,
|
|
2425
|
+
registeredNameTokens: serializeRegisteredNameTokens(response.registeredNameTokens)
|
|
2426
|
+
};
|
|
2427
|
+
case NameTokensResponseCodes.Error:
|
|
2428
|
+
return response;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
// src/api/registrar-actions/deserialize.ts
|
|
2433
|
+
import { prettifyError as prettifyError8 } from "zod/v4";
|
|
2434
|
+
|
|
2435
|
+
// src/api/registrar-actions/zod-schemas.ts
|
|
2436
|
+
import { namehash as namehash3 } from "viem/ens";
|
|
2437
|
+
import z11 from "zod/v4";
|
|
2438
|
+
|
|
2439
|
+
// ../ens-referrals/src/address.ts
|
|
2440
|
+
import { isAddress as isAddress3 } from "viem";
|
|
2441
|
+
|
|
2442
|
+
// ../ens-referrals/src/encoding.ts
|
|
2443
|
+
import { getAddress, pad, size as size2, slice, zeroAddress as zeroAddress4 } from "viem";
|
|
2444
|
+
var ENCODED_REFERRER_BYTE_OFFSET = 12;
|
|
2445
|
+
var ENCODED_REFERRER_BYTE_LENGTH = 32;
|
|
2446
|
+
var EXPECTED_ENCODED_REFERRER_PADDING = pad("0x", {
|
|
2447
|
+
size: ENCODED_REFERRER_BYTE_OFFSET,
|
|
2448
|
+
dir: "left"
|
|
2449
|
+
});
|
|
2450
|
+
var ZERO_ENCODED_REFERRER = pad("0x", {
|
|
2451
|
+
size: ENCODED_REFERRER_BYTE_LENGTH,
|
|
2452
|
+
dir: "left"
|
|
2453
|
+
});
|
|
2454
|
+
function decodeEncodedReferrer(encodedReferrer) {
|
|
2455
|
+
if (size2(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
|
|
2456
|
+
throw new Error(
|
|
2457
|
+
`Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
const padding = slice(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
|
|
2461
|
+
if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
|
|
2462
|
+
return zeroAddress4;
|
|
2463
|
+
}
|
|
2464
|
+
const decodedReferrer = slice(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
|
|
2465
|
+
try {
|
|
2466
|
+
return getAddress(decodedReferrer);
|
|
2467
|
+
} catch {
|
|
2468
|
+
throw new Error(`Decoded referrer value must be a valid EVM address.`);
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
// ../ens-referrals/src/leaderboard-page.ts
|
|
2473
|
+
var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
|
|
2474
|
+
|
|
2475
|
+
// ../ens-referrals/src/link.ts
|
|
2476
|
+
import { getAddress as getAddress2 } from "viem";
|
|
2477
|
+
|
|
2478
|
+
// ../ens-referrals/src/referrer-detail.ts
|
|
2479
|
+
var ReferrerDetailTypeIds = {
|
|
2480
|
+
/**
|
|
2481
|
+
* Represents a referrer who is ranked on the leaderboard.
|
|
2482
|
+
*/
|
|
2483
|
+
Ranked: "ranked",
|
|
2484
|
+
/**
|
|
2485
|
+
* Represents a referrer who is not ranked on the leaderboard.
|
|
2486
|
+
*/
|
|
2487
|
+
Unranked: "unranked"
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2490
|
+
// src/registrars/zod-schemas.ts
|
|
2491
|
+
import z9 from "zod/v4";
|
|
2492
|
+
|
|
2493
|
+
// src/registrars/registrar-action.ts
|
|
2494
|
+
var RegistrarActionTypes = {
|
|
2495
|
+
Registration: "registration",
|
|
2496
|
+
Renewal: "renewal"
|
|
2497
|
+
};
|
|
2498
|
+
function isRegistrarActionPricingAvailable(registrarActionPricing) {
|
|
2499
|
+
const { baseCost, premium, total } = registrarActionPricing;
|
|
2500
|
+
return baseCost !== null && premium !== null && total !== null;
|
|
2501
|
+
}
|
|
2502
|
+
function isRegistrarActionReferralAvailable(registrarActionReferral) {
|
|
2503
|
+
const { encodedReferrer, decodedReferrer } = registrarActionReferral;
|
|
2504
|
+
return encodedReferrer !== null && decodedReferrer !== null;
|
|
2505
|
+
}
|
|
1993
2506
|
function serializeRegistrarActionPricing(pricing) {
|
|
1994
2507
|
if (isRegistrarActionPricingAvailable(pricing)) {
|
|
1995
2508
|
return {
|
|
@@ -2006,7 +2519,7 @@ function serializeRegistrarAction(registrarAction) {
|
|
|
2006
2519
|
type: registrarAction.type,
|
|
2007
2520
|
incrementalDuration: registrarAction.incrementalDuration,
|
|
2008
2521
|
registrant: registrarAction.registrant,
|
|
2009
|
-
registrationLifecycle:
|
|
2522
|
+
registrationLifecycle: registrarAction.registrationLifecycle,
|
|
2010
2523
|
pricing: serializeRegistrarActionPricing(registrarAction.pricing),
|
|
2011
2524
|
referral: registrarAction.referral,
|
|
2012
2525
|
block: registrarAction.block,
|
|
@@ -2016,11 +2529,11 @@ function serializeRegistrarAction(registrarAction) {
|
|
|
2016
2529
|
}
|
|
2017
2530
|
|
|
2018
2531
|
// src/registrars/zod-schemas.ts
|
|
2019
|
-
var makeSubregistrySchema = (valueLabel = "Subregistry") =>
|
|
2020
|
-
subregistryId:
|
|
2532
|
+
var makeSubregistrySchema = (valueLabel = "Subregistry") => z9.object({
|
|
2533
|
+
subregistryId: makeAccountIdSchema(`${valueLabel} Subregistry ID`),
|
|
2021
2534
|
node: makeNodeSchema(`${valueLabel} Node`)
|
|
2022
2535
|
});
|
|
2023
|
-
var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") =>
|
|
2536
|
+
var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => z9.object({
|
|
2024
2537
|
subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
|
|
2025
2538
|
node: makeNodeSchema(`${valueLabel} Node`),
|
|
2026
2539
|
expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
|
|
@@ -2036,18 +2549,18 @@ function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
|
|
|
2036
2549
|
});
|
|
2037
2550
|
}
|
|
2038
2551
|
}
|
|
2039
|
-
var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") =>
|
|
2552
|
+
var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => z9.union([
|
|
2040
2553
|
// pricing available
|
|
2041
|
-
|
|
2554
|
+
z9.object({
|
|
2042
2555
|
baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
|
|
2043
2556
|
premium: makePriceEthSchema(`${valueLabel} Premium`),
|
|
2044
2557
|
total: makePriceEthSchema(`${valueLabel} Total`)
|
|
2045
2558
|
}).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
|
|
2046
2559
|
// pricing unknown
|
|
2047
|
-
|
|
2048
|
-
baseCost:
|
|
2049
|
-
premium:
|
|
2050
|
-
total:
|
|
2560
|
+
z9.object({
|
|
2561
|
+
baseCost: z9.null(),
|
|
2562
|
+
premium: z9.null(),
|
|
2563
|
+
total: z9.null()
|
|
2051
2564
|
}).transform((v) => v)
|
|
2052
2565
|
]);
|
|
2053
2566
|
function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
|
|
@@ -2070,9 +2583,9 @@ function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
|
|
|
2070
2583
|
});
|
|
2071
2584
|
}
|
|
2072
2585
|
}
|
|
2073
|
-
var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") =>
|
|
2586
|
+
var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => z9.union([
|
|
2074
2587
|
// referral available
|
|
2075
|
-
|
|
2588
|
+
z9.object({
|
|
2076
2589
|
encodedReferrer: makeHexStringSchema(
|
|
2077
2590
|
{ bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
|
|
2078
2591
|
`${valueLabel} Encoded Referrer`
|
|
@@ -2080,9 +2593,9 @@ var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral
|
|
|
2080
2593
|
decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
|
|
2081
2594
|
}).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
|
|
2082
2595
|
// referral not applicable
|
|
2083
|
-
|
|
2084
|
-
encodedReferrer:
|
|
2085
|
-
decodedReferrer:
|
|
2596
|
+
z9.object({
|
|
2597
|
+
encodedReferrer: z9.null(),
|
|
2598
|
+
decodedReferrer: z9.null()
|
|
2086
2599
|
})
|
|
2087
2600
|
]);
|
|
2088
2601
|
function invariant_eventIdsInitialElementIsTheActionId(ctx) {
|
|
@@ -2095,9 +2608,9 @@ function invariant_eventIdsInitialElementIsTheActionId(ctx) {
|
|
|
2095
2608
|
});
|
|
2096
2609
|
}
|
|
2097
2610
|
}
|
|
2098
|
-
var EventIdSchema =
|
|
2099
|
-
var EventIdsSchema =
|
|
2100
|
-
var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") =>
|
|
2611
|
+
var EventIdSchema = z9.string().nonempty();
|
|
2612
|
+
var EventIdsSchema = z9.array(EventIdSchema).min(1).transform((v) => v);
|
|
2613
|
+
var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z9.object({
|
|
2101
2614
|
id: EventIdSchema,
|
|
2102
2615
|
incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
|
|
2103
2616
|
registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
|
|
@@ -2111,168 +2624,135 @@ var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z8
|
|
|
2111
2624
|
eventIds: EventIdsSchema
|
|
2112
2625
|
}).check(invariant_eventIdsInitialElementIsTheActionId);
|
|
2113
2626
|
var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
2114
|
-
type:
|
|
2627
|
+
type: z9.literal(RegistrarActionTypes.Registration)
|
|
2115
2628
|
});
|
|
2116
2629
|
var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
2117
|
-
type:
|
|
2630
|
+
type: z9.literal(RegistrarActionTypes.Renewal)
|
|
2118
2631
|
});
|
|
2119
|
-
var makeRegistrarActionSchema = (valueLabel = "Registrar Action") =>
|
|
2632
|
+
var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => z9.discriminatedUnion("type", [
|
|
2120
2633
|
makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
|
|
2121
2634
|
makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
|
|
2122
2635
|
]);
|
|
2123
2636
|
|
|
2124
|
-
// src/shared/
|
|
2125
|
-
import
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
const
|
|
2149
|
-
|
|
2637
|
+
// src/api/shared/pagination/zod-schemas.ts
|
|
2638
|
+
import z10 from "zod/v4";
|
|
2639
|
+
|
|
2640
|
+
// src/api/shared/pagination/request.ts
|
|
2641
|
+
var RECORDS_PER_PAGE_DEFAULT = 10;
|
|
2642
|
+
var RECORDS_PER_PAGE_MAX = 100;
|
|
2643
|
+
|
|
2644
|
+
// src/api/shared/pagination/zod-schemas.ts
|
|
2645
|
+
var makeRequestPageParamsSchema = (valueLabel = "RequestPageParams") => z10.object({
|
|
2646
|
+
page: makePositiveIntegerSchema(`${valueLabel}.page`),
|
|
2647
|
+
recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
|
|
2648
|
+
RECORDS_PER_PAGE_MAX,
|
|
2649
|
+
`${valueLabel}.recordsPerPage must not exceed ${RECORDS_PER_PAGE_MAX}`
|
|
2650
|
+
)
|
|
2651
|
+
});
|
|
2652
|
+
var makeResponsePageContextSchemaWithNoRecords = (valueLabel = "ResponsePageContextWithNoRecords") => z10.object({
|
|
2653
|
+
totalRecords: z10.literal(0),
|
|
2654
|
+
totalPages: z10.literal(1),
|
|
2655
|
+
hasNext: z10.literal(false),
|
|
2656
|
+
hasPrev: z10.literal(false),
|
|
2657
|
+
startIndex: z10.undefined(),
|
|
2658
|
+
endIndex: z10.undefined()
|
|
2659
|
+
}).extend(makeRequestPageParamsSchema(valueLabel).shape);
|
|
2660
|
+
function invariant_responsePageWithRecordsIsCorrect(ctx) {
|
|
2661
|
+
const { hasNext, hasPrev, recordsPerPage, page, totalRecords, startIndex, endIndex } = ctx.value;
|
|
2662
|
+
const expectedHasNext = page * recordsPerPage < totalRecords;
|
|
2663
|
+
if (hasNext !== expectedHasNext) {
|
|
2150
2664
|
ctx.issues.push({
|
|
2151
2665
|
code: "custom",
|
|
2152
|
-
input:
|
|
2153
|
-
message: `
|
|
2666
|
+
input: ctx.value,
|
|
2667
|
+
message: `hasNext must be equal to '${expectedHasNext ? "true" : "false"}'`
|
|
2154
2668
|
});
|
|
2155
2669
|
}
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
const endpoints = ctx.value;
|
|
2159
|
-
const wsEndpoints = endpoints.filter(isWebSocketProtocol);
|
|
2160
|
-
if (wsEndpoints.length > 1) {
|
|
2670
|
+
const expectedHasPrev = page > 1;
|
|
2671
|
+
if (hasPrev !== expectedHasPrev) {
|
|
2161
2672
|
ctx.issues.push({
|
|
2162
2673
|
code: "custom",
|
|
2163
|
-
input:
|
|
2164
|
-
message: `
|
|
2674
|
+
input: ctx.value,
|
|
2675
|
+
message: `hasPrev must be equal to '${expectedHasPrev ? "true" : "false"}'`
|
|
2165
2676
|
});
|
|
2166
2677
|
}
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
var DatabaseSchemaNameSchema = z9.string({
|
|
2173
|
-
error: "DATABASE_SCHEMA is required."
|
|
2174
|
-
}).trim().min(1, {
|
|
2175
|
-
error: "DATABASE_SCHEMA is required and cannot be an empty string."
|
|
2176
|
-
});
|
|
2177
|
-
var RpcConfigSchema = z9.string().transform((val) => val.split(",")).pipe(z9.array(makeUrlSchema("RPC URL"))).check(invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL).check(invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL);
|
|
2178
|
-
var RpcConfigsSchema = z9.record(makeChainIdStringSchema("RPC URL"), RpcConfigSchema, {
|
|
2179
|
-
error: "Chains configuration must be an object mapping valid chain IDs to their configs."
|
|
2180
|
-
}).transform((records) => {
|
|
2181
|
-
const rpcConfigs = /* @__PURE__ */ new Map();
|
|
2182
|
-
for (const [chainIdString, rpcConfig] of Object.entries(records)) {
|
|
2183
|
-
const httpRPCs = rpcConfig.filter(isHttpProtocol);
|
|
2184
|
-
const websocketRPC = rpcConfig.find(isWebSocketProtocol);
|
|
2185
|
-
rpcConfigs.set(deserializeChainId(chainIdString), {
|
|
2186
|
-
httpRPCs,
|
|
2187
|
-
websocketRPC
|
|
2678
|
+
if (endIndex < startIndex) {
|
|
2679
|
+
ctx.issues.push({
|
|
2680
|
+
code: "custom",
|
|
2681
|
+
input: ctx.value,
|
|
2682
|
+
message: `endIndex must be greater than or equal to startIndex`
|
|
2188
2683
|
});
|
|
2189
2684
|
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
});
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
];
|
|
2211
|
-
|
|
2212
|
-
// src/shared/log-level.ts
|
|
2213
|
-
import { z as z10 } from "zod/v4";
|
|
2214
|
-
var LogLevelSchema = z10.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]);
|
|
2215
|
-
|
|
2216
|
-
// src/shared/protocol-acceleration/interpret-record-values.ts
|
|
2217
|
-
import { isAddress as isAddress4, isAddressEqual as isAddressEqual2, zeroAddress as zeroAddress2 } from "viem";
|
|
2685
|
+
if (endIndex >= totalRecords) {
|
|
2686
|
+
ctx.issues.push({
|
|
2687
|
+
code: "custom",
|
|
2688
|
+
input: ctx.value,
|
|
2689
|
+
message: `endIndex must be lower than totalRecords`
|
|
2690
|
+
});
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
var makeResponsePageContextSchemaWithRecords = (valueLabel = "ResponsePageContextWithRecords") => z10.object({
|
|
2694
|
+
totalRecords: makePositiveIntegerSchema(`${valueLabel}.totalRecords`),
|
|
2695
|
+
totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
|
|
2696
|
+
hasNext: z10.boolean(),
|
|
2697
|
+
hasPrev: z10.boolean(),
|
|
2698
|
+
startIndex: makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`),
|
|
2699
|
+
endIndex: makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`)
|
|
2700
|
+
}).extend(makeRequestPageParamsSchema(valueLabel).shape).check(invariant_responsePageWithRecordsIsCorrect);
|
|
2701
|
+
var makeResponsePageContextSchema = (valueLabel = "ResponsePageContext") => z10.union([
|
|
2702
|
+
makeResponsePageContextSchemaWithNoRecords(valueLabel),
|
|
2703
|
+
makeResponsePageContextSchemaWithRecords(valueLabel)
|
|
2704
|
+
]);
|
|
2218
2705
|
|
|
2219
|
-
// src/api/
|
|
2220
|
-
var
|
|
2706
|
+
// src/api/registrar-actions/response.ts
|
|
2707
|
+
var RegistrarActionsResponseCodes = {
|
|
2221
2708
|
/**
|
|
2222
|
-
* Represents that
|
|
2709
|
+
* Represents that Registrar Actions are available.
|
|
2223
2710
|
*/
|
|
2224
2711
|
Ok: "ok",
|
|
2225
2712
|
/**
|
|
2226
|
-
* Represents that
|
|
2713
|
+
* Represents that Registrar Actions are unavailable.
|
|
2227
2714
|
*/
|
|
2228
2715
|
Error: "error"
|
|
2229
2716
|
};
|
|
2230
2717
|
|
|
2231
|
-
// src/api/
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2718
|
+
// src/api/registrar-actions/zod-schemas.ts
|
|
2719
|
+
function invariant_registrationLifecycleNodeMatchesName(ctx) {
|
|
2720
|
+
const { name, action } = ctx.value;
|
|
2721
|
+
const expectedNode = action.registrationLifecycle.node;
|
|
2722
|
+
const actualNode = namehash3(name);
|
|
2723
|
+
if (actualNode !== expectedNode) {
|
|
2724
|
+
ctx.issues.push({
|
|
2725
|
+
code: "custom",
|
|
2726
|
+
input: ctx.value,
|
|
2727
|
+
message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
|
|
2728
|
+
});
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z11.object({
|
|
2732
|
+
action: makeRegistrarActionSchema(valueLabel),
|
|
2733
|
+
name: makeReinterpretedNameSchema(valueLabel)
|
|
2734
|
+
}).check(invariant_registrationLifecycleNodeMatchesName);
|
|
2735
|
+
var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z11.strictObject({
|
|
2736
|
+
responseCode: z11.literal(RegistrarActionsResponseCodes.Ok),
|
|
2737
|
+
registrarActions: z11.array(makeNamedRegistrarActionSchema(valueLabel)),
|
|
2738
|
+
pageContext: makeResponsePageContextSchema(`${valueLabel}.pageContext`)
|
|
2235
2739
|
});
|
|
2236
|
-
var
|
|
2237
|
-
responseCode: z11.literal(
|
|
2740
|
+
var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => z11.strictObject({
|
|
2741
|
+
responseCode: z11.literal(RegistrarActionsResponseCodes.Error),
|
|
2742
|
+
error: ErrorResponseSchema
|
|
2238
2743
|
});
|
|
2239
|
-
var
|
|
2240
|
-
|
|
2241
|
-
|
|
2744
|
+
var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => z11.discriminatedUnion("responseCode", [
|
|
2745
|
+
makeRegistrarActionsResponseOkSchema(valueLabel),
|
|
2746
|
+
makeRegistrarActionsResponseErrorSchema(valueLabel)
|
|
2242
2747
|
]);
|
|
2243
2748
|
|
|
2244
|
-
// src/api/indexing-status/deserialize.ts
|
|
2245
|
-
function deserializeIndexingStatusResponse(maybeResponse) {
|
|
2246
|
-
const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
|
|
2247
|
-
if (parsed.error) {
|
|
2248
|
-
throw new Error(`Cannot deserialize IndexingStatusResponse:
|
|
2249
|
-
${prettifyError5(parsed.error)}
|
|
2250
|
-
`);
|
|
2251
|
-
}
|
|
2252
|
-
return parsed.data;
|
|
2253
|
-
}
|
|
2254
|
-
|
|
2255
|
-
// src/api/indexing-status/serialize.ts
|
|
2256
|
-
function serializeIndexingStatusResponse(response) {
|
|
2257
|
-
switch (response.responseCode) {
|
|
2258
|
-
case IndexingStatusResponseCodes.Ok:
|
|
2259
|
-
return {
|
|
2260
|
-
responseCode: response.responseCode,
|
|
2261
|
-
realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
|
|
2262
|
-
};
|
|
2263
|
-
case IndexingStatusResponseCodes.Error:
|
|
2264
|
-
return response;
|
|
2265
|
-
}
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
2749
|
// src/api/registrar-actions/deserialize.ts
|
|
2269
|
-
import { prettifyError as prettifyError6 } from "zod/v4";
|
|
2270
2750
|
function deserializeRegistrarActionsResponse(maybeResponse) {
|
|
2271
2751
|
const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
|
|
2272
2752
|
if (parsed.error) {
|
|
2273
2753
|
throw new Error(
|
|
2274
2754
|
`Cannot deserialize RegistrarActionsResponse:
|
|
2275
|
-
${
|
|
2755
|
+
${prettifyError8(parsed.error)}
|
|
2276
2756
|
`
|
|
2277
2757
|
);
|
|
2278
2758
|
}
|
|
@@ -2282,7 +2762,8 @@ ${prettifyError6(parsed.error)}
|
|
|
2282
2762
|
// src/api/registrar-actions/request.ts
|
|
2283
2763
|
var RegistrarActionsFilterTypes = {
|
|
2284
2764
|
BySubregistryNode: "bySubregistryNode",
|
|
2285
|
-
WithEncodedReferral: "withEncodedReferral"
|
|
2765
|
+
WithEncodedReferral: "withEncodedReferral",
|
|
2766
|
+
ByDecodedReferrer: "byDecodedReferrer"
|
|
2286
2767
|
};
|
|
2287
2768
|
var RegistrarActionsOrders = {
|
|
2288
2769
|
LatestRegistrarActions: "orderBy[timestamp]=desc"
|
|
@@ -2306,9 +2787,19 @@ function withReferral(withReferral2) {
|
|
|
2306
2787
|
filterType: RegistrarActionsFilterTypes.WithEncodedReferral
|
|
2307
2788
|
};
|
|
2308
2789
|
}
|
|
2790
|
+
function byDecodedReferrer(decodedReferrer) {
|
|
2791
|
+
if (typeof decodedReferrer === "undefined") {
|
|
2792
|
+
return void 0;
|
|
2793
|
+
}
|
|
2794
|
+
return {
|
|
2795
|
+
filterType: RegistrarActionsFilterTypes.ByDecodedReferrer,
|
|
2796
|
+
value: decodedReferrer
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2309
2799
|
var registrarActionsFilter = {
|
|
2310
2800
|
byParentNode,
|
|
2311
|
-
withReferral
|
|
2801
|
+
withReferral,
|
|
2802
|
+
byDecodedReferrer
|
|
2312
2803
|
};
|
|
2313
2804
|
|
|
2314
2805
|
// src/api/registrar-actions/prerequisites.ts
|
|
@@ -2361,12 +2852,50 @@ var registrarActionsPrerequisites = Object.freeze({
|
|
|
2361
2852
|
}
|
|
2362
2853
|
});
|
|
2363
2854
|
|
|
2855
|
+
// src/registrars/basenames-subregistry.ts
|
|
2856
|
+
import {
|
|
2857
|
+
DatasourceNames as DatasourceNames2,
|
|
2858
|
+
ENSNamespaceIds as ENSNamespaceIds3,
|
|
2859
|
+
maybeGetDatasource as maybeGetDatasource2
|
|
2860
|
+
} from "@ensnode/datasources";
|
|
2861
|
+
function getBasenamesSubregistryId(namespace) {
|
|
2862
|
+
const datasource = maybeGetDatasource2(namespace, DatasourceNames2.Basenames);
|
|
2863
|
+
if (!datasource) {
|
|
2864
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames2.Basenames}`);
|
|
2865
|
+
}
|
|
2866
|
+
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2867
|
+
if (address === void 0 || Array.isArray(address)) {
|
|
2868
|
+
throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
|
|
2869
|
+
}
|
|
2870
|
+
return {
|
|
2871
|
+
chainId: datasource.chain.id,
|
|
2872
|
+
address
|
|
2873
|
+
};
|
|
2874
|
+
}
|
|
2875
|
+
function getBasenamesSubregistryManagedName(namespaceId) {
|
|
2876
|
+
switch (namespaceId) {
|
|
2877
|
+
case ENSNamespaceIds3.Mainnet:
|
|
2878
|
+
return "base.eth";
|
|
2879
|
+
case ENSNamespaceIds3.Sepolia:
|
|
2880
|
+
return "basetest.eth";
|
|
2881
|
+
case ENSNamespaceIds3.Holesky:
|
|
2882
|
+
case ENSNamespaceIds3.EnsTestEnv:
|
|
2883
|
+
throw new Error(
|
|
2884
|
+
`No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`
|
|
2885
|
+
);
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2364
2889
|
// src/registrars/ethnames-subregistry.ts
|
|
2365
|
-
import {
|
|
2890
|
+
import {
|
|
2891
|
+
DatasourceNames as DatasourceNames3,
|
|
2892
|
+
ENSNamespaceIds as ENSNamespaceIds4,
|
|
2893
|
+
maybeGetDatasource as maybeGetDatasource3
|
|
2894
|
+
} from "@ensnode/datasources";
|
|
2366
2895
|
function getEthnamesSubregistryId(namespace) {
|
|
2367
|
-
const datasource =
|
|
2896
|
+
const datasource = maybeGetDatasource3(namespace, DatasourceNames3.ENSRoot);
|
|
2368
2897
|
if (!datasource) {
|
|
2369
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
2898
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames3.ENSRoot}`);
|
|
2370
2899
|
}
|
|
2371
2900
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2372
2901
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -2377,6 +2906,49 @@ function getEthnamesSubregistryId(namespace) {
|
|
|
2377
2906
|
address
|
|
2378
2907
|
};
|
|
2379
2908
|
}
|
|
2909
|
+
function getEthnamesSubregistryManagedName(namespaceId) {
|
|
2910
|
+
switch (namespaceId) {
|
|
2911
|
+
case ENSNamespaceIds4.Mainnet:
|
|
2912
|
+
case ENSNamespaceIds4.Sepolia:
|
|
2913
|
+
case ENSNamespaceIds4.Holesky:
|
|
2914
|
+
case ENSNamespaceIds4.EnsTestEnv:
|
|
2915
|
+
return "eth";
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
// src/registrars/lineanames-subregistry.ts
|
|
2920
|
+
import {
|
|
2921
|
+
DatasourceNames as DatasourceNames4,
|
|
2922
|
+
ENSNamespaceIds as ENSNamespaceIds5,
|
|
2923
|
+
maybeGetDatasource as maybeGetDatasource4
|
|
2924
|
+
} from "@ensnode/datasources";
|
|
2925
|
+
function getLineanamesSubregistryId(namespace) {
|
|
2926
|
+
const datasource = maybeGetDatasource4(namespace, DatasourceNames4.Lineanames);
|
|
2927
|
+
if (!datasource) {
|
|
2928
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames4.Lineanames}`);
|
|
2929
|
+
}
|
|
2930
|
+
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2931
|
+
if (address === void 0 || Array.isArray(address)) {
|
|
2932
|
+
throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
|
|
2933
|
+
}
|
|
2934
|
+
return {
|
|
2935
|
+
chainId: datasource.chain.id,
|
|
2936
|
+
address
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2939
|
+
function getLineanamesSubregistryManagedName(namespaceId) {
|
|
2940
|
+
switch (namespaceId) {
|
|
2941
|
+
case ENSNamespaceIds5.Mainnet:
|
|
2942
|
+
return "linea.eth";
|
|
2943
|
+
case ENSNamespaceIds5.Sepolia:
|
|
2944
|
+
return "linea-sepolia.eth";
|
|
2945
|
+
case ENSNamespaceIds5.Holesky:
|
|
2946
|
+
case ENSNamespaceIds5.EnsTestEnv:
|
|
2947
|
+
throw new Error(
|
|
2948
|
+
`No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`
|
|
2949
|
+
);
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2380
2952
|
|
|
2381
2953
|
// src/api/registrar-actions/serialize.ts
|
|
2382
2954
|
function serializeNamedRegistrarAction({
|
|
@@ -2393,7 +2965,8 @@ function serializeRegistrarActionsResponse(response) {
|
|
|
2393
2965
|
case RegistrarActionsResponseCodes.Ok:
|
|
2394
2966
|
return {
|
|
2395
2967
|
responseCode: response.responseCode,
|
|
2396
|
-
registrarActions: response.registrarActions.map(serializeNamedRegistrarAction)
|
|
2968
|
+
registrarActions: response.registrarActions.map(serializeNamedRegistrarAction),
|
|
2969
|
+
pageContext: response.pageContext
|
|
2397
2970
|
};
|
|
2398
2971
|
case RegistrarActionsResponseCodes.Error:
|
|
2399
2972
|
return response;
|
|
@@ -2401,17 +2974,52 @@ function serializeRegistrarActionsResponse(response) {
|
|
|
2401
2974
|
}
|
|
2402
2975
|
|
|
2403
2976
|
// src/api/shared/errors/deserialize.ts
|
|
2404
|
-
import { prettifyError as
|
|
2977
|
+
import { prettifyError as prettifyError9 } from "zod/v4";
|
|
2405
2978
|
function deserializeErrorResponse(maybeErrorResponse) {
|
|
2406
2979
|
const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
|
|
2407
2980
|
if (parsed.error) {
|
|
2408
2981
|
throw new Error(`Cannot deserialize ErrorResponse:
|
|
2409
|
-
${
|
|
2982
|
+
${prettifyError9(parsed.error)}
|
|
2410
2983
|
`);
|
|
2411
2984
|
}
|
|
2412
2985
|
return parsed.data;
|
|
2413
2986
|
}
|
|
2414
2987
|
|
|
2988
|
+
// src/api/shared/pagination/build-page-context.ts
|
|
2989
|
+
function buildPageContext(page, recordsPerPage, totalRecords) {
|
|
2990
|
+
const totalPages = Math.max(1, Math.ceil(totalRecords / recordsPerPage));
|
|
2991
|
+
if (page > totalPages) {
|
|
2992
|
+
throw new Error(`Invalid page: page ${page} exceeds total pages ${totalPages}.`);
|
|
2993
|
+
}
|
|
2994
|
+
if (totalRecords === 0) {
|
|
2995
|
+
return {
|
|
2996
|
+
page,
|
|
2997
|
+
recordsPerPage,
|
|
2998
|
+
totalRecords: 0,
|
|
2999
|
+
totalPages: 1,
|
|
3000
|
+
hasNext: false,
|
|
3001
|
+
hasPrev: false,
|
|
3002
|
+
startIndex: void 0,
|
|
3003
|
+
endIndex: void 0
|
|
3004
|
+
};
|
|
3005
|
+
}
|
|
3006
|
+
const startIndex = (page - 1) * recordsPerPage;
|
|
3007
|
+
const maxTheoreticalIndexOnPage = startIndex + (recordsPerPage - 1);
|
|
3008
|
+
const endIndex = Math.min(maxTheoreticalIndexOnPage, totalRecords - 1);
|
|
3009
|
+
const hasNext = maxTheoreticalIndexOnPage < totalRecords - 1;
|
|
3010
|
+
const hasPrev = page > 1;
|
|
3011
|
+
return {
|
|
3012
|
+
page,
|
|
3013
|
+
recordsPerPage,
|
|
3014
|
+
totalRecords,
|
|
3015
|
+
totalPages,
|
|
3016
|
+
hasNext,
|
|
3017
|
+
hasPrev,
|
|
3018
|
+
startIndex,
|
|
3019
|
+
endIndex
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
|
|
2415
3023
|
// src/client-error.ts
|
|
2416
3024
|
var ClientError = class _ClientError extends Error {
|
|
2417
3025
|
details;
|
|
@@ -2426,7 +3034,7 @@ var ClientError = class _ClientError extends Error {
|
|
|
2426
3034
|
};
|
|
2427
3035
|
|
|
2428
3036
|
// src/ensanalytics/deserialize.ts
|
|
2429
|
-
import { prettifyError as
|
|
3037
|
+
import { prettifyError as prettifyError10 } from "zod/v4";
|
|
2430
3038
|
|
|
2431
3039
|
// src/ensanalytics/zod-schemas.ts
|
|
2432
3040
|
import z12 from "zod/v4";
|
|
@@ -2511,9 +3119,9 @@ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetri
|
|
|
2511
3119
|
});
|
|
2512
3120
|
var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => z12.object({
|
|
2513
3121
|
page: makePositiveIntegerSchema(`${valueLabel}.page`),
|
|
2514
|
-
|
|
3122
|
+
recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
|
|
2515
3123
|
REFERRERS_PER_LEADERBOARD_PAGE_MAX,
|
|
2516
|
-
`${valueLabel}.
|
|
3124
|
+
`${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
|
|
2517
3125
|
),
|
|
2518
3126
|
totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
|
|
2519
3127
|
totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
|
|
@@ -2524,9 +3132,9 @@ var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboar
|
|
|
2524
3132
|
});
|
|
2525
3133
|
var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => z12.object({
|
|
2526
3134
|
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
2527
|
-
referrers: z12.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[
|
|
3135
|
+
referrers: z12.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[record]`)),
|
|
2528
3136
|
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
2529
|
-
|
|
3137
|
+
pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
|
|
2530
3138
|
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
2531
3139
|
});
|
|
2532
3140
|
var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => z12.object({
|
|
@@ -2580,7 +3188,7 @@ function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
|
|
|
2580
3188
|
if (parsed.error) {
|
|
2581
3189
|
throw new Error(
|
|
2582
3190
|
`Cannot deserialize SerializedReferrerLeaderboardPageResponse:
|
|
2583
|
-
${
|
|
3191
|
+
${prettifyError10(parsed.error)}
|
|
2584
3192
|
`
|
|
2585
3193
|
);
|
|
2586
3194
|
}
|
|
@@ -2591,7 +3199,7 @@ function deserializeReferrerDetailResponse(maybeResponse, valueLabel) {
|
|
|
2591
3199
|
const parsed = schema.safeParse(maybeResponse);
|
|
2592
3200
|
if (parsed.error) {
|
|
2593
3201
|
throw new Error(`Cannot deserialize ReferrerDetailResponse:
|
|
2594
|
-
${
|
|
3202
|
+
${prettifyError10(parsed.error)}
|
|
2595
3203
|
`);
|
|
2596
3204
|
}
|
|
2597
3205
|
return parsed.data;
|
|
@@ -2859,7 +3467,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2859
3467
|
*
|
|
2860
3468
|
* @param request - Pagination parameters
|
|
2861
3469
|
* @param request.page - The page number to retrieve (1-indexed, default: 1)
|
|
2862
|
-
* @param request.
|
|
3470
|
+
* @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
|
|
2863
3471
|
* @returns {ReferrerLeaderboardPageResponse}
|
|
2864
3472
|
*
|
|
2865
3473
|
* @throws if the ENSNode request fails
|
|
@@ -2868,28 +3476,28 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2868
3476
|
*
|
|
2869
3477
|
* @example
|
|
2870
3478
|
* ```typescript
|
|
2871
|
-
* // Get first page with default page size (25
|
|
3479
|
+
* // Get first page with default page size (25 records)
|
|
2872
3480
|
* const response = await client.getReferrerLeaderboardPage();
|
|
2873
3481
|
* if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
|
|
2874
3482
|
* const {
|
|
2875
3483
|
* aggregatedMetrics,
|
|
2876
3484
|
* referrers,
|
|
2877
3485
|
* rules,
|
|
2878
|
-
*
|
|
3486
|
+
* pageContext,
|
|
2879
3487
|
* updatedAt
|
|
2880
3488
|
* } = response.data;
|
|
2881
3489
|
* console.log(aggregatedMetrics);
|
|
2882
3490
|
* console.log(referrers);
|
|
2883
3491
|
* console.log(rules);
|
|
2884
3492
|
* console.log(updatedAt);
|
|
2885
|
-
* console.log(`Page ${
|
|
3493
|
+
* console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
|
|
2886
3494
|
* }
|
|
2887
3495
|
* ```
|
|
2888
3496
|
*
|
|
2889
3497
|
* @example
|
|
2890
3498
|
* ```typescript
|
|
2891
|
-
* // Get second page with 50
|
|
2892
|
-
* const response = await client.getReferrerLeaderboardPage({ page: 2,
|
|
3499
|
+
* // Get second page with 50 records per page
|
|
3500
|
+
* const response = await client.getReferrerLeaderboardPage({ page: 2, recordsPerPage: 50 });
|
|
2893
3501
|
* ```
|
|
2894
3502
|
*
|
|
2895
3503
|
* @example
|
|
@@ -2906,8 +3514,8 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2906
3514
|
async getReferrerLeaderboardPage(request) {
|
|
2907
3515
|
const url = new URL(`/ensanalytics/referrers`, this.options.url);
|
|
2908
3516
|
if (request?.page) url.searchParams.set("page", request.page.toString());
|
|
2909
|
-
if (request?.
|
|
2910
|
-
url.searchParams.set("
|
|
3517
|
+
if (request?.recordsPerPage)
|
|
3518
|
+
url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
|
|
2911
3519
|
const response = await fetch(url);
|
|
2912
3520
|
let responseData;
|
|
2913
3521
|
try {
|
|
@@ -3012,11 +3620,13 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3012
3620
|
/**
|
|
3013
3621
|
* Fetch ENSNode Registrar Actions
|
|
3014
3622
|
*
|
|
3015
|
-
*
|
|
3016
|
-
*
|
|
3017
|
-
* @param
|
|
3018
|
-
* @param
|
|
3019
|
-
*
|
|
3623
|
+
* Retrieves a paginated list of registrar actions with optional filters.
|
|
3624
|
+
*
|
|
3625
|
+
* @param request is a request configuration.
|
|
3626
|
+
* @param request.page sets the page number to retrieve (1-indexed, default: 1)
|
|
3627
|
+
* @param request.recordsPerPage sets the number of records per page (default: 10, max: 100)
|
|
3628
|
+
* @param request.filters is an optional request filter configuration.
|
|
3629
|
+
* @param request.order sets the order of results in the response by field and direction.
|
|
3020
3630
|
* @returns {RegistrarActionsResponse}
|
|
3021
3631
|
*
|
|
3022
3632
|
* @throws if the ENSNode request fails
|
|
@@ -3026,23 +3636,25 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3026
3636
|
* @example
|
|
3027
3637
|
* ```ts
|
|
3028
3638
|
* import {
|
|
3029
|
-
* registrarActionsFilter
|
|
3639
|
+
* registrarActionsFilter,
|
|
3030
3640
|
* ENSNodeClient,
|
|
3031
3641
|
* } from "@ensnode/ensnode-sdk";
|
|
3032
3642
|
* import { namehash } from "viem/ens";
|
|
3033
3643
|
*
|
|
3034
3644
|
* const client: ENSNodeClient;
|
|
3035
3645
|
*
|
|
3036
|
-
* //
|
|
3037
|
-
*
|
|
3038
|
-
*
|
|
3039
|
-
*
|
|
3646
|
+
* // Get first page with default page size (10 records)
|
|
3647
|
+
* const response = await client.registrarActions();
|
|
3648
|
+
* if (response.responseCode === RegistrarActionsResponseCodes.Ok) {
|
|
3649
|
+
* const { registrarActions, pageContext } = response;
|
|
3650
|
+
* console.log(registrarActions);
|
|
3651
|
+
* console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
|
|
3652
|
+
* }
|
|
3040
3653
|
*
|
|
3041
|
-
* //
|
|
3042
|
-
*
|
|
3043
|
-
*
|
|
3044
|
-
*
|
|
3045
|
-
* limit: 5,
|
|
3654
|
+
* // Get second page with 25 records per page
|
|
3655
|
+
* const response = await client.registrarActions({
|
|
3656
|
+
* page: 2,
|
|
3657
|
+
* recordsPerPage: 25,
|
|
3046
3658
|
* });
|
|
3047
3659
|
*
|
|
3048
3660
|
* // get latest registrar action records associated with
|
|
@@ -3056,11 +3668,16 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3056
3668
|
* filters: [registrarActionsFilter.withReferral(true)],
|
|
3057
3669
|
* });
|
|
3058
3670
|
*
|
|
3671
|
+
* // get latest registrar action records for a specific decoded referrer
|
|
3672
|
+
* await client.registrarActions({
|
|
3673
|
+
* filters: [registrarActionsFilter.byDecodedReferrer("0x1234567890123456789012345678901234567890")],
|
|
3674
|
+
* });
|
|
3675
|
+
*
|
|
3059
3676
|
* // get latest 10 registrar action records associated with
|
|
3060
3677
|
* // subregistry managing `base.eth` name
|
|
3061
3678
|
* await client.registrarActions({
|
|
3062
3679
|
* filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
|
|
3063
|
-
*
|
|
3680
|
+
* recordsPerPage: 10
|
|
3064
3681
|
* });
|
|
3065
3682
|
* ```
|
|
3066
3683
|
*/
|
|
@@ -3077,6 +3694,12 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3077
3694
|
);
|
|
3078
3695
|
return withReferralFilter ? { key: "withReferral", value: "true" } : null;
|
|
3079
3696
|
};
|
|
3697
|
+
const buildDecodedReferrerArg = (filters) => {
|
|
3698
|
+
const decodedReferrerFilter = filters?.find(
|
|
3699
|
+
(f) => f.filterType === RegistrarActionsFilterTypes.ByDecodedReferrer
|
|
3700
|
+
);
|
|
3701
|
+
return decodedReferrerFilter ? { key: "decodedReferrer", value: decodedReferrerFilter.value } : null;
|
|
3702
|
+
};
|
|
3080
3703
|
const buildOrderArg = (order) => {
|
|
3081
3704
|
switch (order) {
|
|
3082
3705
|
case RegistrarActionsOrders.LatestRegistrarActions: {
|
|
@@ -3093,13 +3716,76 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3093
3716
|
const orderArgs = buildOrderArg(request.order);
|
|
3094
3717
|
url.searchParams.set(orderArgs.key, orderArgs.value);
|
|
3095
3718
|
}
|
|
3096
|
-
if (request.
|
|
3097
|
-
url.searchParams.set("
|
|
3719
|
+
if (request.page) {
|
|
3720
|
+
url.searchParams.set("page", request.page.toString());
|
|
3721
|
+
}
|
|
3722
|
+
if (request.recordsPerPage) {
|
|
3723
|
+
url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
|
|
3098
3724
|
}
|
|
3099
3725
|
const referralArg = buildWithReferralArg(request.filters);
|
|
3100
3726
|
if (referralArg) {
|
|
3101
3727
|
url.searchParams.set(referralArg.key, referralArg.value);
|
|
3102
3728
|
}
|
|
3729
|
+
const decodedReferrerArg = buildDecodedReferrerArg(request.filters);
|
|
3730
|
+
if (decodedReferrerArg) {
|
|
3731
|
+
url.searchParams.set(decodedReferrerArg.key, decodedReferrerArg.value);
|
|
3732
|
+
}
|
|
3733
|
+
const response = await fetch(url);
|
|
3734
|
+
let responseData;
|
|
3735
|
+
try {
|
|
3736
|
+
responseData = await response.json();
|
|
3737
|
+
} catch {
|
|
3738
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
3739
|
+
}
|
|
3740
|
+
if (!response.ok) {
|
|
3741
|
+
let errorResponse;
|
|
3742
|
+
try {
|
|
3743
|
+
errorResponse = deserializeErrorResponse(responseData);
|
|
3744
|
+
} catch {
|
|
3745
|
+
console.log("Registrar Actions API: handling a known server error.");
|
|
3746
|
+
}
|
|
3747
|
+
if (typeof errorResponse !== "undefined") {
|
|
3748
|
+
throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3751
|
+
return deserializeRegistrarActionsResponse(responseData);
|
|
3752
|
+
}
|
|
3753
|
+
/**
|
|
3754
|
+
* Fetch Name Tokens for requested name.
|
|
3755
|
+
*
|
|
3756
|
+
* @param request.name - Name for which Name Tokens will be fetched.
|
|
3757
|
+
* @returns {NameTokensResponse}
|
|
3758
|
+
*
|
|
3759
|
+
* @throws if the ENSNode request fails
|
|
3760
|
+
* @throws if the ENSNode API returns an error response
|
|
3761
|
+
* @throws if the ENSNode response breaks required invariants
|
|
3762
|
+
*
|
|
3763
|
+
* @example
|
|
3764
|
+
* ```ts
|
|
3765
|
+
* import {
|
|
3766
|
+
* ENSNodeClient,
|
|
3767
|
+
* } from "@ensnode/ensnode-sdk";
|
|
3768
|
+
* import { namehash } from "viem/ens";
|
|
3769
|
+
*
|
|
3770
|
+
* const client: ENSNodeClient;
|
|
3771
|
+
*
|
|
3772
|
+
* // get latest name token records from the indexed subregistry based on the requested name
|
|
3773
|
+
* const response = await client.nameTokens({
|
|
3774
|
+
* name: "vitalik.eth"
|
|
3775
|
+
* });
|
|
3776
|
+
*
|
|
3777
|
+
* const response = await client.nameTokens({
|
|
3778
|
+
* domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
|
|
3779
|
+
* })
|
|
3780
|
+
* ```
|
|
3781
|
+
*/
|
|
3782
|
+
async nameTokens(request) {
|
|
3783
|
+
const url = new URL(`/api/name-tokens`, this.options.url);
|
|
3784
|
+
if (request.name !== void 0) {
|
|
3785
|
+
url.searchParams.set("name", request.name);
|
|
3786
|
+
} else {
|
|
3787
|
+
url.searchParams.set("domainId", request.domainId);
|
|
3788
|
+
}
|
|
3103
3789
|
const response = await fetch(url);
|
|
3104
3790
|
let responseData;
|
|
3105
3791
|
try {
|
|
@@ -3112,18 +3798,18 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3112
3798
|
try {
|
|
3113
3799
|
errorResponse = deserializeErrorResponse(responseData);
|
|
3114
3800
|
} catch {
|
|
3115
|
-
console.log("
|
|
3801
|
+
console.log("Name Tokens API: handling a known server error.");
|
|
3116
3802
|
}
|
|
3117
3803
|
if (typeof errorResponse !== "undefined") {
|
|
3118
|
-
throw new Error(`Fetching ENSNode
|
|
3804
|
+
throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
|
|
3119
3805
|
}
|
|
3120
3806
|
}
|
|
3121
|
-
return
|
|
3807
|
+
return deserializedNameTokensResponse(responseData);
|
|
3122
3808
|
}
|
|
3123
3809
|
};
|
|
3124
3810
|
|
|
3125
3811
|
// src/identity/identity.ts
|
|
3126
|
-
import { getENSRootChainId as
|
|
3812
|
+
import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
|
|
3127
3813
|
|
|
3128
3814
|
// src/identity/types.ts
|
|
3129
3815
|
var ResolutionStatusIds = {
|
|
@@ -3150,7 +3836,7 @@ var ResolutionStatusIds = {
|
|
|
3150
3836
|
function buildUnresolvedIdentity(address, namespaceId, chainId) {
|
|
3151
3837
|
return {
|
|
3152
3838
|
resolutionStatus: ResolutionStatusIds.Unresolved,
|
|
3153
|
-
chainId: chainId ??
|
|
3839
|
+
chainId: chainId ?? getENSRootChainId2(namespaceId),
|
|
3154
3840
|
address
|
|
3155
3841
|
};
|
|
3156
3842
|
}
|
|
@@ -3159,245 +3845,24 @@ function isResolvedIdentity(identity) {
|
|
|
3159
3845
|
}
|
|
3160
3846
|
|
|
3161
3847
|
// src/resolution/ensip19-chainid.ts
|
|
3162
|
-
import { mainnet
|
|
3163
|
-
import { getENSRootChainId as
|
|
3848
|
+
import { mainnet } from "viem/chains";
|
|
3849
|
+
import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
|
|
3164
3850
|
var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
|
|
3165
|
-
const ensRootChainId =
|
|
3166
|
-
return chainId === ensRootChainId ?
|
|
3851
|
+
const ensRootChainId = getENSRootChainId3(namespaceId);
|
|
3852
|
+
return chainId === ensRootChainId ? mainnet.id : chainId;
|
|
3167
3853
|
};
|
|
3168
3854
|
var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
|
|
3169
|
-
return chainId === DEFAULT_EVM_CHAIN_ID ?
|
|
3855
|
+
return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId3(namespaceId) : chainId;
|
|
3170
3856
|
};
|
|
3171
3857
|
|
|
3172
3858
|
// src/resolution/resolver-records-selection.ts
|
|
3173
3859
|
var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
|
|
3174
3860
|
|
|
3175
|
-
// src/
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
var
|
|
3179
|
-
|
|
3180
|
-
ERC1155: "erc1155"
|
|
3181
|
-
};
|
|
3182
|
-
function serializeAssetId(assetId) {
|
|
3183
|
-
const { assetNamespace, contract, tokenId } = assetId;
|
|
3184
|
-
return CaipAssetId.format({
|
|
3185
|
-
chainId: { namespace: "eip155", reference: contract.chainId.toString() },
|
|
3186
|
-
assetName: { namespace: assetNamespace, reference: contract.address },
|
|
3187
|
-
tokenId: uint256ToHex32(tokenId)
|
|
3188
|
-
}).toLowerCase();
|
|
3189
|
-
}
|
|
3190
|
-
var buildAssetId = (contract, tokenId, assetNamespace) => {
|
|
3191
|
-
return {
|
|
3192
|
-
assetNamespace,
|
|
3193
|
-
contract,
|
|
3194
|
-
tokenId
|
|
3195
|
-
};
|
|
3196
|
-
};
|
|
3197
|
-
var NFTMintStatuses = {
|
|
3198
|
-
Minted: "minted",
|
|
3199
|
-
Burned: "burned"
|
|
3200
|
-
};
|
|
3201
|
-
var formatNFTTransferEventMetadata = (metadata) => {
|
|
3202
|
-
const serializedAssetId = serializeAssetId(metadata.nft);
|
|
3203
|
-
return [
|
|
3204
|
-
`Event: ${metadata.eventHandlerName}`,
|
|
3205
|
-
`Chain ID: ${metadata.chainId}`,
|
|
3206
|
-
`Block Number: ${metadata.blockNumber}`,
|
|
3207
|
-
`Transaction Hash: ${metadata.transactionHash}`,
|
|
3208
|
-
`NFT: ${serializedAssetId}`
|
|
3209
|
-
].map((line) => ` - ${line}`).join("\n");
|
|
3210
|
-
};
|
|
3211
|
-
var NFTTransferTypes = {
|
|
3212
|
-
/**
|
|
3213
|
-
* Initial transfer from zeroAddress to a non-zeroAddress
|
|
3214
|
-
* Can happen at most once to a NFT AssetId
|
|
3215
|
-
*
|
|
3216
|
-
* Invariants:
|
|
3217
|
-
* - NFT is not indexed and therefore has no previous mint status or owner
|
|
3218
|
-
* - new NFT mint status is `minted`
|
|
3219
|
-
* - new NFT owner is a non-zeroAddress
|
|
3220
|
-
*/
|
|
3221
|
-
Mint: "mint",
|
|
3222
|
-
/**
|
|
3223
|
-
* Subsequent transfer from zeroAddress to a non-zeroAddress
|
|
3224
|
-
* Can happen any number of times to a NFT AssetId as it passes in a cycle from
|
|
3225
|
-
* mint -> burn -> remint -> burn -> remint -> ...
|
|
3226
|
-
*
|
|
3227
|
-
* Invariants:
|
|
3228
|
-
* - NFT is indexed
|
|
3229
|
-
* - previous NFT mint status was `burned`
|
|
3230
|
-
* - previous NFT owner is the zeroAddress
|
|
3231
|
-
* - new NFT mint status is `minted`
|
|
3232
|
-
* - new NFT owner is a non-zeroAddress
|
|
3233
|
-
*/
|
|
3234
|
-
Remint: "remint",
|
|
3235
|
-
/**
|
|
3236
|
-
* Special transfer type for improperly implemented NFT contracts that allow a NFT
|
|
3237
|
-
* that is currently minted to be reminted before an intermediate burn.
|
|
3238
|
-
*
|
|
3239
|
-
* Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
|
|
3240
|
-
* previously indexed nft had status `minted` with a non-zeroAddress owner.
|
|
3241
|
-
*
|
|
3242
|
-
* Invariants:
|
|
3243
|
-
* - NFT is indexed
|
|
3244
|
-
* - previous NFT mint status was `minted`
|
|
3245
|
-
* - previous NFT owner was a non-zeroAddress
|
|
3246
|
-
* - new NFT mint status is `minted`
|
|
3247
|
-
* - new NFT owner is a non-zeroAddress
|
|
3248
|
-
*/
|
|
3249
|
-
MintedRemint: "minted-remint",
|
|
3250
|
-
/**
|
|
3251
|
-
* Transfer from a non-zeroAddress to zeroAddress
|
|
3252
|
-
*
|
|
3253
|
-
* Invariants:
|
|
3254
|
-
* - NFT is indexed
|
|
3255
|
-
* - previous NFT mint status was `minted`
|
|
3256
|
-
* - previous NFT owner is a non-zeroAddress
|
|
3257
|
-
* - new NFT mint status is `burned`
|
|
3258
|
-
* - new NFT owner is the zeroAddress
|
|
3259
|
-
*/
|
|
3260
|
-
Burn: "burn",
|
|
3261
|
-
/**
|
|
3262
|
-
* Transfer from a non-zeroAddress to a distinct non-zeroAddress
|
|
3263
|
-
*
|
|
3264
|
-
* Invariants:
|
|
3265
|
-
* - NFT is indexed
|
|
3266
|
-
* - previous and new NFT mint status is `minted`
|
|
3267
|
-
* - previous and new NFT owner are distinct non-zeroAddress
|
|
3268
|
-
*/
|
|
3269
|
-
Transfer: "transfer",
|
|
3270
|
-
/**
|
|
3271
|
-
* Transfer from a non-zeroAddress to the same non-zeroAddress
|
|
3272
|
-
*
|
|
3273
|
-
* Invariants:
|
|
3274
|
-
* - NFT is indexed
|
|
3275
|
-
* - previous and new NFT mint status is `minted`
|
|
3276
|
-
* - previous and new NFT owner are equivalent non-zeroAddress
|
|
3277
|
-
*/
|
|
3278
|
-
SelfTransfer: "self-transfer",
|
|
3279
|
-
/**
|
|
3280
|
-
* Transfer from zeroAddress to zeroAddress for an indexed NFT
|
|
3281
|
-
*
|
|
3282
|
-
* Invariants:
|
|
3283
|
-
* - NFT is indexed
|
|
3284
|
-
* - previous and new NFT mint status is `burned`
|
|
3285
|
-
* - previous and new NFT owner are zeroAddress
|
|
3286
|
-
*/
|
|
3287
|
-
RemintBurn: "remint-burn",
|
|
3288
|
-
/**
|
|
3289
|
-
* Special transfer type for improperly implemented NFT contracts that allow a NFT
|
|
3290
|
-
* that is currently minted to be reminted again before an intermediate burn.
|
|
3291
|
-
*
|
|
3292
|
-
* Transfer from zeroAddress to zeroAddress for an indexed NFT where the
|
|
3293
|
-
* previously indexed nft had status `minted` with a non-zeroAddress owner.
|
|
3294
|
-
*
|
|
3295
|
-
* Invariants:
|
|
3296
|
-
* - NFT is indexed
|
|
3297
|
-
* - previous NFT mint status was `minted`
|
|
3298
|
-
* - previous NFT owner was a non-zeroAddress
|
|
3299
|
-
* - new NFT mint status is `burned`
|
|
3300
|
-
* - new NFT owner is the zeroAddress
|
|
3301
|
-
*/
|
|
3302
|
-
MintedRemintBurn: "minted-remint-burn",
|
|
3303
|
-
/**
|
|
3304
|
-
* Transfer from zeroAddress to zeroAddress for an unindexed NFT
|
|
3305
|
-
*
|
|
3306
|
-
* Invariants:
|
|
3307
|
-
* - NFT is not indexed and therefore has no previous mint status or owner
|
|
3308
|
-
* - NFT should remain unindexed and without any mint status or owner
|
|
3309
|
-
*/
|
|
3310
|
-
MintBurn: "mint-burn"
|
|
3311
|
-
};
|
|
3312
|
-
var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
|
|
3313
|
-
const isIndexed = currentlyIndexedOwner !== void 0;
|
|
3314
|
-
const isIndexedAsMinted = isIndexed && !isAddressEqual3(currentlyIndexedOwner, zeroAddress3);
|
|
3315
|
-
const isMint = isAddressEqual3(from, zeroAddress3);
|
|
3316
|
-
const isBurn = isAddressEqual3(to, zeroAddress3);
|
|
3317
|
-
const isSelfTransfer = isAddressEqual3(from, to);
|
|
3318
|
-
if (isIndexed && !isAddressEqual3(currentlyIndexedOwner, from)) {
|
|
3319
|
-
if (isMint && allowMintedRemint) {
|
|
3320
|
-
} else {
|
|
3321
|
-
throw new Error(
|
|
3322
|
-
`Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
|
|
3323
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3324
|
-
);
|
|
3325
|
-
}
|
|
3326
|
-
}
|
|
3327
|
-
if (isSelfTransfer) {
|
|
3328
|
-
if (isMint) {
|
|
3329
|
-
if (!isIndexed) {
|
|
3330
|
-
return NFTTransferTypes.MintBurn;
|
|
3331
|
-
} else if (!isIndexedAsMinted) {
|
|
3332
|
-
return NFTTransferTypes.RemintBurn;
|
|
3333
|
-
} else if (allowMintedRemint) {
|
|
3334
|
-
return NFTTransferTypes.MintedRemintBurn;
|
|
3335
|
-
} else {
|
|
3336
|
-
throw new Error(
|
|
3337
|
-
`Error: Invalid state transition from minted -> remint-burn
|
|
3338
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3339
|
-
);
|
|
3340
|
-
}
|
|
3341
|
-
} else {
|
|
3342
|
-
if (!isIndexed) {
|
|
3343
|
-
throw new Error(
|
|
3344
|
-
`Error: Invalid state transition from unindexed -> self-transfer
|
|
3345
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3346
|
-
);
|
|
3347
|
-
} else if (!isIndexedAsMinted) {
|
|
3348
|
-
throw new Error(
|
|
3349
|
-
`Error: invalid state transition from burned -> self-transfer
|
|
3350
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3351
|
-
);
|
|
3352
|
-
} else {
|
|
3353
|
-
return NFTTransferTypes.SelfTransfer;
|
|
3354
|
-
}
|
|
3355
|
-
}
|
|
3356
|
-
} else if (isMint) {
|
|
3357
|
-
if (!isIndexed) {
|
|
3358
|
-
return NFTTransferTypes.Mint;
|
|
3359
|
-
} else if (!isIndexedAsMinted) {
|
|
3360
|
-
return NFTTransferTypes.Remint;
|
|
3361
|
-
} else if (allowMintedRemint) {
|
|
3362
|
-
return NFTTransferTypes.MintedRemint;
|
|
3363
|
-
} else {
|
|
3364
|
-
throw new Error(
|
|
3365
|
-
`Error: Invalid state transition from minted -> mint
|
|
3366
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3367
|
-
);
|
|
3368
|
-
}
|
|
3369
|
-
} else if (isBurn) {
|
|
3370
|
-
if (!isIndexed) {
|
|
3371
|
-
throw new Error(
|
|
3372
|
-
`Error: Invalid state transition from unindexed -> burn
|
|
3373
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3374
|
-
);
|
|
3375
|
-
} else if (!isIndexedAsMinted) {
|
|
3376
|
-
throw new Error(
|
|
3377
|
-
`Error: Invalid state transition from burned -> burn
|
|
3378
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3379
|
-
);
|
|
3380
|
-
} else {
|
|
3381
|
-
return NFTTransferTypes.Burn;
|
|
3382
|
-
}
|
|
3383
|
-
} else {
|
|
3384
|
-
if (!isIndexed) {
|
|
3385
|
-
throw new Error(
|
|
3386
|
-
`Error: Invalid state transition from unindexed -> transfer
|
|
3387
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3388
|
-
);
|
|
3389
|
-
} else if (!isIndexedAsMinted) {
|
|
3390
|
-
throw new Error(
|
|
3391
|
-
`Error: Invalid state transition from burned -> transfer
|
|
3392
|
-
${formatNFTTransferEventMetadata(metadata)}`
|
|
3393
|
-
);
|
|
3394
|
-
} else {
|
|
3395
|
-
return NFTTransferTypes.Transfer;
|
|
3396
|
-
}
|
|
3397
|
-
}
|
|
3398
|
-
};
|
|
3399
|
-
|
|
3400
|
-
// src/tracing/index.ts
|
|
3861
|
+
// src/tracing/ens-protocol-tracing.ts
|
|
3862
|
+
var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|
|
3863
|
+
var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
|
|
3864
|
+
var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
|
|
3865
|
+
var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
|
|
3401
3866
|
var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
|
|
3402
3867
|
TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
|
|
3403
3868
|
TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
|
|
@@ -3422,10 +3887,6 @@ var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolS
|
|
|
3422
3887
|
ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
|
|
3423
3888
|
return ReverseResolutionProtocolStep2;
|
|
3424
3889
|
})(ReverseResolutionProtocolStep || {});
|
|
3425
|
-
var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|
|
3426
|
-
var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
|
|
3427
|
-
var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
|
|
3428
|
-
var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
|
|
3429
3890
|
export {
|
|
3430
3891
|
ADDR_REVERSE_NODE,
|
|
3431
3892
|
ATTR_PROTOCOL_NAME,
|
|
@@ -3442,6 +3903,7 @@ export {
|
|
|
3442
3903
|
DEFAULT_EVM_COIN_TYPE,
|
|
3443
3904
|
ENSNamespaceIds,
|
|
3444
3905
|
ENSNodeClient,
|
|
3906
|
+
ENS_ROOT,
|
|
3445
3907
|
ETH_COIN_TYPE,
|
|
3446
3908
|
ETH_NODE,
|
|
3447
3909
|
ForwardResolutionProtocolStep,
|
|
@@ -3450,6 +3912,9 @@ export {
|
|
|
3450
3912
|
LruCache,
|
|
3451
3913
|
NFTMintStatuses,
|
|
3452
3914
|
NFTTransferTypes,
|
|
3915
|
+
NameTokenOwnershipTypes,
|
|
3916
|
+
NameTokensResponseCodes,
|
|
3917
|
+
NameTokensResponseErrorCodes,
|
|
3453
3918
|
OmnichainIndexingStatusIds,
|
|
3454
3919
|
PROTOCOL_ATTRIBUTE_PREFIX,
|
|
3455
3920
|
PluginName,
|
|
@@ -3482,6 +3947,7 @@ export {
|
|
|
3482
3947
|
buildEnsRainbowClientLabelSet,
|
|
3483
3948
|
buildLabelSetId,
|
|
3484
3949
|
buildLabelSetVersion,
|
|
3950
|
+
buildPageContext,
|
|
3485
3951
|
buildUnresolvedIdentity,
|
|
3486
3952
|
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
|
|
3487
3953
|
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
|
|
@@ -3494,7 +3960,7 @@ export {
|
|
|
3494
3960
|
decodeDNSEncodedLiteralName,
|
|
3495
3961
|
decodeDNSEncodedName,
|
|
3496
3962
|
decodeEncodedReferrer,
|
|
3497
|
-
|
|
3963
|
+
deserializeAssetId,
|
|
3498
3964
|
deserializeBlockNumber,
|
|
3499
3965
|
deserializeBlockRef,
|
|
3500
3966
|
deserializeBlockrange,
|
|
@@ -3515,18 +3981,30 @@ export {
|
|
|
3515
3981
|
deserializeRegistrarActionsResponse,
|
|
3516
3982
|
deserializeUnixTimestamp,
|
|
3517
3983
|
deserializeUrl,
|
|
3984
|
+
deserializedNameTokensResponse,
|
|
3518
3985
|
durationBetween,
|
|
3519
3986
|
encodeLabelHash,
|
|
3520
3987
|
evmChainIdToCoinType,
|
|
3988
|
+
formatAccountId,
|
|
3989
|
+
formatAssetId,
|
|
3521
3990
|
formatNFTTransferEventMetadata,
|
|
3991
|
+
getBasenamesSubregistryId,
|
|
3992
|
+
getBasenamesSubregistryManagedName,
|
|
3522
3993
|
getCurrencyInfo,
|
|
3994
|
+
getDatasourceContract,
|
|
3523
3995
|
getENSRootChainId,
|
|
3524
3996
|
getEthnamesSubregistryId,
|
|
3997
|
+
getEthnamesSubregistryManagedName,
|
|
3525
3998
|
getLatestIndexedBlockRef,
|
|
3999
|
+
getLineanamesSubregistryId,
|
|
4000
|
+
getLineanamesSubregistryManagedName,
|
|
3526
4001
|
getNFTTransferType,
|
|
3527
4002
|
getNameHierarchy,
|
|
4003
|
+
getNameTokenOwnership,
|
|
4004
|
+
getNameWrapperAccounts,
|
|
3528
4005
|
getOmnichainIndexingCursor,
|
|
3529
4006
|
getOmnichainIndexingStatus,
|
|
4007
|
+
getParentNameFQDN,
|
|
3530
4008
|
getResolvePrimaryNameChainIdParam,
|
|
3531
4009
|
getTimestampForHighestOmnichainKnownBlock,
|
|
3532
4010
|
getTimestampForLowestOmnichainStartBlock,
|
|
@@ -3552,6 +4030,10 @@ export {
|
|
|
3552
4030
|
literalLabelsToLiteralName,
|
|
3553
4031
|
makeENSApiPublicConfigSchema,
|
|
3554
4032
|
makeSubdomainNode,
|
|
4033
|
+
maybeGetDatasourceContract,
|
|
4034
|
+
nameTokensPrerequisites,
|
|
4035
|
+
parseAccountId,
|
|
4036
|
+
parseAssetId,
|
|
3555
4037
|
parseNonNegativeInteger,
|
|
3556
4038
|
parseReverseName,
|
|
3557
4039
|
priceDai,
|
|
@@ -3560,17 +4042,19 @@ export {
|
|
|
3560
4042
|
registrarActionsFilter,
|
|
3561
4043
|
registrarActionsPrerequisites,
|
|
3562
4044
|
reverseName,
|
|
3563
|
-
serializeAccountId,
|
|
3564
4045
|
serializeAssetId,
|
|
3565
4046
|
serializeChainId,
|
|
3566
4047
|
serializeChainIndexingSnapshots,
|
|
3567
4048
|
serializeConfigResponse,
|
|
3568
4049
|
serializeCrossChainIndexingStatusSnapshotOmnichain,
|
|
3569
4050
|
serializeDatetime,
|
|
4051
|
+
serializeDomainAssetId,
|
|
3570
4052
|
serializeENSApiPublicConfig,
|
|
3571
4053
|
serializeENSIndexerPublicConfig,
|
|
3572
4054
|
serializeIndexedChainIds,
|
|
3573
4055
|
serializeIndexingStatusResponse,
|
|
4056
|
+
serializeNameToken,
|
|
4057
|
+
serializeNameTokensResponse,
|
|
3574
4058
|
serializeNamedRegistrarAction,
|
|
3575
4059
|
serializeOmnichainIndexingStatusSnapshot,
|
|
3576
4060
|
serializePrice,
|
|
@@ -3578,11 +4062,10 @@ export {
|
|
|
3578
4062
|
serializeRealtimeIndexingStatusProjection,
|
|
3579
4063
|
serializeReferrerDetailResponse,
|
|
3580
4064
|
serializeReferrerLeaderboardPageResponse,
|
|
4065
|
+
serializeRegisteredNameTokens,
|
|
3581
4066
|
serializeRegistrarAction,
|
|
3582
4067
|
serializeRegistrarActionPricing,
|
|
3583
4068
|
serializeRegistrarActionsResponse,
|
|
3584
|
-
serializeRegistrationLifecycle,
|
|
3585
|
-
serializeSubregistry,
|
|
3586
4069
|
serializeUrl,
|
|
3587
4070
|
sortChainStatusesByStartBlockAsc,
|
|
3588
4071
|
stripNullBytes,
|