@ensnode/ensnode-sdk 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2298 -1238
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1924 -933
- package/dist/index.d.ts +1924 -933
- package/dist/index.js +2307 -1252
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,32 +1,12 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import { prettifyError as prettifyError2 } from "zod/v4";
|
|
1
|
+
// src/ensapi/config/deserialize.ts
|
|
2
|
+
import { prettifyError as prettifyError2, ZodError } from "zod/v4";
|
|
3
3
|
|
|
4
|
-
// src/
|
|
5
|
-
import {
|
|
6
|
-
import z7 from "zod/v4";
|
|
4
|
+
// src/ensapi/config/zod-schemas.ts
|
|
5
|
+
import { z as z3 } from "zod/v4";
|
|
7
6
|
|
|
8
|
-
// src/ensindexer/
|
|
7
|
+
// src/ensindexer/config/zod-schemas.ts
|
|
9
8
|
import z2 from "zod/v4";
|
|
10
9
|
|
|
11
|
-
// src/ens/is-normalized.ts
|
|
12
|
-
import { normalize } from "viem/ens";
|
|
13
|
-
function isNormalizedName(name) {
|
|
14
|
-
try {
|
|
15
|
-
return name === normalize(name);
|
|
16
|
-
} catch {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function isNormalizedLabel(label) {
|
|
21
|
-
if (label === "") return false;
|
|
22
|
-
if (label.includes(".")) return false;
|
|
23
|
-
try {
|
|
24
|
-
return label === normalize(label);
|
|
25
|
-
} catch {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
10
|
// src/shared/account-id.ts
|
|
31
11
|
import { isAddressEqual } from "viem";
|
|
32
12
|
var accountIdEqual = (a, b) => {
|
|
@@ -180,9 +160,39 @@ function isEncodedLabelHash(maybeEncodedLabelHash) {
|
|
|
180
160
|
return expectedFormatting && includesLabelHash;
|
|
181
161
|
}
|
|
182
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
|
+
|
|
183
182
|
// src/ens/names.ts
|
|
184
183
|
import { ens_beautify } from "@adraffy/ens-normalize";
|
|
184
|
+
var ENS_ROOT = "";
|
|
185
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
|
+
};
|
|
186
196
|
var beautifyName = (name) => {
|
|
187
197
|
const beautifiedLabels = name.split(".").map((label) => {
|
|
188
198
|
if (isNormalizedLabel(label)) {
|
|
@@ -425,7 +435,7 @@ var makeAccountIdSchema = (valueLabel = "AccountId") => z.strictObject({
|
|
|
425
435
|
chainId: makeChainIdSchema(`${valueLabel} chain ID`),
|
|
426
436
|
address: makeLowercaseAddressSchema(`${valueLabel} address`)
|
|
427
437
|
});
|
|
428
|
-
var
|
|
438
|
+
var makeAccountIdStringSchema = (valueLabel = "Account ID String") => z.coerce.string().transform((v) => {
|
|
429
439
|
const result = new CaipAccountId(v);
|
|
430
440
|
return {
|
|
431
441
|
chainId: Number(result.chainId.reference),
|
|
@@ -437,7 +447,7 @@ var makeHexStringSchema = (options, valueLabel = "String representation of bytes
|
|
|
437
447
|
ctx.issues.push({
|
|
438
448
|
code: "custom",
|
|
439
449
|
input: ctx.value,
|
|
440
|
-
message: `${valueLabel} must
|
|
450
|
+
message: `${valueLabel} must be a hexadecimal value which starts with '0x'.`
|
|
441
451
|
});
|
|
442
452
|
}
|
|
443
453
|
}).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
|
|
@@ -547,8 +557,8 @@ ${prettifyError(parsed.error)}
|
|
|
547
557
|
}
|
|
548
558
|
return parsed.data;
|
|
549
559
|
}
|
|
550
|
-
function
|
|
551
|
-
const schema =
|
|
560
|
+
function parseAccountId(maybeAccountId, valueLabel) {
|
|
561
|
+
const schema = makeAccountIdStringSchema(valueLabel);
|
|
552
562
|
const parsed = schema.safeParse(maybeAccountId);
|
|
553
563
|
if (parsed.error) {
|
|
554
564
|
throw new RangeError(`Cannot deserialize AccountId:
|
|
@@ -811,6 +821,28 @@ var TtlCache = class {
|
|
|
811
821
|
// src/shared/collections.ts
|
|
812
822
|
var uniq = (arr) => [...new Set(arr)];
|
|
813
823
|
|
|
824
|
+
// src/shared/datasource-contract.ts
|
|
825
|
+
import { maybeGetDatasource } from "@ensnode/datasources";
|
|
826
|
+
var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
827
|
+
const datasource = maybeGetDatasource(namespaceId, datasourceName);
|
|
828
|
+
if (!datasource) return void 0;
|
|
829
|
+
const address = datasource.contracts[contractName]?.address;
|
|
830
|
+
if (address === void 0 || Array.isArray(address)) return void 0;
|
|
831
|
+
return {
|
|
832
|
+
chainId: datasource.chain.id,
|
|
833
|
+
address
|
|
834
|
+
};
|
|
835
|
+
};
|
|
836
|
+
var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
837
|
+
const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
|
|
838
|
+
if (!contract) {
|
|
839
|
+
throw new Error(
|
|
840
|
+
`Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
return contract;
|
|
844
|
+
};
|
|
845
|
+
|
|
814
846
|
// src/shared/labelhash.ts
|
|
815
847
|
import { keccak256 as keccak2562, stringToBytes } from "viem";
|
|
816
848
|
var labelhashLiteralLabel = (label) => keccak2562(stringToBytes(label));
|
|
@@ -869,7 +901,7 @@ function serializePrice(price) {
|
|
|
869
901
|
function serializePriceEth(price) {
|
|
870
902
|
return serializePrice(price);
|
|
871
903
|
}
|
|
872
|
-
function
|
|
904
|
+
function formatAccountId(accountId) {
|
|
873
905
|
return CaipAccountId2.format({
|
|
874
906
|
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
875
907
|
address: accountId.address
|
|
@@ -884,770 +916,1647 @@ function isWebSocketProtocol(url) {
|
|
|
884
916
|
return ["ws:", "wss:"].includes(url.protocol);
|
|
885
917
|
}
|
|
886
918
|
|
|
887
|
-
// src/ensindexer/
|
|
888
|
-
|
|
889
|
-
/**
|
|
890
|
-
* Represents that indexing of the chain should be performed for an indefinite range.
|
|
891
|
-
*/
|
|
892
|
-
Indefinite: "indefinite",
|
|
893
|
-
/**
|
|
894
|
-
* Represents that indexing of the chain should be performed for a definite range.
|
|
895
|
-
*/
|
|
896
|
-
Definite: "definite"
|
|
897
|
-
};
|
|
898
|
-
var ChainIndexingStatusIds = {
|
|
899
|
-
/**
|
|
900
|
-
* Represents that indexing of the chain is not ready to begin yet because:
|
|
901
|
-
* - ENSIndexer is in its initialization phase and the data to build a
|
|
902
|
-
* "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
|
|
903
|
-
* - ENSIndexer is using an omnichain indexing strategy and the
|
|
904
|
-
* `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
|
|
905
|
-
* {@link ChainIndexingSnapshot}.
|
|
906
|
-
*/
|
|
907
|
-
Queued: "chain-queued",
|
|
908
|
-
/**
|
|
909
|
-
* Represents that indexing of the chain is in progress and under a special
|
|
910
|
-
* "backfill" phase that optimizes for accelerated indexing until reaching the
|
|
911
|
-
* "fixed target" `backfillEndBlock`.
|
|
912
|
-
*/
|
|
913
|
-
Backfill: "chain-backfill",
|
|
914
|
-
/**
|
|
915
|
-
* Represents that the "backfill" phase of indexing the chain is completed
|
|
916
|
-
* and that the chain is configured to be indexed for an indefinite range.
|
|
917
|
-
* Therefore, indexing of the chain remains indefinitely in progress where
|
|
918
|
-
* ENSIndexer will continuously work to discover and index new blocks as they
|
|
919
|
-
* are added to the chain across time.
|
|
920
|
-
*/
|
|
921
|
-
Following: "chain-following",
|
|
922
|
-
/**
|
|
923
|
-
* Represents that indexing of the chain is completed as the chain is configured
|
|
924
|
-
* to be indexed for a definite range and the indexing of all blocks through
|
|
925
|
-
* that definite range is completed.
|
|
926
|
-
*/
|
|
927
|
-
Completed: "chain-completed"
|
|
928
|
-
};
|
|
929
|
-
var OmnichainIndexingStatusIds = {
|
|
930
|
-
/**
|
|
931
|
-
* Represents that omnichain indexing is not ready to begin yet because
|
|
932
|
-
* ENSIndexer is in its initialization phase and the data to build a "true"
|
|
933
|
-
* {@link OmnichainIndexingStatusSnapshot} is still being loaded.
|
|
934
|
-
*/
|
|
935
|
-
Unstarted: "omnichain-unstarted",
|
|
936
|
-
/**
|
|
937
|
-
* Represents that omnichain indexing is in an overall "backfill" status because
|
|
938
|
-
* - At least one indexed chain has a `chainStatus` of
|
|
939
|
-
* {@link ChainIndexingStatusIds.Backfill}; and
|
|
940
|
-
* - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
|
|
941
|
-
*/
|
|
942
|
-
Backfill: "omnichain-backfill",
|
|
943
|
-
/**
|
|
944
|
-
* Represents that omnichain indexing is in an overall "following" status because
|
|
945
|
-
* at least one indexed chain has a `chainStatus` of
|
|
946
|
-
* {@link ChainIndexingStatusIds.Following}.
|
|
947
|
-
*/
|
|
948
|
-
Following: "omnichain-following",
|
|
949
|
-
/**
|
|
950
|
-
* Represents that omnichain indexing has completed because all indexed chains have
|
|
951
|
-
* a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
|
|
952
|
-
*/
|
|
953
|
-
Completed: "omnichain-completed"
|
|
954
|
-
};
|
|
955
|
-
var CrossChainIndexingStrategyIds = {
|
|
956
|
-
/**
|
|
957
|
-
* Represents that the indexing of events across all indexed chains will
|
|
958
|
-
* proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
|
|
959
|
-
* and block number.
|
|
960
|
-
*
|
|
961
|
-
* This strategy is "deterministic" in that the order of processing cross-chain indexed
|
|
962
|
-
* events and each resulting indexed data state transition recorded in ENSDb is always
|
|
963
|
-
* the same for each ENSIndexer instance operating with an equivalent
|
|
964
|
-
* `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
|
|
965
|
-
* - increased indexing latency that must wait for the slowest indexed chain to
|
|
966
|
-
* add new blocks or to discover new blocks through the configured RPCs.
|
|
967
|
-
* - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
|
|
968
|
-
* will be affected.
|
|
969
|
-
*/
|
|
970
|
-
Omnichain: "omnichain"
|
|
971
|
-
};
|
|
919
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
920
|
+
import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
|
|
972
921
|
|
|
973
|
-
// src/
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
922
|
+
// src/ensindexer/config/types.ts
|
|
923
|
+
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
924
|
+
PluginName2["Subgraph"] = "subgraph";
|
|
925
|
+
PluginName2["Basenames"] = "basenames";
|
|
926
|
+
PluginName2["Lineanames"] = "lineanames";
|
|
927
|
+
PluginName2["ThreeDNS"] = "threedns";
|
|
928
|
+
PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
|
|
929
|
+
PluginName2["Registrars"] = "registrars";
|
|
930
|
+
PluginName2["TokenScope"] = "tokenscope";
|
|
931
|
+
return PluginName2;
|
|
932
|
+
})(PluginName || {});
|
|
933
|
+
|
|
934
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
935
|
+
function isSubgraphCompatible(config) {
|
|
936
|
+
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
937
|
+
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
938
|
+
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
939
|
+
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
940
|
+
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
982
941
|
}
|
|
983
942
|
|
|
984
|
-
// src/ensindexer/
|
|
985
|
-
function
|
|
986
|
-
|
|
987
|
-
|
|
943
|
+
// src/ensindexer/config/validations.ts
|
|
944
|
+
function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
|
|
945
|
+
const versionInfo = ctx.value;
|
|
946
|
+
if (versionInfo.ensDb !== versionInfo.ensIndexer) {
|
|
947
|
+
ctx.issues.push({
|
|
948
|
+
code: "custom",
|
|
949
|
+
input: versionInfo,
|
|
950
|
+
message: "`ensDb` version must be same as `ensIndexer` version"
|
|
951
|
+
});
|
|
988
952
|
}
|
|
989
|
-
|
|
990
|
-
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
// src/ensindexer/config/zod-schemas.ts
|
|
956
|
+
var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => z2.array(makeChainIdSchema(valueLabel), {
|
|
957
|
+
error: `${valueLabel} must be an array.`
|
|
958
|
+
}).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
|
|
959
|
+
var makePluginsListSchema = (valueLabel = "Plugins") => z2.array(z2.string(), {
|
|
960
|
+
error: `${valueLabel} must be a list of strings.`
|
|
961
|
+
}).min(1, {
|
|
962
|
+
error: `${valueLabel} must be a list of strings with at least one string value`
|
|
963
|
+
}).refine((arr) => arr.length === uniq(arr).length, {
|
|
964
|
+
error: `${valueLabel} cannot contain duplicate values.`
|
|
965
|
+
});
|
|
966
|
+
var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => z2.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
|
|
967
|
+
error: `${valueLabel} is required and must be a non-empty string.`
|
|
968
|
+
});
|
|
969
|
+
var makeLabelSetIdSchema = (valueLabel) => {
|
|
970
|
+
return z2.string({ error: `${valueLabel} must be a string` }).min(1, { error: `${valueLabel} must be 1-50 characters long` }).max(50, { error: `${valueLabel} must be 1-50 characters long` }).regex(/^[a-z-]+$/, {
|
|
971
|
+
error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
|
|
972
|
+
});
|
|
973
|
+
};
|
|
974
|
+
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
975
|
+
return z2.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
976
|
+
};
|
|
977
|
+
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
978
|
+
let valueLabelLabelSetId = valueLabel;
|
|
979
|
+
let valueLabelLabelSetVersion = valueLabel;
|
|
980
|
+
if (valueLabel === "LABEL_SET") {
|
|
981
|
+
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
982
|
+
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
983
|
+
} else {
|
|
984
|
+
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
985
|
+
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
991
986
|
}
|
|
992
|
-
|
|
993
|
-
|
|
987
|
+
return z2.object({
|
|
988
|
+
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
989
|
+
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
990
|
+
});
|
|
991
|
+
};
|
|
992
|
+
var makeNonEmptyStringSchema = (valueLabel = "Value") => z2.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
993
|
+
var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z2.strictObject(
|
|
994
|
+
{
|
|
995
|
+
nodejs: makeNonEmptyStringSchema(),
|
|
996
|
+
ponder: makeNonEmptyStringSchema(),
|
|
997
|
+
ensDb: makeNonEmptyStringSchema(),
|
|
998
|
+
ensIndexer: makeNonEmptyStringSchema(),
|
|
999
|
+
ensNormalize: makeNonEmptyStringSchema(),
|
|
1000
|
+
ensRainbow: makeNonEmptyStringSchema(),
|
|
1001
|
+
ensRainbowSchema: makePositiveIntegerSchema()
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
|
|
994
1005
|
}
|
|
995
|
-
|
|
996
|
-
|
|
1006
|
+
).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
|
|
1007
|
+
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
1008
|
+
const { value: config } = ctx;
|
|
1009
|
+
if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
|
|
1010
|
+
ctx.issues.push({
|
|
1011
|
+
code: "custom",
|
|
1012
|
+
input: config,
|
|
1013
|
+
message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
|
|
1014
|
+
});
|
|
997
1015
|
}
|
|
998
|
-
throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
|
|
999
|
-
}
|
|
1000
|
-
function getTimestampForLowestOmnichainStartBlock(chains) {
|
|
1001
|
-
const earliestKnownBlockTimestamps = chains.map(
|
|
1002
|
-
(chain) => chain.config.startBlock.timestamp
|
|
1003
|
-
);
|
|
1004
|
-
return Math.min(...earliestKnownBlockTimestamps);
|
|
1005
1016
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1017
|
+
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => z2.object({
|
|
1018
|
+
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
1019
|
+
indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
|
|
1020
|
+
isSubgraphCompatible: z2.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
1021
|
+
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
1022
|
+
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
1023
|
+
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
1024
|
+
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
1025
|
+
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
1026
|
+
|
|
1027
|
+
// src/ensapi/config/zod-schemas.ts
|
|
1028
|
+
var TheGraphCannotFallbackReasonSchema = z3.enum({
|
|
1029
|
+
NotSubgraphCompatible: "not-subgraph-compatible",
|
|
1030
|
+
NoApiKey: "no-api-key",
|
|
1031
|
+
NoSubgraphUrl: "no-subgraph-url"
|
|
1032
|
+
});
|
|
1033
|
+
var TheGraphFallbackSchema = z3.strictObject({
|
|
1034
|
+
canFallback: z3.boolean(),
|
|
1035
|
+
reason: TheGraphCannotFallbackReasonSchema.nullable()
|
|
1036
|
+
});
|
|
1037
|
+
function makeENSApiPublicConfigSchema(valueLabel) {
|
|
1038
|
+
const label = valueLabel ?? "ENSApiPublicConfig";
|
|
1039
|
+
return z3.strictObject({
|
|
1040
|
+
version: z3.string().min(1, `${label}.version must be a non-empty string`),
|
|
1041
|
+
theGraphFallback: TheGraphFallbackSchema,
|
|
1042
|
+
ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// src/ensapi/config/deserialize.ts
|
|
1047
|
+
function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
|
|
1048
|
+
const schema = makeENSApiPublicConfigSchema(valueLabel);
|
|
1049
|
+
try {
|
|
1050
|
+
return schema.parse(maybeConfig);
|
|
1051
|
+
} catch (error) {
|
|
1052
|
+
if (error instanceof ZodError) {
|
|
1053
|
+
throw new Error(`Cannot deserialize ENSApiPublicConfig:
|
|
1054
|
+
${prettifyError2(error)}
|
|
1055
|
+
`);
|
|
1056
|
+
}
|
|
1057
|
+
throw error;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
// src/ensindexer/config/deserialize.ts
|
|
1062
|
+
import { prettifyError as prettifyError3 } from "zod/v4";
|
|
1063
|
+
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
1064
|
+
const schema = makeENSIndexerPublicConfigSchema(valueLabel);
|
|
1065
|
+
const parsed = schema.safeParse(maybeConfig);
|
|
1066
|
+
if (parsed.error) {
|
|
1067
|
+
throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
|
|
1068
|
+
${prettifyError3(parsed.error)}
|
|
1069
|
+
`);
|
|
1070
|
+
}
|
|
1071
|
+
return parsed.data;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// src/ensindexer/config/label-utils.ts
|
|
1075
|
+
import { hexToBytes as hexToBytes2 } from "viem";
|
|
1076
|
+
function labelHashToBytes(labelHash) {
|
|
1077
|
+
try {
|
|
1078
|
+
if (labelHash.length !== 66) {
|
|
1079
|
+
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
1080
|
+
}
|
|
1081
|
+
if (labelHash !== labelHash.toLowerCase()) {
|
|
1082
|
+
throw new Error("Labelhash must be in lowercase");
|
|
1083
|
+
}
|
|
1084
|
+
if (!labelHash.startsWith("0x")) {
|
|
1085
|
+
throw new Error("Labelhash must be 0x-prefixed");
|
|
1086
|
+
}
|
|
1087
|
+
const bytes = hexToBytes2(labelHash);
|
|
1088
|
+
if (bytes.length !== 32) {
|
|
1089
|
+
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
1090
|
+
}
|
|
1091
|
+
return bytes;
|
|
1092
|
+
} catch (e) {
|
|
1093
|
+
if (e instanceof Error) {
|
|
1094
|
+
throw e;
|
|
1024
1095
|
}
|
|
1096
|
+
throw new Error("Invalid hex format");
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// src/ensindexer/config/labelset-utils.ts
|
|
1101
|
+
function buildLabelSetId(maybeLabelSetId) {
|
|
1102
|
+
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
1103
|
+
}
|
|
1104
|
+
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
1105
|
+
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
1106
|
+
}
|
|
1107
|
+
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
1108
|
+
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
1109
|
+
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
1110
|
+
}
|
|
1111
|
+
return { labelSetId, labelSetVersion };
|
|
1112
|
+
}
|
|
1113
|
+
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
1114
|
+
if (clientSet.labelSetId === void 0) {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
1118
|
+
throw new Error(
|
|
1119
|
+
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
1120
|
+
);
|
|
1121
|
+
}
|
|
1122
|
+
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
1123
|
+
throw new Error(
|
|
1124
|
+
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/ensindexer/config/parsing.ts
|
|
1130
|
+
function parseNonNegativeInteger(maybeNumber) {
|
|
1131
|
+
const trimmed = maybeNumber.trim();
|
|
1132
|
+
if (!trimmed) {
|
|
1133
|
+
throw new Error("Input cannot be empty");
|
|
1134
|
+
}
|
|
1135
|
+
if (trimmed === "-0") {
|
|
1136
|
+
throw new Error("Negative zero is not a valid non-negative integer");
|
|
1137
|
+
}
|
|
1138
|
+
const num = Number(maybeNumber);
|
|
1139
|
+
if (Number.isNaN(num)) {
|
|
1140
|
+
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
1141
|
+
}
|
|
1142
|
+
if (!Number.isFinite(num)) {
|
|
1143
|
+
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
1144
|
+
}
|
|
1145
|
+
if (!Number.isInteger(num)) {
|
|
1146
|
+
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
1147
|
+
}
|
|
1148
|
+
if (num < 0) {
|
|
1149
|
+
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
1150
|
+
}
|
|
1151
|
+
return num;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// src/ensindexer/config/serialize.ts
|
|
1155
|
+
function serializeIndexedChainIds(indexedChainIds) {
|
|
1156
|
+
return Array.from(indexedChainIds);
|
|
1157
|
+
}
|
|
1158
|
+
function serializeENSIndexerPublicConfig(config) {
|
|
1159
|
+
const {
|
|
1160
|
+
labelSet,
|
|
1161
|
+
indexedChainIds,
|
|
1162
|
+
databaseSchemaName,
|
|
1163
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1164
|
+
namespace,
|
|
1165
|
+
plugins,
|
|
1166
|
+
versionInfo
|
|
1167
|
+
} = config;
|
|
1168
|
+
return {
|
|
1169
|
+
labelSet,
|
|
1170
|
+
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
1171
|
+
databaseSchemaName,
|
|
1172
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1173
|
+
namespace,
|
|
1174
|
+
plugins,
|
|
1175
|
+
versionInfo
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// src/ensindexer/indexing-status/deserialize.ts
|
|
1180
|
+
import { prettifyError as prettifyError4 } from "zod/v4";
|
|
1181
|
+
|
|
1182
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1183
|
+
import z4 from "zod/v4";
|
|
1184
|
+
|
|
1185
|
+
// src/ensindexer/indexing-status/types.ts
|
|
1186
|
+
var ChainIndexingConfigTypeIds = {
|
|
1187
|
+
/**
|
|
1188
|
+
* Represents that indexing of the chain should be performed for an indefinite range.
|
|
1189
|
+
*/
|
|
1190
|
+
Indefinite: "indefinite",
|
|
1191
|
+
/**
|
|
1192
|
+
* Represents that indexing of the chain should be performed for a definite range.
|
|
1193
|
+
*/
|
|
1194
|
+
Definite: "definite"
|
|
1195
|
+
};
|
|
1196
|
+
var ChainIndexingStatusIds = {
|
|
1197
|
+
/**
|
|
1198
|
+
* Represents that indexing of the chain is not ready to begin yet because:
|
|
1199
|
+
* - ENSIndexer is in its initialization phase and the data to build a
|
|
1200
|
+
* "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
|
|
1201
|
+
* - ENSIndexer is using an omnichain indexing strategy and the
|
|
1202
|
+
* `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
|
|
1203
|
+
* {@link ChainIndexingSnapshot}.
|
|
1204
|
+
*/
|
|
1205
|
+
Queued: "chain-queued",
|
|
1206
|
+
/**
|
|
1207
|
+
* Represents that indexing of the chain is in progress and under a special
|
|
1208
|
+
* "backfill" phase that optimizes for accelerated indexing until reaching the
|
|
1209
|
+
* "fixed target" `backfillEndBlock`.
|
|
1210
|
+
*/
|
|
1211
|
+
Backfill: "chain-backfill",
|
|
1212
|
+
/**
|
|
1213
|
+
* Represents that the "backfill" phase of indexing the chain is completed
|
|
1214
|
+
* and that the chain is configured to be indexed for an indefinite range.
|
|
1215
|
+
* Therefore, indexing of the chain remains indefinitely in progress where
|
|
1216
|
+
* ENSIndexer will continuously work to discover and index new blocks as they
|
|
1217
|
+
* are added to the chain across time.
|
|
1218
|
+
*/
|
|
1219
|
+
Following: "chain-following",
|
|
1220
|
+
/**
|
|
1221
|
+
* Represents that indexing of the chain is completed as the chain is configured
|
|
1222
|
+
* to be indexed for a definite range and the indexing of all blocks through
|
|
1223
|
+
* that definite range is completed.
|
|
1224
|
+
*/
|
|
1225
|
+
Completed: "chain-completed"
|
|
1226
|
+
};
|
|
1227
|
+
var OmnichainIndexingStatusIds = {
|
|
1228
|
+
/**
|
|
1229
|
+
* Represents that omnichain indexing is not ready to begin yet because
|
|
1230
|
+
* ENSIndexer is in its initialization phase and the data to build a "true"
|
|
1231
|
+
* {@link OmnichainIndexingStatusSnapshot} is still being loaded.
|
|
1232
|
+
*/
|
|
1233
|
+
Unstarted: "omnichain-unstarted",
|
|
1234
|
+
/**
|
|
1235
|
+
* Represents that omnichain indexing is in an overall "backfill" status because
|
|
1236
|
+
* - At least one indexed chain has a `chainStatus` of
|
|
1237
|
+
* {@link ChainIndexingStatusIds.Backfill}; and
|
|
1238
|
+
* - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
|
|
1239
|
+
*/
|
|
1240
|
+
Backfill: "omnichain-backfill",
|
|
1241
|
+
/**
|
|
1242
|
+
* Represents that omnichain indexing is in an overall "following" status because
|
|
1243
|
+
* at least one indexed chain has a `chainStatus` of
|
|
1244
|
+
* {@link ChainIndexingStatusIds.Following}.
|
|
1245
|
+
*/
|
|
1246
|
+
Following: "omnichain-following",
|
|
1247
|
+
/**
|
|
1248
|
+
* Represents that omnichain indexing has completed because all indexed chains have
|
|
1249
|
+
* a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
|
|
1250
|
+
*/
|
|
1251
|
+
Completed: "omnichain-completed"
|
|
1252
|
+
};
|
|
1253
|
+
var CrossChainIndexingStrategyIds = {
|
|
1254
|
+
/**
|
|
1255
|
+
* Represents that the indexing of events across all indexed chains will
|
|
1256
|
+
* proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
|
|
1257
|
+
* and block number.
|
|
1258
|
+
*
|
|
1259
|
+
* This strategy is "deterministic" in that the order of processing cross-chain indexed
|
|
1260
|
+
* events and each resulting indexed data state transition recorded in ENSDb is always
|
|
1261
|
+
* the same for each ENSIndexer instance operating with an equivalent
|
|
1262
|
+
* `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
|
|
1263
|
+
* - increased indexing latency that must wait for the slowest indexed chain to
|
|
1264
|
+
* add new blocks or to discover new blocks through the configured RPCs.
|
|
1265
|
+
* - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
|
|
1266
|
+
* will be affected.
|
|
1267
|
+
*/
|
|
1268
|
+
Omnichain: "omnichain"
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
// src/shared/block-ref.ts
|
|
1272
|
+
function isBefore(blockA, blockB) {
|
|
1273
|
+
return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
|
|
1274
|
+
}
|
|
1275
|
+
function isEqualTo(blockA, blockB) {
|
|
1276
|
+
return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
|
|
1277
|
+
}
|
|
1278
|
+
function isBeforeOrEqualTo(blockA, blockB) {
|
|
1279
|
+
return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
// src/ensindexer/indexing-status/helpers.ts
|
|
1283
|
+
function getOmnichainIndexingStatus(chains) {
|
|
1284
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
|
|
1285
|
+
return OmnichainIndexingStatusIds.Following;
|
|
1286
|
+
}
|
|
1287
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
|
|
1288
|
+
return OmnichainIndexingStatusIds.Backfill;
|
|
1289
|
+
}
|
|
1290
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
|
|
1291
|
+
return OmnichainIndexingStatusIds.Unstarted;
|
|
1292
|
+
}
|
|
1293
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
|
|
1294
|
+
return OmnichainIndexingStatusIds.Completed;
|
|
1295
|
+
}
|
|
1296
|
+
throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
|
|
1297
|
+
}
|
|
1298
|
+
function getTimestampForLowestOmnichainStartBlock(chains) {
|
|
1299
|
+
const earliestKnownBlockTimestamps = chains.map(
|
|
1300
|
+
(chain) => chain.config.startBlock.timestamp
|
|
1301
|
+
);
|
|
1302
|
+
return Math.min(...earliestKnownBlockTimestamps);
|
|
1303
|
+
}
|
|
1304
|
+
function getTimestampForHighestOmnichainKnownBlock(chains) {
|
|
1305
|
+
const latestKnownBlockTimestamps = [];
|
|
1306
|
+
for (const chain of chains) {
|
|
1307
|
+
switch (chain.chainStatus) {
|
|
1308
|
+
case ChainIndexingStatusIds.Queued:
|
|
1309
|
+
if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
|
|
1310
|
+
latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
|
|
1311
|
+
}
|
|
1312
|
+
break;
|
|
1313
|
+
case ChainIndexingStatusIds.Backfill:
|
|
1314
|
+
latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
|
|
1315
|
+
break;
|
|
1316
|
+
case ChainIndexingStatusIds.Completed:
|
|
1317
|
+
latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
|
|
1318
|
+
break;
|
|
1319
|
+
case ChainIndexingStatusIds.Following:
|
|
1320
|
+
latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
|
|
1321
|
+
break;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
return Math.max(...latestKnownBlockTimestamps);
|
|
1325
|
+
}
|
|
1326
|
+
function getOmnichainIndexingCursor(chains) {
|
|
1327
|
+
if (chains.length === 0) {
|
|
1328
|
+
throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
|
|
1329
|
+
}
|
|
1330
|
+
if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
|
|
1331
|
+
const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1332
|
+
return Math.min(...earliestStartBlockTimestamps) - 1;
|
|
1333
|
+
}
|
|
1334
|
+
const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
|
|
1335
|
+
if (latestIndexedBlockTimestamps.length < 1) {
|
|
1336
|
+
throw new Error("latestIndexedBlockTimestamps array must include at least one element");
|
|
1337
|
+
}
|
|
1338
|
+
return Math.max(...latestIndexedBlockTimestamps);
|
|
1339
|
+
}
|
|
1340
|
+
function createIndexingConfig(startBlock, endBlock) {
|
|
1341
|
+
if (endBlock) {
|
|
1342
|
+
return {
|
|
1343
|
+
configType: ChainIndexingConfigTypeIds.Definite,
|
|
1344
|
+
startBlock,
|
|
1345
|
+
endBlock
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
return {
|
|
1349
|
+
configType: ChainIndexingConfigTypeIds.Indefinite,
|
|
1350
|
+
startBlock
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
|
|
1354
|
+
return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
|
|
1355
|
+
}
|
|
1356
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
|
|
1357
|
+
const atLeastOneChainInTargetStatus = chains.some(
|
|
1358
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1359
|
+
);
|
|
1360
|
+
const otherChainsHaveValidStatuses = chains.every(
|
|
1361
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1362
|
+
);
|
|
1363
|
+
return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
|
|
1364
|
+
}
|
|
1365
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
|
|
1366
|
+
const allChainsHaveValidStatuses = chains.every(
|
|
1367
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1368
|
+
);
|
|
1369
|
+
return allChainsHaveValidStatuses;
|
|
1370
|
+
}
|
|
1371
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
|
|
1372
|
+
const allChainsHaveValidStatuses = chains.some(
|
|
1373
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1374
|
+
);
|
|
1375
|
+
return allChainsHaveValidStatuses;
|
|
1376
|
+
}
|
|
1377
|
+
function sortChainStatusesByStartBlockAsc(chains) {
|
|
1378
|
+
chains.sort(
|
|
1379
|
+
([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
|
|
1380
|
+
);
|
|
1381
|
+
return chains;
|
|
1382
|
+
}
|
|
1383
|
+
function getLatestIndexedBlockRef(indexingStatus, chainId) {
|
|
1384
|
+
const chainIndexingStatus = indexingStatus.omnichainSnapshot.chains.get(chainId);
|
|
1385
|
+
if (chainIndexingStatus === void 0) {
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
if (chainIndexingStatus.chainStatus === ChainIndexingStatusIds.Queued) {
|
|
1389
|
+
return null;
|
|
1390
|
+
}
|
|
1391
|
+
return chainIndexingStatus.latestIndexedBlock;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// src/ensindexer/indexing-status/validations.ts
|
|
1395
|
+
function invariant_chainSnapshotQueuedBlocks(ctx) {
|
|
1396
|
+
const { config } = ctx.value;
|
|
1397
|
+
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
|
|
1401
|
+
ctx.issues.push({
|
|
1402
|
+
code: "custom",
|
|
1403
|
+
input: ctx.value,
|
|
1404
|
+
message: "`config.startBlock` must be before or same as `config.endBlock`."
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function invariant_chainSnapshotBackfillBlocks(ctx) {
|
|
1409
|
+
const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
|
|
1410
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1411
|
+
ctx.issues.push({
|
|
1412
|
+
code: "custom",
|
|
1413
|
+
input: ctx.value,
|
|
1414
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
|
|
1418
|
+
ctx.issues.push({
|
|
1419
|
+
code: "custom",
|
|
1420
|
+
input: ctx.value,
|
|
1421
|
+
message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1424
|
+
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
|
|
1428
|
+
ctx.issues.push({
|
|
1429
|
+
code: "custom",
|
|
1430
|
+
input: ctx.value,
|
|
1431
|
+
message: "`backfillEndBlock` must be the same as `config.endBlock`."
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
function invariant_chainSnapshotCompletedBlocks(ctx) {
|
|
1436
|
+
const { config, latestIndexedBlock } = ctx.value;
|
|
1437
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1438
|
+
ctx.issues.push({
|
|
1439
|
+
code: "custom",
|
|
1440
|
+
input: ctx.value,
|
|
1441
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
|
|
1445
|
+
ctx.issues.push({
|
|
1446
|
+
code: "custom",
|
|
1447
|
+
input: ctx.value,
|
|
1448
|
+
message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function invariant_chainSnapshotFollowingBlocks(ctx) {
|
|
1453
|
+
const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
|
|
1454
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1455
|
+
ctx.issues.push({
|
|
1456
|
+
code: "custom",
|
|
1457
|
+
input: ctx.value,
|
|
1458
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
|
|
1462
|
+
ctx.issues.push({
|
|
1463
|
+
code: "custom",
|
|
1464
|
+
input: ctx.value,
|
|
1465
|
+
message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
|
|
1470
|
+
const snapshot = ctx.value;
|
|
1471
|
+
const chains = Array.from(snapshot.chains.values());
|
|
1472
|
+
const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
|
|
1473
|
+
const actualOmnichainStatus = snapshot.omnichainStatus;
|
|
1474
|
+
if (expectedOmnichainStatus !== actualOmnichainStatus) {
|
|
1475
|
+
ctx.issues.push({
|
|
1476
|
+
code: "custom",
|
|
1477
|
+
input: snapshot,
|
|
1478
|
+
message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
|
|
1483
|
+
const snapshot = ctx.value;
|
|
1484
|
+
const queuedChains = Array.from(snapshot.chains.values()).filter(
|
|
1485
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
|
|
1486
|
+
);
|
|
1487
|
+
if (queuedChains.length === 0) {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
|
|
1491
|
+
const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
|
|
1492
|
+
if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
|
|
1493
|
+
ctx.issues.push({
|
|
1494
|
+
code: "custom",
|
|
1495
|
+
input: snapshot,
|
|
1496
|
+
message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
|
|
1501
|
+
const snapshot = ctx.value;
|
|
1502
|
+
const backfillChains = Array.from(snapshot.chains.values()).filter(
|
|
1503
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1504
|
+
);
|
|
1505
|
+
if (backfillChains.length === 0) {
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
|
|
1509
|
+
const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
|
|
1510
|
+
if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
|
|
1511
|
+
ctx.issues.push({
|
|
1512
|
+
code: "custom",
|
|
1513
|
+
input: snapshot,
|
|
1514
|
+
message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
|
|
1519
|
+
const snapshot = ctx.value;
|
|
1520
|
+
const indexedChains = Array.from(snapshot.chains.values()).filter(
|
|
1521
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1522
|
+
);
|
|
1523
|
+
if (indexedChains.length === 0) {
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
const indexedChainLatestIndexedBlocks = indexedChains.map(
|
|
1527
|
+
(chain) => chain.latestIndexedBlock.timestamp
|
|
1528
|
+
);
|
|
1529
|
+
const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
|
|
1530
|
+
if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
|
|
1531
|
+
ctx.issues.push({
|
|
1532
|
+
code: "custom",
|
|
1533
|
+
input: snapshot,
|
|
1534
|
+
message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
|
|
1539
|
+
const chains = ctx.value;
|
|
1540
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
|
|
1541
|
+
Array.from(chains.values())
|
|
1542
|
+
);
|
|
1543
|
+
if (hasValidChains === false) {
|
|
1544
|
+
ctx.issues.push({
|
|
1545
|
+
code: "custom",
|
|
1546
|
+
input: chains,
|
|
1547
|
+
message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
|
|
1548
|
+
});
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
|
|
1552
|
+
const chains = ctx.value;
|
|
1553
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
|
|
1554
|
+
Array.from(chains.values())
|
|
1555
|
+
);
|
|
1556
|
+
if (hasValidChains === false) {
|
|
1557
|
+
ctx.issues.push({
|
|
1558
|
+
code: "custom",
|
|
1559
|
+
input: chains,
|
|
1560
|
+
message: `For omnichain status snapshot 'backfill', at least one chain must be in "backfill" status and each chain has to have a status of either "queued", "backfill" or "completed".`
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
|
|
1565
|
+
const chains = ctx.value;
|
|
1566
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
|
|
1567
|
+
Array.from(chains.values())
|
|
1568
|
+
);
|
|
1569
|
+
if (hasValidChains === false) {
|
|
1570
|
+
ctx.issues.push({
|
|
1571
|
+
code: "custom",
|
|
1572
|
+
input: chains,
|
|
1573
|
+
message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
|
|
1574
|
+
});
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
|
|
1578
|
+
const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
|
|
1579
|
+
const { omnichainIndexingCursor } = omnichainSnapshot;
|
|
1580
|
+
if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
|
|
1581
|
+
console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
|
|
1582
|
+
slowestChainIndexingCursor,
|
|
1583
|
+
omnichainIndexingCursor
|
|
1584
|
+
});
|
|
1585
|
+
ctx.issues.push({
|
|
1586
|
+
code: "custom",
|
|
1587
|
+
input: ctx.value,
|
|
1588
|
+
message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
|
|
1593
|
+
const { snapshotTime, omnichainSnapshot } = ctx.value;
|
|
1594
|
+
const chains = Array.from(omnichainSnapshot.chains.values());
|
|
1595
|
+
const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1596
|
+
const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
|
|
1597
|
+
const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
|
|
1598
|
+
const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
|
|
1599
|
+
const highestKnownBlockTimestamp = Math.max(
|
|
1600
|
+
...startBlockTimestamps,
|
|
1601
|
+
...endBlockTimestamps,
|
|
1602
|
+
...backfillEndBlockTimestamps,
|
|
1603
|
+
...latestKnownBlockTimestamps
|
|
1604
|
+
);
|
|
1605
|
+
if (snapshotTime < highestKnownBlockTimestamp) {
|
|
1606
|
+
ctx.issues.push({
|
|
1607
|
+
code: "custom",
|
|
1608
|
+
input: ctx.value,
|
|
1609
|
+
message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
|
|
1614
|
+
const projection = ctx.value;
|
|
1615
|
+
const { snapshot, projectedAt } = projection;
|
|
1616
|
+
if (snapshot.snapshotTime > projectedAt) {
|
|
1617
|
+
ctx.issues.push({
|
|
1618
|
+
code: "custom",
|
|
1619
|
+
input: projection,
|
|
1620
|
+
message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
|
|
1621
|
+
});
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
|
|
1625
|
+
const projection = ctx.value;
|
|
1626
|
+
const { projectedAt, snapshot, worstCaseDistance } = projection;
|
|
1627
|
+
const { omnichainSnapshot } = snapshot;
|
|
1628
|
+
const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
|
|
1629
|
+
if (worstCaseDistance !== expectedWorstCaseDistance) {
|
|
1630
|
+
ctx.issues.push({
|
|
1631
|
+
code: "custom",
|
|
1632
|
+
input: projection,
|
|
1633
|
+
message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1639
|
+
var makeChainIndexingConfigSchema = (valueLabel = "Value") => z4.discriminatedUnion("configType", [
|
|
1640
|
+
z4.strictObject({
|
|
1641
|
+
configType: z4.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1642
|
+
startBlock: makeBlockRefSchema(valueLabel)
|
|
1643
|
+
}),
|
|
1644
|
+
z4.strictObject({
|
|
1645
|
+
configType: z4.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1646
|
+
startBlock: makeBlockRefSchema(valueLabel),
|
|
1647
|
+
endBlock: makeBlockRefSchema(valueLabel)
|
|
1648
|
+
})
|
|
1649
|
+
]);
|
|
1650
|
+
var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => z4.strictObject({
|
|
1651
|
+
chainStatus: z4.literal(ChainIndexingStatusIds.Queued),
|
|
1652
|
+
config: makeChainIndexingConfigSchema(valueLabel)
|
|
1653
|
+
}).check(invariant_chainSnapshotQueuedBlocks);
|
|
1654
|
+
var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => z4.strictObject({
|
|
1655
|
+
chainStatus: z4.literal(ChainIndexingStatusIds.Backfill),
|
|
1656
|
+
config: makeChainIndexingConfigSchema(valueLabel),
|
|
1657
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1658
|
+
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
1659
|
+
}).check(invariant_chainSnapshotBackfillBlocks);
|
|
1660
|
+
var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => z4.strictObject({
|
|
1661
|
+
chainStatus: z4.literal(ChainIndexingStatusIds.Completed),
|
|
1662
|
+
config: z4.strictObject({
|
|
1663
|
+
configType: z4.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1664
|
+
startBlock: makeBlockRefSchema(valueLabel),
|
|
1665
|
+
endBlock: makeBlockRefSchema(valueLabel)
|
|
1666
|
+
}),
|
|
1667
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel)
|
|
1668
|
+
}).check(invariant_chainSnapshotCompletedBlocks);
|
|
1669
|
+
var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => z4.strictObject({
|
|
1670
|
+
chainStatus: z4.literal(ChainIndexingStatusIds.Following),
|
|
1671
|
+
config: z4.strictObject({
|
|
1672
|
+
configType: z4.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1673
|
+
startBlock: makeBlockRefSchema(valueLabel)
|
|
1674
|
+
}),
|
|
1675
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1676
|
+
latestKnownBlock: makeBlockRefSchema(valueLabel)
|
|
1677
|
+
}).check(invariant_chainSnapshotFollowingBlocks);
|
|
1678
|
+
var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => z4.discriminatedUnion("chainStatus", [
|
|
1679
|
+
makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
|
|
1680
|
+
makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1681
|
+
makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1682
|
+
makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1683
|
+
]);
|
|
1684
|
+
var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z4.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
|
|
1685
|
+
error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
|
|
1686
|
+
}).transform((serializedChainsIndexingStatus) => {
|
|
1687
|
+
const chainsIndexingStatus = /* @__PURE__ */ new Map();
|
|
1688
|
+
for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
|
|
1689
|
+
chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
|
|
1690
|
+
}
|
|
1691
|
+
return chainsIndexingStatus;
|
|
1692
|
+
});
|
|
1693
|
+
var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => z4.strictObject({
|
|
1694
|
+
omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Unstarted),
|
|
1695
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
|
|
1696
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1697
|
+
});
|
|
1698
|
+
var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => z4.strictObject({
|
|
1699
|
+
omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Backfill),
|
|
1700
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
|
|
1701
|
+
(chains) => chains
|
|
1702
|
+
),
|
|
1703
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1704
|
+
});
|
|
1705
|
+
var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => z4.strictObject({
|
|
1706
|
+
omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Completed),
|
|
1707
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
|
|
1708
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1709
|
+
});
|
|
1710
|
+
var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => z4.strictObject({
|
|
1711
|
+
omnichainStatus: z4.literal(OmnichainIndexingStatusIds.Following),
|
|
1712
|
+
chains: makeChainIndexingStatusesSchema(valueLabel),
|
|
1713
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1714
|
+
});
|
|
1715
|
+
var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => z4.discriminatedUnion("omnichainStatus", [
|
|
1716
|
+
makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
|
|
1717
|
+
makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1718
|
+
makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1719
|
+
makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1720
|
+
]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
|
|
1721
|
+
invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
|
|
1722
|
+
).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
|
|
1723
|
+
var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => z4.strictObject({
|
|
1724
|
+
strategy: z4.literal(CrossChainIndexingStrategyIds.Omnichain),
|
|
1725
|
+
slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
|
|
1726
|
+
snapshotTime: makeUnixTimestampSchema(valueLabel),
|
|
1727
|
+
omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
|
|
1728
|
+
}).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
|
|
1729
|
+
var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => z4.discriminatedUnion("strategy", [
|
|
1730
|
+
makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
|
|
1731
|
+
]);
|
|
1732
|
+
var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => z4.strictObject({
|
|
1733
|
+
projectedAt: makeUnixTimestampSchema(valueLabel),
|
|
1734
|
+
worstCaseDistance: makeDurationSchema(valueLabel),
|
|
1735
|
+
snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
|
|
1736
|
+
}).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
|
|
1737
|
+
|
|
1738
|
+
// src/ensindexer/indexing-status/deserialize.ts
|
|
1739
|
+
function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1740
|
+
const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
|
|
1741
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
1742
|
+
if (parsed.error) {
|
|
1743
|
+
throw new Error(
|
|
1744
|
+
`Cannot deserialize into ChainIndexingStatusSnapshot:
|
|
1745
|
+
${prettifyError4(parsed.error)}
|
|
1746
|
+
`
|
|
1747
|
+
);
|
|
1025
1748
|
}
|
|
1026
|
-
return
|
|
1749
|
+
return parsed.data;
|
|
1027
1750
|
}
|
|
1028
|
-
function
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1751
|
+
function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1752
|
+
const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
|
|
1753
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
1754
|
+
if (parsed.error) {
|
|
1755
|
+
throw new Error(
|
|
1756
|
+
`Cannot deserialize into OmnichainIndexingStatusSnapshot:
|
|
1757
|
+
${prettifyError4(parsed.error)}
|
|
1758
|
+
`
|
|
1759
|
+
);
|
|
1035
1760
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1761
|
+
return parsed.data;
|
|
1762
|
+
}
|
|
1763
|
+
function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1764
|
+
const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
|
|
1765
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
1766
|
+
if (parsed.error) {
|
|
1767
|
+
throw new Error(
|
|
1768
|
+
`Cannot deserialize into CrossChainIndexingStatusSnapshot:
|
|
1769
|
+
${prettifyError4(parsed.error)}
|
|
1770
|
+
`
|
|
1771
|
+
);
|
|
1039
1772
|
}
|
|
1040
|
-
return
|
|
1773
|
+
return parsed.data;
|
|
1041
1774
|
}
|
|
1042
|
-
function
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1775
|
+
function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
|
|
1776
|
+
const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
|
|
1777
|
+
const parsed = schema.safeParse(maybeProjection);
|
|
1778
|
+
if (parsed.error) {
|
|
1779
|
+
throw new Error(
|
|
1780
|
+
`Cannot deserialize into RealtimeIndexingStatusProjection:
|
|
1781
|
+
${prettifyError4(parsed.error)}
|
|
1782
|
+
`
|
|
1783
|
+
);
|
|
1049
1784
|
}
|
|
1785
|
+
return parsed.data;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
// src/ensindexer/indexing-status/projection.ts
|
|
1789
|
+
function createRealtimeIndexingStatusProjection(snapshot, now) {
|
|
1790
|
+
const projectedAt = Math.max(now, snapshot.snapshotTime);
|
|
1050
1791
|
return {
|
|
1051
|
-
|
|
1052
|
-
|
|
1792
|
+
projectedAt,
|
|
1793
|
+
worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
|
|
1794
|
+
snapshot
|
|
1053
1795
|
};
|
|
1054
1796
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1797
|
+
|
|
1798
|
+
// src/ensindexer/indexing-status/serialize.ts
|
|
1799
|
+
function serializeCrossChainIndexingStatusSnapshotOmnichain({
|
|
1800
|
+
strategy,
|
|
1801
|
+
slowestChainIndexingCursor,
|
|
1802
|
+
snapshotTime,
|
|
1803
|
+
omnichainSnapshot
|
|
1804
|
+
}) {
|
|
1805
|
+
return {
|
|
1806
|
+
strategy,
|
|
1807
|
+
slowestChainIndexingCursor,
|
|
1808
|
+
snapshotTime,
|
|
1809
|
+
omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
|
|
1810
|
+
};
|
|
1057
1811
|
}
|
|
1058
|
-
function
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
);
|
|
1065
|
-
return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
|
|
1812
|
+
function serializeRealtimeIndexingStatusProjection(indexingProjection) {
|
|
1813
|
+
return {
|
|
1814
|
+
projectedAt: indexingProjection.projectedAt,
|
|
1815
|
+
worstCaseDistance: indexingProjection.worstCaseDistance,
|
|
1816
|
+
snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
|
|
1817
|
+
};
|
|
1066
1818
|
}
|
|
1067
|
-
function
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1819
|
+
function serializeChainIndexingSnapshots(chains) {
|
|
1820
|
+
const serializedSnapshots = {};
|
|
1821
|
+
for (const [chainId, snapshot] of chains.entries()) {
|
|
1822
|
+
serializedSnapshots[serializeChainId(chainId)] = snapshot;
|
|
1823
|
+
}
|
|
1824
|
+
return serializedSnapshots;
|
|
1072
1825
|
}
|
|
1073
|
-
function
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1826
|
+
function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
|
|
1827
|
+
switch (indexingStatus.omnichainStatus) {
|
|
1828
|
+
case OmnichainIndexingStatusIds.Unstarted:
|
|
1829
|
+
return {
|
|
1830
|
+
omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
|
|
1831
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
1832
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
1833
|
+
};
|
|
1834
|
+
case OmnichainIndexingStatusIds.Backfill:
|
|
1835
|
+
return {
|
|
1836
|
+
omnichainStatus: OmnichainIndexingStatusIds.Backfill,
|
|
1837
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
1838
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
1839
|
+
};
|
|
1840
|
+
case OmnichainIndexingStatusIds.Completed: {
|
|
1841
|
+
return {
|
|
1842
|
+
omnichainStatus: OmnichainIndexingStatusIds.Completed,
|
|
1843
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
1844
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
case OmnichainIndexingStatusIds.Following:
|
|
1848
|
+
return {
|
|
1849
|
+
omnichainStatus: OmnichainIndexingStatusIds.Following,
|
|
1850
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
1851
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
1852
|
+
};
|
|
1853
|
+
}
|
|
1078
1854
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
return
|
|
1855
|
+
|
|
1856
|
+
// src/ensapi/config/serialize.ts
|
|
1857
|
+
function serializeENSApiPublicConfig(config) {
|
|
1858
|
+
const { version, theGraphFallback, ensIndexerPublicConfig } = config;
|
|
1859
|
+
return {
|
|
1860
|
+
version,
|
|
1861
|
+
theGraphFallback,
|
|
1862
|
+
ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
|
|
1863
|
+
};
|
|
1084
1864
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1865
|
+
|
|
1866
|
+
// src/api/config/deserialize.ts
|
|
1867
|
+
function deserializeConfigResponse(serializedResponse) {
|
|
1868
|
+
return deserializeENSApiPublicConfig(serializedResponse);
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
// src/api/config/serialize.ts
|
|
1872
|
+
function serializeConfigResponse(response) {
|
|
1873
|
+
return serializeENSApiPublicConfig(response);
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// src/api/indexing-status/deserialize.ts
|
|
1877
|
+
import { prettifyError as prettifyError5 } from "zod/v4";
|
|
1878
|
+
|
|
1879
|
+
// src/api/indexing-status/zod-schemas.ts
|
|
1880
|
+
import z5 from "zod/v4";
|
|
1881
|
+
|
|
1882
|
+
// src/api/indexing-status/response.ts
|
|
1883
|
+
var IndexingStatusResponseCodes = {
|
|
1884
|
+
/**
|
|
1885
|
+
* Represents that the indexing status is available.
|
|
1886
|
+
*/
|
|
1887
|
+
Ok: "ok",
|
|
1888
|
+
/**
|
|
1889
|
+
* Represents that the indexing status is unavailable.
|
|
1890
|
+
*/
|
|
1891
|
+
Error: "error"
|
|
1892
|
+
};
|
|
1893
|
+
|
|
1894
|
+
// src/api/indexing-status/zod-schemas.ts
|
|
1895
|
+
var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z5.strictObject({
|
|
1896
|
+
responseCode: z5.literal(IndexingStatusResponseCodes.Ok),
|
|
1897
|
+
realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
|
|
1898
|
+
});
|
|
1899
|
+
var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => z5.strictObject({
|
|
1900
|
+
responseCode: z5.literal(IndexingStatusResponseCodes.Error)
|
|
1901
|
+
});
|
|
1902
|
+
var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z5.discriminatedUnion("responseCode", [
|
|
1903
|
+
makeIndexingStatusResponseOkSchema(valueLabel),
|
|
1904
|
+
makeIndexingStatusResponseErrorSchema(valueLabel)
|
|
1905
|
+
]);
|
|
1906
|
+
|
|
1907
|
+
// src/api/indexing-status/deserialize.ts
|
|
1908
|
+
function deserializeIndexingStatusResponse(maybeResponse) {
|
|
1909
|
+
const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
|
|
1910
|
+
if (parsed.error) {
|
|
1911
|
+
throw new Error(`Cannot deserialize IndexingStatusResponse:
|
|
1912
|
+
${prettifyError5(parsed.error)}
|
|
1913
|
+
`);
|
|
1089
1914
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1915
|
+
return parsed.data;
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
// src/api/indexing-status/serialize.ts
|
|
1919
|
+
function serializeIndexingStatusResponse(response) {
|
|
1920
|
+
switch (response.responseCode) {
|
|
1921
|
+
case IndexingStatusResponseCodes.Ok:
|
|
1922
|
+
return {
|
|
1923
|
+
responseCode: response.responseCode,
|
|
1924
|
+
realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
|
|
1925
|
+
};
|
|
1926
|
+
case IndexingStatusResponseCodes.Error:
|
|
1927
|
+
return response;
|
|
1092
1928
|
}
|
|
1093
|
-
return chainIndexingStatus.latestIndexedBlock;
|
|
1094
1929
|
}
|
|
1095
|
-
|
|
1096
|
-
// src/
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1930
|
+
|
|
1931
|
+
// src/api/name-tokens/deserialize.ts
|
|
1932
|
+
import { prettifyError as prettifyError7 } from "zod/v4";
|
|
1933
|
+
|
|
1934
|
+
// src/api/name-tokens/zod-schemas.ts
|
|
1935
|
+
import { namehash as namehash2 } from "viem";
|
|
1936
|
+
import z8 from "zod/v4";
|
|
1937
|
+
|
|
1938
|
+
// src/tokenscope/assets.ts
|
|
1939
|
+
import { AssetId as CaipAssetId2 } from "caip";
|
|
1940
|
+
import { isAddressEqual as isAddressEqual3, zeroAddress as zeroAddress3 } from "viem";
|
|
1941
|
+
import { prettifyError as prettifyError6 } from "zod/v4";
|
|
1942
|
+
|
|
1943
|
+
// src/tokenscope/zod-schemas.ts
|
|
1944
|
+
import { AssetId as CaipAssetId } from "caip";
|
|
1945
|
+
import { zeroAddress as zeroAddress2 } from "viem";
|
|
1946
|
+
import z6 from "zod/v4";
|
|
1947
|
+
|
|
1948
|
+
// src/tokenscope/name-token.ts
|
|
1949
|
+
import { isAddressEqual as isAddressEqual2, zeroAddress } from "viem";
|
|
1950
|
+
import { DatasourceNames } from "@ensnode/datasources";
|
|
1951
|
+
var NameTokenOwnershipTypes = {
|
|
1952
|
+
/**
|
|
1953
|
+
* Name Token is owned by NameWrapper account.
|
|
1954
|
+
*/
|
|
1955
|
+
NameWrapper: "namewrapper",
|
|
1956
|
+
/**
|
|
1957
|
+
* Name Token is owned fully onchain.
|
|
1958
|
+
*
|
|
1959
|
+
* This ownership type can only apply to direct subnames of `.eth`
|
|
1960
|
+
*/
|
|
1961
|
+
FullyOnchain: "fully-onchain",
|
|
1962
|
+
/**
|
|
1963
|
+
* Name Token ownership has been transferred to the null address.
|
|
1964
|
+
*/
|
|
1965
|
+
Burned: "burned",
|
|
1966
|
+
/**
|
|
1967
|
+
* Name Token ownership is unknown.
|
|
1968
|
+
*/
|
|
1969
|
+
Unknown: "unknown"
|
|
1970
|
+
};
|
|
1971
|
+
function serializeNameToken(nameToken) {
|
|
1972
|
+
return {
|
|
1973
|
+
token: serializeAssetId(nameToken.token),
|
|
1974
|
+
ownership: nameToken.ownership,
|
|
1975
|
+
mintStatus: nameToken.mintStatus
|
|
1976
|
+
};
|
|
1977
|
+
}
|
|
1978
|
+
function getNameWrapperAccounts(namespaceId) {
|
|
1979
|
+
const ethnamesNameWrapperAccount = getDatasourceContract(
|
|
1980
|
+
namespaceId,
|
|
1981
|
+
DatasourceNames.ENSRoot,
|
|
1982
|
+
"NameWrapper"
|
|
1983
|
+
);
|
|
1984
|
+
const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
|
|
1985
|
+
namespaceId,
|
|
1986
|
+
DatasourceNames.Lineanames,
|
|
1987
|
+
"NameWrapper"
|
|
1988
|
+
);
|
|
1989
|
+
const nameWrapperAccounts = [
|
|
1990
|
+
// NameWrapper for direct subnames of .eth is defined for all ENS namespaces
|
|
1991
|
+
ethnamesNameWrapperAccount
|
|
1992
|
+
];
|
|
1993
|
+
if (lineanamesNameWrapperAccount) {
|
|
1994
|
+
nameWrapperAccounts.push(lineanamesNameWrapperAccount);
|
|
1995
|
+
}
|
|
1996
|
+
return nameWrapperAccounts;
|
|
1109
1997
|
}
|
|
1110
|
-
function
|
|
1111
|
-
const
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
ctx.issues.push({
|
|
1121
|
-
code: "custom",
|
|
1122
|
-
input: ctx.value,
|
|
1123
|
-
message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
|
|
1124
|
-
});
|
|
1998
|
+
function getNameTokenOwnership(namespaceId, name, owner) {
|
|
1999
|
+
const nameWrapperAccounts = getNameWrapperAccounts(namespaceId);
|
|
2000
|
+
const hasNameWrapperOwnership = nameWrapperAccounts.some(
|
|
2001
|
+
(nameWrapperAccount) => accountIdEqual(owner, nameWrapperAccount)
|
|
2002
|
+
);
|
|
2003
|
+
if (hasNameWrapperOwnership) {
|
|
2004
|
+
return {
|
|
2005
|
+
ownershipType: NameTokenOwnershipTypes.NameWrapper,
|
|
2006
|
+
owner
|
|
2007
|
+
};
|
|
1125
2008
|
}
|
|
1126
|
-
if (
|
|
1127
|
-
return
|
|
2009
|
+
if (isAddressEqual2(owner.address, zeroAddress)) {
|
|
2010
|
+
return {
|
|
2011
|
+
ownershipType: NameTokenOwnershipTypes.Burned,
|
|
2012
|
+
owner
|
|
2013
|
+
};
|
|
1128
2014
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
}
|
|
2015
|
+
const parentName = getParentNameFQDN(name);
|
|
2016
|
+
if (parentName === "eth") {
|
|
2017
|
+
return {
|
|
2018
|
+
ownershipType: NameTokenOwnershipTypes.FullyOnchain,
|
|
2019
|
+
owner
|
|
2020
|
+
};
|
|
1135
2021
|
}
|
|
2022
|
+
return {
|
|
2023
|
+
ownershipType: NameTokenOwnershipTypes.Unknown,
|
|
2024
|
+
owner
|
|
2025
|
+
};
|
|
1136
2026
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
2027
|
+
|
|
2028
|
+
// src/tokenscope/zod-schemas.ts
|
|
2029
|
+
var makeAssetIdSchema = (valueLabel = "Asset ID Schema") => z6.object({
|
|
2030
|
+
assetNamespace: z6.enum(AssetNamespaces),
|
|
2031
|
+
contract: makeAccountIdSchema(valueLabel),
|
|
2032
|
+
tokenId: z6.preprocess((v) => typeof v === "string" ? BigInt(v) : v, z6.bigint().positive())
|
|
2033
|
+
});
|
|
2034
|
+
var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => z6.preprocess((v) => {
|
|
2035
|
+
if (typeof v === "string") {
|
|
2036
|
+
const result = new CaipAssetId(v);
|
|
2037
|
+
return {
|
|
2038
|
+
assetNamespace: result.assetName.namespace,
|
|
2039
|
+
contract: {
|
|
2040
|
+
chainId: Number(result.chainId.reference),
|
|
2041
|
+
address: result.assetName.reference
|
|
2042
|
+
},
|
|
2043
|
+
tokenId: result.tokenId
|
|
2044
|
+
};
|
|
1145
2045
|
}
|
|
1146
|
-
|
|
2046
|
+
return v;
|
|
2047
|
+
}, makeAssetIdSchema(valueLabel));
|
|
2048
|
+
function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
|
|
2049
|
+
const ownership = ctx.value;
|
|
2050
|
+
if (ctx.value.owner.address === zeroAddress2) {
|
|
1147
2051
|
ctx.issues.push({
|
|
1148
2052
|
code: "custom",
|
|
1149
2053
|
input: ctx.value,
|
|
1150
|
-
message:
|
|
2054
|
+
message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' other than the zero address.`
|
|
1151
2055
|
});
|
|
1152
2056
|
}
|
|
1153
2057
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
2058
|
+
var makeNameTokenOwnershipNameWrapperSchema = (valueLabel = "Name Token Ownership NameWrapper") => z6.object({
|
|
2059
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.NameWrapper),
|
|
2060
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
2061
|
+
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
2062
|
+
var makeNameTokenOwnershipFullyOnchainSchema = (valueLabel = "Name Token Ownership Fully Onchain") => z6.object({
|
|
2063
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.FullyOnchain),
|
|
2064
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
2065
|
+
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
2066
|
+
var makeNameTokenOwnershipBurnedSchema = (valueLabel = "Name Token Ownership Burned") => z6.object({
|
|
2067
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.Burned),
|
|
2068
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
2069
|
+
}).check(invariant_nameTokenOwnershipHasZeroAddressOwner);
|
|
2070
|
+
var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Unknown") => z6.object({
|
|
2071
|
+
ownershipType: z6.literal(NameTokenOwnershipTypes.Unknown),
|
|
2072
|
+
owner: makeAccountIdSchema(`${valueLabel}.owner`)
|
|
2073
|
+
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
2074
|
+
function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
|
|
2075
|
+
const ownership = ctx.value;
|
|
2076
|
+
if (ctx.value.owner.address !== zeroAddress2) {
|
|
1164
2077
|
ctx.issues.push({
|
|
1165
2078
|
code: "custom",
|
|
1166
2079
|
input: ctx.value,
|
|
1167
|
-
message:
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
|
|
1172
|
-
const snapshot = ctx.value;
|
|
1173
|
-
const chains = Array.from(snapshot.chains.values());
|
|
1174
|
-
const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
|
|
1175
|
-
const actualOmnichainStatus = snapshot.omnichainStatus;
|
|
1176
|
-
if (expectedOmnichainStatus !== actualOmnichainStatus) {
|
|
1177
|
-
ctx.issues.push({
|
|
1178
|
-
code: "custom",
|
|
1179
|
-
input: snapshot,
|
|
1180
|
-
message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
|
|
2080
|
+
message: `Name Token Ownership with '${ownership.ownershipType}' must have 'address' set to the zero address.`
|
|
1181
2081
|
});
|
|
1182
2082
|
}
|
|
1183
2083
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
)
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
2084
|
+
var makeNameTokenOwnershipSchema = (valueLabel = "Name Token Ownership") => z6.discriminatedUnion("ownershipType", [
|
|
2085
|
+
makeNameTokenOwnershipNameWrapperSchema(valueLabel),
|
|
2086
|
+
makeNameTokenOwnershipFullyOnchainSchema(valueLabel),
|
|
2087
|
+
makeNameTokenOwnershipBurnedSchema(valueLabel),
|
|
2088
|
+
makeNameTokenOwnershipUnknownSchema(valueLabel)
|
|
2089
|
+
]);
|
|
2090
|
+
var makeNameTokenSchema = (valueLabel = "Name Token Schema") => z6.object({
|
|
2091
|
+
token: makeAssetIdSchema(`${valueLabel}.token`),
|
|
2092
|
+
ownership: makeNameTokenOwnershipSchema(`${valueLabel}.ownership`),
|
|
2093
|
+
mintStatus: z6.enum(NFTMintStatuses)
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
// src/tokenscope/assets.ts
|
|
2097
|
+
var AssetNamespaces = {
|
|
2098
|
+
ERC721: "erc721",
|
|
2099
|
+
ERC1155: "erc1155"
|
|
2100
|
+
};
|
|
2101
|
+
function serializeAssetId(assetId) {
|
|
2102
|
+
return {
|
|
2103
|
+
assetNamespace: assetId.assetNamespace,
|
|
2104
|
+
contract: assetId.contract,
|
|
2105
|
+
tokenId: uint256ToHex32(assetId.tokenId)
|
|
2106
|
+
};
|
|
1201
2107
|
}
|
|
1202
|
-
function
|
|
1203
|
-
const
|
|
1204
|
-
const
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
}
|
|
1210
|
-
const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
|
|
1211
|
-
const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
|
|
1212
|
-
if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
|
|
1213
|
-
ctx.issues.push({
|
|
1214
|
-
code: "custom",
|
|
1215
|
-
input: snapshot,
|
|
1216
|
-
message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
|
|
1217
|
-
});
|
|
2108
|
+
function deserializeAssetId(maybeAssetId, valueLabel) {
|
|
2109
|
+
const schema = makeAssetIdSchema(valueLabel);
|
|
2110
|
+
const parsed = schema.safeParse(maybeAssetId);
|
|
2111
|
+
if (parsed.error) {
|
|
2112
|
+
throw new RangeError(`Cannot deserialize AssetId:
|
|
2113
|
+
${prettifyError6(parsed.error)}
|
|
2114
|
+
`);
|
|
1218
2115
|
}
|
|
2116
|
+
return parsed.data;
|
|
1219
2117
|
}
|
|
1220
|
-
function
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
}
|
|
1228
|
-
const indexedChainLatestIndexedBlocks = indexedChains.map(
|
|
1229
|
-
(chain) => chain.latestIndexedBlock.timestamp
|
|
1230
|
-
);
|
|
1231
|
-
const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
|
|
1232
|
-
if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
|
|
1233
|
-
ctx.issues.push({
|
|
1234
|
-
code: "custom",
|
|
1235
|
-
input: snapshot,
|
|
1236
|
-
message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
|
|
1237
|
-
});
|
|
1238
|
-
}
|
|
2118
|
+
function formatAssetId(assetId) {
|
|
2119
|
+
const { assetNamespace, contract, tokenId } = serializeAssetId(assetId);
|
|
2120
|
+
return CaipAssetId2.format({
|
|
2121
|
+
chainId: { namespace: "eip155", reference: contract.chainId.toString() },
|
|
2122
|
+
assetName: { namespace: assetNamespace, reference: contract.address },
|
|
2123
|
+
tokenId
|
|
2124
|
+
}).toLowerCase();
|
|
1239
2125
|
}
|
|
1240
|
-
function
|
|
1241
|
-
const
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
code: "custom",
|
|
1248
|
-
input: chains,
|
|
1249
|
-
message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
|
|
1250
|
-
});
|
|
2126
|
+
function parseAssetId(maybeAssetId, valueLabel) {
|
|
2127
|
+
const schema = makeAssetIdStringSchema(valueLabel);
|
|
2128
|
+
const parsed = schema.safeParse(maybeAssetId);
|
|
2129
|
+
if (parsed.error) {
|
|
2130
|
+
throw new RangeError(`Cannot parse AssetId:
|
|
2131
|
+
${prettifyError6(parsed.error)}
|
|
2132
|
+
`);
|
|
1251
2133
|
}
|
|
2134
|
+
return parsed.data;
|
|
1252
2135
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
}
|
|
2136
|
+
var buildAssetId = (contract, tokenId, assetNamespace) => {
|
|
2137
|
+
return {
|
|
2138
|
+
assetNamespace,
|
|
2139
|
+
contract,
|
|
2140
|
+
tokenId
|
|
2141
|
+
};
|
|
2142
|
+
};
|
|
2143
|
+
function serializeDomainAssetId(domainAsset) {
|
|
2144
|
+
return {
|
|
2145
|
+
...serializeAssetId(domainAsset),
|
|
2146
|
+
domainId: domainAsset.domainId
|
|
2147
|
+
};
|
|
1265
2148
|
}
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
}
|
|
2149
|
+
var NFTMintStatuses = {
|
|
2150
|
+
Minted: "minted",
|
|
2151
|
+
Burned: "burned"
|
|
2152
|
+
};
|
|
2153
|
+
var formatNFTTransferEventMetadata = (metadata) => {
|
|
2154
|
+
const serializedAssetId = serializeAssetId(metadata.nft);
|
|
2155
|
+
return [
|
|
2156
|
+
`Event: ${metadata.eventHandlerName}`,
|
|
2157
|
+
`Chain ID: ${metadata.chainId}`,
|
|
2158
|
+
`Block Number: ${metadata.blockNumber}`,
|
|
2159
|
+
`Transaction Hash: ${metadata.transactionHash}`,
|
|
2160
|
+
`NFT: ${serializedAssetId}`
|
|
2161
|
+
].map((line) => ` - ${line}`).join("\n");
|
|
2162
|
+
};
|
|
2163
|
+
var NFTTransferTypes = {
|
|
2164
|
+
/**
|
|
2165
|
+
* Initial transfer from zeroAddress to a non-zeroAddress
|
|
2166
|
+
* Can happen at most once to a NFT AssetId
|
|
2167
|
+
*
|
|
2168
|
+
* Invariants:
|
|
2169
|
+
* - NFT is not indexed and therefore has no previous mint status or owner
|
|
2170
|
+
* - new NFT mint status is `minted`
|
|
2171
|
+
* - new NFT owner is a non-zeroAddress
|
|
2172
|
+
*/
|
|
2173
|
+
Mint: "mint",
|
|
2174
|
+
/**
|
|
2175
|
+
* Subsequent transfer from zeroAddress to a non-zeroAddress
|
|
2176
|
+
* Can happen any number of times to a NFT AssetId as it passes in a cycle from
|
|
2177
|
+
* mint -> burn -> remint -> burn -> remint -> ...
|
|
2178
|
+
*
|
|
2179
|
+
* Invariants:
|
|
2180
|
+
* - NFT is indexed
|
|
2181
|
+
* - previous NFT mint status was `burned`
|
|
2182
|
+
* - previous NFT owner is the zeroAddress
|
|
2183
|
+
* - new NFT mint status is `minted`
|
|
2184
|
+
* - new NFT owner is a non-zeroAddress
|
|
2185
|
+
*/
|
|
2186
|
+
Remint: "remint",
|
|
2187
|
+
/**
|
|
2188
|
+
* Special transfer type for improperly implemented NFT contracts that allow a NFT
|
|
2189
|
+
* that is currently minted to be reminted before an intermediate burn.
|
|
2190
|
+
*
|
|
2191
|
+
* Transfer from zeroAddress to non-zeroAddress for an indexed NFT where the
|
|
2192
|
+
* previously indexed nft had status `minted` with a non-zeroAddress owner.
|
|
2193
|
+
*
|
|
2194
|
+
* Invariants:
|
|
2195
|
+
* - NFT is indexed
|
|
2196
|
+
* - previous NFT mint status was `minted`
|
|
2197
|
+
* - previous NFT owner was a non-zeroAddress
|
|
2198
|
+
* - new NFT mint status is `minted`
|
|
2199
|
+
* - new NFT owner is a non-zeroAddress
|
|
2200
|
+
*/
|
|
2201
|
+
MintedRemint: "minted-remint",
|
|
2202
|
+
/**
|
|
2203
|
+
* Transfer from a non-zeroAddress to zeroAddress
|
|
2204
|
+
*
|
|
2205
|
+
* Invariants:
|
|
2206
|
+
* - NFT is indexed
|
|
2207
|
+
* - previous NFT mint status was `minted`
|
|
2208
|
+
* - previous NFT owner is a non-zeroAddress
|
|
2209
|
+
* - new NFT mint status is `burned`
|
|
2210
|
+
* - new NFT owner is the zeroAddress
|
|
2211
|
+
*/
|
|
2212
|
+
Burn: "burn",
|
|
2213
|
+
/**
|
|
2214
|
+
* Transfer from a non-zeroAddress to a distinct non-zeroAddress
|
|
2215
|
+
*
|
|
2216
|
+
* Invariants:
|
|
2217
|
+
* - NFT is indexed
|
|
2218
|
+
* - previous and new NFT mint status is `minted`
|
|
2219
|
+
* - previous and new NFT owner are distinct non-zeroAddress
|
|
2220
|
+
*/
|
|
2221
|
+
Transfer: "transfer",
|
|
2222
|
+
/**
|
|
2223
|
+
* Transfer from a non-zeroAddress to the same non-zeroAddress
|
|
2224
|
+
*
|
|
2225
|
+
* Invariants:
|
|
2226
|
+
* - NFT is indexed
|
|
2227
|
+
* - previous and new NFT mint status is `minted`
|
|
2228
|
+
* - previous and new NFT owner are equivalent non-zeroAddress
|
|
2229
|
+
*/
|
|
2230
|
+
SelfTransfer: "self-transfer",
|
|
2231
|
+
/**
|
|
2232
|
+
* Transfer from zeroAddress to zeroAddress for an indexed NFT
|
|
2233
|
+
*
|
|
2234
|
+
* Invariants:
|
|
2235
|
+
* - NFT is indexed
|
|
2236
|
+
* - previous and new NFT mint status is `burned`
|
|
2237
|
+
* - previous and new NFT owner are zeroAddress
|
|
2238
|
+
*/
|
|
2239
|
+
RemintBurn: "remint-burn",
|
|
2240
|
+
/**
|
|
2241
|
+
* Special transfer type for improperly implemented NFT contracts that allow a NFT
|
|
2242
|
+
* that is currently minted to be reminted again before an intermediate burn.
|
|
2243
|
+
*
|
|
2244
|
+
* Transfer from zeroAddress to zeroAddress for an indexed NFT where the
|
|
2245
|
+
* previously indexed nft had status `minted` with a non-zeroAddress owner.
|
|
2246
|
+
*
|
|
2247
|
+
* Invariants:
|
|
2248
|
+
* - NFT is indexed
|
|
2249
|
+
* - previous NFT mint status was `minted`
|
|
2250
|
+
* - previous NFT owner was a non-zeroAddress
|
|
2251
|
+
* - new NFT mint status is `burned`
|
|
2252
|
+
* - new NFT owner is the zeroAddress
|
|
2253
|
+
*/
|
|
2254
|
+
MintedRemintBurn: "minted-remint-burn",
|
|
2255
|
+
/**
|
|
2256
|
+
* Transfer from zeroAddress to zeroAddress for an unindexed NFT
|
|
2257
|
+
*
|
|
2258
|
+
* Invariants:
|
|
2259
|
+
* - NFT is not indexed and therefore has no previous mint status or owner
|
|
2260
|
+
* - NFT should remain unindexed and without any mint status or owner
|
|
2261
|
+
*/
|
|
2262
|
+
MintBurn: "mint-burn"
|
|
2263
|
+
};
|
|
2264
|
+
var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
|
|
2265
|
+
const isIndexed = currentlyIndexedOwner !== void 0;
|
|
2266
|
+
const isIndexedAsMinted = isIndexed && !isAddressEqual3(currentlyIndexedOwner, zeroAddress3);
|
|
2267
|
+
const isMint = isAddressEqual3(from, zeroAddress3);
|
|
2268
|
+
const isBurn = isAddressEqual3(to, zeroAddress3);
|
|
2269
|
+
const isSelfTransfer = isAddressEqual3(from, to);
|
|
2270
|
+
if (isIndexed && !isAddressEqual3(currentlyIndexedOwner, from)) {
|
|
2271
|
+
if (isMint && allowMintedRemint) {
|
|
2272
|
+
} else {
|
|
2273
|
+
throw new Error(
|
|
2274
|
+
`Error: Sending from ${from} conflicts with currently indexed owner ${currentlyIndexedOwner}.
|
|
2275
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
1277
2278
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
2279
|
+
if (isSelfTransfer) {
|
|
2280
|
+
if (isMint) {
|
|
2281
|
+
if (!isIndexed) {
|
|
2282
|
+
return NFTTransferTypes.MintBurn;
|
|
2283
|
+
} else if (!isIndexedAsMinted) {
|
|
2284
|
+
return NFTTransferTypes.RemintBurn;
|
|
2285
|
+
} else if (allowMintedRemint) {
|
|
2286
|
+
return NFTTransferTypes.MintedRemintBurn;
|
|
2287
|
+
} else {
|
|
2288
|
+
throw new Error(
|
|
2289
|
+
`Error: Invalid state transition from minted -> remint-burn
|
|
2290
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2291
|
+
);
|
|
2292
|
+
}
|
|
2293
|
+
} else {
|
|
2294
|
+
if (!isIndexed) {
|
|
2295
|
+
throw new Error(
|
|
2296
|
+
`Error: Invalid state transition from unindexed -> self-transfer
|
|
2297
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2298
|
+
);
|
|
2299
|
+
} else if (!isIndexedAsMinted) {
|
|
2300
|
+
throw new Error(
|
|
2301
|
+
`Error: invalid state transition from burned -> self-transfer
|
|
2302
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2303
|
+
);
|
|
2304
|
+
} else {
|
|
2305
|
+
return NFTTransferTypes.SelfTransfer;
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
} else if (isMint) {
|
|
2309
|
+
if (!isIndexed) {
|
|
2310
|
+
return NFTTransferTypes.Mint;
|
|
2311
|
+
} else if (!isIndexedAsMinted) {
|
|
2312
|
+
return NFTTransferTypes.Remint;
|
|
2313
|
+
} else if (allowMintedRemint) {
|
|
2314
|
+
return NFTTransferTypes.MintedRemint;
|
|
2315
|
+
} else {
|
|
2316
|
+
throw new Error(
|
|
2317
|
+
`Error: Invalid state transition from minted -> mint
|
|
2318
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2319
|
+
);
|
|
2320
|
+
}
|
|
2321
|
+
} else if (isBurn) {
|
|
2322
|
+
if (!isIndexed) {
|
|
2323
|
+
throw new Error(
|
|
2324
|
+
`Error: Invalid state transition from unindexed -> burn
|
|
2325
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2326
|
+
);
|
|
2327
|
+
} else if (!isIndexedAsMinted) {
|
|
2328
|
+
throw new Error(
|
|
2329
|
+
`Error: Invalid state transition from burned -> burn
|
|
2330
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2331
|
+
);
|
|
2332
|
+
} else {
|
|
2333
|
+
return NFTTransferTypes.Burn;
|
|
2334
|
+
}
|
|
2335
|
+
} else {
|
|
2336
|
+
if (!isIndexed) {
|
|
2337
|
+
throw new Error(
|
|
2338
|
+
`Error: Invalid state transition from unindexed -> transfer
|
|
2339
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2340
|
+
);
|
|
2341
|
+
} else if (!isIndexedAsMinted) {
|
|
2342
|
+
throw new Error(
|
|
2343
|
+
`Error: Invalid state transition from burned -> transfer
|
|
2344
|
+
${formatNFTTransferEventMetadata(metadata)}`
|
|
2345
|
+
);
|
|
2346
|
+
} else {
|
|
2347
|
+
return NFTTransferTypes.Transfer;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
};
|
|
2351
|
+
|
|
2352
|
+
// src/api/shared/errors/zod-schemas.ts
|
|
2353
|
+
import z7 from "zod/v4";
|
|
2354
|
+
var ErrorResponseSchema = z7.object({
|
|
2355
|
+
message: z7.string(),
|
|
2356
|
+
details: z7.optional(z7.unknown())
|
|
2357
|
+
});
|
|
2358
|
+
|
|
2359
|
+
// src/api/name-tokens/response.ts
|
|
2360
|
+
var NameTokensResponseCodes = {
|
|
2361
|
+
/**
|
|
2362
|
+
* Represents a response when Name Tokens API can respond with requested data.
|
|
2363
|
+
*/
|
|
2364
|
+
Ok: "ok",
|
|
2365
|
+
/**
|
|
2366
|
+
* Represents a response when Name Tokens API could not respond with requested data.
|
|
2367
|
+
*/
|
|
2368
|
+
Error: "error"
|
|
2369
|
+
};
|
|
2370
|
+
var NameTokensResponseErrorCodes = {
|
|
2371
|
+
/**
|
|
2372
|
+
* Name tokens not indexed
|
|
2373
|
+
*
|
|
2374
|
+
* Represents an error when tokens for the requested name are not indexed by
|
|
2375
|
+
* the ENSNode instance's configuration.
|
|
2376
|
+
*/
|
|
2377
|
+
NameTokensNotIndexed: "name-tokens-not-indexed",
|
|
2378
|
+
/**
|
|
2379
|
+
* Unsupported ENSIndexer Config
|
|
2380
|
+
*
|
|
2381
|
+
* Represents a prerequisites error when connected ENSIndexer config lacks
|
|
2382
|
+
* params required to enable Name Tokens API.
|
|
2383
|
+
*/
|
|
2384
|
+
EnsIndexerConfigUnsupported: "unsupported-ensindexer-config",
|
|
2385
|
+
/**
|
|
2386
|
+
* Unsupported Indexing Status
|
|
2387
|
+
*
|
|
2388
|
+
* Represents a prerequisites error when Indexing Status has not yet reached
|
|
2389
|
+
* status required to enable Name Tokens API.
|
|
2390
|
+
*/
|
|
2391
|
+
IndexingStatusUnsupported: "unsupported-indexing-status"
|
|
2392
|
+
};
|
|
2393
|
+
|
|
2394
|
+
// src/api/name-tokens/zod-schemas.ts
|
|
2395
|
+
function invariant_nameIsAssociatedWithDomainId(ctx) {
|
|
2396
|
+
const { name, domainId } = ctx.value;
|
|
2397
|
+
if (namehash2(name) !== domainId) {
|
|
1287
2398
|
ctx.issues.push({
|
|
1288
2399
|
code: "custom",
|
|
1289
2400
|
input: ctx.value,
|
|
1290
|
-
message: `'
|
|
2401
|
+
message: `'name' must be associated with 'domainId': ${domainId}`
|
|
1291
2402
|
});
|
|
1292
2403
|
}
|
|
1293
2404
|
}
|
|
1294
|
-
function
|
|
1295
|
-
const {
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1298
|
-
const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
|
|
1299
|
-
const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
|
|
1300
|
-
const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
|
|
1301
|
-
const highestKnownBlockTimestamp = Math.max(
|
|
1302
|
-
...startBlockTimestamps,
|
|
1303
|
-
...endBlockTimestamps,
|
|
1304
|
-
...backfillEndBlockTimestamps,
|
|
1305
|
-
...latestKnownBlockTimestamps
|
|
2405
|
+
function invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown(ctx) {
|
|
2406
|
+
const { tokens } = ctx.value;
|
|
2407
|
+
const containsOwnershipNameWrapper = tokens.some(
|
|
2408
|
+
(t) => t.ownership.ownershipType === NameTokenOwnershipTypes.NameWrapper
|
|
1306
2409
|
);
|
|
1307
|
-
|
|
2410
|
+
const containsOwnershipFullyOnchainOrUnknown = tokens.some(
|
|
2411
|
+
(t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain || t.ownership.ownershipType === NameTokenOwnershipTypes.Unknown
|
|
2412
|
+
);
|
|
2413
|
+
if (containsOwnershipNameWrapper && !containsOwnershipFullyOnchainOrUnknown) {
|
|
1308
2414
|
ctx.issues.push({
|
|
1309
2415
|
code: "custom",
|
|
1310
2416
|
input: ctx.value,
|
|
1311
|
-
message: `'
|
|
1312
|
-
});
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
|
|
1316
|
-
const projection = ctx.value;
|
|
1317
|
-
const { snapshot, projectedAt } = projection;
|
|
1318
|
-
if (snapshot.snapshotTime > projectedAt) {
|
|
1319
|
-
ctx.issues.push({
|
|
1320
|
-
code: "custom",
|
|
1321
|
-
input: projection,
|
|
1322
|
-
message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
|
|
2417
|
+
message: `'tokens' must contain name token with ownership type 'fully-onchain' or 'unknown' when name token with ownership type 'namewrapper' in listed`
|
|
1323
2418
|
});
|
|
1324
2419
|
}
|
|
1325
2420
|
}
|
|
1326
|
-
function
|
|
1327
|
-
const
|
|
1328
|
-
const
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
if (
|
|
2421
|
+
function invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective(ctx) {
|
|
2422
|
+
const { tokens } = ctx.value;
|
|
2423
|
+
const tokensCountWithOwnershipFullyOnchain = tokens.filter(
|
|
2424
|
+
(t) => t.ownership.ownershipType === NameTokenOwnershipTypes.FullyOnchain
|
|
2425
|
+
).length;
|
|
2426
|
+
if (tokensCountWithOwnershipFullyOnchain > 1) {
|
|
1332
2427
|
ctx.issues.push({
|
|
1333
2428
|
code: "custom",
|
|
1334
|
-
input:
|
|
1335
|
-
message:
|
|
2429
|
+
input: ctx.value,
|
|
2430
|
+
message: `'tokens' must contain at most one name token with ownership type 'fully-onchain', current count: ${tokensCountWithOwnershipFullyOnchain}`
|
|
1336
2431
|
});
|
|
1337
2432
|
}
|
|
1338
2433
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
endBlock: makeBlockRefSchema(valueLabel)
|
|
1350
|
-
})
|
|
1351
|
-
]);
|
|
1352
|
-
var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => z2.strictObject({
|
|
1353
|
-
chainStatus: z2.literal(ChainIndexingStatusIds.Queued),
|
|
1354
|
-
config: makeChainIndexingConfigSchema(valueLabel)
|
|
1355
|
-
}).check(invariant_chainSnapshotQueuedBlocks);
|
|
1356
|
-
var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => z2.strictObject({
|
|
1357
|
-
chainStatus: z2.literal(ChainIndexingStatusIds.Backfill),
|
|
1358
|
-
config: makeChainIndexingConfigSchema(valueLabel),
|
|
1359
|
-
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1360
|
-
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
1361
|
-
}).check(invariant_chainSnapshotBackfillBlocks);
|
|
1362
|
-
var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => z2.strictObject({
|
|
1363
|
-
chainStatus: z2.literal(ChainIndexingStatusIds.Completed),
|
|
1364
|
-
config: z2.strictObject({
|
|
1365
|
-
configType: z2.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1366
|
-
startBlock: makeBlockRefSchema(valueLabel),
|
|
1367
|
-
endBlock: makeBlockRefSchema(valueLabel)
|
|
1368
|
-
}),
|
|
1369
|
-
latestIndexedBlock: makeBlockRefSchema(valueLabel)
|
|
1370
|
-
}).check(invariant_chainSnapshotCompletedBlocks);
|
|
1371
|
-
var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => z2.strictObject({
|
|
1372
|
-
chainStatus: z2.literal(ChainIndexingStatusIds.Following),
|
|
1373
|
-
config: z2.strictObject({
|
|
1374
|
-
configType: z2.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1375
|
-
startBlock: makeBlockRefSchema(valueLabel)
|
|
1376
|
-
}),
|
|
1377
|
-
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1378
|
-
latestKnownBlock: makeBlockRefSchema(valueLabel)
|
|
1379
|
-
}).check(invariant_chainSnapshotFollowingBlocks);
|
|
1380
|
-
var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => z2.discriminatedUnion("chainStatus", [
|
|
1381
|
-
makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
|
|
1382
|
-
makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1383
|
-
makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1384
|
-
makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1385
|
-
]);
|
|
1386
|
-
var makeChainIndexingStatusesSchema = (valueLabel = "Value") => z2.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
|
|
1387
|
-
error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
|
|
1388
|
-
}).transform((serializedChainsIndexingStatus) => {
|
|
1389
|
-
const chainsIndexingStatus = /* @__PURE__ */ new Map();
|
|
1390
|
-
for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
|
|
1391
|
-
chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
|
|
1392
|
-
}
|
|
1393
|
-
return chainsIndexingStatus;
|
|
1394
|
-
});
|
|
1395
|
-
var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => z2.strictObject({
|
|
1396
|
-
omnichainStatus: z2.literal(OmnichainIndexingStatusIds.Unstarted),
|
|
1397
|
-
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
|
|
1398
|
-
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
2434
|
+
var makeRegisteredNameTokenSchema = (valueLabel = "Registered Name Token") => z8.object({
|
|
2435
|
+
domainId: makeNodeSchema(`${valueLabel}.domainId`),
|
|
2436
|
+
name: makeReinterpretedNameSchema(valueLabel),
|
|
2437
|
+
tokens: z8.array(makeNameTokenSchema(`${valueLabel}.tokens`)).nonempty(),
|
|
2438
|
+
expiresAt: makeUnixTimestampSchema(`${valueLabel}.expiresAt`),
|
|
2439
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
2440
|
+
}).check(invariant_nameIsAssociatedWithDomainId).check(invariant_nameTokensContainAtMostOneWithOwnershipTypeEffective).check(invariant_nameTokensOwnershipTypeNameWrapperRequiresOwnershipTypeFullyOnchainOrUnknown);
|
|
2441
|
+
var makeNameTokensResponseOkSchema = (valueLabel = "Name Tokens Response OK") => z8.strictObject({
|
|
2442
|
+
responseCode: z8.literal(NameTokensResponseCodes.Ok),
|
|
2443
|
+
registeredNameTokens: makeRegisteredNameTokenSchema(`${valueLabel}.nameTokens`)
|
|
1399
2444
|
});
|
|
1400
|
-
var
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
),
|
|
1405
|
-
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
2445
|
+
var makeNameTokensResponseErrorNameTokensNotIndexedSchema = (_valueLabel = "Name Tokens Response Error Name Not Indexed") => z8.strictObject({
|
|
2446
|
+
responseCode: z8.literal(NameTokensResponseCodes.Error),
|
|
2447
|
+
errorCode: z8.literal(NameTokensResponseErrorCodes.NameTokensNotIndexed),
|
|
2448
|
+
error: ErrorResponseSchema
|
|
1406
2449
|
});
|
|
1407
|
-
var
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
2450
|
+
var makeNameTokensResponseErrorEnsIndexerConfigUnsupported = (_valueLabel = "Name Tokens Response Error ENSIndexer Config Unsupported") => z8.strictObject({
|
|
2451
|
+
responseCode: z8.literal(NameTokensResponseCodes.Error),
|
|
2452
|
+
errorCode: z8.literal(NameTokensResponseErrorCodes.EnsIndexerConfigUnsupported),
|
|
2453
|
+
error: ErrorResponseSchema
|
|
1411
2454
|
});
|
|
1412
|
-
var
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
2455
|
+
var makeNameTokensResponseErrorNameIndexingStatusUnsupported = (_valueLabel = "Name Tokens Response Error Indexing Status Unsupported") => z8.strictObject({
|
|
2456
|
+
responseCode: z8.literal(NameTokensResponseCodes.Error),
|
|
2457
|
+
errorCode: z8.literal(NameTokensResponseErrorCodes.IndexingStatusUnsupported),
|
|
2458
|
+
error: ErrorResponseSchema
|
|
1416
2459
|
});
|
|
1417
|
-
var
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => z2.strictObject({
|
|
1426
|
-
strategy: z2.literal(CrossChainIndexingStrategyIds.Omnichain),
|
|
1427
|
-
slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
|
|
1428
|
-
snapshotTime: makeUnixTimestampSchema(valueLabel),
|
|
1429
|
-
omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
|
|
1430
|
-
}).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
|
|
1431
|
-
var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => z2.discriminatedUnion("strategy", [
|
|
1432
|
-
makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
|
|
2460
|
+
var makeNameTokensResponseErrorSchema = (valueLabel = "Name Tokens Response Error") => z8.discriminatedUnion("errorCode", [
|
|
2461
|
+
makeNameTokensResponseErrorNameTokensNotIndexedSchema(valueLabel),
|
|
2462
|
+
makeNameTokensResponseErrorEnsIndexerConfigUnsupported(valueLabel),
|
|
2463
|
+
makeNameTokensResponseErrorNameIndexingStatusUnsupported(valueLabel)
|
|
2464
|
+
]);
|
|
2465
|
+
var makeNameTokensResponseSchema = (valueLabel = "Name Tokens Response") => z8.discriminatedUnion("responseCode", [
|
|
2466
|
+
makeNameTokensResponseOkSchema(valueLabel),
|
|
2467
|
+
makeNameTokensResponseErrorSchema(valueLabel)
|
|
1433
2468
|
]);
|
|
1434
|
-
var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => z2.strictObject({
|
|
1435
|
-
projectedAt: makeUnixTimestampSchema(valueLabel),
|
|
1436
|
-
worstCaseDistance: makeDurationSchema(valueLabel),
|
|
1437
|
-
snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
|
|
1438
|
-
}).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
|
|
1439
|
-
|
|
1440
|
-
// src/ensindexer/config/zod-schemas.ts
|
|
1441
|
-
import z3 from "zod/v4";
|
|
1442
|
-
|
|
1443
|
-
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
1444
|
-
import { ENSNamespaceIds as ENSNamespaceIds2 } from "@ensnode/datasources";
|
|
1445
|
-
|
|
1446
|
-
// src/ensindexer/config/types.ts
|
|
1447
|
-
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
1448
|
-
PluginName2["Subgraph"] = "subgraph";
|
|
1449
|
-
PluginName2["Basenames"] = "basenames";
|
|
1450
|
-
PluginName2["Lineanames"] = "lineanames";
|
|
1451
|
-
PluginName2["ThreeDNS"] = "threedns";
|
|
1452
|
-
PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
|
|
1453
|
-
PluginName2["Registrars"] = "registrars";
|
|
1454
|
-
PluginName2["TokenScope"] = "tokenscope";
|
|
1455
|
-
return PluginName2;
|
|
1456
|
-
})(PluginName || {});
|
|
1457
|
-
|
|
1458
|
-
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
1459
|
-
function isSubgraphCompatible(config) {
|
|
1460
|
-
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
1461
|
-
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
1462
|
-
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
1463
|
-
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === ENSNamespaceIds2.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
1464
|
-
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
1465
|
-
}
|
|
1466
2469
|
|
|
1467
|
-
// src/
|
|
1468
|
-
function
|
|
1469
|
-
const
|
|
1470
|
-
if (
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
message: "`ensDb` version must be same as `ensIndexer` version"
|
|
1475
|
-
});
|
|
2470
|
+
// src/api/name-tokens/deserialize.ts
|
|
2471
|
+
function deserializedNameTokensResponse(maybeResponse) {
|
|
2472
|
+
const parsed = makeNameTokensResponseSchema().safeParse(maybeResponse);
|
|
2473
|
+
if (parsed.error) {
|
|
2474
|
+
throw new Error(`Cannot deserialize NameTokensResponse:
|
|
2475
|
+
${prettifyError7(parsed.error)}
|
|
2476
|
+
`);
|
|
1476
2477
|
}
|
|
2478
|
+
return parsed.data;
|
|
1477
2479
|
}
|
|
1478
2480
|
|
|
1479
|
-
// src/
|
|
1480
|
-
var
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
};
|
|
1498
|
-
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
1499
|
-
return z3.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
1500
|
-
};
|
|
1501
|
-
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
1502
|
-
let valueLabelLabelSetId = valueLabel;
|
|
1503
|
-
let valueLabelLabelSetVersion = valueLabel;
|
|
1504
|
-
if (valueLabel === "LABEL_SET") {
|
|
1505
|
-
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
1506
|
-
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
1507
|
-
} else {
|
|
1508
|
-
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
1509
|
-
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
1510
|
-
}
|
|
1511
|
-
return z3.object({
|
|
1512
|
-
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
1513
|
-
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
1514
|
-
});
|
|
1515
|
-
};
|
|
1516
|
-
var makeNonEmptyStringSchema = (valueLabel = "Value") => z3.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
1517
|
-
var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => z3.strictObject(
|
|
1518
|
-
{
|
|
1519
|
-
nodejs: makeNonEmptyStringSchema(),
|
|
1520
|
-
ponder: makeNonEmptyStringSchema(),
|
|
1521
|
-
ensDb: makeNonEmptyStringSchema(),
|
|
1522
|
-
ensIndexer: makeNonEmptyStringSchema(),
|
|
1523
|
-
ensNormalize: makeNonEmptyStringSchema(),
|
|
1524
|
-
ensRainbow: makeNonEmptyStringSchema(),
|
|
1525
|
-
ensRainbowSchema: makePositiveIntegerSchema()
|
|
2481
|
+
// src/api/name-tokens/prerequisites.ts
|
|
2482
|
+
var nameTokensPrerequisites = Object.freeze({
|
|
2483
|
+
/**
|
|
2484
|
+
* Required plugins to enable Name Tokens API routes.
|
|
2485
|
+
*
|
|
2486
|
+
* 1. `registrars` plugin is required so that data in the `registrationLifecycles`
|
|
2487
|
+
* table is populated.
|
|
2488
|
+
* 2. `tokenscope` plugin is required so that data in the `nameTokens`
|
|
2489
|
+
* table is populated.
|
|
2490
|
+
*/
|
|
2491
|
+
requiredPlugins: ["registrars" /* Registrars */, "tokenscope" /* TokenScope */],
|
|
2492
|
+
/**
|
|
2493
|
+
* Check if provided ENSApiPublicConfig supports the Name Tokens API.
|
|
2494
|
+
*/
|
|
2495
|
+
hasEnsIndexerConfigSupport(config) {
|
|
2496
|
+
return nameTokensPrerequisites.requiredPlugins.every(
|
|
2497
|
+
(plugin) => config.plugins.includes(plugin)
|
|
2498
|
+
);
|
|
1526
2499
|
},
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
isSubgraphCompatible: z3.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
1545
|
-
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
1546
|
-
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
1547
|
-
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
1548
|
-
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
1549
|
-
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
1550
|
-
|
|
1551
|
-
// src/shared/config/build-rpc-urls.ts
|
|
1552
|
-
import {
|
|
1553
|
-
arbitrum,
|
|
1554
|
-
arbitrumSepolia,
|
|
1555
|
-
base,
|
|
1556
|
-
baseSepolia,
|
|
1557
|
-
holesky,
|
|
1558
|
-
linea,
|
|
1559
|
-
lineaSepolia,
|
|
1560
|
-
mainnet,
|
|
1561
|
-
optimism,
|
|
1562
|
-
optimismSepolia,
|
|
1563
|
-
scroll,
|
|
1564
|
-
scrollSepolia,
|
|
1565
|
-
sepolia
|
|
1566
|
-
} from "viem/chains";
|
|
1567
|
-
|
|
1568
|
-
// src/shared/config/rpc-configs-from-env.ts
|
|
1569
|
-
import { getENSNamespace } from "@ensnode/datasources";
|
|
1570
|
-
|
|
1571
|
-
// src/shared/config/validatons.ts
|
|
1572
|
-
import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
|
|
1573
|
-
function invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL(ctx) {
|
|
1574
|
-
const endpoints = ctx.value;
|
|
1575
|
-
const httpEndpoints = endpoints.filter(isHttpProtocol);
|
|
1576
|
-
if (httpEndpoints.length < 1) {
|
|
1577
|
-
ctx.issues.push({
|
|
1578
|
-
code: "custom",
|
|
1579
|
-
input: endpoints,
|
|
1580
|
-
message: `RPC endpoint configuration for a chain must include at least one http/https protocol URL.`
|
|
1581
|
-
});
|
|
2500
|
+
/**
|
|
2501
|
+
* Required Indexing Status IDs
|
|
2502
|
+
*
|
|
2503
|
+
* Database indexes are created by the time the omnichain indexing status
|
|
2504
|
+
* is either `completed` or `following`.
|
|
2505
|
+
*/
|
|
2506
|
+
supportedIndexingStatusIds: [
|
|
2507
|
+
OmnichainIndexingStatusIds.Completed,
|
|
2508
|
+
OmnichainIndexingStatusIds.Following
|
|
2509
|
+
],
|
|
2510
|
+
/**
|
|
2511
|
+
* Check if provided indexing status supports the Name Tokens API.
|
|
2512
|
+
*/
|
|
2513
|
+
hasIndexingStatusSupport(omnichainIndexingStatusId) {
|
|
2514
|
+
return nameTokensPrerequisites.supportedIndexingStatusIds.some(
|
|
2515
|
+
(supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
|
|
2516
|
+
);
|
|
1582
2517
|
}
|
|
2518
|
+
});
|
|
2519
|
+
|
|
2520
|
+
// src/api/name-tokens/serialize.ts
|
|
2521
|
+
function serializeRegisteredNameTokens({
|
|
2522
|
+
domainId,
|
|
2523
|
+
name,
|
|
2524
|
+
tokens,
|
|
2525
|
+
expiresAt,
|
|
2526
|
+
accurateAsOf
|
|
2527
|
+
}) {
|
|
2528
|
+
return {
|
|
2529
|
+
domainId,
|
|
2530
|
+
name,
|
|
2531
|
+
tokens: tokens.map(serializeNameToken),
|
|
2532
|
+
expiresAt,
|
|
2533
|
+
accurateAsOf
|
|
2534
|
+
};
|
|
1583
2535
|
}
|
|
1584
|
-
function
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
2536
|
+
function serializeNameTokensResponse(response) {
|
|
2537
|
+
switch (response.responseCode) {
|
|
2538
|
+
case NameTokensResponseCodes.Ok:
|
|
2539
|
+
return {
|
|
2540
|
+
responseCode: response.responseCode,
|
|
2541
|
+
registeredNameTokens: serializeRegisteredNameTokens(response.registeredNameTokens)
|
|
2542
|
+
};
|
|
2543
|
+
case NameTokensResponseCodes.Error:
|
|
2544
|
+
return response;
|
|
1593
2545
|
}
|
|
1594
2546
|
}
|
|
1595
2547
|
|
|
1596
|
-
// src/
|
|
1597
|
-
import {
|
|
1598
|
-
import { ENSNamespaceIds as ENSNamespaceIds3 } from "@ensnode/datasources";
|
|
1599
|
-
var DatabaseSchemaNameSchema = z4.string({
|
|
1600
|
-
error: "DATABASE_SCHEMA is required."
|
|
1601
|
-
}).trim().min(1, {
|
|
1602
|
-
error: "DATABASE_SCHEMA is required and cannot be an empty string."
|
|
1603
|
-
});
|
|
1604
|
-
var RpcConfigSchema = z4.string().transform((val) => val.split(",")).pipe(z4.array(makeUrlSchema("RPC URL"))).check(invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL).check(invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL);
|
|
1605
|
-
var RpcConfigsSchema = z4.record(makeChainIdStringSchema("RPC URL"), RpcConfigSchema, {
|
|
1606
|
-
error: "Chains configuration must be an object mapping valid chain IDs to their configs."
|
|
1607
|
-
}).transform((records) => {
|
|
1608
|
-
const rpcConfigs = /* @__PURE__ */ new Map();
|
|
1609
|
-
for (const [chainIdString, rpcConfig] of Object.entries(records)) {
|
|
1610
|
-
const httpRPCs = rpcConfig.filter(isHttpProtocol);
|
|
1611
|
-
const websocketRPC = rpcConfig.find(isWebSocketProtocol);
|
|
1612
|
-
rpcConfigs.set(deserializeChainId(chainIdString), {
|
|
1613
|
-
httpRPCs,
|
|
1614
|
-
websocketRPC
|
|
1615
|
-
});
|
|
1616
|
-
}
|
|
1617
|
-
return rpcConfigs;
|
|
1618
|
-
});
|
|
1619
|
-
var EnsIndexerUrlSchema = makeUrlSchema("ENSINDEXER_URL");
|
|
1620
|
-
var ENSNamespaceSchema = z4.enum(ENSNamespaceIds3, {
|
|
1621
|
-
error: ({ input }) => `Invalid NAMESPACE. Got '${input}', but supported ENS namespaces are: ${Object.keys(ENSNamespaceIds3).join(", ")}`
|
|
1622
|
-
});
|
|
1623
|
-
var PortSchema = z4.coerce.number({ error: "PORT must be a number." }).min(1, { error: "PORT must be greater than 1." }).max(65535, { error: "PORT must be less than 65535" }).optional();
|
|
1624
|
-
var TheGraphApiKeySchema = z4.string().optional();
|
|
1625
|
-
|
|
1626
|
-
// src/shared/datasources-with-resolvers.ts
|
|
1627
|
-
import {
|
|
1628
|
-
DatasourceNames,
|
|
1629
|
-
maybeGetDatasource
|
|
1630
|
-
} from "@ensnode/datasources";
|
|
1631
|
-
var DATASOURCE_NAMES_WITH_RESOLVERS = [
|
|
1632
|
-
DatasourceNames.ENSRoot,
|
|
1633
|
-
DatasourceNames.Basenames,
|
|
1634
|
-
DatasourceNames.Lineanames,
|
|
1635
|
-
DatasourceNames.ThreeDNSOptimism,
|
|
1636
|
-
DatasourceNames.ThreeDNSBase
|
|
1637
|
-
];
|
|
1638
|
-
|
|
1639
|
-
// src/shared/log-level.ts
|
|
1640
|
-
import { z as z5 } from "zod/v4";
|
|
1641
|
-
var LogLevelSchema = z5.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]);
|
|
2548
|
+
// src/api/registrar-actions/deserialize.ts
|
|
2549
|
+
import { prettifyError as prettifyError8 } from "zod/v4";
|
|
1642
2550
|
|
|
1643
|
-
// src/
|
|
1644
|
-
import {
|
|
2551
|
+
// src/api/registrar-actions/zod-schemas.ts
|
|
2552
|
+
import { namehash as namehash3 } from "viem/ens";
|
|
2553
|
+
import z11 from "zod/v4";
|
|
1645
2554
|
|
|
1646
2555
|
// ../ens-referrals/src/address.ts
|
|
1647
|
-
import { isAddress as
|
|
2556
|
+
import { isAddress as isAddress3 } from "viem";
|
|
1648
2557
|
|
|
1649
2558
|
// ../ens-referrals/src/encoding.ts
|
|
1650
|
-
import { getAddress, pad, size as size2, slice, zeroAddress as
|
|
2559
|
+
import { getAddress, pad, size as size2, slice, zeroAddress as zeroAddress4 } from "viem";
|
|
1651
2560
|
var ENCODED_REFERRER_BYTE_OFFSET = 12;
|
|
1652
2561
|
var ENCODED_REFERRER_BYTE_LENGTH = 32;
|
|
1653
2562
|
var EXPECTED_ENCODED_REFERRER_PADDING = pad("0x", {
|
|
@@ -1666,7 +2575,7 @@ function decodeEncodedReferrer(encodedReferrer) {
|
|
|
1666
2575
|
}
|
|
1667
2576
|
const padding = slice(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
|
|
1668
2577
|
if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
|
|
1669
|
-
return
|
|
2578
|
+
return zeroAddress4;
|
|
1670
2579
|
}
|
|
1671
2580
|
const decodedReferrer = slice(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
|
|
1672
2581
|
try {
|
|
@@ -1682,25 +2591,20 @@ var REFERRERS_PER_LEADERBOARD_PAGE_MAX = 100;
|
|
|
1682
2591
|
// ../ens-referrals/src/link.ts
|
|
1683
2592
|
import { getAddress as getAddress2 } from "viem";
|
|
1684
2593
|
|
|
1685
|
-
// src/
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
2594
|
+
// ../ens-referrals/src/referrer-detail.ts
|
|
2595
|
+
var ReferrerDetailTypeIds = {
|
|
2596
|
+
/**
|
|
2597
|
+
* Represents a referrer who is ranked on the leaderboard.
|
|
2598
|
+
*/
|
|
2599
|
+
Ranked: "ranked",
|
|
2600
|
+
/**
|
|
2601
|
+
* Represents a referrer who is not ranked on the leaderboard.
|
|
2602
|
+
*/
|
|
2603
|
+
Unranked: "unranked"
|
|
2604
|
+
};
|
|
1695
2605
|
|
|
1696
|
-
// src/registrars/
|
|
1697
|
-
|
|
1698
|
-
return {
|
|
1699
|
-
subregistry: serializeSubregistry(registrationLifecycle.subregistry),
|
|
1700
|
-
node: registrationLifecycle.node,
|
|
1701
|
-
expiresAt: registrationLifecycle.expiresAt
|
|
1702
|
-
};
|
|
1703
|
-
}
|
|
2606
|
+
// src/registrars/zod-schemas.ts
|
|
2607
|
+
import z9 from "zod/v4";
|
|
1704
2608
|
|
|
1705
2609
|
// src/registrars/registrar-action.ts
|
|
1706
2610
|
var RegistrarActionTypes = {
|
|
@@ -1731,7 +2635,7 @@ function serializeRegistrarAction(registrarAction) {
|
|
|
1731
2635
|
type: registrarAction.type,
|
|
1732
2636
|
incrementalDuration: registrarAction.incrementalDuration,
|
|
1733
2637
|
registrant: registrarAction.registrant,
|
|
1734
|
-
registrationLifecycle:
|
|
2638
|
+
registrationLifecycle: registrarAction.registrationLifecycle,
|
|
1735
2639
|
pricing: serializeRegistrarActionPricing(registrarAction.pricing),
|
|
1736
2640
|
referral: registrarAction.referral,
|
|
1737
2641
|
block: registrarAction.block,
|
|
@@ -1741,11 +2645,11 @@ function serializeRegistrarAction(registrarAction) {
|
|
|
1741
2645
|
}
|
|
1742
2646
|
|
|
1743
2647
|
// src/registrars/zod-schemas.ts
|
|
1744
|
-
var makeSubregistrySchema = (valueLabel = "Subregistry") =>
|
|
1745
|
-
subregistryId:
|
|
2648
|
+
var makeSubregistrySchema = (valueLabel = "Subregistry") => z9.object({
|
|
2649
|
+
subregistryId: makeAccountIdSchema(`${valueLabel} Subregistry ID`),
|
|
1746
2650
|
node: makeNodeSchema(`${valueLabel} Node`)
|
|
1747
2651
|
});
|
|
1748
|
-
var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") =>
|
|
2652
|
+
var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => z9.object({
|
|
1749
2653
|
subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
|
|
1750
2654
|
node: makeNodeSchema(`${valueLabel} Node`),
|
|
1751
2655
|
expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
|
|
@@ -1761,18 +2665,18 @@ function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
|
|
|
1761
2665
|
});
|
|
1762
2666
|
}
|
|
1763
2667
|
}
|
|
1764
|
-
var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") =>
|
|
2668
|
+
var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => z9.union([
|
|
1765
2669
|
// pricing available
|
|
1766
|
-
|
|
2670
|
+
z9.object({
|
|
1767
2671
|
baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
|
|
1768
2672
|
premium: makePriceEthSchema(`${valueLabel} Premium`),
|
|
1769
2673
|
total: makePriceEthSchema(`${valueLabel} Total`)
|
|
1770
2674
|
}).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
|
|
1771
2675
|
// pricing unknown
|
|
1772
|
-
|
|
1773
|
-
baseCost:
|
|
1774
|
-
premium:
|
|
1775
|
-
total:
|
|
2676
|
+
z9.object({
|
|
2677
|
+
baseCost: z9.null(),
|
|
2678
|
+
premium: z9.null(),
|
|
2679
|
+
total: z9.null()
|
|
1776
2680
|
}).transform((v) => v)
|
|
1777
2681
|
]);
|
|
1778
2682
|
function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
|
|
@@ -1794,422 +2698,225 @@ function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
|
|
|
1794
2698
|
message: errorMessage
|
|
1795
2699
|
});
|
|
1796
2700
|
}
|
|
1797
|
-
}
|
|
1798
|
-
var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") =>
|
|
1799
|
-
// referral available
|
|
1800
|
-
|
|
1801
|
-
encodedReferrer: makeHexStringSchema(
|
|
1802
|
-
{ bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
|
|
1803
|
-
`${valueLabel} Encoded Referrer`
|
|
1804
|
-
),
|
|
1805
|
-
decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
|
|
1806
|
-
}).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
|
|
1807
|
-
// referral not applicable
|
|
1808
|
-
|
|
1809
|
-
encodedReferrer:
|
|
1810
|
-
decodedReferrer:
|
|
1811
|
-
})
|
|
1812
|
-
]);
|
|
1813
|
-
function invariant_eventIdsInitialElementIsTheActionId(ctx) {
|
|
1814
|
-
const { id, eventIds } = ctx.value;
|
|
1815
|
-
if (eventIds[0] !== id) {
|
|
1816
|
-
ctx.issues.push({
|
|
1817
|
-
code: "custom",
|
|
1818
|
-
input: ctx.value,
|
|
1819
|
-
message: "The initial element of `eventIds` must be the `id` value"
|
|
1820
|
-
});
|
|
1821
|
-
}
|
|
1822
|
-
}
|
|
1823
|
-
var EventIdSchema = z6.string().nonempty();
|
|
1824
|
-
var EventIdsSchema = z6.array(EventIdSchema).min(1).transform((v) => v);
|
|
1825
|
-
var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z6.object({
|
|
1826
|
-
id: EventIdSchema,
|
|
1827
|
-
incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
|
|
1828
|
-
registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
|
|
1829
|
-
registrationLifecycle: makeRegistrationLifecycleSchema(
|
|
1830
|
-
`${valueLabel} Registration Lifecycle`
|
|
1831
|
-
),
|
|
1832
|
-
pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
|
|
1833
|
-
referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
|
|
1834
|
-
block: makeBlockRefSchema(`${valueLabel} Block`),
|
|
1835
|
-
transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
|
|
1836
|
-
eventIds: EventIdsSchema
|
|
1837
|
-
}).check(invariant_eventIdsInitialElementIsTheActionId);
|
|
1838
|
-
var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
1839
|
-
type: z6.literal(RegistrarActionTypes.Registration)
|
|
1840
|
-
});
|
|
1841
|
-
var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
1842
|
-
type: z6.literal(RegistrarActionTypes.Renewal)
|
|
1843
|
-
});
|
|
1844
|
-
var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => z6.discriminatedUnion("type", [
|
|
1845
|
-
makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
|
|
1846
|
-
makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
|
|
1847
|
-
]);
|
|
1848
|
-
|
|
1849
|
-
// src/api/types.ts
|
|
1850
|
-
var IndexingStatusResponseCodes = {
|
|
1851
|
-
/**
|
|
1852
|
-
* Represents that the indexing status is available.
|
|
1853
|
-
*/
|
|
1854
|
-
Ok: "ok",
|
|
1855
|
-
/**
|
|
1856
|
-
* Represents that the indexing status is unavailable.
|
|
1857
|
-
*/
|
|
1858
|
-
Error: "error"
|
|
1859
|
-
};
|
|
1860
|
-
var RegistrarActionsFilterTypes = {
|
|
1861
|
-
BySubregistryNode: "bySubregistryNode",
|
|
1862
|
-
WithEncodedReferral: "withEncodedReferral"
|
|
1863
|
-
};
|
|
1864
|
-
var RegistrarActionsOrders = {
|
|
1865
|
-
LatestRegistrarActions: "orderBy[timestamp]=desc"
|
|
1866
|
-
};
|
|
1867
|
-
var RegistrarActionsResponseCodes = {
|
|
1868
|
-
/**
|
|
1869
|
-
* Represents that Registrar Actions are available.
|
|
1870
|
-
*/
|
|
1871
|
-
Ok: "ok",
|
|
1872
|
-
/**
|
|
1873
|
-
* Represents that Registrar Actions are unavailable.
|
|
1874
|
-
*/
|
|
1875
|
-
Error: "error"
|
|
1876
|
-
};
|
|
1877
|
-
|
|
1878
|
-
// src/api/zod-schemas.ts
|
|
1879
|
-
var ErrorResponseSchema = z7.object({
|
|
1880
|
-
message: z7.string(),
|
|
1881
|
-
details: z7.optional(z7.unknown())
|
|
1882
|
-
});
|
|
1883
|
-
var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => z7.strictObject({
|
|
1884
|
-
responseCode: z7.literal(IndexingStatusResponseCodes.Ok),
|
|
1885
|
-
realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
|
|
1886
|
-
});
|
|
1887
|
-
var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => z7.strictObject({
|
|
1888
|
-
responseCode: z7.literal(IndexingStatusResponseCodes.Error)
|
|
1889
|
-
});
|
|
1890
|
-
var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => z7.discriminatedUnion("responseCode", [
|
|
1891
|
-
makeIndexingStatusResponseOkSchema(valueLabel),
|
|
1892
|
-
makeIndexingStatusResponseErrorSchema(valueLabel)
|
|
1893
|
-
]);
|
|
1894
|
-
function invariant_registrationLifecycleNodeMatchesName(ctx) {
|
|
1895
|
-
const { name, action } = ctx.value;
|
|
1896
|
-
const expectedNode = action.registrationLifecycle.node;
|
|
1897
|
-
const actualNode = namehash2(name);
|
|
1898
|
-
if (actualNode !== expectedNode) {
|
|
1899
|
-
ctx.issues.push({
|
|
1900
|
-
code: "custom",
|
|
1901
|
-
input: ctx.value,
|
|
1902
|
-
message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
|
|
1903
|
-
});
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z7.object({
|
|
1907
|
-
action: makeRegistrarActionSchema(valueLabel),
|
|
1908
|
-
name: makeReinterpretedNameSchema(valueLabel)
|
|
1909
|
-
}).check(invariant_registrationLifecycleNodeMatchesName);
|
|
1910
|
-
var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z7.strictObject({
|
|
1911
|
-
responseCode: z7.literal(RegistrarActionsResponseCodes.Ok),
|
|
1912
|
-
registrarActions: z7.array(makeNamedRegistrarActionSchema(valueLabel))
|
|
1913
|
-
});
|
|
1914
|
-
var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => z7.strictObject({
|
|
1915
|
-
responseCode: z7.literal(RegistrarActionsResponseCodes.Error),
|
|
1916
|
-
error: ErrorResponseSchema
|
|
1917
|
-
});
|
|
1918
|
-
var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => z7.discriminatedUnion("responseCode", [
|
|
1919
|
-
makeRegistrarActionsResponseOkSchema(valueLabel),
|
|
1920
|
-
makeRegistrarActionsResponseErrorSchema(valueLabel)
|
|
1921
|
-
]);
|
|
1922
|
-
|
|
1923
|
-
// src/api/deserialize.ts
|
|
1924
|
-
function deserializeErrorResponse(maybeErrorResponse) {
|
|
1925
|
-
const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
|
|
1926
|
-
if (parsed.error) {
|
|
1927
|
-
throw new Error(`Cannot deserialize ErrorResponse:
|
|
1928
|
-
${prettifyError2(parsed.error)}
|
|
1929
|
-
`);
|
|
1930
|
-
}
|
|
1931
|
-
return parsed.data;
|
|
1932
|
-
}
|
|
1933
|
-
function deserializeIndexingStatusResponse(maybeResponse) {
|
|
1934
|
-
const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
|
|
1935
|
-
if (parsed.error) {
|
|
1936
|
-
throw new Error(`Cannot deserialize IndexingStatusResponse:
|
|
1937
|
-
${prettifyError2(parsed.error)}
|
|
1938
|
-
`);
|
|
1939
|
-
}
|
|
1940
|
-
return parsed.data;
|
|
1941
|
-
}
|
|
1942
|
-
function deserializeRegistrarActionsResponse(maybeResponse) {
|
|
1943
|
-
const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
|
|
1944
|
-
if (parsed.error) {
|
|
1945
|
-
throw new Error(
|
|
1946
|
-
`Cannot deserialize RegistrarActionsResponse:
|
|
1947
|
-
${prettifyError2(parsed.error)}
|
|
1948
|
-
`
|
|
1949
|
-
);
|
|
1950
|
-
}
|
|
1951
|
-
return parsed.data;
|
|
1952
|
-
}
|
|
1953
|
-
|
|
1954
|
-
// src/api/registrar-actions/filters.ts
|
|
1955
|
-
function byParentNode(parentNode) {
|
|
1956
|
-
if (typeof parentNode === "undefined") {
|
|
1957
|
-
return void 0;
|
|
1958
|
-
}
|
|
1959
|
-
return {
|
|
1960
|
-
filterType: RegistrarActionsFilterTypes.BySubregistryNode,
|
|
1961
|
-
value: parentNode
|
|
1962
|
-
};
|
|
1963
|
-
}
|
|
1964
|
-
function withReferral(withReferral2) {
|
|
1965
|
-
if (!withReferral2) {
|
|
1966
|
-
return void 0;
|
|
1967
|
-
}
|
|
1968
|
-
return {
|
|
1969
|
-
filterType: RegistrarActionsFilterTypes.WithEncodedReferral
|
|
1970
|
-
};
|
|
1971
|
-
}
|
|
1972
|
-
var registrarActionsFilter = {
|
|
1973
|
-
byParentNode,
|
|
1974
|
-
withReferral
|
|
1975
|
-
};
|
|
1976
|
-
|
|
1977
|
-
// src/ensindexer/config/deserialize.ts
|
|
1978
|
-
import { prettifyError as prettifyError3 } from "zod/v4";
|
|
1979
|
-
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
1980
|
-
const schema = makeENSIndexerPublicConfigSchema(valueLabel);
|
|
1981
|
-
const parsed = schema.safeParse(maybeConfig);
|
|
1982
|
-
if (parsed.error) {
|
|
1983
|
-
throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
|
|
1984
|
-
${prettifyError3(parsed.error)}
|
|
1985
|
-
`);
|
|
1986
|
-
}
|
|
1987
|
-
return parsed.data;
|
|
1988
|
-
}
|
|
1989
|
-
|
|
1990
|
-
// src/ensindexer/config/label-utils.ts
|
|
1991
|
-
import { hexToBytes as hexToBytes2 } from "viem";
|
|
1992
|
-
function labelHashToBytes(labelHash) {
|
|
1993
|
-
try {
|
|
1994
|
-
if (labelHash.length !== 66) {
|
|
1995
|
-
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
1996
|
-
}
|
|
1997
|
-
if (labelHash !== labelHash.toLowerCase()) {
|
|
1998
|
-
throw new Error("Labelhash must be in lowercase");
|
|
1999
|
-
}
|
|
2000
|
-
if (!labelHash.startsWith("0x")) {
|
|
2001
|
-
throw new Error("Labelhash must be 0x-prefixed");
|
|
2002
|
-
}
|
|
2003
|
-
const bytes = hexToBytes2(labelHash);
|
|
2004
|
-
if (bytes.length !== 32) {
|
|
2005
|
-
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
2006
|
-
}
|
|
2007
|
-
return bytes;
|
|
2008
|
-
} catch (e) {
|
|
2009
|
-
if (e instanceof Error) {
|
|
2010
|
-
throw e;
|
|
2011
|
-
}
|
|
2012
|
-
throw new Error("Invalid hex format");
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
|
|
2016
|
-
// src/ensindexer/config/labelset-utils.ts
|
|
2017
|
-
function buildLabelSetId(maybeLabelSetId) {
|
|
2018
|
-
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
2019
|
-
}
|
|
2020
|
-
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
2021
|
-
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
2022
|
-
}
|
|
2023
|
-
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
2024
|
-
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
2025
|
-
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
2026
|
-
}
|
|
2027
|
-
return { labelSetId, labelSetVersion };
|
|
2028
|
-
}
|
|
2029
|
-
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
2030
|
-
if (clientSet.labelSetId === void 0) {
|
|
2031
|
-
return;
|
|
2032
|
-
}
|
|
2033
|
-
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
2034
|
-
throw new Error(
|
|
2035
|
-
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
2036
|
-
);
|
|
2037
|
-
}
|
|
2038
|
-
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
2039
|
-
throw new Error(
|
|
2040
|
-
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
2041
|
-
);
|
|
2701
|
+
}
|
|
2702
|
+
var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => z9.union([
|
|
2703
|
+
// referral available
|
|
2704
|
+
z9.object({
|
|
2705
|
+
encodedReferrer: makeHexStringSchema(
|
|
2706
|
+
{ bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
|
|
2707
|
+
`${valueLabel} Encoded Referrer`
|
|
2708
|
+
),
|
|
2709
|
+
decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
|
|
2710
|
+
}).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
|
|
2711
|
+
// referral not applicable
|
|
2712
|
+
z9.object({
|
|
2713
|
+
encodedReferrer: z9.null(),
|
|
2714
|
+
decodedReferrer: z9.null()
|
|
2715
|
+
})
|
|
2716
|
+
]);
|
|
2717
|
+
function invariant_eventIdsInitialElementIsTheActionId(ctx) {
|
|
2718
|
+
const { id, eventIds } = ctx.value;
|
|
2719
|
+
if (eventIds[0] !== id) {
|
|
2720
|
+
ctx.issues.push({
|
|
2721
|
+
code: "custom",
|
|
2722
|
+
input: ctx.value,
|
|
2723
|
+
message: "The initial element of `eventIds` must be the `id` value"
|
|
2724
|
+
});
|
|
2042
2725
|
}
|
|
2043
2726
|
}
|
|
2727
|
+
var EventIdSchema = z9.string().nonempty();
|
|
2728
|
+
var EventIdsSchema = z9.array(EventIdSchema).min(1).transform((v) => v);
|
|
2729
|
+
var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => z9.object({
|
|
2730
|
+
id: EventIdSchema,
|
|
2731
|
+
incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
|
|
2732
|
+
registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
|
|
2733
|
+
registrationLifecycle: makeRegistrationLifecycleSchema(
|
|
2734
|
+
`${valueLabel} Registration Lifecycle`
|
|
2735
|
+
),
|
|
2736
|
+
pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
|
|
2737
|
+
referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
|
|
2738
|
+
block: makeBlockRefSchema(`${valueLabel} Block`),
|
|
2739
|
+
transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
|
|
2740
|
+
eventIds: EventIdsSchema
|
|
2741
|
+
}).check(invariant_eventIdsInitialElementIsTheActionId);
|
|
2742
|
+
var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
2743
|
+
type: z9.literal(RegistrarActionTypes.Registration)
|
|
2744
|
+
});
|
|
2745
|
+
var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
2746
|
+
type: z9.literal(RegistrarActionTypes.Renewal)
|
|
2747
|
+
});
|
|
2748
|
+
var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => z9.discriminatedUnion("type", [
|
|
2749
|
+
makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
|
|
2750
|
+
makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
|
|
2751
|
+
]);
|
|
2044
2752
|
|
|
2045
|
-
// src/
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2753
|
+
// src/api/shared/pagination/zod-schemas.ts
|
|
2754
|
+
import z10 from "zod/v4";
|
|
2755
|
+
|
|
2756
|
+
// src/api/shared/pagination/request.ts
|
|
2757
|
+
var RECORDS_PER_PAGE_DEFAULT = 10;
|
|
2758
|
+
var RECORDS_PER_PAGE_MAX = 100;
|
|
2759
|
+
|
|
2760
|
+
// src/api/shared/pagination/zod-schemas.ts
|
|
2761
|
+
var makeRequestPageParamsSchema = (valueLabel = "RequestPageParams") => z10.object({
|
|
2762
|
+
page: makePositiveIntegerSchema(`${valueLabel}.page`),
|
|
2763
|
+
recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
|
|
2764
|
+
RECORDS_PER_PAGE_MAX,
|
|
2765
|
+
`${valueLabel}.recordsPerPage must not exceed ${RECORDS_PER_PAGE_MAX}`
|
|
2766
|
+
)
|
|
2767
|
+
});
|
|
2768
|
+
var makeResponsePageContextSchemaWithNoRecords = (valueLabel = "ResponsePageContextWithNoRecords") => z10.object({
|
|
2769
|
+
totalRecords: z10.literal(0),
|
|
2770
|
+
totalPages: z10.literal(1),
|
|
2771
|
+
hasNext: z10.literal(false),
|
|
2772
|
+
hasPrev: z10.literal(false),
|
|
2773
|
+
startIndex: z10.undefined(),
|
|
2774
|
+
endIndex: z10.undefined()
|
|
2775
|
+
}).extend(makeRequestPageParamsSchema(valueLabel).shape);
|
|
2776
|
+
function invariant_responsePageWithRecordsIsCorrect(ctx) {
|
|
2777
|
+
const { hasNext, hasPrev, recordsPerPage, page, totalRecords, startIndex, endIndex } = ctx.value;
|
|
2778
|
+
const expectedHasNext = page * recordsPerPage < totalRecords;
|
|
2779
|
+
if (hasNext !== expectedHasNext) {
|
|
2780
|
+
ctx.issues.push({
|
|
2781
|
+
code: "custom",
|
|
2782
|
+
input: ctx.value,
|
|
2783
|
+
message: `hasNext must be equal to '${expectedHasNext ? "true" : "false"}'`
|
|
2784
|
+
});
|
|
2057
2785
|
}
|
|
2058
|
-
|
|
2059
|
-
|
|
2786
|
+
const expectedHasPrev = page > 1;
|
|
2787
|
+
if (hasPrev !== expectedHasPrev) {
|
|
2788
|
+
ctx.issues.push({
|
|
2789
|
+
code: "custom",
|
|
2790
|
+
input: ctx.value,
|
|
2791
|
+
message: `hasPrev must be equal to '${expectedHasPrev ? "true" : "false"}'`
|
|
2792
|
+
});
|
|
2060
2793
|
}
|
|
2061
|
-
if (
|
|
2062
|
-
|
|
2794
|
+
if (endIndex < startIndex) {
|
|
2795
|
+
ctx.issues.push({
|
|
2796
|
+
code: "custom",
|
|
2797
|
+
input: ctx.value,
|
|
2798
|
+
message: `endIndex must be greater than or equal to startIndex`
|
|
2799
|
+
});
|
|
2063
2800
|
}
|
|
2064
|
-
if (
|
|
2065
|
-
|
|
2801
|
+
if (endIndex >= totalRecords) {
|
|
2802
|
+
ctx.issues.push({
|
|
2803
|
+
code: "custom",
|
|
2804
|
+
input: ctx.value,
|
|
2805
|
+
message: `endIndex must be lower than totalRecords`
|
|
2806
|
+
});
|
|
2066
2807
|
}
|
|
2067
|
-
return num;
|
|
2068
2808
|
}
|
|
2809
|
+
var makeResponsePageContextSchemaWithRecords = (valueLabel = "ResponsePageContextWithRecords") => z10.object({
|
|
2810
|
+
totalRecords: makePositiveIntegerSchema(`${valueLabel}.totalRecords`),
|
|
2811
|
+
totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
|
|
2812
|
+
hasNext: z10.boolean(),
|
|
2813
|
+
hasPrev: z10.boolean(),
|
|
2814
|
+
startIndex: makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`),
|
|
2815
|
+
endIndex: makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`)
|
|
2816
|
+
}).extend(makeRequestPageParamsSchema(valueLabel).shape).check(invariant_responsePageWithRecordsIsCorrect);
|
|
2817
|
+
var makeResponsePageContextSchema = (valueLabel = "ResponsePageContext") => z10.union([
|
|
2818
|
+
makeResponsePageContextSchemaWithNoRecords(valueLabel),
|
|
2819
|
+
makeResponsePageContextSchemaWithRecords(valueLabel)
|
|
2820
|
+
]);
|
|
2069
2821
|
|
|
2070
|
-
// src/
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
plugins,
|
|
2082
|
-
versionInfo
|
|
2083
|
-
} = config;
|
|
2084
|
-
return {
|
|
2085
|
-
labelSet,
|
|
2086
|
-
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
2087
|
-
databaseSchemaName,
|
|
2088
|
-
isSubgraphCompatible: isSubgraphCompatible2,
|
|
2089
|
-
namespace,
|
|
2090
|
-
plugins,
|
|
2091
|
-
versionInfo
|
|
2092
|
-
};
|
|
2093
|
-
}
|
|
2822
|
+
// src/api/registrar-actions/response.ts
|
|
2823
|
+
var RegistrarActionsResponseCodes = {
|
|
2824
|
+
/**
|
|
2825
|
+
* Represents that Registrar Actions are available.
|
|
2826
|
+
*/
|
|
2827
|
+
Ok: "ok",
|
|
2828
|
+
/**
|
|
2829
|
+
* Represents that Registrar Actions are unavailable.
|
|
2830
|
+
*/
|
|
2831
|
+
Error: "error"
|
|
2832
|
+
};
|
|
2094
2833
|
|
|
2095
|
-
// src/
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
const
|
|
2099
|
-
const
|
|
2100
|
-
if (
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
`
|
|
2105
|
-
);
|
|
2106
|
-
}
|
|
2107
|
-
return parsed.data;
|
|
2108
|
-
}
|
|
2109
|
-
function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
2110
|
-
const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
|
|
2111
|
-
const parsed = schema.safeParse(maybeSnapshot);
|
|
2112
|
-
if (parsed.error) {
|
|
2113
|
-
throw new Error(
|
|
2114
|
-
`Cannot deserialize into OmnichainIndexingStatusSnapshot:
|
|
2115
|
-
${prettifyError4(parsed.error)}
|
|
2116
|
-
`
|
|
2117
|
-
);
|
|
2118
|
-
}
|
|
2119
|
-
return parsed.data;
|
|
2120
|
-
}
|
|
2121
|
-
function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
2122
|
-
const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
|
|
2123
|
-
const parsed = schema.safeParse(maybeSnapshot);
|
|
2124
|
-
if (parsed.error) {
|
|
2125
|
-
throw new Error(
|
|
2126
|
-
`Cannot deserialize into CrossChainIndexingStatusSnapshot:
|
|
2127
|
-
${prettifyError4(parsed.error)}
|
|
2128
|
-
`
|
|
2129
|
-
);
|
|
2834
|
+
// src/api/registrar-actions/zod-schemas.ts
|
|
2835
|
+
function invariant_registrationLifecycleNodeMatchesName(ctx) {
|
|
2836
|
+
const { name, action } = ctx.value;
|
|
2837
|
+
const expectedNode = action.registrationLifecycle.node;
|
|
2838
|
+
const actualNode = namehash3(name);
|
|
2839
|
+
if (actualNode !== expectedNode) {
|
|
2840
|
+
ctx.issues.push({
|
|
2841
|
+
code: "custom",
|
|
2842
|
+
input: ctx.value,
|
|
2843
|
+
message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
|
|
2844
|
+
});
|
|
2130
2845
|
}
|
|
2131
|
-
return parsed.data;
|
|
2132
2846
|
}
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2847
|
+
var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => z11.object({
|
|
2848
|
+
action: makeRegistrarActionSchema(valueLabel),
|
|
2849
|
+
name: makeReinterpretedNameSchema(valueLabel)
|
|
2850
|
+
}).check(invariant_registrationLifecycleNodeMatchesName);
|
|
2851
|
+
var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => z11.strictObject({
|
|
2852
|
+
responseCode: z11.literal(RegistrarActionsResponseCodes.Ok),
|
|
2853
|
+
registrarActions: z11.array(makeNamedRegistrarActionSchema(valueLabel)),
|
|
2854
|
+
pageContext: makeResponsePageContextSchema(`${valueLabel}.pageContext`)
|
|
2855
|
+
});
|
|
2856
|
+
var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => z11.strictObject({
|
|
2857
|
+
responseCode: z11.literal(RegistrarActionsResponseCodes.Error),
|
|
2858
|
+
error: ErrorResponseSchema
|
|
2859
|
+
});
|
|
2860
|
+
var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => z11.discriminatedUnion("responseCode", [
|
|
2861
|
+
makeRegistrarActionsResponseOkSchema(valueLabel),
|
|
2862
|
+
makeRegistrarActionsResponseErrorSchema(valueLabel)
|
|
2863
|
+
]);
|
|
2864
|
+
|
|
2865
|
+
// src/api/registrar-actions/deserialize.ts
|
|
2866
|
+
function deserializeRegistrarActionsResponse(maybeResponse) {
|
|
2867
|
+
const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
|
|
2136
2868
|
if (parsed.error) {
|
|
2137
2869
|
throw new Error(
|
|
2138
|
-
`Cannot deserialize
|
|
2139
|
-
${
|
|
2870
|
+
`Cannot deserialize RegistrarActionsResponse:
|
|
2871
|
+
${prettifyError8(parsed.error)}
|
|
2140
2872
|
`
|
|
2141
2873
|
);
|
|
2142
2874
|
}
|
|
2143
2875
|
return parsed.data;
|
|
2144
2876
|
}
|
|
2145
2877
|
|
|
2146
|
-
// src/
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
}
|
|
2878
|
+
// src/api/registrar-actions/request.ts
|
|
2879
|
+
var RegistrarActionsFilterTypes = {
|
|
2880
|
+
BySubregistryNode: "bySubregistryNode",
|
|
2881
|
+
WithEncodedReferral: "withEncodedReferral",
|
|
2882
|
+
ByDecodedReferrer: "byDecodedReferrer"
|
|
2883
|
+
};
|
|
2884
|
+
var RegistrarActionsOrders = {
|
|
2885
|
+
LatestRegistrarActions: "orderBy[timestamp]=desc"
|
|
2886
|
+
};
|
|
2155
2887
|
|
|
2156
|
-
// src/
|
|
2157
|
-
function
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
snapshotTime,
|
|
2161
|
-
omnichainSnapshot
|
|
2162
|
-
}) {
|
|
2163
|
-
return {
|
|
2164
|
-
strategy,
|
|
2165
|
-
slowestChainIndexingCursor,
|
|
2166
|
-
snapshotTime,
|
|
2167
|
-
omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
|
|
2168
|
-
};
|
|
2169
|
-
}
|
|
2170
|
-
function serializeRealtimeIndexingStatusProjection(indexingProjection) {
|
|
2171
|
-
return {
|
|
2172
|
-
projectedAt: indexingProjection.projectedAt,
|
|
2173
|
-
worstCaseDistance: indexingProjection.worstCaseDistance,
|
|
2174
|
-
snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
|
|
2175
|
-
};
|
|
2176
|
-
}
|
|
2177
|
-
function serializeChainIndexingSnapshots(chains) {
|
|
2178
|
-
const serializedSnapshots = {};
|
|
2179
|
-
for (const [chainId, snapshot] of chains.entries()) {
|
|
2180
|
-
serializedSnapshots[serializeChainId(chainId)] = snapshot;
|
|
2888
|
+
// src/api/registrar-actions/filters.ts
|
|
2889
|
+
function byParentNode(parentNode) {
|
|
2890
|
+
if (typeof parentNode === "undefined") {
|
|
2891
|
+
return void 0;
|
|
2181
2892
|
}
|
|
2182
|
-
return
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
case OmnichainIndexingStatusIds.Completed: {
|
|
2199
|
-
return {
|
|
2200
|
-
omnichainStatus: OmnichainIndexingStatusIds.Completed,
|
|
2201
|
-
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
2202
|
-
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
2203
|
-
};
|
|
2204
|
-
}
|
|
2205
|
-
case OmnichainIndexingStatusIds.Following:
|
|
2206
|
-
return {
|
|
2207
|
-
omnichainStatus: OmnichainIndexingStatusIds.Following,
|
|
2208
|
-
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
2209
|
-
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
2210
|
-
};
|
|
2893
|
+
return {
|
|
2894
|
+
filterType: RegistrarActionsFilterTypes.BySubregistryNode,
|
|
2895
|
+
value: parentNode
|
|
2896
|
+
};
|
|
2897
|
+
}
|
|
2898
|
+
function withReferral(withReferral2) {
|
|
2899
|
+
if (!withReferral2) {
|
|
2900
|
+
return void 0;
|
|
2901
|
+
}
|
|
2902
|
+
return {
|
|
2903
|
+
filterType: RegistrarActionsFilterTypes.WithEncodedReferral
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
function byDecodedReferrer(decodedReferrer) {
|
|
2907
|
+
if (typeof decodedReferrer === "undefined") {
|
|
2908
|
+
return void 0;
|
|
2211
2909
|
}
|
|
2910
|
+
return {
|
|
2911
|
+
filterType: RegistrarActionsFilterTypes.ByDecodedReferrer,
|
|
2912
|
+
value: decodedReferrer
|
|
2913
|
+
};
|
|
2212
2914
|
}
|
|
2915
|
+
var registrarActionsFilter = {
|
|
2916
|
+
byParentNode,
|
|
2917
|
+
withReferral,
|
|
2918
|
+
byDecodedReferrer
|
|
2919
|
+
};
|
|
2213
2920
|
|
|
2214
2921
|
// src/api/registrar-actions/prerequisites.ts
|
|
2215
2922
|
var registrarActionsPrerequisites = Object.freeze({
|
|
@@ -2261,12 +2968,50 @@ var registrarActionsPrerequisites = Object.freeze({
|
|
|
2261
2968
|
}
|
|
2262
2969
|
});
|
|
2263
2970
|
|
|
2971
|
+
// src/registrars/basenames-subregistry.ts
|
|
2972
|
+
import {
|
|
2973
|
+
DatasourceNames as DatasourceNames2,
|
|
2974
|
+
ENSNamespaceIds as ENSNamespaceIds3,
|
|
2975
|
+
maybeGetDatasource as maybeGetDatasource2
|
|
2976
|
+
} from "@ensnode/datasources";
|
|
2977
|
+
function getBasenamesSubregistryId(namespace) {
|
|
2978
|
+
const datasource = maybeGetDatasource2(namespace, DatasourceNames2.Basenames);
|
|
2979
|
+
if (!datasource) {
|
|
2980
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames2.Basenames}`);
|
|
2981
|
+
}
|
|
2982
|
+
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2983
|
+
if (address === void 0 || Array.isArray(address)) {
|
|
2984
|
+
throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
|
|
2985
|
+
}
|
|
2986
|
+
return {
|
|
2987
|
+
chainId: datasource.chain.id,
|
|
2988
|
+
address
|
|
2989
|
+
};
|
|
2990
|
+
}
|
|
2991
|
+
function getBasenamesSubregistryManagedName(namespaceId) {
|
|
2992
|
+
switch (namespaceId) {
|
|
2993
|
+
case ENSNamespaceIds3.Mainnet:
|
|
2994
|
+
return "base.eth";
|
|
2995
|
+
case ENSNamespaceIds3.Sepolia:
|
|
2996
|
+
return "basetest.eth";
|
|
2997
|
+
case ENSNamespaceIds3.Holesky:
|
|
2998
|
+
case ENSNamespaceIds3.EnsTestEnv:
|
|
2999
|
+
throw new Error(
|
|
3000
|
+
`No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`
|
|
3001
|
+
);
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
|
|
2264
3005
|
// src/registrars/ethnames-subregistry.ts
|
|
2265
|
-
import {
|
|
3006
|
+
import {
|
|
3007
|
+
DatasourceNames as DatasourceNames3,
|
|
3008
|
+
ENSNamespaceIds as ENSNamespaceIds4,
|
|
3009
|
+
maybeGetDatasource as maybeGetDatasource3
|
|
3010
|
+
} from "@ensnode/datasources";
|
|
2266
3011
|
function getEthnamesSubregistryId(namespace) {
|
|
2267
|
-
const datasource =
|
|
3012
|
+
const datasource = maybeGetDatasource3(namespace, DatasourceNames3.ENSRoot);
|
|
2268
3013
|
if (!datasource) {
|
|
2269
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
3014
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames3.ENSRoot}`);
|
|
2270
3015
|
}
|
|
2271
3016
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2272
3017
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -2277,19 +3022,51 @@ function getEthnamesSubregistryId(namespace) {
|
|
|
2277
3022
|
address
|
|
2278
3023
|
};
|
|
2279
3024
|
}
|
|
3025
|
+
function getEthnamesSubregistryManagedName(namespaceId) {
|
|
3026
|
+
switch (namespaceId) {
|
|
3027
|
+
case ENSNamespaceIds4.Mainnet:
|
|
3028
|
+
case ENSNamespaceIds4.Sepolia:
|
|
3029
|
+
case ENSNamespaceIds4.Holesky:
|
|
3030
|
+
case ENSNamespaceIds4.EnsTestEnv:
|
|
3031
|
+
return "eth";
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
2280
3034
|
|
|
2281
|
-
// src/
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
3035
|
+
// src/registrars/lineanames-subregistry.ts
|
|
3036
|
+
import {
|
|
3037
|
+
DatasourceNames as DatasourceNames4,
|
|
3038
|
+
ENSNamespaceIds as ENSNamespaceIds5,
|
|
3039
|
+
maybeGetDatasource as maybeGetDatasource4
|
|
3040
|
+
} from "@ensnode/datasources";
|
|
3041
|
+
function getLineanamesSubregistryId(namespace) {
|
|
3042
|
+
const datasource = maybeGetDatasource4(namespace, DatasourceNames4.Lineanames);
|
|
3043
|
+
if (!datasource) {
|
|
3044
|
+
throw new Error(`Datasource not found for ${namespace} ${DatasourceNames4.Lineanames}`);
|
|
3045
|
+
}
|
|
3046
|
+
const address = datasource.contracts.BaseRegistrar?.address;
|
|
3047
|
+
if (address === void 0 || Array.isArray(address)) {
|
|
3048
|
+
throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
|
|
3049
|
+
}
|
|
3050
|
+
return {
|
|
3051
|
+
chainId: datasource.chain.id,
|
|
3052
|
+
address
|
|
3053
|
+
};
|
|
3054
|
+
}
|
|
3055
|
+
function getLineanamesSubregistryManagedName(namespaceId) {
|
|
3056
|
+
switch (namespaceId) {
|
|
3057
|
+
case ENSNamespaceIds5.Mainnet:
|
|
3058
|
+
return "linea.eth";
|
|
3059
|
+
case ENSNamespaceIds5.Sepolia:
|
|
3060
|
+
return "linea-sepolia.eth";
|
|
3061
|
+
case ENSNamespaceIds5.Holesky:
|
|
3062
|
+
case ENSNamespaceIds5.EnsTestEnv:
|
|
3063
|
+
throw new Error(
|
|
3064
|
+
`No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`
|
|
3065
|
+
);
|
|
2291
3066
|
}
|
|
2292
3067
|
}
|
|
3068
|
+
|
|
3069
|
+
// src/api/registrar-actions/serialize.ts
|
|
2293
3070
|
function serializeNamedRegistrarAction({
|
|
2294
3071
|
action,
|
|
2295
3072
|
name
|
|
@@ -2304,13 +3081,61 @@ function serializeRegistrarActionsResponse(response) {
|
|
|
2304
3081
|
case RegistrarActionsResponseCodes.Ok:
|
|
2305
3082
|
return {
|
|
2306
3083
|
responseCode: response.responseCode,
|
|
2307
|
-
registrarActions: response.registrarActions.map(serializeNamedRegistrarAction)
|
|
3084
|
+
registrarActions: response.registrarActions.map(serializeNamedRegistrarAction),
|
|
3085
|
+
pageContext: response.pageContext
|
|
2308
3086
|
};
|
|
2309
3087
|
case RegistrarActionsResponseCodes.Error:
|
|
2310
3088
|
return response;
|
|
2311
3089
|
}
|
|
2312
3090
|
}
|
|
2313
3091
|
|
|
3092
|
+
// src/api/shared/errors/deserialize.ts
|
|
3093
|
+
import { prettifyError as prettifyError9 } from "zod/v4";
|
|
3094
|
+
function deserializeErrorResponse(maybeErrorResponse) {
|
|
3095
|
+
const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
|
|
3096
|
+
if (parsed.error) {
|
|
3097
|
+
throw new Error(`Cannot deserialize ErrorResponse:
|
|
3098
|
+
${prettifyError9(parsed.error)}
|
|
3099
|
+
`);
|
|
3100
|
+
}
|
|
3101
|
+
return parsed.data;
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
// src/api/shared/pagination/build-page-context.ts
|
|
3105
|
+
function buildPageContext(page, recordsPerPage, totalRecords) {
|
|
3106
|
+
const totalPages = Math.max(1, Math.ceil(totalRecords / recordsPerPage));
|
|
3107
|
+
if (page > totalPages) {
|
|
3108
|
+
throw new Error(`Invalid page: page ${page} exceeds total pages ${totalPages}.`);
|
|
3109
|
+
}
|
|
3110
|
+
if (totalRecords === 0) {
|
|
3111
|
+
return {
|
|
3112
|
+
page,
|
|
3113
|
+
recordsPerPage,
|
|
3114
|
+
totalRecords: 0,
|
|
3115
|
+
totalPages: 1,
|
|
3116
|
+
hasNext: false,
|
|
3117
|
+
hasPrev: false,
|
|
3118
|
+
startIndex: void 0,
|
|
3119
|
+
endIndex: void 0
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
const startIndex = (page - 1) * recordsPerPage;
|
|
3123
|
+
const maxTheoreticalIndexOnPage = startIndex + (recordsPerPage - 1);
|
|
3124
|
+
const endIndex = Math.min(maxTheoreticalIndexOnPage, totalRecords - 1);
|
|
3125
|
+
const hasNext = maxTheoreticalIndexOnPage < totalRecords - 1;
|
|
3126
|
+
const hasPrev = page > 1;
|
|
3127
|
+
return {
|
|
3128
|
+
page,
|
|
3129
|
+
recordsPerPage,
|
|
3130
|
+
totalRecords,
|
|
3131
|
+
totalPages,
|
|
3132
|
+
hasNext,
|
|
3133
|
+
hasPrev,
|
|
3134
|
+
startIndex,
|
|
3135
|
+
endIndex
|
|
3136
|
+
};
|
|
3137
|
+
}
|
|
3138
|
+
|
|
2314
3139
|
// src/client-error.ts
|
|
2315
3140
|
var ClientError = class _ClientError extends Error {
|
|
2316
3141
|
details;
|
|
@@ -2325,10 +3150,10 @@ var ClientError = class _ClientError extends Error {
|
|
|
2325
3150
|
};
|
|
2326
3151
|
|
|
2327
3152
|
// src/ensanalytics/deserialize.ts
|
|
2328
|
-
import { prettifyError as
|
|
3153
|
+
import { prettifyError as prettifyError10 } from "zod/v4";
|
|
2329
3154
|
|
|
2330
3155
|
// src/ensanalytics/zod-schemas.ts
|
|
2331
|
-
import
|
|
3156
|
+
import z12 from "zod/v4";
|
|
2332
3157
|
|
|
2333
3158
|
// src/ensanalytics/types.ts
|
|
2334
3159
|
var ReferrerLeaderboardPageResponseCodes = {
|
|
@@ -2341,22 +3166,50 @@ var ReferrerLeaderboardPageResponseCodes = {
|
|
|
2341
3166
|
*/
|
|
2342
3167
|
Error: "error"
|
|
2343
3168
|
};
|
|
3169
|
+
var ReferrerDetailResponseCodes = {
|
|
3170
|
+
/**
|
|
3171
|
+
* Represents that the referrer detail data is available.
|
|
3172
|
+
*/
|
|
3173
|
+
Ok: "ok",
|
|
3174
|
+
/**
|
|
3175
|
+
* Represents that an error occurred while fetching the data.
|
|
3176
|
+
*/
|
|
3177
|
+
Error: "error"
|
|
3178
|
+
};
|
|
2344
3179
|
|
|
2345
3180
|
// src/ensanalytics/zod-schemas.ts
|
|
2346
|
-
var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") =>
|
|
3181
|
+
var makeReferralProgramRulesSchema = (valueLabel = "ReferralProgramRules") => z12.object({
|
|
2347
3182
|
totalAwardPoolValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.totalAwardPoolValue`),
|
|
2348
3183
|
maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`),
|
|
2349
3184
|
startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
|
|
2350
3185
|
endTime: makeUnixTimestampSchema(`${valueLabel}.endTime`),
|
|
2351
3186
|
subregistryId: makeAccountIdSchema(`${valueLabel}.subregistryId`)
|
|
2352
3187
|
});
|
|
2353
|
-
var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") =>
|
|
3188
|
+
var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") => z12.object({
|
|
2354
3189
|
referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
|
|
2355
3190
|
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
2356
3191
|
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
2357
3192
|
score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
|
|
2358
3193
|
rank: makePositiveIntegerSchema(`${valueLabel}.rank`),
|
|
2359
|
-
isQualified:
|
|
3194
|
+
isQualified: z12.boolean(),
|
|
3195
|
+
finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
|
|
3196
|
+
1,
|
|
3197
|
+
`${valueLabel}.finalScoreBoost must be <= 1`
|
|
3198
|
+
),
|
|
3199
|
+
finalScore: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScore`),
|
|
3200
|
+
awardPoolShare: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolShare`).max(
|
|
3201
|
+
1,
|
|
3202
|
+
`${valueLabel}.awardPoolShare must be <= 1`
|
|
3203
|
+
),
|
|
3204
|
+
awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
|
|
3205
|
+
});
|
|
3206
|
+
var makeUnrankedReferrerMetricsSchema = (valueLabel = "UnrankedReferrerMetrics") => z12.object({
|
|
3207
|
+
referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
|
|
3208
|
+
totalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
3209
|
+
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`),
|
|
3210
|
+
score: makeFiniteNonNegativeNumberSchema(`${valueLabel}.score`),
|
|
3211
|
+
rank: z12.null(),
|
|
3212
|
+
isQualified: z12.literal(false),
|
|
2360
3213
|
finalScoreBoost: makeFiniteNonNegativeNumberSchema(`${valueLabel}.finalScoreBoost`).max(
|
|
2361
3214
|
1,
|
|
2362
3215
|
`${valueLabel}.finalScoreBoost must be <= 1`
|
|
@@ -2368,7 +3221,7 @@ var makeAwardedReferrerMetricsSchema = (valueLabel = "AwardedReferrerMetrics") =
|
|
|
2368
3221
|
),
|
|
2369
3222
|
awardPoolApproxValue: makeFiniteNonNegativeNumberSchema(`${valueLabel}.awardPoolApproxValue`)
|
|
2370
3223
|
});
|
|
2371
|
-
var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") =>
|
|
3224
|
+
var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => z12.object({
|
|
2372
3225
|
grandTotalReferrals: makeNonNegativeIntegerSchema(`${valueLabel}.grandTotalReferrals`),
|
|
2373
3226
|
grandTotalIncrementalDuration: makeDurationSchema(
|
|
2374
3227
|
`${valueLabel}.grandTotalIncrementalDuration`
|
|
@@ -2380,41 +3233,69 @@ var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetri
|
|
|
2380
3233
|
`${valueLabel}.minFinalScoreToQualify`
|
|
2381
3234
|
)
|
|
2382
3235
|
});
|
|
2383
|
-
var
|
|
3236
|
+
var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboardPageContext") => z12.object({
|
|
2384
3237
|
page: makePositiveIntegerSchema(`${valueLabel}.page`),
|
|
2385
|
-
|
|
3238
|
+
recordsPerPage: makePositiveIntegerSchema(`${valueLabel}.recordsPerPage`).max(
|
|
2386
3239
|
REFERRERS_PER_LEADERBOARD_PAGE_MAX,
|
|
2387
|
-
`${valueLabel}.
|
|
3240
|
+
`${valueLabel}.recordsPerPage must not exceed ${REFERRERS_PER_LEADERBOARD_PAGE_MAX}`
|
|
2388
3241
|
),
|
|
2389
3242
|
totalRecords: makeNonNegativeIntegerSchema(`${valueLabel}.totalRecords`),
|
|
2390
3243
|
totalPages: makePositiveIntegerSchema(`${valueLabel}.totalPages`),
|
|
2391
|
-
hasNext:
|
|
2392
|
-
hasPrev:
|
|
2393
|
-
startIndex:
|
|
2394
|
-
endIndex:
|
|
3244
|
+
hasNext: z12.boolean(),
|
|
3245
|
+
hasPrev: z12.boolean(),
|
|
3246
|
+
startIndex: z12.optional(makeNonNegativeIntegerSchema(`${valueLabel}.startIndex`)),
|
|
3247
|
+
endIndex: z12.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
|
|
2395
3248
|
});
|
|
2396
|
-
var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") =>
|
|
3249
|
+
var makeReferrerLeaderboardPageSchema = (valueLabel = "ReferrerLeaderboardPage") => z12.object({
|
|
2397
3250
|
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
2398
|
-
referrers:
|
|
3251
|
+
referrers: z12.array(makeAwardedReferrerMetricsSchema(`${valueLabel}.referrers[record]`)),
|
|
2399
3252
|
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
2400
|
-
|
|
2401
|
-
`${valueLabel}.paginationContext`
|
|
2402
|
-
),
|
|
3253
|
+
pageContext: makeReferrerLeaderboardPageContextSchema(`${valueLabel}.pageContext`),
|
|
2403
3254
|
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
2404
3255
|
});
|
|
2405
|
-
var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") =>
|
|
2406
|
-
responseCode:
|
|
3256
|
+
var makeReferrerLeaderboardPageResponseOkSchema = (valueLabel = "ReferrerLeaderboardPageResponseOk") => z12.object({
|
|
3257
|
+
responseCode: z12.literal(ReferrerLeaderboardPageResponseCodes.Ok),
|
|
2407
3258
|
data: makeReferrerLeaderboardPageSchema(`${valueLabel}.data`)
|
|
2408
3259
|
});
|
|
2409
|
-
var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") =>
|
|
2410
|
-
responseCode:
|
|
2411
|
-
error:
|
|
2412
|
-
errorMessage:
|
|
3260
|
+
var makeReferrerLeaderboardPageResponseErrorSchema = (_valueLabel = "ReferrerLeaderboardPageResponseError") => z12.object({
|
|
3261
|
+
responseCode: z12.literal(ReferrerLeaderboardPageResponseCodes.Error),
|
|
3262
|
+
error: z12.string(),
|
|
3263
|
+
errorMessage: z12.string()
|
|
2413
3264
|
});
|
|
2414
|
-
var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") =>
|
|
3265
|
+
var makeReferrerLeaderboardPageResponseSchema = (valueLabel = "ReferrerLeaderboardPageResponse") => z12.union([
|
|
2415
3266
|
makeReferrerLeaderboardPageResponseOkSchema(valueLabel),
|
|
2416
3267
|
makeReferrerLeaderboardPageResponseErrorSchema(valueLabel)
|
|
2417
3268
|
]);
|
|
3269
|
+
var makeReferrerDetailRankedSchema = (valueLabel = "ReferrerDetailRanked") => z12.object({
|
|
3270
|
+
type: z12.literal(ReferrerDetailTypeIds.Ranked),
|
|
3271
|
+
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
3272
|
+
referrer: makeAwardedReferrerMetricsSchema(`${valueLabel}.referrer`),
|
|
3273
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
3274
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
3275
|
+
});
|
|
3276
|
+
var makeReferrerDetailUnrankedSchema = (valueLabel = "ReferrerDetailUnranked") => z12.object({
|
|
3277
|
+
type: z12.literal(ReferrerDetailTypeIds.Unranked),
|
|
3278
|
+
rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`),
|
|
3279
|
+
referrer: makeUnrankedReferrerMetricsSchema(`${valueLabel}.referrer`),
|
|
3280
|
+
aggregatedMetrics: makeAggregatedReferrerMetricsSchema(`${valueLabel}.aggregatedMetrics`),
|
|
3281
|
+
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
3282
|
+
});
|
|
3283
|
+
var makeReferrerDetailResponseOkSchema = (valueLabel = "ReferrerDetailResponse") => z12.object({
|
|
3284
|
+
responseCode: z12.literal(ReferrerDetailResponseCodes.Ok),
|
|
3285
|
+
data: z12.union([
|
|
3286
|
+
makeReferrerDetailRankedSchema(`${valueLabel}.data`),
|
|
3287
|
+
makeReferrerDetailUnrankedSchema(`${valueLabel}.data`)
|
|
3288
|
+
])
|
|
3289
|
+
});
|
|
3290
|
+
var makeReferrerDetailResponseErrorSchema = (_valueLabel = "ReferrerDetailResponse") => z12.object({
|
|
3291
|
+
responseCode: z12.literal(ReferrerDetailResponseCodes.Error),
|
|
3292
|
+
error: z12.string(),
|
|
3293
|
+
errorMessage: z12.string()
|
|
3294
|
+
});
|
|
3295
|
+
var makeReferrerDetailResponseSchema = (valueLabel = "ReferrerDetailResponse") => z12.union([
|
|
3296
|
+
makeReferrerDetailResponseOkSchema(valueLabel),
|
|
3297
|
+
makeReferrerDetailResponseErrorSchema(valueLabel)
|
|
3298
|
+
]);
|
|
2418
3299
|
|
|
2419
3300
|
// src/ensanalytics/deserialize.ts
|
|
2420
3301
|
function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
|
|
@@ -2423,12 +3304,22 @@ function deserializeReferrerLeaderboardPageResponse(maybeResponse, valueLabel) {
|
|
|
2423
3304
|
if (parsed.error) {
|
|
2424
3305
|
throw new Error(
|
|
2425
3306
|
`Cannot deserialize SerializedReferrerLeaderboardPageResponse:
|
|
2426
|
-
${
|
|
3307
|
+
${prettifyError10(parsed.error)}
|
|
2427
3308
|
`
|
|
2428
3309
|
);
|
|
2429
3310
|
}
|
|
2430
3311
|
return parsed.data;
|
|
2431
3312
|
}
|
|
3313
|
+
function deserializeReferrerDetailResponse(maybeResponse, valueLabel) {
|
|
3314
|
+
const schema = makeReferrerDetailResponseSchema(valueLabel);
|
|
3315
|
+
const parsed = schema.safeParse(maybeResponse);
|
|
3316
|
+
if (parsed.error) {
|
|
3317
|
+
throw new Error(`Cannot deserialize ReferrerDetailResponse:
|
|
3318
|
+
${prettifyError10(parsed.error)}
|
|
3319
|
+
`);
|
|
3320
|
+
}
|
|
3321
|
+
return parsed.data;
|
|
3322
|
+
}
|
|
2432
3323
|
|
|
2433
3324
|
// src/ensanalytics/serialize.ts
|
|
2434
3325
|
function serializeReferrerLeaderboardPageResponse(response) {
|
|
@@ -2439,55 +3330,15 @@ function serializeReferrerLeaderboardPageResponse(response) {
|
|
|
2439
3330
|
return response;
|
|
2440
3331
|
}
|
|
2441
3332
|
}
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
var TheGraphCannotFallbackReasonSchema = z9.enum({
|
|
2449
|
-
NotSubgraphCompatible: "not-subgraph-compatible",
|
|
2450
|
-
NoApiKey: "no-api-key",
|
|
2451
|
-
NoSubgraphUrl: "no-subgraph-url"
|
|
2452
|
-
});
|
|
2453
|
-
var TheGraphFallbackSchema = z9.strictObject({
|
|
2454
|
-
canFallback: z9.boolean(),
|
|
2455
|
-
reason: TheGraphCannotFallbackReasonSchema.nullable()
|
|
2456
|
-
});
|
|
2457
|
-
function makeENSApiPublicConfigSchema(valueLabel) {
|
|
2458
|
-
const label = valueLabel ?? "ENSApiPublicConfig";
|
|
2459
|
-
return z9.strictObject({
|
|
2460
|
-
version: z9.string().min(1, `${label}.version must be a non-empty string`),
|
|
2461
|
-
theGraphFallback: TheGraphFallbackSchema,
|
|
2462
|
-
ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
|
|
2463
|
-
});
|
|
2464
|
-
}
|
|
2465
|
-
|
|
2466
|
-
// src/ensapi/config/deserialize.ts
|
|
2467
|
-
function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
|
|
2468
|
-
const schema = makeENSApiPublicConfigSchema(valueLabel);
|
|
2469
|
-
try {
|
|
2470
|
-
return schema.parse(maybeConfig);
|
|
2471
|
-
} catch (error) {
|
|
2472
|
-
if (error instanceof ZodError) {
|
|
2473
|
-
throw new Error(`Cannot deserialize ENSApiPublicConfig:
|
|
2474
|
-
${prettifyError6(error)}
|
|
2475
|
-
`);
|
|
2476
|
-
}
|
|
2477
|
-
throw error;
|
|
3333
|
+
function serializeReferrerDetailResponse(response) {
|
|
3334
|
+
switch (response.responseCode) {
|
|
3335
|
+
case ReferrerDetailResponseCodes.Ok:
|
|
3336
|
+
return response;
|
|
3337
|
+
case ReferrerDetailResponseCodes.Error:
|
|
3338
|
+
return response;
|
|
2478
3339
|
}
|
|
2479
3340
|
}
|
|
2480
3341
|
|
|
2481
|
-
// src/ensapi/config/serialize.ts
|
|
2482
|
-
function serializeENSApiPublicConfig(config) {
|
|
2483
|
-
const { version, theGraphFallback, ensIndexerPublicConfig } = config;
|
|
2484
|
-
return {
|
|
2485
|
-
version,
|
|
2486
|
-
theGraphFallback,
|
|
2487
|
-
ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
|
|
2488
|
-
};
|
|
2489
|
-
}
|
|
2490
|
-
|
|
2491
3342
|
// src/client.ts
|
|
2492
3343
|
var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
|
|
2493
3344
|
var ENSNodeClient = class _ENSNodeClient {
|
|
@@ -2691,7 +3542,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2691
3542
|
const errorResponse = deserializeErrorResponse(responseData);
|
|
2692
3543
|
throw new Error(`Fetching ENSNode Config Failed: ${errorResponse.message}`);
|
|
2693
3544
|
}
|
|
2694
|
-
return
|
|
3545
|
+
return deserializeConfigResponse(responseData);
|
|
2695
3546
|
}
|
|
2696
3547
|
/**
|
|
2697
3548
|
* Fetch ENSNode Indexing Status
|
|
@@ -2732,7 +3583,7 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2732
3583
|
*
|
|
2733
3584
|
* @param request - Pagination parameters
|
|
2734
3585
|
* @param request.page - The page number to retrieve (1-indexed, default: 1)
|
|
2735
|
-
* @param request.
|
|
3586
|
+
* @param request.recordsPerPage - Number of records per page (default: 25, max: 100)
|
|
2736
3587
|
* @returns {ReferrerLeaderboardPageResponse}
|
|
2737
3588
|
*
|
|
2738
3589
|
* @throws if the ENSNode request fails
|
|
@@ -2741,34 +3592,34 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2741
3592
|
*
|
|
2742
3593
|
* @example
|
|
2743
3594
|
* ```typescript
|
|
2744
|
-
* // Get first page with default page size (25
|
|
2745
|
-
* const response = await client.
|
|
3595
|
+
* // Get first page with default page size (25 records)
|
|
3596
|
+
* const response = await client.getReferrerLeaderboardPage();
|
|
2746
3597
|
* if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {
|
|
2747
3598
|
* const {
|
|
2748
3599
|
* aggregatedMetrics,
|
|
2749
3600
|
* referrers,
|
|
2750
3601
|
* rules,
|
|
2751
|
-
*
|
|
3602
|
+
* pageContext,
|
|
2752
3603
|
* updatedAt
|
|
2753
3604
|
* } = response.data;
|
|
2754
3605
|
* console.log(aggregatedMetrics);
|
|
2755
3606
|
* console.log(referrers);
|
|
2756
3607
|
* console.log(rules);
|
|
2757
3608
|
* console.log(updatedAt);
|
|
2758
|
-
* console.log(`Page ${
|
|
3609
|
+
* console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
|
|
2759
3610
|
* }
|
|
2760
3611
|
* ```
|
|
2761
3612
|
*
|
|
2762
3613
|
* @example
|
|
2763
3614
|
* ```typescript
|
|
2764
|
-
* // Get second page with 50
|
|
2765
|
-
* const response = await client.
|
|
3615
|
+
* // Get second page with 50 records per page
|
|
3616
|
+
* const response = await client.getReferrerLeaderboardPage({ page: 2, recordsPerPage: 50 });
|
|
2766
3617
|
* ```
|
|
2767
3618
|
*
|
|
2768
3619
|
* @example
|
|
2769
3620
|
* ```typescript
|
|
2770
3621
|
* // Handle error response, ie. when Referrer Leaderboard is not currently available.
|
|
2771
|
-
* const response = await client.
|
|
3622
|
+
* const response = await client.getReferrerLeaderboardPage();
|
|
2772
3623
|
*
|
|
2773
3624
|
* if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Error) {
|
|
2774
3625
|
* console.error(response.error);
|
|
@@ -2776,11 +3627,11 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2776
3627
|
* }
|
|
2777
3628
|
* ```
|
|
2778
3629
|
*/
|
|
2779
|
-
async
|
|
3630
|
+
async getReferrerLeaderboardPage(request) {
|
|
2780
3631
|
const url = new URL(`/ensanalytics/referrers`, this.options.url);
|
|
2781
3632
|
if (request?.page) url.searchParams.set("page", request.page.toString());
|
|
2782
|
-
if (request?.
|
|
2783
|
-
url.searchParams.set("
|
|
3633
|
+
if (request?.recordsPerPage)
|
|
3634
|
+
url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
|
|
2784
3635
|
const response = await fetch(url);
|
|
2785
3636
|
let responseData;
|
|
2786
3637
|
try {
|
|
@@ -2792,14 +3643,106 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2792
3643
|
responseData
|
|
2793
3644
|
);
|
|
2794
3645
|
}
|
|
3646
|
+
/**
|
|
3647
|
+
* Fetch Referrer Detail
|
|
3648
|
+
*
|
|
3649
|
+
* Retrieves detailed information about a specific referrer, whether they are on the
|
|
3650
|
+
* leaderboard or not.
|
|
3651
|
+
*
|
|
3652
|
+
* The response data is a discriminated union type with a `type` field:
|
|
3653
|
+
*
|
|
3654
|
+
* **For referrers on the leaderboard** (`ReferrerDetailRanked`):
|
|
3655
|
+
* - `type`: {@link ReferrerDetailTypeIds.Ranked}
|
|
3656
|
+
* - `referrer`: The `AwardedReferrerMetrics` from @namehash/ens-referrals
|
|
3657
|
+
* - `rules`: The referral program rules
|
|
3658
|
+
* - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
|
|
3659
|
+
* - `accurateAsOf`: Unix timestamp indicating when the data was last updated
|
|
3660
|
+
*
|
|
3661
|
+
* **For referrers NOT on the leaderboard** (`ReferrerDetailUnranked`):
|
|
3662
|
+
* - `type`: {@link ReferrerDetailTypeIds.Unranked}
|
|
3663
|
+
* - `referrer`: The `UnrankedReferrerMetrics` from @namehash/ens-referrals
|
|
3664
|
+
* - `rules`: The referral program rules
|
|
3665
|
+
* - `aggregatedMetrics`: Aggregated metrics for all referrers on the leaderboard
|
|
3666
|
+
* - `accurateAsOf`: Unix timestamp indicating when the data was last updated
|
|
3667
|
+
*
|
|
3668
|
+
* @see {@link https://www.npmjs.com/package/@namehash/ens-referrals|@namehash/ens-referrals} for calculation details
|
|
3669
|
+
*
|
|
3670
|
+
* @param request The referrer address to query
|
|
3671
|
+
* @returns {ReferrerDetailResponse} Returns the referrer detail response
|
|
3672
|
+
*
|
|
3673
|
+
* @throws if the ENSNode request fails
|
|
3674
|
+
* @throws if the response data is malformed
|
|
3675
|
+
*
|
|
3676
|
+
* @example
|
|
3677
|
+
* ```typescript
|
|
3678
|
+
* // Get referrer detail for a specific address
|
|
3679
|
+
* const response = await client.getReferrerDetail({
|
|
3680
|
+
* referrer: "0x1234567890123456789012345678901234567890"
|
|
3681
|
+
* });
|
|
3682
|
+
* if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
|
|
3683
|
+
* const { type, referrer, rules, aggregatedMetrics, accurateAsOf } = response.data;
|
|
3684
|
+
* console.log(type); // ReferrerDetailTypeIds.Ranked or ReferrerDetailTypeIds.Unranked
|
|
3685
|
+
* console.log(referrer);
|
|
3686
|
+
* console.log(accurateAsOf);
|
|
3687
|
+
* }
|
|
3688
|
+
* ```
|
|
3689
|
+
*
|
|
3690
|
+
* @example
|
|
3691
|
+
* ```typescript
|
|
3692
|
+
* // Use discriminated union to check if referrer is ranked
|
|
3693
|
+
* const response = await client.getReferrerDetail({
|
|
3694
|
+
* referrer: "0x1234567890123456789012345678901234567890"
|
|
3695
|
+
* });
|
|
3696
|
+
* if (response.responseCode === ReferrerDetailResponseCodes.Ok) {
|
|
3697
|
+
* if (response.data.type === ReferrerDetailTypeIds.Ranked) {
|
|
3698
|
+
* // TypeScript knows this is ReferrerDetailRanked
|
|
3699
|
+
* console.log(`Rank: ${response.data.referrer.rank}`);
|
|
3700
|
+
* console.log(`Qualified: ${response.data.referrer.isQualified}`);
|
|
3701
|
+
* console.log(`Award Pool Share: ${response.data.referrer.awardPoolShare * 100}%`);
|
|
3702
|
+
* } else {
|
|
3703
|
+
* // TypeScript knows this is ReferrerDetailUnranked
|
|
3704
|
+
* console.log("Referrer is not on the leaderboard (no referrals yet)");
|
|
3705
|
+
* }
|
|
3706
|
+
* }
|
|
3707
|
+
* ```
|
|
3708
|
+
*
|
|
3709
|
+
* @example
|
|
3710
|
+
* ```typescript
|
|
3711
|
+
* // Handle error response, ie. when Referrer Detail is not currently available.
|
|
3712
|
+
* const response = await client.getReferrerDetail({
|
|
3713
|
+
* referrer: "0x1234567890123456789012345678901234567890"
|
|
3714
|
+
* });
|
|
3715
|
+
*
|
|
3716
|
+
* if (response.responseCode === ReferrerDetailResponseCodes.Error) {
|
|
3717
|
+
* console.error(response.error);
|
|
3718
|
+
* console.error(response.errorMessage);
|
|
3719
|
+
* }
|
|
3720
|
+
* ```
|
|
3721
|
+
*/
|
|
3722
|
+
async getReferrerDetail(request) {
|
|
3723
|
+
const url = new URL(
|
|
3724
|
+
`/api/ensanalytics/referrers/${encodeURIComponent(request.referrer)}`,
|
|
3725
|
+
this.options.url
|
|
3726
|
+
);
|
|
3727
|
+
const response = await fetch(url);
|
|
3728
|
+
let responseData;
|
|
3729
|
+
try {
|
|
3730
|
+
responseData = await response.json();
|
|
3731
|
+
} catch {
|
|
3732
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
3733
|
+
}
|
|
3734
|
+
return deserializeReferrerDetailResponse(responseData);
|
|
3735
|
+
}
|
|
2795
3736
|
/**
|
|
2796
3737
|
* Fetch ENSNode Registrar Actions
|
|
2797
3738
|
*
|
|
2798
|
-
*
|
|
2799
|
-
*
|
|
2800
|
-
* @param
|
|
2801
|
-
* @param
|
|
2802
|
-
*
|
|
3739
|
+
* Retrieves a paginated list of registrar actions with optional filters.
|
|
3740
|
+
*
|
|
3741
|
+
* @param request is a request configuration.
|
|
3742
|
+
* @param request.page sets the page number to retrieve (1-indexed, default: 1)
|
|
3743
|
+
* @param request.recordsPerPage sets the number of records per page (default: 10, max: 100)
|
|
3744
|
+
* @param request.filters is an optional request filter configuration.
|
|
3745
|
+
* @param request.order sets the order of results in the response by field and direction.
|
|
2803
3746
|
* @returns {RegistrarActionsResponse}
|
|
2804
3747
|
*
|
|
2805
3748
|
* @throws if the ENSNode request fails
|
|
@@ -2809,23 +3752,25 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2809
3752
|
* @example
|
|
2810
3753
|
* ```ts
|
|
2811
3754
|
* import {
|
|
2812
|
-
* registrarActionsFilter
|
|
3755
|
+
* registrarActionsFilter,
|
|
2813
3756
|
* ENSNodeClient,
|
|
2814
3757
|
* } from "@ensnode/ensnode-sdk";
|
|
2815
3758
|
* import { namehash } from "viem/ens";
|
|
2816
3759
|
*
|
|
2817
3760
|
* const client: ENSNodeClient;
|
|
2818
3761
|
*
|
|
2819
|
-
* //
|
|
2820
|
-
*
|
|
2821
|
-
*
|
|
2822
|
-
*
|
|
3762
|
+
* // Get first page with default page size (10 records)
|
|
3763
|
+
* const response = await client.registrarActions();
|
|
3764
|
+
* if (response.responseCode === RegistrarActionsResponseCodes.Ok) {
|
|
3765
|
+
* const { registrarActions, pageContext } = response;
|
|
3766
|
+
* console.log(registrarActions);
|
|
3767
|
+
* console.log(`Page ${pageContext.page} of ${pageContext.totalPages}`);
|
|
3768
|
+
* }
|
|
2823
3769
|
*
|
|
2824
|
-
* //
|
|
2825
|
-
*
|
|
2826
|
-
*
|
|
2827
|
-
*
|
|
2828
|
-
* limit: 5,
|
|
3770
|
+
* // Get second page with 25 records per page
|
|
3771
|
+
* const response = await client.registrarActions({
|
|
3772
|
+
* page: 2,
|
|
3773
|
+
* recordsPerPage: 25,
|
|
2829
3774
|
* });
|
|
2830
3775
|
*
|
|
2831
3776
|
* // get latest registrar action records associated with
|
|
@@ -2839,11 +3784,16 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2839
3784
|
* filters: [registrarActionsFilter.withReferral(true)],
|
|
2840
3785
|
* });
|
|
2841
3786
|
*
|
|
3787
|
+
* // get latest registrar action records for a specific decoded referrer
|
|
3788
|
+
* await client.registrarActions({
|
|
3789
|
+
* filters: [registrarActionsFilter.byDecodedReferrer("0x1234567890123456789012345678901234567890")],
|
|
3790
|
+
* });
|
|
3791
|
+
*
|
|
2842
3792
|
* // get latest 10 registrar action records associated with
|
|
2843
3793
|
* // subregistry managing `base.eth` name
|
|
2844
3794
|
* await client.registrarActions({
|
|
2845
3795
|
* filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
|
|
2846
|
-
*
|
|
3796
|
+
* recordsPerPage: 10
|
|
2847
3797
|
* });
|
|
2848
3798
|
* ```
|
|
2849
3799
|
*/
|
|
@@ -2860,6 +3810,12 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2860
3810
|
);
|
|
2861
3811
|
return withReferralFilter ? { key: "withReferral", value: "true" } : null;
|
|
2862
3812
|
};
|
|
3813
|
+
const buildDecodedReferrerArg = (filters) => {
|
|
3814
|
+
const decodedReferrerFilter = filters?.find(
|
|
3815
|
+
(f) => f.filterType === RegistrarActionsFilterTypes.ByDecodedReferrer
|
|
3816
|
+
);
|
|
3817
|
+
return decodedReferrerFilter ? { key: "decodedReferrer", value: decodedReferrerFilter.value } : null;
|
|
3818
|
+
};
|
|
2863
3819
|
const buildOrderArg = (order) => {
|
|
2864
3820
|
switch (order) {
|
|
2865
3821
|
case RegistrarActionsOrders.LatestRegistrarActions: {
|
|
@@ -2876,13 +3832,20 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2876
3832
|
const orderArgs = buildOrderArg(request.order);
|
|
2877
3833
|
url.searchParams.set(orderArgs.key, orderArgs.value);
|
|
2878
3834
|
}
|
|
2879
|
-
if (request.
|
|
2880
|
-
url.searchParams.set("
|
|
3835
|
+
if (request.page) {
|
|
3836
|
+
url.searchParams.set("page", request.page.toString());
|
|
3837
|
+
}
|
|
3838
|
+
if (request.recordsPerPage) {
|
|
3839
|
+
url.searchParams.set("recordsPerPage", request.recordsPerPage.toString());
|
|
2881
3840
|
}
|
|
2882
3841
|
const referralArg = buildWithReferralArg(request.filters);
|
|
2883
3842
|
if (referralArg) {
|
|
2884
3843
|
url.searchParams.set(referralArg.key, referralArg.value);
|
|
2885
3844
|
}
|
|
3845
|
+
const decodedReferrerArg = buildDecodedReferrerArg(request.filters);
|
|
3846
|
+
if (decodedReferrerArg) {
|
|
3847
|
+
url.searchParams.set(decodedReferrerArg.key, decodedReferrerArg.value);
|
|
3848
|
+
}
|
|
2886
3849
|
const response = await fetch(url);
|
|
2887
3850
|
let responseData;
|
|
2888
3851
|
try {
|
|
@@ -2903,10 +3866,66 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
2903
3866
|
}
|
|
2904
3867
|
return deserializeRegistrarActionsResponse(responseData);
|
|
2905
3868
|
}
|
|
3869
|
+
/**
|
|
3870
|
+
* Fetch Name Tokens for requested name.
|
|
3871
|
+
*
|
|
3872
|
+
* @param request.name - Name for which Name Tokens will be fetched.
|
|
3873
|
+
* @returns {NameTokensResponse}
|
|
3874
|
+
*
|
|
3875
|
+
* @throws if the ENSNode request fails
|
|
3876
|
+
* @throws if the ENSNode API returns an error response
|
|
3877
|
+
* @throws if the ENSNode response breaks required invariants
|
|
3878
|
+
*
|
|
3879
|
+
* @example
|
|
3880
|
+
* ```ts
|
|
3881
|
+
* import {
|
|
3882
|
+
* ENSNodeClient,
|
|
3883
|
+
* } from "@ensnode/ensnode-sdk";
|
|
3884
|
+
* import { namehash } from "viem/ens";
|
|
3885
|
+
*
|
|
3886
|
+
* const client: ENSNodeClient;
|
|
3887
|
+
*
|
|
3888
|
+
* // get latest name token records from the indexed subregistry based on the requested name
|
|
3889
|
+
* const response = await client.nameTokens({
|
|
3890
|
+
* name: "vitalik.eth"
|
|
3891
|
+
* });
|
|
3892
|
+
*
|
|
3893
|
+
* const response = await client.nameTokens({
|
|
3894
|
+
* domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
|
|
3895
|
+
* })
|
|
3896
|
+
* ```
|
|
3897
|
+
*/
|
|
3898
|
+
async nameTokens(request) {
|
|
3899
|
+
const url = new URL(`/api/name-tokens`, this.options.url);
|
|
3900
|
+
if (request.name !== void 0) {
|
|
3901
|
+
url.searchParams.set("name", request.name);
|
|
3902
|
+
} else {
|
|
3903
|
+
url.searchParams.set("domainId", request.domainId);
|
|
3904
|
+
}
|
|
3905
|
+
const response = await fetch(url);
|
|
3906
|
+
let responseData;
|
|
3907
|
+
try {
|
|
3908
|
+
responseData = await response.json();
|
|
3909
|
+
} catch {
|
|
3910
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
3911
|
+
}
|
|
3912
|
+
if (!response.ok) {
|
|
3913
|
+
let errorResponse;
|
|
3914
|
+
try {
|
|
3915
|
+
errorResponse = deserializeErrorResponse(responseData);
|
|
3916
|
+
} catch {
|
|
3917
|
+
console.log("Name Tokens API: handling a known server error.");
|
|
3918
|
+
}
|
|
3919
|
+
if (typeof errorResponse !== "undefined") {
|
|
3920
|
+
throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
return deserializedNameTokensResponse(responseData);
|
|
3924
|
+
}
|
|
2906
3925
|
};
|
|
2907
3926
|
|
|
2908
3927
|
// src/identity/identity.ts
|
|
2909
|
-
import { getENSRootChainId as
|
|
3928
|
+
import { getENSRootChainId as getENSRootChainId2 } from "@ensnode/datasources";
|
|
2910
3929
|
|
|
2911
3930
|
// src/identity/types.ts
|
|
2912
3931
|
var ResolutionStatusIds = {
|
|
@@ -2933,7 +3952,7 @@ var ResolutionStatusIds = {
|
|
|
2933
3952
|
function buildUnresolvedIdentity(address, namespaceId, chainId) {
|
|
2934
3953
|
return {
|
|
2935
3954
|
resolutionStatus: ResolutionStatusIds.Unresolved,
|
|
2936
|
-
chainId: chainId ??
|
|
3955
|
+
chainId: chainId ?? getENSRootChainId2(namespaceId),
|
|
2937
3956
|
address
|
|
2938
3957
|
};
|
|
2939
3958
|
}
|
|
@@ -2942,14 +3961,14 @@ function isResolvedIdentity(identity) {
|
|
|
2942
3961
|
}
|
|
2943
3962
|
|
|
2944
3963
|
// src/resolution/ensip19-chainid.ts
|
|
2945
|
-
import { mainnet
|
|
2946
|
-
import { getENSRootChainId as
|
|
3964
|
+
import { mainnet } from "viem/chains";
|
|
3965
|
+
import { getENSRootChainId as getENSRootChainId3 } from "@ensnode/datasources";
|
|
2947
3966
|
var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
|
|
2948
|
-
const ensRootChainId =
|
|
2949
|
-
return chainId === ensRootChainId ?
|
|
3967
|
+
const ensRootChainId = getENSRootChainId3(namespaceId);
|
|
3968
|
+
return chainId === ensRootChainId ? mainnet.id : chainId;
|
|
2950
3969
|
};
|
|
2951
3970
|
var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
|
|
2952
|
-
return chainId === DEFAULT_EVM_CHAIN_ID ?
|
|
3971
|
+
return chainId === DEFAULT_EVM_CHAIN_ID ? getENSRootChainId3(namespaceId) : chainId;
|
|
2953
3972
|
};
|
|
2954
3973
|
|
|
2955
3974
|
// src/resolution/resolver-records-selection.ts
|
|
@@ -2989,6 +4008,7 @@ export {
|
|
|
2989
4008
|
ATTR_PROTOCOL_NAME,
|
|
2990
4009
|
ATTR_PROTOCOL_STEP,
|
|
2991
4010
|
ATTR_PROTOCOL_STEP_RESULT,
|
|
4011
|
+
AssetNamespaces,
|
|
2992
4012
|
BASENAMES_NODE,
|
|
2993
4013
|
ChainIndexingConfigTypeIds,
|
|
2994
4014
|
ChainIndexingStatusIds,
|
|
@@ -2999,16 +4019,25 @@ export {
|
|
|
2999
4019
|
DEFAULT_EVM_COIN_TYPE,
|
|
3000
4020
|
ENSNamespaceIds,
|
|
3001
4021
|
ENSNodeClient,
|
|
4022
|
+
ENS_ROOT,
|
|
3002
4023
|
ETH_COIN_TYPE,
|
|
3003
4024
|
ETH_NODE,
|
|
3004
4025
|
ForwardResolutionProtocolStep,
|
|
3005
4026
|
IndexingStatusResponseCodes,
|
|
3006
4027
|
LINEANAMES_NODE,
|
|
3007
4028
|
LruCache,
|
|
4029
|
+
NFTMintStatuses,
|
|
4030
|
+
NFTTransferTypes,
|
|
4031
|
+
NameTokenOwnershipTypes,
|
|
4032
|
+
NameTokensResponseCodes,
|
|
4033
|
+
NameTokensResponseErrorCodes,
|
|
3008
4034
|
OmnichainIndexingStatusIds,
|
|
3009
4035
|
PROTOCOL_ATTRIBUTE_PREFIX,
|
|
3010
4036
|
PluginName,
|
|
4037
|
+
RECORDS_PER_PAGE_DEFAULT,
|
|
4038
|
+
RECORDS_PER_PAGE_MAX,
|
|
3011
4039
|
ROOT_NODE,
|
|
4040
|
+
ReferrerDetailResponseCodes,
|
|
3012
4041
|
ReferrerLeaderboardPageResponseCodes,
|
|
3013
4042
|
RegistrarActionTypes,
|
|
3014
4043
|
RegistrarActionsFilterTypes,
|
|
@@ -3030,9 +4059,11 @@ export {
|
|
|
3030
4059
|
beautifyName,
|
|
3031
4060
|
bigIntToNumber,
|
|
3032
4061
|
bigintToCoinType,
|
|
4062
|
+
buildAssetId,
|
|
3033
4063
|
buildEnsRainbowClientLabelSet,
|
|
3034
4064
|
buildLabelSetId,
|
|
3035
4065
|
buildLabelSetVersion,
|
|
4066
|
+
buildPageContext,
|
|
3036
4067
|
buildUnresolvedIdentity,
|
|
3037
4068
|
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
|
|
3038
4069
|
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
|
|
@@ -3045,12 +4076,13 @@ export {
|
|
|
3045
4076
|
decodeDNSEncodedLiteralName,
|
|
3046
4077
|
decodeDNSEncodedName,
|
|
3047
4078
|
decodeEncodedReferrer,
|
|
3048
|
-
|
|
4079
|
+
deserializeAssetId,
|
|
3049
4080
|
deserializeBlockNumber,
|
|
3050
4081
|
deserializeBlockRef,
|
|
3051
4082
|
deserializeBlockrange,
|
|
3052
4083
|
deserializeChainId,
|
|
3053
4084
|
deserializeChainIndexingStatusSnapshot,
|
|
4085
|
+
deserializeConfigResponse,
|
|
3054
4086
|
deserializeCrossChainIndexingStatusSnapshot,
|
|
3055
4087
|
deserializeDatetime,
|
|
3056
4088
|
deserializeDuration,
|
|
@@ -3060,20 +4092,35 @@ export {
|
|
|
3060
4092
|
deserializeIndexingStatusResponse,
|
|
3061
4093
|
deserializeOmnichainIndexingStatusSnapshot,
|
|
3062
4094
|
deserializeRealtimeIndexingStatusProjection,
|
|
4095
|
+
deserializeReferrerDetailResponse,
|
|
3063
4096
|
deserializeReferrerLeaderboardPageResponse,
|
|
3064
4097
|
deserializeRegistrarActionsResponse,
|
|
3065
4098
|
deserializeUnixTimestamp,
|
|
3066
4099
|
deserializeUrl,
|
|
4100
|
+
deserializedNameTokensResponse,
|
|
3067
4101
|
durationBetween,
|
|
3068
4102
|
encodeLabelHash,
|
|
3069
4103
|
evmChainIdToCoinType,
|
|
4104
|
+
formatAccountId,
|
|
4105
|
+
formatAssetId,
|
|
4106
|
+
formatNFTTransferEventMetadata,
|
|
4107
|
+
getBasenamesSubregistryId,
|
|
4108
|
+
getBasenamesSubregistryManagedName,
|
|
3070
4109
|
getCurrencyInfo,
|
|
4110
|
+
getDatasourceContract,
|
|
3071
4111
|
getENSRootChainId,
|
|
3072
4112
|
getEthnamesSubregistryId,
|
|
4113
|
+
getEthnamesSubregistryManagedName,
|
|
3073
4114
|
getLatestIndexedBlockRef,
|
|
4115
|
+
getLineanamesSubregistryId,
|
|
4116
|
+
getLineanamesSubregistryManagedName,
|
|
4117
|
+
getNFTTransferType,
|
|
3074
4118
|
getNameHierarchy,
|
|
4119
|
+
getNameTokenOwnership,
|
|
4120
|
+
getNameWrapperAccounts,
|
|
3075
4121
|
getOmnichainIndexingCursor,
|
|
3076
4122
|
getOmnichainIndexingStatus,
|
|
4123
|
+
getParentNameFQDN,
|
|
3077
4124
|
getResolvePrimaryNameChainIdParam,
|
|
3078
4125
|
getTimestampForHighestOmnichainKnownBlock,
|
|
3079
4126
|
getTimestampForLowestOmnichainStartBlock,
|
|
@@ -3099,6 +4146,10 @@ export {
|
|
|
3099
4146
|
literalLabelsToLiteralName,
|
|
3100
4147
|
makeENSApiPublicConfigSchema,
|
|
3101
4148
|
makeSubdomainNode,
|
|
4149
|
+
maybeGetDatasourceContract,
|
|
4150
|
+
nameTokensPrerequisites,
|
|
4151
|
+
parseAccountId,
|
|
4152
|
+
parseAssetId,
|
|
3102
4153
|
parseNonNegativeInteger,
|
|
3103
4154
|
parseReverseName,
|
|
3104
4155
|
priceDai,
|
|
@@ -3107,26 +4158,30 @@ export {
|
|
|
3107
4158
|
registrarActionsFilter,
|
|
3108
4159
|
registrarActionsPrerequisites,
|
|
3109
4160
|
reverseName,
|
|
3110
|
-
|
|
4161
|
+
serializeAssetId,
|
|
3111
4162
|
serializeChainId,
|
|
3112
4163
|
serializeChainIndexingSnapshots,
|
|
4164
|
+
serializeConfigResponse,
|
|
3113
4165
|
serializeCrossChainIndexingStatusSnapshotOmnichain,
|
|
3114
4166
|
serializeDatetime,
|
|
4167
|
+
serializeDomainAssetId,
|
|
3115
4168
|
serializeENSApiPublicConfig,
|
|
3116
4169
|
serializeENSIndexerPublicConfig,
|
|
3117
4170
|
serializeIndexedChainIds,
|
|
3118
4171
|
serializeIndexingStatusResponse,
|
|
4172
|
+
serializeNameToken,
|
|
4173
|
+
serializeNameTokensResponse,
|
|
3119
4174
|
serializeNamedRegistrarAction,
|
|
3120
4175
|
serializeOmnichainIndexingStatusSnapshot,
|
|
3121
4176
|
serializePrice,
|
|
3122
4177
|
serializePriceEth,
|
|
3123
4178
|
serializeRealtimeIndexingStatusProjection,
|
|
4179
|
+
serializeReferrerDetailResponse,
|
|
3124
4180
|
serializeReferrerLeaderboardPageResponse,
|
|
4181
|
+
serializeRegisteredNameTokens,
|
|
3125
4182
|
serializeRegistrarAction,
|
|
3126
4183
|
serializeRegistrarActionPricing,
|
|
3127
4184
|
serializeRegistrarActionsResponse,
|
|
3128
|
-
serializeRegistrationLifecycle,
|
|
3129
|
-
serializeSubregistry,
|
|
3130
4185
|
serializeUrl,
|
|
3131
4186
|
sortChainStatusesByStartBlockAsc,
|
|
3132
4187
|
stripNullBytes,
|