@ensnode/ensnode-sdk 1.0.1 → 1.0.2
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 +2948 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3556 -0
- package/dist/index.js +31 -5
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2948 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
ADDR_REVERSE_NODE: () => ADDR_REVERSE_NODE,
|
|
34
|
+
ATTR_PROTOCOL_NAME: () => ATTR_PROTOCOL_NAME,
|
|
35
|
+
ATTR_PROTOCOL_STEP: () => ATTR_PROTOCOL_STEP,
|
|
36
|
+
ATTR_PROTOCOL_STEP_RESULT: () => ATTR_PROTOCOL_STEP_RESULT,
|
|
37
|
+
BASENAMES_NODE: () => BASENAMES_NODE,
|
|
38
|
+
ChainIndexingConfigTypeIds: () => ChainIndexingConfigTypeIds,
|
|
39
|
+
ChainIndexingStatusIds: () => ChainIndexingStatusIds,
|
|
40
|
+
ClientError: () => ClientError,
|
|
41
|
+
CrossChainIndexingStrategyIds: () => CrossChainIndexingStrategyIds,
|
|
42
|
+
CurrencyIds: () => CurrencyIds,
|
|
43
|
+
DEFAULT_EVM_CHAIN_ID: () => DEFAULT_EVM_CHAIN_ID,
|
|
44
|
+
DEFAULT_EVM_COIN_TYPE: () => DEFAULT_EVM_COIN_TYPE,
|
|
45
|
+
ENSNamespaceIds: () => import_datasources.ENSNamespaceIds,
|
|
46
|
+
ENSNodeClient: () => ENSNodeClient,
|
|
47
|
+
ETH_COIN_TYPE: () => ETH_COIN_TYPE,
|
|
48
|
+
ETH_NODE: () => ETH_NODE,
|
|
49
|
+
ForwardResolutionProtocolStep: () => ForwardResolutionProtocolStep,
|
|
50
|
+
ITEMS_PER_PAGE_DEFAULT: () => ITEMS_PER_PAGE_DEFAULT,
|
|
51
|
+
ITEMS_PER_PAGE_MAX: () => ITEMS_PER_PAGE_MAX,
|
|
52
|
+
IndexingStatusResponseCodes: () => IndexingStatusResponseCodes,
|
|
53
|
+
LINEANAMES_NODE: () => LINEANAMES_NODE,
|
|
54
|
+
LruCache: () => LruCache,
|
|
55
|
+
OmnichainIndexingStatusIds: () => OmnichainIndexingStatusIds,
|
|
56
|
+
PROTOCOL_ATTRIBUTE_PREFIX: () => PROTOCOL_ATTRIBUTE_PREFIX,
|
|
57
|
+
PaginatedAggregatedReferrersResponseCodes: () => PaginatedAggregatedReferrersResponseCodes,
|
|
58
|
+
PluginName: () => PluginName,
|
|
59
|
+
ROOT_NODE: () => ROOT_NODE,
|
|
60
|
+
RegistrarActionTypes: () => RegistrarActionTypes,
|
|
61
|
+
RegistrarActionsFilterTypes: () => RegistrarActionsFilterTypes,
|
|
62
|
+
RegistrarActionsOrders: () => RegistrarActionsOrders,
|
|
63
|
+
RegistrarActionsResponseCodes: () => RegistrarActionsResponseCodes,
|
|
64
|
+
ResolutionStatusIds: () => ResolutionStatusIds,
|
|
65
|
+
ReverseResolutionProtocolStep: () => ReverseResolutionProtocolStep,
|
|
66
|
+
TheGraphCannotFallbackReasonSchema: () => TheGraphCannotFallbackReasonSchema,
|
|
67
|
+
TheGraphFallbackSchema: () => TheGraphFallbackSchema,
|
|
68
|
+
TraceableENSProtocol: () => TraceableENSProtocol,
|
|
69
|
+
TtlCache: () => TtlCache,
|
|
70
|
+
accountIdEqual: () => accountIdEqual,
|
|
71
|
+
addDuration: () => addDuration,
|
|
72
|
+
addPrices: () => addPrices,
|
|
73
|
+
addrReverseLabel: () => addrReverseLabel,
|
|
74
|
+
asLowerCaseAddress: () => asLowerCaseAddress,
|
|
75
|
+
beautifyName: () => beautifyName,
|
|
76
|
+
bigIntToNumber: () => bigIntToNumber,
|
|
77
|
+
bigintToCoinType: () => bigintToCoinType,
|
|
78
|
+
buildEnsRainbowClientLabelSet: () => buildEnsRainbowClientLabelSet,
|
|
79
|
+
buildLabelSetId: () => buildLabelSetId,
|
|
80
|
+
buildLabelSetVersion: () => buildLabelSetVersion,
|
|
81
|
+
buildUnresolvedIdentity: () => buildUnresolvedIdentity,
|
|
82
|
+
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill,
|
|
83
|
+
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted,
|
|
84
|
+
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing,
|
|
85
|
+
checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted: () => checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted,
|
|
86
|
+
coinTypeReverseLabel: () => coinTypeReverseLabel,
|
|
87
|
+
coinTypeToEvmChainId: () => coinTypeToEvmChainId,
|
|
88
|
+
createIndexingConfig: () => createIndexingConfig,
|
|
89
|
+
createRealtimeIndexingStatusProjection: () => createRealtimeIndexingStatusProjection,
|
|
90
|
+
decodeDNSEncodedLiteralName: () => decodeDNSEncodedLiteralName,
|
|
91
|
+
decodeDNSEncodedName: () => decodeDNSEncodedName,
|
|
92
|
+
decodeEncodedReferrer: () => decodeEncodedReferrer,
|
|
93
|
+
deserializeAccountId: () => deserializeAccountId,
|
|
94
|
+
deserializeBlockNumber: () => deserializeBlockNumber,
|
|
95
|
+
deserializeBlockRef: () => deserializeBlockRef,
|
|
96
|
+
deserializeBlockrange: () => deserializeBlockrange,
|
|
97
|
+
deserializeChainId: () => deserializeChainId,
|
|
98
|
+
deserializeChainIndexingStatusSnapshot: () => deserializeChainIndexingStatusSnapshot,
|
|
99
|
+
deserializeCrossChainIndexingStatusSnapshot: () => deserializeCrossChainIndexingStatusSnapshot,
|
|
100
|
+
deserializeDatetime: () => deserializeDatetime,
|
|
101
|
+
deserializeDuration: () => deserializeDuration,
|
|
102
|
+
deserializeENSApiPublicConfig: () => deserializeENSApiPublicConfig,
|
|
103
|
+
deserializeENSIndexerPublicConfig: () => deserializeENSIndexerPublicConfig,
|
|
104
|
+
deserializeErrorResponse: () => deserializeErrorResponse,
|
|
105
|
+
deserializeIndexingStatusResponse: () => deserializeIndexingStatusResponse,
|
|
106
|
+
deserializeOmnichainIndexingStatusSnapshot: () => deserializeOmnichainIndexingStatusSnapshot,
|
|
107
|
+
deserializePaginatedAggregatedReferrersResponse: () => deserializePaginatedAggregatedReferrersResponse,
|
|
108
|
+
deserializeRealtimeIndexingStatusProjection: () => deserializeRealtimeIndexingStatusProjection,
|
|
109
|
+
deserializeRegistrarActionsResponse: () => deserializeRegistrarActionsResponse,
|
|
110
|
+
deserializeUnixTimestamp: () => deserializeUnixTimestamp,
|
|
111
|
+
deserializeUrl: () => deserializeUrl,
|
|
112
|
+
durationBetween: () => durationBetween,
|
|
113
|
+
encodeLabelHash: () => encodeLabelHash,
|
|
114
|
+
evmChainIdToCoinType: () => evmChainIdToCoinType,
|
|
115
|
+
getCurrencyInfo: () => getCurrencyInfo,
|
|
116
|
+
getENSRootChainId: () => import_datasources2.getENSRootChainId,
|
|
117
|
+
getEthnamesSubregistryId: () => getEthnamesSubregistryId,
|
|
118
|
+
getNameHierarchy: () => getNameHierarchy,
|
|
119
|
+
getOmnichainIndexingCursor: () => getOmnichainIndexingCursor,
|
|
120
|
+
getOmnichainIndexingStatus: () => getOmnichainIndexingStatus,
|
|
121
|
+
getResolvePrimaryNameChainIdParam: () => getResolvePrimaryNameChainIdParam,
|
|
122
|
+
getTimestampForHighestOmnichainKnownBlock: () => getTimestampForHighestOmnichainKnownBlock,
|
|
123
|
+
getTimestampForLowestOmnichainStartBlock: () => getTimestampForLowestOmnichainStartBlock,
|
|
124
|
+
hasNullByte: () => hasNullByte,
|
|
125
|
+
interpretedLabelsToInterpretedName: () => interpretedLabelsToInterpretedName,
|
|
126
|
+
isEncodedLabelHash: () => isEncodedLabelHash,
|
|
127
|
+
isHttpProtocol: () => isHttpProtocol,
|
|
128
|
+
isLabelHash: () => isLabelHash,
|
|
129
|
+
isNormalizedLabel: () => isNormalizedLabel,
|
|
130
|
+
isNormalizedName: () => isNormalizedName,
|
|
131
|
+
isPriceCurrencyEqual: () => isPriceCurrencyEqual,
|
|
132
|
+
isPriceEqual: () => isPriceEqual,
|
|
133
|
+
isRegistrarActionPricingAvailable: () => isRegistrarActionPricingAvailable,
|
|
134
|
+
isRegistrarActionReferralAvailable: () => isRegistrarActionReferralAvailable,
|
|
135
|
+
isResolvedIdentity: () => isResolvedIdentity,
|
|
136
|
+
isSelectionEmpty: () => isSelectionEmpty,
|
|
137
|
+
isSubgraphCompatible: () => isSubgraphCompatible,
|
|
138
|
+
isWebSocketProtocol: () => isWebSocketProtocol,
|
|
139
|
+
labelHashToBytes: () => labelHashToBytes,
|
|
140
|
+
labelhashLiteralLabel: () => labelhashLiteralLabel,
|
|
141
|
+
literalLabelToInterpretedLabel: () => literalLabelToInterpretedLabel,
|
|
142
|
+
literalLabelsToInterpretedName: () => literalLabelsToInterpretedName,
|
|
143
|
+
literalLabelsToLiteralName: () => literalLabelsToLiteralName,
|
|
144
|
+
makeENSApiPublicConfigSchema: () => makeENSApiPublicConfigSchema,
|
|
145
|
+
makeSubdomainNode: () => makeSubdomainNode,
|
|
146
|
+
parseNonNegativeInteger: () => parseNonNegativeInteger,
|
|
147
|
+
parseReverseName: () => parseReverseName,
|
|
148
|
+
priceDai: () => priceDai,
|
|
149
|
+
priceEth: () => priceEth,
|
|
150
|
+
priceUsdc: () => priceUsdc,
|
|
151
|
+
registrarActionsFilter: () => registrarActionsFilter,
|
|
152
|
+
registrarActionsPrerequisites: () => registrarActionsPrerequisites,
|
|
153
|
+
reverseName: () => reverseName,
|
|
154
|
+
serializeAccountId: () => serializeAccountId,
|
|
155
|
+
serializeChainId: () => serializeChainId,
|
|
156
|
+
serializeChainIndexingSnapshots: () => serializeChainIndexingSnapshots,
|
|
157
|
+
serializeCrossChainIndexingStatusSnapshotOmnichain: () => serializeCrossChainIndexingStatusSnapshotOmnichain,
|
|
158
|
+
serializeDatetime: () => serializeDatetime,
|
|
159
|
+
serializeENSApiPublicConfig: () => serializeENSApiPublicConfig,
|
|
160
|
+
serializeENSIndexerPublicConfig: () => serializeENSIndexerPublicConfig,
|
|
161
|
+
serializeIndexedChainIds: () => serializeIndexedChainIds,
|
|
162
|
+
serializeIndexingStatusResponse: () => serializeIndexingStatusResponse,
|
|
163
|
+
serializeNamedRegistrarAction: () => serializeNamedRegistrarAction,
|
|
164
|
+
serializeOmnichainIndexingStatusSnapshot: () => serializeOmnichainIndexingStatusSnapshot,
|
|
165
|
+
serializePaginatedAggregatedReferrersResponse: () => serializePaginatedAggregatedReferrersResponse,
|
|
166
|
+
serializePrice: () => serializePrice,
|
|
167
|
+
serializePriceEth: () => serializePriceEth,
|
|
168
|
+
serializeRealtimeIndexingStatusProjection: () => serializeRealtimeIndexingStatusProjection,
|
|
169
|
+
serializeRegistrarAction: () => serializeRegistrarAction,
|
|
170
|
+
serializeRegistrarActionPricing: () => serializeRegistrarActionPricing,
|
|
171
|
+
serializeRegistrarActionsResponse: () => serializeRegistrarActionsResponse,
|
|
172
|
+
serializeRegistrationLifecycle: () => serializeRegistrationLifecycle,
|
|
173
|
+
serializeSubregistry: () => serializeSubregistry,
|
|
174
|
+
serializeUrl: () => serializeUrl,
|
|
175
|
+
sortChainStatusesByStartBlockAsc: () => sortChainStatusesByStartBlockAsc,
|
|
176
|
+
staleWhileRevalidate: () => staleWhileRevalidate,
|
|
177
|
+
stripNullBytes: () => stripNullBytes,
|
|
178
|
+
translateDefaultableChainIdToChainId: () => translateDefaultableChainIdToChainId,
|
|
179
|
+
uint256ToHex32: () => uint256ToHex32,
|
|
180
|
+
uniq: () => uniq,
|
|
181
|
+
validateSupportedLabelSetAndVersion: () => validateSupportedLabelSetAndVersion,
|
|
182
|
+
zeroEncodedReferrer: () => zeroEncodedReferrer
|
|
183
|
+
});
|
|
184
|
+
module.exports = __toCommonJS(index_exports);
|
|
185
|
+
|
|
186
|
+
// src/api/deserialize.ts
|
|
187
|
+
var import_v49 = require("zod/v4");
|
|
188
|
+
|
|
189
|
+
// src/api/zod-schemas.ts
|
|
190
|
+
var import_viem12 = require("viem");
|
|
191
|
+
var import_v48 = __toESM(require("zod/v4"), 1);
|
|
192
|
+
|
|
193
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
194
|
+
var import_v43 = __toESM(require("zod/v4"), 1);
|
|
195
|
+
|
|
196
|
+
// src/ens/is-normalized.ts
|
|
197
|
+
var import_ens = require("viem/ens");
|
|
198
|
+
function isNormalizedName(name) {
|
|
199
|
+
try {
|
|
200
|
+
return name === (0, import_ens.normalize)(name);
|
|
201
|
+
} catch {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function isNormalizedLabel(label) {
|
|
206
|
+
if (label === "") return false;
|
|
207
|
+
if (label.includes(".")) return false;
|
|
208
|
+
try {
|
|
209
|
+
return label === (0, import_ens.normalize)(label);
|
|
210
|
+
} catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/shared/account-id.ts
|
|
216
|
+
var import_viem = require("viem");
|
|
217
|
+
var accountIdEqual = (a, b) => {
|
|
218
|
+
return a.chainId === b.chainId && (0, import_viem.isAddressEqual)(a.address, b.address);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// src/shared/address.ts
|
|
222
|
+
function asLowerCaseAddress(address) {
|
|
223
|
+
return address.toLowerCase();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// src/shared/cache.ts
|
|
227
|
+
var import_date_fns = require("date-fns");
|
|
228
|
+
|
|
229
|
+
// src/shared/deserialize.ts
|
|
230
|
+
var import_v42 = require("zod/v4");
|
|
231
|
+
|
|
232
|
+
// src/shared/zod-schemas.ts
|
|
233
|
+
var import_caip = require("caip");
|
|
234
|
+
var import_viem8 = require("viem");
|
|
235
|
+
var import_v4 = __toESM(require("zod/v4"), 1);
|
|
236
|
+
|
|
237
|
+
// src/ens/index.ts
|
|
238
|
+
var import_datasources2 = require("@ensnode/datasources");
|
|
239
|
+
|
|
240
|
+
// src/ens/coin-type.ts
|
|
241
|
+
var import_utils = require("@ensdomains/address-encoder/utils");
|
|
242
|
+
var ETH_COIN_TYPE = 60;
|
|
243
|
+
var DEFAULT_EVM_CHAIN_ID = 0;
|
|
244
|
+
var DEFAULT_EVM_COIN_TYPE = 2147483648;
|
|
245
|
+
var coinTypeToEvmChainId = (coinType) => {
|
|
246
|
+
if (coinType === ETH_COIN_TYPE) return 1;
|
|
247
|
+
return (0, import_utils.coinTypeToEvmChainId)(coinType);
|
|
248
|
+
};
|
|
249
|
+
var evmChainIdToCoinType = (chainId) => {
|
|
250
|
+
if (chainId === 1) return ETH_COIN_TYPE;
|
|
251
|
+
return (0, import_utils.evmChainIdToCoinType)(chainId);
|
|
252
|
+
};
|
|
253
|
+
var bigintToCoinType = (value) => {
|
|
254
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
255
|
+
throw new Error(`'${value}' cannot represent as CoinType, it is too large.`);
|
|
256
|
+
}
|
|
257
|
+
return Number(value);
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// src/ens/constants.ts
|
|
261
|
+
var import_viem2 = require("viem");
|
|
262
|
+
var ROOT_NODE = (0, import_viem2.namehash)("");
|
|
263
|
+
var ETH_NODE = (0, import_viem2.namehash)("eth");
|
|
264
|
+
var BASENAMES_NODE = (0, import_viem2.namehash)("base.eth");
|
|
265
|
+
var LINEANAMES_NODE = (0, import_viem2.namehash)("linea.eth");
|
|
266
|
+
var ADDR_REVERSE_NODE = (0, import_viem2.namehash)("addr.reverse");
|
|
267
|
+
|
|
268
|
+
// src/ens/dns-encoded-name.ts
|
|
269
|
+
var import_viem3 = require("viem");
|
|
270
|
+
function decodeDNSEncodedLiteralName(packet) {
|
|
271
|
+
return decodeDNSEncodedName(packet);
|
|
272
|
+
}
|
|
273
|
+
function decodeDNSEncodedName(packet) {
|
|
274
|
+
const segments = [];
|
|
275
|
+
const bytes = (0, import_viem3.hexToBytes)(packet);
|
|
276
|
+
if (bytes.length === 0) throw new Error(`Packet is empty.`);
|
|
277
|
+
let offset = 0;
|
|
278
|
+
while (offset < bytes.length) {
|
|
279
|
+
const len = bytes[offset];
|
|
280
|
+
if (len === void 0) {
|
|
281
|
+
throw new Error(`Invariant: bytes[offset] is undefined after offset < bytes.length check.`);
|
|
282
|
+
}
|
|
283
|
+
if (len < 0 || len > 255) {
|
|
284
|
+
throw new Error(
|
|
285
|
+
`Invariant: this should be literally impossible, but an unsigned byte was less than zero or greater than 255. The value in question is ${len}`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
if (len === 0) break;
|
|
289
|
+
const segment = (0, import_viem3.bytesToString)(bytes.subarray(offset + 1, offset + len + 1));
|
|
290
|
+
segments.push(segment);
|
|
291
|
+
offset += len + 1;
|
|
292
|
+
}
|
|
293
|
+
if (offset >= bytes.length) throw new Error(`Overflow, offset >= bytes.length`);
|
|
294
|
+
if (offset !== bytes.length - 1) throw new Error(`Junk at end of name`);
|
|
295
|
+
return segments;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/ens/labelhash.ts
|
|
299
|
+
var import_viem4 = require("viem");
|
|
300
|
+
function isLabelHash(maybeLabelHash) {
|
|
301
|
+
const expectedLength = maybeLabelHash.length === 66;
|
|
302
|
+
const expectedEncoding = (0, import_viem4.isHex)(maybeLabelHash);
|
|
303
|
+
const expectedCasing = maybeLabelHash === maybeLabelHash.toLowerCase();
|
|
304
|
+
return expectedLength && expectedEncoding && expectedCasing;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// src/ens/encode-labelhash.ts
|
|
308
|
+
var encodeLabelHash = (labelHash) => `[${labelHash.slice(2)}]`;
|
|
309
|
+
function isEncodedLabelHash(maybeEncodedLabelHash) {
|
|
310
|
+
const expectedFormatting = maybeEncodedLabelHash.startsWith("[") && maybeEncodedLabelHash.endsWith("]");
|
|
311
|
+
const includesLabelHash = isLabelHash(`0x${maybeEncodedLabelHash.slice(1, -1)}`);
|
|
312
|
+
return expectedFormatting && includesLabelHash;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/ens/names.ts
|
|
316
|
+
var import_ens_normalize = require("@adraffy/ens-normalize");
|
|
317
|
+
var getNameHierarchy = (name) => name.split(".").map((_, i, labels) => labels.slice(i).join("."));
|
|
318
|
+
var beautifyName = (name) => {
|
|
319
|
+
const beautifiedLabels = name.split(".").map((label) => {
|
|
320
|
+
if (isNormalizedLabel(label)) {
|
|
321
|
+
return (0, import_ens_normalize.ens_beautify)(label);
|
|
322
|
+
} else {
|
|
323
|
+
return label;
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
return beautifiedLabels.join(".");
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/ens/parse-reverse-name.ts
|
|
330
|
+
var import_viem5 = require("viem");
|
|
331
|
+
var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
|
|
332
|
+
var parseAddressLabel = (addressLabel) => {
|
|
333
|
+
const maybeAddress = `0x${addressLabel}`;
|
|
334
|
+
if (!(0, import_viem5.isAddress)(maybeAddress)) {
|
|
335
|
+
throw new Error(`Invalid EVM address "${maybeAddress}"`);
|
|
336
|
+
}
|
|
337
|
+
return asLowerCaseAddress(maybeAddress);
|
|
338
|
+
};
|
|
339
|
+
var parseCoinTypeLabel = (coinTypeLabel) => {
|
|
340
|
+
if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
|
|
341
|
+
if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
|
|
342
|
+
return bigintToCoinType((0, import_viem5.hexToBigInt)(`0x${coinTypeLabel}`));
|
|
343
|
+
};
|
|
344
|
+
function parseReverseName(name) {
|
|
345
|
+
const match = name.match(REVERSE_NAME_REGEX);
|
|
346
|
+
if (!match) return null;
|
|
347
|
+
try {
|
|
348
|
+
const [, addressLabel, coinTypeLabel] = match;
|
|
349
|
+
if (!addressLabel) return null;
|
|
350
|
+
if (!coinTypeLabel) return null;
|
|
351
|
+
return {
|
|
352
|
+
address: parseAddressLabel(addressLabel),
|
|
353
|
+
coinType: parseCoinTypeLabel(coinTypeLabel)
|
|
354
|
+
};
|
|
355
|
+
} catch {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/ens/reverse-name.ts
|
|
361
|
+
var addrReverseLabel = (address) => address.slice(2);
|
|
362
|
+
var coinTypeReverseLabel = (coinType) => coinType.toString(16);
|
|
363
|
+
function reverseName(address, coinType) {
|
|
364
|
+
const label = addrReverseLabel(address);
|
|
365
|
+
const middle = (() => {
|
|
366
|
+
switch (coinType) {
|
|
367
|
+
case ETH_COIN_TYPE:
|
|
368
|
+
return "addr";
|
|
369
|
+
case DEFAULT_EVM_COIN_TYPE:
|
|
370
|
+
return "default";
|
|
371
|
+
default:
|
|
372
|
+
return coinTypeReverseLabel(coinType);
|
|
373
|
+
}
|
|
374
|
+
})();
|
|
375
|
+
return `${label}.${middle}.reverse`;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// src/ens/subname-helpers.ts
|
|
379
|
+
var import_viem6 = require("viem");
|
|
380
|
+
var makeSubdomainNode = (labelHash, node) => (0, import_viem6.keccak256)((0, import_viem6.concat)([node, labelHash]));
|
|
381
|
+
var uint256ToHex32 = (num) => (0, import_viem6.toHex)(num, { size: 32 });
|
|
382
|
+
|
|
383
|
+
// src/ens/types.ts
|
|
384
|
+
var import_datasources = require("@ensnode/datasources");
|
|
385
|
+
|
|
386
|
+
// src/shared/currencies.ts
|
|
387
|
+
var CurrencyIds = {
|
|
388
|
+
ETH: "ETH",
|
|
389
|
+
USDC: "USDC",
|
|
390
|
+
DAI: "DAI"
|
|
391
|
+
};
|
|
392
|
+
var currencyInfo = {
|
|
393
|
+
[CurrencyIds.ETH]: {
|
|
394
|
+
id: CurrencyIds.ETH,
|
|
395
|
+
name: "ETH",
|
|
396
|
+
decimals: 18
|
|
397
|
+
},
|
|
398
|
+
[CurrencyIds.USDC]: {
|
|
399
|
+
id: CurrencyIds.USDC,
|
|
400
|
+
name: "USDC",
|
|
401
|
+
decimals: 6
|
|
402
|
+
},
|
|
403
|
+
[CurrencyIds.DAI]: {
|
|
404
|
+
id: CurrencyIds.DAI,
|
|
405
|
+
name: "Dai Stablecoin",
|
|
406
|
+
decimals: 18
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
function getCurrencyInfo(currencyId) {
|
|
410
|
+
return currencyInfo[currencyId];
|
|
411
|
+
}
|
|
412
|
+
function priceEth(amount) {
|
|
413
|
+
return {
|
|
414
|
+
amount,
|
|
415
|
+
currency: CurrencyIds.ETH
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
function priceUsdc(amount) {
|
|
419
|
+
return {
|
|
420
|
+
amount,
|
|
421
|
+
currency: CurrencyIds.USDC
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
function priceDai(amount) {
|
|
425
|
+
return {
|
|
426
|
+
amount,
|
|
427
|
+
currency: CurrencyIds.DAI
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function isPriceCurrencyEqual(priceA, priceB) {
|
|
431
|
+
return priceA.currency === priceB.currency;
|
|
432
|
+
}
|
|
433
|
+
function isPriceEqual(priceA, priceB) {
|
|
434
|
+
return isPriceCurrencyEqual(priceA, priceB) && priceA.amount === priceB.amount;
|
|
435
|
+
}
|
|
436
|
+
function addPrices(...prices) {
|
|
437
|
+
const firstPrice = prices[0];
|
|
438
|
+
const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
|
|
439
|
+
if (allPricesInSameCurrency === false) {
|
|
440
|
+
throw new Error("All prices must have the same currency to be added together.");
|
|
441
|
+
}
|
|
442
|
+
const { currency } = firstPrice;
|
|
443
|
+
return prices.reduce(
|
|
444
|
+
(acc, price) => ({
|
|
445
|
+
amount: acc.amount + price.amount,
|
|
446
|
+
currency
|
|
447
|
+
}),
|
|
448
|
+
{
|
|
449
|
+
amount: 0n,
|
|
450
|
+
currency: firstPrice.currency
|
|
451
|
+
}
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// src/shared/reinterpretation.ts
|
|
456
|
+
var import_viem7 = require("viem");
|
|
457
|
+
function reinterpretLabel(label) {
|
|
458
|
+
if (label === "") {
|
|
459
|
+
throw new Error(
|
|
460
|
+
`Cannot reinterpret an empty label that violates the invariants of an InterpretedLabel.`
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
if (isEncodedLabelHash(label)) return label;
|
|
464
|
+
if (isNormalizedLabel(label)) return label;
|
|
465
|
+
return encodeLabelHash((0, import_viem7.labelhash)(label));
|
|
466
|
+
}
|
|
467
|
+
function reinterpretName(name) {
|
|
468
|
+
if (name === "") return name;
|
|
469
|
+
const interpretedLabels = name.split(".");
|
|
470
|
+
const reinterpretedLabels = interpretedLabels.map(reinterpretLabel);
|
|
471
|
+
const reinterpretedName = reinterpretedLabels.join(".");
|
|
472
|
+
return reinterpretedName;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// src/shared/zod-schemas.ts
|
|
476
|
+
var makeIntegerSchema = (valueLabel = "Value") => import_v4.default.int({
|
|
477
|
+
error: `${valueLabel} must be an integer.`
|
|
478
|
+
});
|
|
479
|
+
var makePositiveIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(valueLabel).positive({
|
|
480
|
+
error: `${valueLabel} must be a positive integer (>0).`
|
|
481
|
+
});
|
|
482
|
+
var makeNonNegativeIntegerSchema = (valueLabel = "Value") => makeIntegerSchema(valueLabel).nonnegative({
|
|
483
|
+
error: `${valueLabel} must be a non-negative integer (>=0).`
|
|
484
|
+
});
|
|
485
|
+
var makeDurationSchema = (valueLabel = "Value") => import_v4.default.coerce.number({
|
|
486
|
+
error: `${valueLabel} must be a number.`
|
|
487
|
+
}).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
488
|
+
var makeChainIdSchema = (valueLabel = "Chain ID") => makePositiveIntegerSchema(valueLabel).transform((val) => val);
|
|
489
|
+
var makeChainIdStringSchema = (valueLabel = "Chain ID String") => import_v4.default.string({ error: `${valueLabel} must be a string representing a chain ID.` }).pipe(import_v4.default.coerce.number({ error: `${valueLabel} must represent a positive integer (>0).` })).pipe(makeChainIdSchema(`The numeric value represented by ${valueLabel}`));
|
|
490
|
+
var makeLowercaseAddressSchema = (valueLabel = "EVM address") => import_v4.default.string().check((ctx) => {
|
|
491
|
+
if (!(0, import_viem8.isAddress)(ctx.value)) {
|
|
492
|
+
ctx.issues.push({
|
|
493
|
+
code: "custom",
|
|
494
|
+
message: `${valueLabel} must be a valid EVM address`,
|
|
495
|
+
input: ctx.value
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}).transform((val) => asLowerCaseAddress(val));
|
|
499
|
+
var makeDatetimeSchema = (valueLabel = "Datetime string") => import_v4.default.iso.datetime({ error: `${valueLabel} must be a string in ISO 8601 format.` }).transform((v) => new Date(v));
|
|
500
|
+
var makeUnixTimestampSchema = (valueLabel = "Timestamp") => makeIntegerSchema(valueLabel);
|
|
501
|
+
var makeUrlSchema = (valueLabel = "Value") => import_v4.default.url({
|
|
502
|
+
error: `${valueLabel} must be a valid URL string (e.g., http://localhost:8080 or https://example.com).`,
|
|
503
|
+
abort: true
|
|
504
|
+
}).transform((v) => new URL(v));
|
|
505
|
+
var makeBlockNumberSchema = (valueLabel = "Block number") => makeNonNegativeIntegerSchema(valueLabel);
|
|
506
|
+
var makeBlockrangeSchema = (valueLabel = "Value") => import_v4.default.strictObject(
|
|
507
|
+
{
|
|
508
|
+
startBlock: makeBlockNumberSchema(`${valueLabel}.startBlock`).optional(),
|
|
509
|
+
endBlock: makeBlockNumberSchema(`${valueLabel}.endBlock`).optional()
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
error: `${valueLabel} must be a valid Blockrange object.`
|
|
513
|
+
}
|
|
514
|
+
).refine(
|
|
515
|
+
(v) => {
|
|
516
|
+
if (v.startBlock && v.endBlock) {
|
|
517
|
+
return v.startBlock <= v.endBlock;
|
|
518
|
+
}
|
|
519
|
+
return true;
|
|
520
|
+
},
|
|
521
|
+
{ error: `${valueLabel}: startBlock must be before or equal to endBlock` }
|
|
522
|
+
);
|
|
523
|
+
var makeBlockRefSchema = (valueLabel = "Value") => import_v4.default.strictObject(
|
|
524
|
+
{
|
|
525
|
+
timestamp: makeUnixTimestampSchema(`${valueLabel}.timestamp`),
|
|
526
|
+
number: makeBlockNumberSchema(`${valueLabel}.number`)
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
error: `${valueLabel} must be a valid BlockRef object.`
|
|
530
|
+
}
|
|
531
|
+
);
|
|
532
|
+
var makeENSNamespaceIdSchema = (valueLabel = "ENSNamespaceId") => import_v4.default.enum(import_datasources.ENSNamespaceIds, {
|
|
533
|
+
error() {
|
|
534
|
+
return `Invalid ${valueLabel}. Supported ENS namespace IDs are: ${Object.keys(import_datasources.ENSNamespaceIds).join(", ")}`;
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
var makePriceAmountSchema = (valueLabel = "Amount") => import_v4.default.coerce.bigint({
|
|
538
|
+
error: `${valueLabel} must represent a bigint.`
|
|
539
|
+
}).nonnegative({
|
|
540
|
+
error: `${valueLabel} must not be negative.`
|
|
541
|
+
});
|
|
542
|
+
var makePriceCurrencySchema = (currency, valueLabel = "Price Currency") => import_v4.default.strictObject({
|
|
543
|
+
amount: makePriceAmountSchema(`${valueLabel} amount`),
|
|
544
|
+
currency: import_v4.default.literal(currency, {
|
|
545
|
+
error: `${valueLabel} currency must be set to '${currency}'.`
|
|
546
|
+
})
|
|
547
|
+
});
|
|
548
|
+
var makePriceEthSchema = (valueLabel = "Price ETH") => makePriceCurrencySchema(CurrencyIds.ETH, valueLabel).transform((v) => v);
|
|
549
|
+
var makeAccountIdSchema = (valueLabel = "AccountId") => import_v4.default.strictObject({
|
|
550
|
+
chainId: makeChainIdStringSchema(`${valueLabel} chain ID`),
|
|
551
|
+
address: makeLowercaseAddressSchema(`${valueLabel} address`)
|
|
552
|
+
});
|
|
553
|
+
var makeSerializedAccountIdSchema = (valueLabel = "Account ID") => import_v4.default.coerce.string().transform((v) => {
|
|
554
|
+
const result = new import_caip.AccountId(v);
|
|
555
|
+
return {
|
|
556
|
+
chainId: result.chainId.reference,
|
|
557
|
+
address: result.address
|
|
558
|
+
};
|
|
559
|
+
}).pipe(makeAccountIdSchema(valueLabel));
|
|
560
|
+
var makeHexStringSchema = (options, valueLabel = "String representation of bytes array") => import_v4.default.string().check(function invariant_isHexEncoded(ctx) {
|
|
561
|
+
if (!(0, import_viem8.isHex)(ctx.value)) {
|
|
562
|
+
ctx.issues.push({
|
|
563
|
+
code: "custom",
|
|
564
|
+
input: ctx.value,
|
|
565
|
+
message: `${valueLabel} must start with '0x'.`
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}).transform((v) => v).check(function invariant_encodesRequiredBytesCount(ctx) {
|
|
569
|
+
const expectedBytesCount = options.bytesCount;
|
|
570
|
+
const actualBytesCount = (0, import_viem8.size)(ctx.value);
|
|
571
|
+
if (actualBytesCount !== expectedBytesCount) {
|
|
572
|
+
ctx.issues.push({
|
|
573
|
+
code: "custom",
|
|
574
|
+
input: ctx.value,
|
|
575
|
+
message: `${valueLabel} must represent exactly ${expectedBytesCount} bytes. Currently represented bytes count: ${actualBytesCount}.`
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
var makeNodeSchema = (valueLabel = "Node") => makeHexStringSchema({ bytesCount: 32 }, valueLabel);
|
|
580
|
+
var makeTransactionHashSchema = (valueLabel = "Transaction hash") => makeHexStringSchema({ bytesCount: 32 }, valueLabel);
|
|
581
|
+
var makeReinterpretedNameSchema = (valueLabel = "Reinterpreted Name") => import_v4.default.string().transform((v) => v).check((ctx) => {
|
|
582
|
+
try {
|
|
583
|
+
reinterpretName(ctx.value);
|
|
584
|
+
} catch (error) {
|
|
585
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
586
|
+
ctx.issues.push({
|
|
587
|
+
code: "custom",
|
|
588
|
+
input: ctx.value,
|
|
589
|
+
message: `${valueLabel} cannot be reinterpreted: ${errorMessage}`
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
}).transform(reinterpretName);
|
|
593
|
+
|
|
594
|
+
// src/shared/deserialize.ts
|
|
595
|
+
function deserializeChainId(maybeChainId, valueLabel) {
|
|
596
|
+
const schema = makeChainIdStringSchema(valueLabel);
|
|
597
|
+
const parsed = schema.safeParse(maybeChainId);
|
|
598
|
+
if (parsed.error) {
|
|
599
|
+
throw new Error(`Cannot deserialize ChainId:
|
|
600
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
601
|
+
`);
|
|
602
|
+
}
|
|
603
|
+
return parsed.data;
|
|
604
|
+
}
|
|
605
|
+
function deserializeDatetime(maybeDatetime, valueLabel) {
|
|
606
|
+
const schema = makeDatetimeSchema(valueLabel);
|
|
607
|
+
const parsed = schema.safeParse(maybeDatetime);
|
|
608
|
+
if (parsed.error) {
|
|
609
|
+
throw new Error(`Cannot deserialize Datetime:
|
|
610
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
611
|
+
`);
|
|
612
|
+
}
|
|
613
|
+
return parsed.data;
|
|
614
|
+
}
|
|
615
|
+
function deserializeUnixTimestamp(maybeTimestamp, valueLabel) {
|
|
616
|
+
const schema = makeUnixTimestampSchema(valueLabel);
|
|
617
|
+
const parsed = schema.safeParse(maybeTimestamp);
|
|
618
|
+
if (parsed.error) {
|
|
619
|
+
throw new Error(`Cannot deserialize Unix Timestamp:
|
|
620
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
621
|
+
`);
|
|
622
|
+
}
|
|
623
|
+
return parsed.data;
|
|
624
|
+
}
|
|
625
|
+
function deserializeUrl(maybeUrl, valueLabel) {
|
|
626
|
+
const schema = makeUrlSchema(valueLabel);
|
|
627
|
+
const parsed = schema.safeParse(maybeUrl);
|
|
628
|
+
if (parsed.error) {
|
|
629
|
+
throw new Error(`Cannot deserialize URL:
|
|
630
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
631
|
+
`);
|
|
632
|
+
}
|
|
633
|
+
return parsed.data;
|
|
634
|
+
}
|
|
635
|
+
function deserializeBlockNumber(maybeBlockNumber, valueLabel) {
|
|
636
|
+
const schema = makeBlockNumberSchema(valueLabel);
|
|
637
|
+
const parsed = schema.safeParse(maybeBlockNumber);
|
|
638
|
+
if (parsed.error) {
|
|
639
|
+
throw new Error(`Cannot deserialize BlockNumber:
|
|
640
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
641
|
+
`);
|
|
642
|
+
}
|
|
643
|
+
return parsed.data;
|
|
644
|
+
}
|
|
645
|
+
function deserializeBlockrange(maybeBlockrange, valueLabel) {
|
|
646
|
+
const schema = makeBlockrangeSchema(valueLabel);
|
|
647
|
+
const parsed = schema.safeParse(maybeBlockrange);
|
|
648
|
+
if (parsed.error) {
|
|
649
|
+
throw new Error(`Cannot deserialize Blockrange:
|
|
650
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
651
|
+
`);
|
|
652
|
+
}
|
|
653
|
+
return parsed.data;
|
|
654
|
+
}
|
|
655
|
+
function deserializeBlockRef(maybeBlockRef, valueLabel) {
|
|
656
|
+
const schema = makeBlockRefSchema(valueLabel);
|
|
657
|
+
const parsed = schema.safeParse(maybeBlockRef);
|
|
658
|
+
if (parsed.error) {
|
|
659
|
+
throw new Error(`Cannot deserialize BlockRef:
|
|
660
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
661
|
+
`);
|
|
662
|
+
}
|
|
663
|
+
return parsed.data;
|
|
664
|
+
}
|
|
665
|
+
function deserializeDuration(maybeDuration, valueLabel) {
|
|
666
|
+
const schema = makeDurationSchema(valueLabel);
|
|
667
|
+
const parsed = schema.safeParse(maybeDuration);
|
|
668
|
+
if (parsed.error) {
|
|
669
|
+
throw new RangeError(`Cannot deserialize Duration:
|
|
670
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
671
|
+
`);
|
|
672
|
+
}
|
|
673
|
+
return parsed.data;
|
|
674
|
+
}
|
|
675
|
+
function deserializeAccountId(maybeAccountId, valueLabel) {
|
|
676
|
+
const schema = makeSerializedAccountIdSchema(valueLabel);
|
|
677
|
+
const parsed = schema.safeParse(maybeAccountId);
|
|
678
|
+
if (parsed.error) {
|
|
679
|
+
throw new RangeError(`Cannot deserialize AccountId:
|
|
680
|
+
${(0, import_v42.prettifyError)(parsed.error)}
|
|
681
|
+
`);
|
|
682
|
+
}
|
|
683
|
+
return parsed.data;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/shared/datetime.ts
|
|
687
|
+
function durationBetween(start, end) {
|
|
688
|
+
return deserializeDuration(end - start, "Duration");
|
|
689
|
+
}
|
|
690
|
+
function addDuration(timestamp, duration) {
|
|
691
|
+
return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// src/shared/cache.ts
|
|
695
|
+
var LruCache = class {
|
|
696
|
+
_cache = /* @__PURE__ */ new Map();
|
|
697
|
+
_capacity;
|
|
698
|
+
/**
|
|
699
|
+
* Create a new LRU cache with the given capacity.
|
|
700
|
+
*
|
|
701
|
+
* @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
|
|
702
|
+
* @throws Error if capacity is not a non-negative integer.
|
|
703
|
+
*/
|
|
704
|
+
constructor(capacity) {
|
|
705
|
+
if (!Number.isInteger(capacity)) {
|
|
706
|
+
throw new Error(
|
|
707
|
+
`LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
if (capacity < 0) {
|
|
711
|
+
throw new Error(
|
|
712
|
+
`LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
this._capacity = capacity;
|
|
716
|
+
}
|
|
717
|
+
set(key, value) {
|
|
718
|
+
this._cache.set(key, value);
|
|
719
|
+
if (this._cache.size > this._capacity) {
|
|
720
|
+
const oldestKey = this._cache.keys().next().value;
|
|
721
|
+
this._cache.delete(oldestKey);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
get(key) {
|
|
725
|
+
const value = this._cache.get(key);
|
|
726
|
+
if (value) {
|
|
727
|
+
this._cache.delete(key);
|
|
728
|
+
this._cache.set(key, value);
|
|
729
|
+
}
|
|
730
|
+
return value;
|
|
731
|
+
}
|
|
732
|
+
clear() {
|
|
733
|
+
this._cache.clear();
|
|
734
|
+
}
|
|
735
|
+
get size() {
|
|
736
|
+
return this._cache.size;
|
|
737
|
+
}
|
|
738
|
+
get capacity() {
|
|
739
|
+
return this._capacity;
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
var TtlCache = class {
|
|
743
|
+
_cache = /* @__PURE__ */ new Map();
|
|
744
|
+
_ttl;
|
|
745
|
+
/**
|
|
746
|
+
* Create a new TTL cache with the given TTL.
|
|
747
|
+
*
|
|
748
|
+
* @param ttl Time-to-live duration in seconds. Items expire after this duration.
|
|
749
|
+
*/
|
|
750
|
+
constructor(ttl) {
|
|
751
|
+
this._ttl = ttl;
|
|
752
|
+
}
|
|
753
|
+
_cleanup() {
|
|
754
|
+
const now = (0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date());
|
|
755
|
+
for (const [key, entry] of this._cache.entries()) {
|
|
756
|
+
if (entry.expiresAt <= now) {
|
|
757
|
+
this._cache.delete(key);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
set(key, value) {
|
|
762
|
+
this._cleanup();
|
|
763
|
+
const expiresAt = addDuration((0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date()), this._ttl);
|
|
764
|
+
this._cache.set(key, { value, expiresAt });
|
|
765
|
+
}
|
|
766
|
+
get(key) {
|
|
767
|
+
this._cleanup();
|
|
768
|
+
const entry = this._cache.get(key);
|
|
769
|
+
if (!entry) {
|
|
770
|
+
return void 0;
|
|
771
|
+
}
|
|
772
|
+
if (entry.expiresAt <= (0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date())) {
|
|
773
|
+
this._cache.delete(key);
|
|
774
|
+
return void 0;
|
|
775
|
+
}
|
|
776
|
+
return entry.value;
|
|
777
|
+
}
|
|
778
|
+
clear() {
|
|
779
|
+
this._cache.clear();
|
|
780
|
+
}
|
|
781
|
+
get size() {
|
|
782
|
+
this._cleanup();
|
|
783
|
+
return this._cache.size;
|
|
784
|
+
}
|
|
785
|
+
get capacity() {
|
|
786
|
+
return Number.MAX_SAFE_INTEGER;
|
|
787
|
+
}
|
|
788
|
+
has(key) {
|
|
789
|
+
this._cleanup();
|
|
790
|
+
const entry = this._cache.get(key);
|
|
791
|
+
if (!entry) {
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
if (entry.expiresAt <= (0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date())) {
|
|
795
|
+
this._cache.delete(key);
|
|
796
|
+
return false;
|
|
797
|
+
}
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
delete(key) {
|
|
801
|
+
return this._cache.delete(key);
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
function staleWhileRevalidate(options) {
|
|
805
|
+
const { fn, ttl } = options;
|
|
806
|
+
let cache = null;
|
|
807
|
+
let cacheInitializer = null;
|
|
808
|
+
return async () => {
|
|
809
|
+
if (!cache) {
|
|
810
|
+
if (cacheInitializer) {
|
|
811
|
+
return cacheInitializer;
|
|
812
|
+
}
|
|
813
|
+
cacheInitializer = fn().then((value) => {
|
|
814
|
+
cache = { value, updatedAt: (0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date()) };
|
|
815
|
+
cacheInitializer = null;
|
|
816
|
+
return value;
|
|
817
|
+
}).catch(() => {
|
|
818
|
+
cacheInitializer = null;
|
|
819
|
+
return null;
|
|
820
|
+
});
|
|
821
|
+
return cacheInitializer;
|
|
822
|
+
}
|
|
823
|
+
const isStale = durationBetween(cache.updatedAt, (0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date())) > ttl;
|
|
824
|
+
if (!isStale) return cache.value;
|
|
825
|
+
if (cache.inProgressRevalidation) return cache.value;
|
|
826
|
+
const revalidationPromise = fn().then((value) => {
|
|
827
|
+
cache = { value, updatedAt: (0, import_date_fns.getUnixTime)(/* @__PURE__ */ new Date()) };
|
|
828
|
+
}).catch(() => {
|
|
829
|
+
if (cache) {
|
|
830
|
+
cache.inProgressRevalidation = void 0;
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
cache.inProgressRevalidation = revalidationPromise;
|
|
834
|
+
return cache.value;
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// src/shared/collections.ts
|
|
839
|
+
var uniq = (arr) => [...new Set(arr)];
|
|
840
|
+
|
|
841
|
+
// src/shared/labelhash.ts
|
|
842
|
+
var import_viem9 = require("viem");
|
|
843
|
+
var labelhashLiteralLabel = (label) => (0, import_viem9.keccak256)((0, import_viem9.stringToBytes)(label));
|
|
844
|
+
|
|
845
|
+
// src/shared/interpretation.ts
|
|
846
|
+
function literalLabelToInterpretedLabel(label) {
|
|
847
|
+
if (isNormalizedLabel(label)) return label;
|
|
848
|
+
return encodeLabelHash(labelhashLiteralLabel(label));
|
|
849
|
+
}
|
|
850
|
+
function literalLabelsToInterpretedName(labels) {
|
|
851
|
+
return labels.map(literalLabelToInterpretedLabel).join(".");
|
|
852
|
+
}
|
|
853
|
+
function interpretedLabelsToInterpretedName(labels) {
|
|
854
|
+
return labels.join(".");
|
|
855
|
+
}
|
|
856
|
+
function literalLabelsToLiteralName(labels) {
|
|
857
|
+
return labels.join(".");
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// src/shared/null-bytes.ts
|
|
861
|
+
var hasNullByte = (value) => value.indexOf("\0") !== -1;
|
|
862
|
+
var stripNullBytes = (value) => value.replaceAll("\0", "");
|
|
863
|
+
|
|
864
|
+
// src/shared/numbers.ts
|
|
865
|
+
function bigIntToNumber(n) {
|
|
866
|
+
if (n < Number.MIN_SAFE_INTEGER) {
|
|
867
|
+
throw new Error(
|
|
868
|
+
`The bigint '${n.toString()}' value is too low to be to converted into a number.'`
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
if (n > Number.MAX_SAFE_INTEGER) {
|
|
872
|
+
throw new Error(
|
|
873
|
+
`The bigint '${n.toString()}' value is too high to be to converted into a number.'`
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
return Number(n);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// src/shared/serialize.ts
|
|
880
|
+
var import_caip2 = require("caip");
|
|
881
|
+
function serializeChainId(chainId) {
|
|
882
|
+
return chainId.toString();
|
|
883
|
+
}
|
|
884
|
+
function serializeDatetime(datetime) {
|
|
885
|
+
return datetime.toISOString();
|
|
886
|
+
}
|
|
887
|
+
function serializeUrl(url) {
|
|
888
|
+
return url.toString();
|
|
889
|
+
}
|
|
890
|
+
function serializePrice(price) {
|
|
891
|
+
return {
|
|
892
|
+
currency: price.currency,
|
|
893
|
+
amount: price.amount.toString()
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
function serializePriceEth(price) {
|
|
897
|
+
return serializePrice(price);
|
|
898
|
+
}
|
|
899
|
+
function serializeAccountId(accountId) {
|
|
900
|
+
return import_caip2.AccountId.format({
|
|
901
|
+
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
902
|
+
address: accountId.address
|
|
903
|
+
}).toLowerCase();
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/shared/url.ts
|
|
907
|
+
function isHttpProtocol(url) {
|
|
908
|
+
return ["http:", "https:"].includes(url.protocol);
|
|
909
|
+
}
|
|
910
|
+
function isWebSocketProtocol(url) {
|
|
911
|
+
return ["ws:", "wss:"].includes(url.protocol);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// src/ensindexer/indexing-status/types.ts
|
|
915
|
+
var ChainIndexingConfigTypeIds = {
|
|
916
|
+
/**
|
|
917
|
+
* Represents that indexing of the chain should be performed for an indefinite range.
|
|
918
|
+
*/
|
|
919
|
+
Indefinite: "indefinite",
|
|
920
|
+
/**
|
|
921
|
+
* Represents that indexing of the chain should be performed for a definite range.
|
|
922
|
+
*/
|
|
923
|
+
Definite: "definite"
|
|
924
|
+
};
|
|
925
|
+
var ChainIndexingStatusIds = {
|
|
926
|
+
/**
|
|
927
|
+
* Represents that indexing of the chain is not ready to begin yet because:
|
|
928
|
+
* - ENSIndexer is in its initialization phase and the data to build a
|
|
929
|
+
* "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
|
|
930
|
+
* - ENSIndexer is using an omnichain indexing strategy and the
|
|
931
|
+
* `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
|
|
932
|
+
* {@link ChainIndexingSnapshot}.
|
|
933
|
+
*/
|
|
934
|
+
Queued: "chain-queued",
|
|
935
|
+
/**
|
|
936
|
+
* Represents that indexing of the chain is in progress and under a special
|
|
937
|
+
* "backfill" phase that optimizes for accelerated indexing until reaching the
|
|
938
|
+
* "fixed target" `backfillEndBlock`.
|
|
939
|
+
*/
|
|
940
|
+
Backfill: "chain-backfill",
|
|
941
|
+
/**
|
|
942
|
+
* Represents that the "backfill" phase of indexing the chain is completed
|
|
943
|
+
* and that the chain is configured to be indexed for an indefinite range.
|
|
944
|
+
* Therefore, indexing of the chain remains indefinitely in progress where
|
|
945
|
+
* ENSIndexer will continuously work to discover and index new blocks as they
|
|
946
|
+
* are added to the chain across time.
|
|
947
|
+
*/
|
|
948
|
+
Following: "chain-following",
|
|
949
|
+
/**
|
|
950
|
+
* Represents that indexing of the chain is completed as the chain is configured
|
|
951
|
+
* to be indexed for a definite range and the indexing of all blocks through
|
|
952
|
+
* that definite range is completed.
|
|
953
|
+
*/
|
|
954
|
+
Completed: "chain-completed"
|
|
955
|
+
};
|
|
956
|
+
var OmnichainIndexingStatusIds = {
|
|
957
|
+
/**
|
|
958
|
+
* Represents that omnichain indexing is not ready to begin yet because
|
|
959
|
+
* ENSIndexer is in its initialization phase and the data to build a "true"
|
|
960
|
+
* {@link OmnichainIndexingStatusSnapshot} is still being loaded.
|
|
961
|
+
*/
|
|
962
|
+
Unstarted: "omnichain-unstarted",
|
|
963
|
+
/**
|
|
964
|
+
* Represents that omnichain indexing is in an overall "backfill" status because
|
|
965
|
+
* - At least one indexed chain has a `chainStatus` of
|
|
966
|
+
* {@link ChainIndexingStatusIds.Backfill}; and
|
|
967
|
+
* - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
|
|
968
|
+
*/
|
|
969
|
+
Backfill: "omnichain-backfill",
|
|
970
|
+
/**
|
|
971
|
+
* Represents that omnichain indexing is in an overall "following" status because
|
|
972
|
+
* at least one indexed chain has a `chainStatus` of
|
|
973
|
+
* {@link ChainIndexingStatusIds.Following}.
|
|
974
|
+
*/
|
|
975
|
+
Following: "omnichain-following",
|
|
976
|
+
/**
|
|
977
|
+
* Represents that omnichain indexing has completed because all indexed chains have
|
|
978
|
+
* a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
|
|
979
|
+
*/
|
|
980
|
+
Completed: "omnichain-completed"
|
|
981
|
+
};
|
|
982
|
+
var CrossChainIndexingStrategyIds = {
|
|
983
|
+
/**
|
|
984
|
+
* Represents that the indexing of events across all indexed chains will
|
|
985
|
+
* proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
|
|
986
|
+
* and block number.
|
|
987
|
+
*
|
|
988
|
+
* This strategy is "deterministic" in that the order of processing cross-chain indexed
|
|
989
|
+
* events and each resulting indexed data state transition recorded in ENSDb is always
|
|
990
|
+
* the same for each ENSIndexer instance operating with an equivalent
|
|
991
|
+
* `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
|
|
992
|
+
* - increased indexing latency that must wait for the slowest indexed chain to
|
|
993
|
+
* add new blocks or to discover new blocks through the configured RPCs.
|
|
994
|
+
* - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
|
|
995
|
+
* will be affected.
|
|
996
|
+
*/
|
|
997
|
+
Omnichain: "omnichain"
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
// src/shared/block-ref.ts
|
|
1001
|
+
function isBefore(blockA, blockB) {
|
|
1002
|
+
return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
|
|
1003
|
+
}
|
|
1004
|
+
function isEqualTo(blockA, blockB) {
|
|
1005
|
+
return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
|
|
1006
|
+
}
|
|
1007
|
+
function isBeforeOrEqualTo(blockA, blockB) {
|
|
1008
|
+
return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// src/ensindexer/indexing-status/helpers.ts
|
|
1012
|
+
function getOmnichainIndexingStatus(chains) {
|
|
1013
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
|
|
1014
|
+
return OmnichainIndexingStatusIds.Following;
|
|
1015
|
+
}
|
|
1016
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
|
|
1017
|
+
return OmnichainIndexingStatusIds.Backfill;
|
|
1018
|
+
}
|
|
1019
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
|
|
1020
|
+
return OmnichainIndexingStatusIds.Unstarted;
|
|
1021
|
+
}
|
|
1022
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
|
|
1023
|
+
return OmnichainIndexingStatusIds.Completed;
|
|
1024
|
+
}
|
|
1025
|
+
throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
|
|
1026
|
+
}
|
|
1027
|
+
function getTimestampForLowestOmnichainStartBlock(chains) {
|
|
1028
|
+
const earliestKnownBlockTimestamps = chains.map(
|
|
1029
|
+
(chain) => chain.config.startBlock.timestamp
|
|
1030
|
+
);
|
|
1031
|
+
return Math.min(...earliestKnownBlockTimestamps);
|
|
1032
|
+
}
|
|
1033
|
+
function getTimestampForHighestOmnichainKnownBlock(chains) {
|
|
1034
|
+
const latestKnownBlockTimestamps = [];
|
|
1035
|
+
for (const chain of chains) {
|
|
1036
|
+
switch (chain.chainStatus) {
|
|
1037
|
+
case ChainIndexingStatusIds.Queued:
|
|
1038
|
+
if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
|
|
1039
|
+
latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
|
|
1040
|
+
}
|
|
1041
|
+
break;
|
|
1042
|
+
case ChainIndexingStatusIds.Backfill:
|
|
1043
|
+
latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
|
|
1044
|
+
break;
|
|
1045
|
+
case ChainIndexingStatusIds.Completed:
|
|
1046
|
+
latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
|
|
1047
|
+
break;
|
|
1048
|
+
case ChainIndexingStatusIds.Following:
|
|
1049
|
+
latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
|
|
1050
|
+
break;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return Math.max(...latestKnownBlockTimestamps);
|
|
1054
|
+
}
|
|
1055
|
+
function getOmnichainIndexingCursor(chains) {
|
|
1056
|
+
if (chains.length === 0) {
|
|
1057
|
+
throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
|
|
1058
|
+
}
|
|
1059
|
+
if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
|
|
1060
|
+
const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1061
|
+
return Math.min(...earliestStartBlockTimestamps) - 1;
|
|
1062
|
+
}
|
|
1063
|
+
const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
|
|
1064
|
+
if (latestIndexedBlockTimestamps.length < 1) {
|
|
1065
|
+
throw new Error("latestIndexedBlockTimestamps array must include at least one element");
|
|
1066
|
+
}
|
|
1067
|
+
return Math.max(...latestIndexedBlockTimestamps);
|
|
1068
|
+
}
|
|
1069
|
+
function createIndexingConfig(startBlock, endBlock) {
|
|
1070
|
+
if (endBlock) {
|
|
1071
|
+
return {
|
|
1072
|
+
configType: ChainIndexingConfigTypeIds.Definite,
|
|
1073
|
+
startBlock,
|
|
1074
|
+
endBlock
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
return {
|
|
1078
|
+
configType: ChainIndexingConfigTypeIds.Indefinite,
|
|
1079
|
+
startBlock
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
|
|
1083
|
+
return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
|
|
1084
|
+
}
|
|
1085
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
|
|
1086
|
+
const atLeastOneChainInTargetStatus = chains.some(
|
|
1087
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1088
|
+
);
|
|
1089
|
+
const otherChainsHaveValidStatuses = chains.every(
|
|
1090
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1091
|
+
);
|
|
1092
|
+
return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
|
|
1093
|
+
}
|
|
1094
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
|
|
1095
|
+
const allChainsHaveValidStatuses = chains.every(
|
|
1096
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1097
|
+
);
|
|
1098
|
+
return allChainsHaveValidStatuses;
|
|
1099
|
+
}
|
|
1100
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
|
|
1101
|
+
const allChainsHaveValidStatuses = chains.some(
|
|
1102
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1103
|
+
);
|
|
1104
|
+
return allChainsHaveValidStatuses;
|
|
1105
|
+
}
|
|
1106
|
+
function sortChainStatusesByStartBlockAsc(chains) {
|
|
1107
|
+
chains.sort(
|
|
1108
|
+
([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
|
|
1109
|
+
);
|
|
1110
|
+
return chains;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
// src/ensindexer/indexing-status/validations.ts
|
|
1114
|
+
function invariant_chainSnapshotQueuedBlocks(ctx) {
|
|
1115
|
+
const { config } = ctx.value;
|
|
1116
|
+
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
|
|
1120
|
+
ctx.issues.push({
|
|
1121
|
+
code: "custom",
|
|
1122
|
+
input: ctx.value,
|
|
1123
|
+
message: "`config.startBlock` must be before or same as `config.endBlock`."
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
function invariant_chainSnapshotBackfillBlocks(ctx) {
|
|
1128
|
+
const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
|
|
1129
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1130
|
+
ctx.issues.push({
|
|
1131
|
+
code: "custom",
|
|
1132
|
+
input: ctx.value,
|
|
1133
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
|
|
1137
|
+
ctx.issues.push({
|
|
1138
|
+
code: "custom",
|
|
1139
|
+
input: ctx.value,
|
|
1140
|
+
message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
|
|
1147
|
+
ctx.issues.push({
|
|
1148
|
+
code: "custom",
|
|
1149
|
+
input: ctx.value,
|
|
1150
|
+
message: "`backfillEndBlock` must be the same as `config.endBlock`."
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
function invariant_chainSnapshotCompletedBlocks(ctx) {
|
|
1155
|
+
const { config, latestIndexedBlock } = ctx.value;
|
|
1156
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1157
|
+
ctx.issues.push({
|
|
1158
|
+
code: "custom",
|
|
1159
|
+
input: ctx.value,
|
|
1160
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
|
|
1164
|
+
ctx.issues.push({
|
|
1165
|
+
code: "custom",
|
|
1166
|
+
input: ctx.value,
|
|
1167
|
+
message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
function invariant_chainSnapshotFollowingBlocks(ctx) {
|
|
1172
|
+
const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
|
|
1173
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1174
|
+
ctx.issues.push({
|
|
1175
|
+
code: "custom",
|
|
1176
|
+
input: ctx.value,
|
|
1177
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
|
|
1181
|
+
ctx.issues.push({
|
|
1182
|
+
code: "custom",
|
|
1183
|
+
input: ctx.value,
|
|
1184
|
+
message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
|
|
1189
|
+
const snapshot = ctx.value;
|
|
1190
|
+
const chains = Array.from(snapshot.chains.values());
|
|
1191
|
+
const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
|
|
1192
|
+
const actualOmnichainStatus = snapshot.omnichainStatus;
|
|
1193
|
+
if (expectedOmnichainStatus !== actualOmnichainStatus) {
|
|
1194
|
+
ctx.issues.push({
|
|
1195
|
+
code: "custom",
|
|
1196
|
+
input: snapshot,
|
|
1197
|
+
message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
|
|
1202
|
+
const snapshot = ctx.value;
|
|
1203
|
+
const queuedChains = Array.from(snapshot.chains.values()).filter(
|
|
1204
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
|
|
1205
|
+
);
|
|
1206
|
+
if (queuedChains.length === 0) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
|
|
1210
|
+
const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
|
|
1211
|
+
if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
|
|
1212
|
+
ctx.issues.push({
|
|
1213
|
+
code: "custom",
|
|
1214
|
+
input: snapshot,
|
|
1215
|
+
message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
|
|
1220
|
+
const snapshot = ctx.value;
|
|
1221
|
+
const backfillChains = Array.from(snapshot.chains.values()).filter(
|
|
1222
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1223
|
+
);
|
|
1224
|
+
if (backfillChains.length === 0) {
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
|
|
1228
|
+
const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
|
|
1229
|
+
if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
|
|
1230
|
+
ctx.issues.push({
|
|
1231
|
+
code: "custom",
|
|
1232
|
+
input: snapshot,
|
|
1233
|
+
message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
|
|
1238
|
+
const snapshot = ctx.value;
|
|
1239
|
+
const indexedChains = Array.from(snapshot.chains.values()).filter(
|
|
1240
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1241
|
+
);
|
|
1242
|
+
if (indexedChains.length === 0) {
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1245
|
+
const indexedChainLatestIndexedBlocks = indexedChains.map(
|
|
1246
|
+
(chain) => chain.latestIndexedBlock.timestamp
|
|
1247
|
+
);
|
|
1248
|
+
const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
|
|
1249
|
+
if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
|
|
1250
|
+
ctx.issues.push({
|
|
1251
|
+
code: "custom",
|
|
1252
|
+
input: snapshot,
|
|
1253
|
+
message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
|
|
1258
|
+
const chains = ctx.value;
|
|
1259
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
|
|
1260
|
+
Array.from(chains.values())
|
|
1261
|
+
);
|
|
1262
|
+
if (hasValidChains === false) {
|
|
1263
|
+
ctx.issues.push({
|
|
1264
|
+
code: "custom",
|
|
1265
|
+
input: chains,
|
|
1266
|
+
message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
|
|
1267
|
+
});
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
|
|
1271
|
+
const chains = ctx.value;
|
|
1272
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
|
|
1273
|
+
Array.from(chains.values())
|
|
1274
|
+
);
|
|
1275
|
+
if (hasValidChains === false) {
|
|
1276
|
+
ctx.issues.push({
|
|
1277
|
+
code: "custom",
|
|
1278
|
+
input: chains,
|
|
1279
|
+
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".`
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
|
|
1284
|
+
const chains = ctx.value;
|
|
1285
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
|
|
1286
|
+
Array.from(chains.values())
|
|
1287
|
+
);
|
|
1288
|
+
if (hasValidChains === false) {
|
|
1289
|
+
ctx.issues.push({
|
|
1290
|
+
code: "custom",
|
|
1291
|
+
input: chains,
|
|
1292
|
+
message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
|
|
1297
|
+
const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
|
|
1298
|
+
const { omnichainIndexingCursor } = omnichainSnapshot;
|
|
1299
|
+
if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
|
|
1300
|
+
console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
|
|
1301
|
+
slowestChainIndexingCursor,
|
|
1302
|
+
omnichainIndexingCursor
|
|
1303
|
+
});
|
|
1304
|
+
ctx.issues.push({
|
|
1305
|
+
code: "custom",
|
|
1306
|
+
input: ctx.value,
|
|
1307
|
+
message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
|
|
1312
|
+
const { snapshotTime, omnichainSnapshot } = ctx.value;
|
|
1313
|
+
const chains = Array.from(omnichainSnapshot.chains.values());
|
|
1314
|
+
const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1315
|
+
const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
|
|
1316
|
+
const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
|
|
1317
|
+
const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
|
|
1318
|
+
const highestKnownBlockTimestamp = Math.max(
|
|
1319
|
+
...startBlockTimestamps,
|
|
1320
|
+
...endBlockTimestamps,
|
|
1321
|
+
...backfillEndBlockTimestamps,
|
|
1322
|
+
...latestKnownBlockTimestamps
|
|
1323
|
+
);
|
|
1324
|
+
if (snapshotTime < highestKnownBlockTimestamp) {
|
|
1325
|
+
ctx.issues.push({
|
|
1326
|
+
code: "custom",
|
|
1327
|
+
input: ctx.value,
|
|
1328
|
+
message: `'snapshotTime' must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
|
|
1333
|
+
const projection = ctx.value;
|
|
1334
|
+
const { snapshot, projectedAt } = projection;
|
|
1335
|
+
if (snapshot.snapshotTime > projectedAt) {
|
|
1336
|
+
ctx.issues.push({
|
|
1337
|
+
code: "custom",
|
|
1338
|
+
input: projection,
|
|
1339
|
+
message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
|
|
1344
|
+
const projection = ctx.value;
|
|
1345
|
+
const { projectedAt, snapshot, worstCaseDistance } = projection;
|
|
1346
|
+
const { omnichainSnapshot } = snapshot;
|
|
1347
|
+
const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
|
|
1348
|
+
if (worstCaseDistance !== expectedWorstCaseDistance) {
|
|
1349
|
+
ctx.issues.push({
|
|
1350
|
+
code: "custom",
|
|
1351
|
+
input: projection,
|
|
1352
|
+
message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1358
|
+
var makeChainIndexingConfigSchema = (valueLabel = "Value") => import_v43.default.discriminatedUnion("configType", [
|
|
1359
|
+
import_v43.default.strictObject({
|
|
1360
|
+
configType: import_v43.default.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1361
|
+
startBlock: makeBlockRefSchema(valueLabel)
|
|
1362
|
+
}),
|
|
1363
|
+
import_v43.default.strictObject({
|
|
1364
|
+
configType: import_v43.default.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1365
|
+
startBlock: makeBlockRefSchema(valueLabel),
|
|
1366
|
+
endBlock: makeBlockRefSchema(valueLabel)
|
|
1367
|
+
})
|
|
1368
|
+
]);
|
|
1369
|
+
var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => import_v43.default.strictObject({
|
|
1370
|
+
chainStatus: import_v43.default.literal(ChainIndexingStatusIds.Queued),
|
|
1371
|
+
config: makeChainIndexingConfigSchema(valueLabel)
|
|
1372
|
+
}).check(invariant_chainSnapshotQueuedBlocks);
|
|
1373
|
+
var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => import_v43.default.strictObject({
|
|
1374
|
+
chainStatus: import_v43.default.literal(ChainIndexingStatusIds.Backfill),
|
|
1375
|
+
config: makeChainIndexingConfigSchema(valueLabel),
|
|
1376
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1377
|
+
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
1378
|
+
}).check(invariant_chainSnapshotBackfillBlocks);
|
|
1379
|
+
var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => import_v43.default.strictObject({
|
|
1380
|
+
chainStatus: import_v43.default.literal(ChainIndexingStatusIds.Completed),
|
|
1381
|
+
config: import_v43.default.strictObject({
|
|
1382
|
+
configType: import_v43.default.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1383
|
+
startBlock: makeBlockRefSchema(valueLabel),
|
|
1384
|
+
endBlock: makeBlockRefSchema(valueLabel)
|
|
1385
|
+
}),
|
|
1386
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel)
|
|
1387
|
+
}).check(invariant_chainSnapshotCompletedBlocks);
|
|
1388
|
+
var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => import_v43.default.strictObject({
|
|
1389
|
+
chainStatus: import_v43.default.literal(ChainIndexingStatusIds.Following),
|
|
1390
|
+
config: import_v43.default.strictObject({
|
|
1391
|
+
configType: import_v43.default.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1392
|
+
startBlock: makeBlockRefSchema(valueLabel)
|
|
1393
|
+
}),
|
|
1394
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1395
|
+
latestKnownBlock: makeBlockRefSchema(valueLabel)
|
|
1396
|
+
}).check(invariant_chainSnapshotFollowingBlocks);
|
|
1397
|
+
var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => import_v43.default.discriminatedUnion("chainStatus", [
|
|
1398
|
+
makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
|
|
1399
|
+
makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1400
|
+
makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1401
|
+
makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1402
|
+
]);
|
|
1403
|
+
var makeChainIndexingStatusesSchema = (valueLabel = "Value") => import_v43.default.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
|
|
1404
|
+
error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
|
|
1405
|
+
}).transform((serializedChainsIndexingStatus) => {
|
|
1406
|
+
const chainsIndexingStatus = /* @__PURE__ */ new Map();
|
|
1407
|
+
for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
|
|
1408
|
+
chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
|
|
1409
|
+
}
|
|
1410
|
+
return chainsIndexingStatus;
|
|
1411
|
+
});
|
|
1412
|
+
var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => import_v43.default.strictObject({
|
|
1413
|
+
omnichainStatus: import_v43.default.literal(OmnichainIndexingStatusIds.Unstarted),
|
|
1414
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
|
|
1415
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1416
|
+
});
|
|
1417
|
+
var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => import_v43.default.strictObject({
|
|
1418
|
+
omnichainStatus: import_v43.default.literal(OmnichainIndexingStatusIds.Backfill),
|
|
1419
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
|
|
1420
|
+
(chains) => chains
|
|
1421
|
+
),
|
|
1422
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1423
|
+
});
|
|
1424
|
+
var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => import_v43.default.strictObject({
|
|
1425
|
+
omnichainStatus: import_v43.default.literal(OmnichainIndexingStatusIds.Completed),
|
|
1426
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
|
|
1427
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1428
|
+
});
|
|
1429
|
+
var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => import_v43.default.strictObject({
|
|
1430
|
+
omnichainStatus: import_v43.default.literal(OmnichainIndexingStatusIds.Following),
|
|
1431
|
+
chains: makeChainIndexingStatusesSchema(valueLabel),
|
|
1432
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1433
|
+
});
|
|
1434
|
+
var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => import_v43.default.discriminatedUnion("omnichainStatus", [
|
|
1435
|
+
makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
|
|
1436
|
+
makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1437
|
+
makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1438
|
+
makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1439
|
+
]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
|
|
1440
|
+
invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
|
|
1441
|
+
).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
|
|
1442
|
+
var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => import_v43.default.strictObject({
|
|
1443
|
+
strategy: import_v43.default.literal(CrossChainIndexingStrategyIds.Omnichain),
|
|
1444
|
+
slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
|
|
1445
|
+
snapshotTime: makeUnixTimestampSchema(valueLabel),
|
|
1446
|
+
omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
|
|
1447
|
+
}).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
|
|
1448
|
+
var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => import_v43.default.discriminatedUnion("strategy", [
|
|
1449
|
+
makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
|
|
1450
|
+
]);
|
|
1451
|
+
var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => import_v43.default.strictObject({
|
|
1452
|
+
projectedAt: makeUnixTimestampSchema(valueLabel),
|
|
1453
|
+
worstCaseDistance: makeDurationSchema(valueLabel),
|
|
1454
|
+
snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
|
|
1455
|
+
}).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
|
|
1456
|
+
|
|
1457
|
+
// src/ensindexer/config/zod-schemas.ts
|
|
1458
|
+
var import_v44 = __toESM(require("zod/v4"), 1);
|
|
1459
|
+
|
|
1460
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
1461
|
+
var import_datasources3 = require("@ensnode/datasources");
|
|
1462
|
+
|
|
1463
|
+
// src/ensindexer/config/types.ts
|
|
1464
|
+
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
1465
|
+
PluginName2["Subgraph"] = "subgraph";
|
|
1466
|
+
PluginName2["Basenames"] = "basenames";
|
|
1467
|
+
PluginName2["Lineanames"] = "lineanames";
|
|
1468
|
+
PluginName2["ThreeDNS"] = "threedns";
|
|
1469
|
+
PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
|
|
1470
|
+
PluginName2["Registrars"] = "registrars";
|
|
1471
|
+
PluginName2["TokenScope"] = "tokenscope";
|
|
1472
|
+
return PluginName2;
|
|
1473
|
+
})(PluginName || {});
|
|
1474
|
+
|
|
1475
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
1476
|
+
function isSubgraphCompatible(config) {
|
|
1477
|
+
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
1478
|
+
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
1479
|
+
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
1480
|
+
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === import_datasources3.ENSNamespaceIds.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
1481
|
+
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
// src/ensindexer/config/validations.ts
|
|
1485
|
+
function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
|
|
1486
|
+
const versionInfo = ctx.value;
|
|
1487
|
+
if (versionInfo.ensDb !== versionInfo.ensIndexer) {
|
|
1488
|
+
ctx.issues.push({
|
|
1489
|
+
code: "custom",
|
|
1490
|
+
input: versionInfo,
|
|
1491
|
+
message: "`ensDb` version must be same as `ensIndexer` version"
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
// src/ensindexer/config/zod-schemas.ts
|
|
1497
|
+
var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => import_v44.default.array(makeChainIdSchema(valueLabel), {
|
|
1498
|
+
error: `${valueLabel} must be an array.`
|
|
1499
|
+
}).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
|
|
1500
|
+
var makePluginsListSchema = (valueLabel = "Plugins") => import_v44.default.array(import_v44.default.string(), {
|
|
1501
|
+
error: `${valueLabel} must be a list of strings.`
|
|
1502
|
+
}).min(1, {
|
|
1503
|
+
error: `${valueLabel} must be a list of strings with at least one string value`
|
|
1504
|
+
}).refine((arr) => arr.length === uniq(arr).length, {
|
|
1505
|
+
error: `${valueLabel} cannot contain duplicate values.`
|
|
1506
|
+
});
|
|
1507
|
+
var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => import_v44.default.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
|
|
1508
|
+
error: `${valueLabel} is required and must be a non-empty string.`
|
|
1509
|
+
});
|
|
1510
|
+
var makeLabelSetIdSchema = (valueLabel) => {
|
|
1511
|
+
return import_v44.default.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-]+$/, {
|
|
1512
|
+
error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
|
|
1513
|
+
});
|
|
1514
|
+
};
|
|
1515
|
+
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
1516
|
+
return import_v44.default.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
1517
|
+
};
|
|
1518
|
+
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
1519
|
+
let valueLabelLabelSetId = valueLabel;
|
|
1520
|
+
let valueLabelLabelSetVersion = valueLabel;
|
|
1521
|
+
if (valueLabel === "LABEL_SET") {
|
|
1522
|
+
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
1523
|
+
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
1524
|
+
} else {
|
|
1525
|
+
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
1526
|
+
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
1527
|
+
}
|
|
1528
|
+
return import_v44.default.object({
|
|
1529
|
+
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
1530
|
+
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
1531
|
+
});
|
|
1532
|
+
};
|
|
1533
|
+
var makeNonEmptyStringSchema = (valueLabel = "Value") => import_v44.default.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
1534
|
+
var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => import_v44.default.strictObject(
|
|
1535
|
+
{
|
|
1536
|
+
nodejs: makeNonEmptyStringSchema(),
|
|
1537
|
+
ponder: makeNonEmptyStringSchema(),
|
|
1538
|
+
ensDb: makeNonEmptyStringSchema(),
|
|
1539
|
+
ensIndexer: makeNonEmptyStringSchema(),
|
|
1540
|
+
ensNormalize: makeNonEmptyStringSchema(),
|
|
1541
|
+
ensRainbow: makeNonEmptyStringSchema(),
|
|
1542
|
+
ensRainbowSchema: makePositiveIntegerSchema()
|
|
1543
|
+
},
|
|
1544
|
+
{
|
|
1545
|
+
error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
|
|
1546
|
+
}
|
|
1547
|
+
).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
|
|
1548
|
+
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
1549
|
+
const { value: config } = ctx;
|
|
1550
|
+
if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
|
|
1551
|
+
ctx.issues.push({
|
|
1552
|
+
code: "custom",
|
|
1553
|
+
input: config,
|
|
1554
|
+
message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
|
|
1555
|
+
});
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => import_v44.default.object({
|
|
1559
|
+
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
1560
|
+
indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
|
|
1561
|
+
isSubgraphCompatible: import_v44.default.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
1562
|
+
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
1563
|
+
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
1564
|
+
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
1565
|
+
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
1566
|
+
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
1567
|
+
|
|
1568
|
+
// src/shared/config/build-rpc-urls.ts
|
|
1569
|
+
var import_chains = require("viem/chains");
|
|
1570
|
+
|
|
1571
|
+
// src/shared/config/rpc-configs-from-env.ts
|
|
1572
|
+
var import_datasources4 = require("@ensnode/datasources");
|
|
1573
|
+
|
|
1574
|
+
// src/shared/config/validatons.ts
|
|
1575
|
+
var import_datasources5 = require("@ensnode/datasources");
|
|
1576
|
+
function invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL(ctx) {
|
|
1577
|
+
const endpoints = ctx.value;
|
|
1578
|
+
const httpEndpoints = endpoints.filter(isHttpProtocol);
|
|
1579
|
+
if (httpEndpoints.length < 1) {
|
|
1580
|
+
ctx.issues.push({
|
|
1581
|
+
code: "custom",
|
|
1582
|
+
input: endpoints,
|
|
1583
|
+
message: `RPC endpoint configuration for a chain must include at least one http/https protocol URL.`
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
function invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL(ctx) {
|
|
1588
|
+
const endpoints = ctx.value;
|
|
1589
|
+
const wsEndpoints = endpoints.filter(isWebSocketProtocol);
|
|
1590
|
+
if (wsEndpoints.length > 1) {
|
|
1591
|
+
ctx.issues.push({
|
|
1592
|
+
code: "custom",
|
|
1593
|
+
input: endpoints,
|
|
1594
|
+
message: `RPC endpoint configuration for a chain must include at most one websocket (ws/wss) protocol URL.`
|
|
1595
|
+
});
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
// src/shared/config/zod-schemas.ts
|
|
1600
|
+
var import_v45 = require("zod/v4");
|
|
1601
|
+
var import_datasources6 = require("@ensnode/datasources");
|
|
1602
|
+
var DatabaseSchemaNameSchema = import_v45.z.string({
|
|
1603
|
+
error: "DATABASE_SCHEMA is required."
|
|
1604
|
+
}).trim().min(1, {
|
|
1605
|
+
error: "DATABASE_SCHEMA is required and cannot be an empty string."
|
|
1606
|
+
});
|
|
1607
|
+
var RpcConfigSchema = import_v45.z.string().transform((val) => val.split(",")).pipe(import_v45.z.array(makeUrlSchema("RPC URL"))).check(invariant_rpcEndpointConfigIncludesAtLeastOneHTTPProtocolURL).check(invariant_rpcEndpointConfigIncludesAtMostOneWebSocketsProtocolURL);
|
|
1608
|
+
var RpcConfigsSchema = import_v45.z.record(makeChainIdStringSchema("RPC URL"), RpcConfigSchema, {
|
|
1609
|
+
error: "Chains configuration must be an object mapping valid chain IDs to their configs."
|
|
1610
|
+
}).transform((records) => {
|
|
1611
|
+
const rpcConfigs = /* @__PURE__ */ new Map();
|
|
1612
|
+
for (const [chainIdString, rpcConfig] of Object.entries(records)) {
|
|
1613
|
+
const httpRPCs = rpcConfig.filter(isHttpProtocol);
|
|
1614
|
+
const websocketRPC = rpcConfig.find(isWebSocketProtocol);
|
|
1615
|
+
rpcConfigs.set(deserializeChainId(chainIdString), {
|
|
1616
|
+
httpRPCs,
|
|
1617
|
+
websocketRPC
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
return rpcConfigs;
|
|
1621
|
+
});
|
|
1622
|
+
var EnsIndexerUrlSchema = makeUrlSchema("ENSINDEXER_URL");
|
|
1623
|
+
var ENSNamespaceSchema = import_v45.z.enum(import_datasources6.ENSNamespaceIds, {
|
|
1624
|
+
error: ({ input }) => `Invalid NAMESPACE. Got '${input}', but supported ENS namespaces are: ${Object.keys(import_datasources6.ENSNamespaceIds).join(", ")}`
|
|
1625
|
+
});
|
|
1626
|
+
var PortSchema = import_v45.z.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();
|
|
1627
|
+
var TheGraphApiKeySchema = import_v45.z.string().optional();
|
|
1628
|
+
|
|
1629
|
+
// src/shared/datasources-with-resolvers.ts
|
|
1630
|
+
var import_datasources7 = require("@ensnode/datasources");
|
|
1631
|
+
var DATASOURCE_NAMES_WITH_RESOLVERS = [
|
|
1632
|
+
import_datasources7.DatasourceNames.ENSRoot,
|
|
1633
|
+
import_datasources7.DatasourceNames.Basenames,
|
|
1634
|
+
import_datasources7.DatasourceNames.Lineanames,
|
|
1635
|
+
import_datasources7.DatasourceNames.ThreeDNSOptimism,
|
|
1636
|
+
import_datasources7.DatasourceNames.ThreeDNSBase
|
|
1637
|
+
];
|
|
1638
|
+
|
|
1639
|
+
// src/shared/log-level.ts
|
|
1640
|
+
var import_v46 = require("zod/v4");
|
|
1641
|
+
var LogLevelSchema = import_v46.z.enum(["fatal", "error", "warn", "info", "debug", "trace", "silent"]);
|
|
1642
|
+
|
|
1643
|
+
// src/shared/protocol-acceleration/interpret-record-values.ts
|
|
1644
|
+
var import_viem10 = require("viem");
|
|
1645
|
+
|
|
1646
|
+
// ../ens-referrals/src/referrer.ts
|
|
1647
|
+
var import_viem11 = require("viem");
|
|
1648
|
+
var ENCODED_REFERRER_BYTE_OFFSET = 12;
|
|
1649
|
+
var ENCODED_REFERRER_BYTE_LENGTH = 32;
|
|
1650
|
+
var encodedReferrerPadding = (0, import_viem11.pad)("0x", {
|
|
1651
|
+
size: ENCODED_REFERRER_BYTE_OFFSET,
|
|
1652
|
+
dir: "left"
|
|
1653
|
+
});
|
|
1654
|
+
var zeroEncodedReferrer = (0, import_viem11.pad)("0x", {
|
|
1655
|
+
size: ENCODED_REFERRER_BYTE_LENGTH,
|
|
1656
|
+
dir: "left"
|
|
1657
|
+
});
|
|
1658
|
+
function decodeEncodedReferrer(encodedReferrer) {
|
|
1659
|
+
if ((0, import_viem11.size)(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
|
|
1660
|
+
throw new Error(
|
|
1661
|
+
`Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
|
|
1662
|
+
);
|
|
1663
|
+
}
|
|
1664
|
+
const padding = (0, import_viem11.slice)(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
|
|
1665
|
+
if (padding !== encodedReferrerPadding) {
|
|
1666
|
+
return import_viem11.zeroAddress;
|
|
1667
|
+
}
|
|
1668
|
+
const decodedReferrer = (0, import_viem11.slice)(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
|
|
1669
|
+
try {
|
|
1670
|
+
return (0, import_viem11.getAddress)(decodedReferrer);
|
|
1671
|
+
} catch {
|
|
1672
|
+
throw new Error(`Decoded referrer value must be a valid EVM address.`);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
// src/registrars/zod-schemas.ts
|
|
1677
|
+
var import_v47 = __toESM(require("zod/v4"), 1);
|
|
1678
|
+
|
|
1679
|
+
// src/registrars/subregistry.ts
|
|
1680
|
+
function serializeSubregistry(subregistry) {
|
|
1681
|
+
return {
|
|
1682
|
+
subregistryId: serializeAccountId(subregistry.subregistryId),
|
|
1683
|
+
node: subregistry.node
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
// src/registrars/registration-lifecycle.ts
|
|
1688
|
+
function serializeRegistrationLifecycle(registrationLifecycle) {
|
|
1689
|
+
return {
|
|
1690
|
+
subregistry: serializeSubregistry(registrationLifecycle.subregistry),
|
|
1691
|
+
node: registrationLifecycle.node,
|
|
1692
|
+
expiresAt: registrationLifecycle.expiresAt
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
// src/registrars/registrar-action.ts
|
|
1697
|
+
var RegistrarActionTypes = {
|
|
1698
|
+
Registration: "registration",
|
|
1699
|
+
Renewal: "renewal"
|
|
1700
|
+
};
|
|
1701
|
+
function isRegistrarActionPricingAvailable(registrarActionPricing) {
|
|
1702
|
+
const { baseCost, premium, total } = registrarActionPricing;
|
|
1703
|
+
return baseCost !== null && premium !== null && total !== null;
|
|
1704
|
+
}
|
|
1705
|
+
function isRegistrarActionReferralAvailable(registrarActionReferral) {
|
|
1706
|
+
const { encodedReferrer, decodedReferrer } = registrarActionReferral;
|
|
1707
|
+
return encodedReferrer !== null && decodedReferrer !== null;
|
|
1708
|
+
}
|
|
1709
|
+
function serializeRegistrarActionPricing(pricing) {
|
|
1710
|
+
if (isRegistrarActionPricingAvailable(pricing)) {
|
|
1711
|
+
return {
|
|
1712
|
+
baseCost: serializePriceEth(pricing.baseCost),
|
|
1713
|
+
premium: serializePriceEth(pricing.premium),
|
|
1714
|
+
total: serializePriceEth(pricing.total)
|
|
1715
|
+
};
|
|
1716
|
+
}
|
|
1717
|
+
return pricing;
|
|
1718
|
+
}
|
|
1719
|
+
function serializeRegistrarAction(registrarAction) {
|
|
1720
|
+
return {
|
|
1721
|
+
id: registrarAction.id,
|
|
1722
|
+
type: registrarAction.type,
|
|
1723
|
+
incrementalDuration: registrarAction.incrementalDuration,
|
|
1724
|
+
registrant: registrarAction.registrant,
|
|
1725
|
+
registrationLifecycle: serializeRegistrationLifecycle(registrarAction.registrationLifecycle),
|
|
1726
|
+
pricing: serializeRegistrarActionPricing(registrarAction.pricing),
|
|
1727
|
+
referral: registrarAction.referral,
|
|
1728
|
+
block: registrarAction.block,
|
|
1729
|
+
transactionHash: registrarAction.transactionHash,
|
|
1730
|
+
eventIds: registrarAction.eventIds
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
// src/registrars/zod-schemas.ts
|
|
1735
|
+
var makeSubregistrySchema = (valueLabel = "Subregistry") => import_v47.default.object({
|
|
1736
|
+
subregistryId: makeSerializedAccountIdSchema(`${valueLabel} Subregistry ID`),
|
|
1737
|
+
node: makeNodeSchema(`${valueLabel} Node`)
|
|
1738
|
+
});
|
|
1739
|
+
var makeRegistrationLifecycleSchema = (valueLabel = "Registration Lifecycle") => import_v47.default.object({
|
|
1740
|
+
subregistry: makeSubregistrySchema(`${valueLabel} Subregistry`),
|
|
1741
|
+
node: makeNodeSchema(`${valueLabel} Node`),
|
|
1742
|
+
expiresAt: makeUnixTimestampSchema(`${valueLabel} Expires at`)
|
|
1743
|
+
});
|
|
1744
|
+
function invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium(ctx) {
|
|
1745
|
+
const { baseCost, premium, total } = ctx.value;
|
|
1746
|
+
const actualTotal = addPrices(baseCost, premium);
|
|
1747
|
+
if (!isPriceEqual(actualTotal, total)) {
|
|
1748
|
+
ctx.issues.push({
|
|
1749
|
+
code: "custom",
|
|
1750
|
+
input: ctx.value,
|
|
1751
|
+
message: `'total' must be equal to the sum of 'baseCost' and 'premium'`
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
var makeRegistrarActionPricingSchema = (valueLabel = "Registrar Action Pricing") => import_v47.default.union([
|
|
1756
|
+
// pricing available
|
|
1757
|
+
import_v47.default.object({
|
|
1758
|
+
baseCost: makePriceEthSchema(`${valueLabel} Base Cost`),
|
|
1759
|
+
premium: makePriceEthSchema(`${valueLabel} Premium`),
|
|
1760
|
+
total: makePriceEthSchema(`${valueLabel} Total`)
|
|
1761
|
+
}).check(invariant_registrarActionPricingTotalIsSumOfBaseCostAndPremium).transform((v) => v),
|
|
1762
|
+
// pricing unknown
|
|
1763
|
+
import_v47.default.object({
|
|
1764
|
+
baseCost: import_v47.default.null(),
|
|
1765
|
+
premium: import_v47.default.null(),
|
|
1766
|
+
total: import_v47.default.null()
|
|
1767
|
+
}).transform((v) => v)
|
|
1768
|
+
]);
|
|
1769
|
+
function invariant_registrarActionDecodedReferrerBasedOnRawReferrer(ctx) {
|
|
1770
|
+
const { encodedReferrer, decodedReferrer } = ctx.value;
|
|
1771
|
+
try {
|
|
1772
|
+
const expectedDecodedReferrer = decodeEncodedReferrer(encodedReferrer).toLowerCase();
|
|
1773
|
+
if (decodedReferrer !== expectedDecodedReferrer) {
|
|
1774
|
+
ctx.issues.push({
|
|
1775
|
+
code: "custom",
|
|
1776
|
+
input: ctx.value,
|
|
1777
|
+
message: `'decodedReferrer' must be based on 'encodedReferrer'`
|
|
1778
|
+
});
|
|
1779
|
+
}
|
|
1780
|
+
} catch (error) {
|
|
1781
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1782
|
+
ctx.issues.push({
|
|
1783
|
+
code: "custom",
|
|
1784
|
+
input: ctx.value,
|
|
1785
|
+
message: errorMessage
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
var makeRegistrarActionReferralSchema = (valueLabel = "Registrar Action Referral") => import_v47.default.union([
|
|
1790
|
+
// referral available
|
|
1791
|
+
import_v47.default.object({
|
|
1792
|
+
encodedReferrer: makeHexStringSchema(
|
|
1793
|
+
{ bytesCount: ENCODED_REFERRER_BYTE_LENGTH },
|
|
1794
|
+
`${valueLabel} Encoded Referrer`
|
|
1795
|
+
),
|
|
1796
|
+
decodedReferrer: makeLowercaseAddressSchema(`${valueLabel} Decoded Referrer`)
|
|
1797
|
+
}).check(invariant_registrarActionDecodedReferrerBasedOnRawReferrer),
|
|
1798
|
+
// referral not applicable
|
|
1799
|
+
import_v47.default.object({
|
|
1800
|
+
encodedReferrer: import_v47.default.null(),
|
|
1801
|
+
decodedReferrer: import_v47.default.null()
|
|
1802
|
+
})
|
|
1803
|
+
]);
|
|
1804
|
+
function invariant_eventIdsInitialElementIsTheActionId(ctx) {
|
|
1805
|
+
const { id, eventIds } = ctx.value;
|
|
1806
|
+
if (eventIds[0] !== id) {
|
|
1807
|
+
ctx.issues.push({
|
|
1808
|
+
code: "custom",
|
|
1809
|
+
input: ctx.value,
|
|
1810
|
+
message: "The initial element of `eventIds` must be the `id` value"
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
var EventIdSchema = import_v47.default.string().nonempty();
|
|
1815
|
+
var EventIdsSchema = import_v47.default.array(EventIdSchema).min(1).transform((v) => v);
|
|
1816
|
+
var makeBaseRegistrarActionSchema = (valueLabel = "Base Registrar Action") => import_v47.default.object({
|
|
1817
|
+
id: EventIdSchema,
|
|
1818
|
+
incrementalDuration: makeDurationSchema(`${valueLabel} Incremental Duration`),
|
|
1819
|
+
registrant: makeLowercaseAddressSchema(`${valueLabel} Registrant`),
|
|
1820
|
+
registrationLifecycle: makeRegistrationLifecycleSchema(
|
|
1821
|
+
`${valueLabel} Registration Lifecycle`
|
|
1822
|
+
),
|
|
1823
|
+
pricing: makeRegistrarActionPricingSchema(`${valueLabel} Pricing`),
|
|
1824
|
+
referral: makeRegistrarActionReferralSchema(`${valueLabel} Referral`),
|
|
1825
|
+
block: makeBlockRefSchema(`${valueLabel} Block`),
|
|
1826
|
+
transactionHash: makeTransactionHashSchema(`${valueLabel} Transaction Hash`),
|
|
1827
|
+
eventIds: EventIdsSchema
|
|
1828
|
+
}).check(invariant_eventIdsInitialElementIsTheActionId);
|
|
1829
|
+
var makeRegistrarActionRegistrationSchema = (valueLabel = "Registration ") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
1830
|
+
type: import_v47.default.literal(RegistrarActionTypes.Registration)
|
|
1831
|
+
});
|
|
1832
|
+
var makeRegistrarActionRenewalSchema = (valueLabel = "Renewal") => makeBaseRegistrarActionSchema(valueLabel).extend({
|
|
1833
|
+
type: import_v47.default.literal(RegistrarActionTypes.Renewal)
|
|
1834
|
+
});
|
|
1835
|
+
var makeRegistrarActionSchema = (valueLabel = "Registrar Action") => import_v47.default.discriminatedUnion("type", [
|
|
1836
|
+
makeRegistrarActionRegistrationSchema(`${valueLabel} Registration`),
|
|
1837
|
+
makeRegistrarActionRenewalSchema(`${valueLabel} Renewal`)
|
|
1838
|
+
]);
|
|
1839
|
+
|
|
1840
|
+
// src/api/types.ts
|
|
1841
|
+
var IndexingStatusResponseCodes = {
|
|
1842
|
+
/**
|
|
1843
|
+
* Represents that the indexing status is available.
|
|
1844
|
+
*/
|
|
1845
|
+
Ok: "ok",
|
|
1846
|
+
/**
|
|
1847
|
+
* Represents that the indexing status is unavailable.
|
|
1848
|
+
*/
|
|
1849
|
+
Error: "error"
|
|
1850
|
+
};
|
|
1851
|
+
var RegistrarActionsFilterTypes = {
|
|
1852
|
+
BySubregistryNode: "bySubregistryNode",
|
|
1853
|
+
WithEncodedReferral: "withEncodedReferral"
|
|
1854
|
+
};
|
|
1855
|
+
var RegistrarActionsOrders = {
|
|
1856
|
+
LatestRegistrarActions: "orderBy[timestamp]=desc"
|
|
1857
|
+
};
|
|
1858
|
+
var RegistrarActionsResponseCodes = {
|
|
1859
|
+
/**
|
|
1860
|
+
* Represents that Registrar Actions are available.
|
|
1861
|
+
*/
|
|
1862
|
+
Ok: "ok",
|
|
1863
|
+
/**
|
|
1864
|
+
* Represents that Registrar Actions are unavailable.
|
|
1865
|
+
*/
|
|
1866
|
+
Error: "error"
|
|
1867
|
+
};
|
|
1868
|
+
|
|
1869
|
+
// src/api/zod-schemas.ts
|
|
1870
|
+
var ErrorResponseSchema = import_v48.default.object({
|
|
1871
|
+
message: import_v48.default.string(),
|
|
1872
|
+
details: import_v48.default.optional(import_v48.default.unknown())
|
|
1873
|
+
});
|
|
1874
|
+
var makeIndexingStatusResponseOkSchema = (valueLabel = "Indexing Status Response OK") => import_v48.default.strictObject({
|
|
1875
|
+
responseCode: import_v48.default.literal(IndexingStatusResponseCodes.Ok),
|
|
1876
|
+
realtimeProjection: makeRealtimeIndexingStatusProjectionSchema(valueLabel)
|
|
1877
|
+
});
|
|
1878
|
+
var makeIndexingStatusResponseErrorSchema = (_valueLabel = "Indexing Status Response Error") => import_v48.default.strictObject({
|
|
1879
|
+
responseCode: import_v48.default.literal(IndexingStatusResponseCodes.Error)
|
|
1880
|
+
});
|
|
1881
|
+
var makeIndexingStatusResponseSchema = (valueLabel = "Indexing Status Response") => import_v48.default.discriminatedUnion("responseCode", [
|
|
1882
|
+
makeIndexingStatusResponseOkSchema(valueLabel),
|
|
1883
|
+
makeIndexingStatusResponseErrorSchema(valueLabel)
|
|
1884
|
+
]);
|
|
1885
|
+
function invariant_registrationLifecycleNodeMatchesName(ctx) {
|
|
1886
|
+
const { name, action } = ctx.value;
|
|
1887
|
+
const expectedNode = action.registrationLifecycle.node;
|
|
1888
|
+
const actualNode = (0, import_viem12.namehash)(name);
|
|
1889
|
+
if (actualNode !== expectedNode) {
|
|
1890
|
+
ctx.issues.push({
|
|
1891
|
+
code: "custom",
|
|
1892
|
+
input: ctx.value,
|
|
1893
|
+
message: `The 'action.registrationLifecycle.node' must match namehash of 'name'`
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
var makeNamedRegistrarActionSchema = (valueLabel = "Named Registrar Action") => import_v48.default.object({
|
|
1898
|
+
action: makeRegistrarActionSchema(valueLabel),
|
|
1899
|
+
name: makeReinterpretedNameSchema(valueLabel)
|
|
1900
|
+
}).check(invariant_registrationLifecycleNodeMatchesName);
|
|
1901
|
+
var makeRegistrarActionsResponseOkSchema = (valueLabel = "Registrar Actions Response OK") => import_v48.default.strictObject({
|
|
1902
|
+
responseCode: import_v48.default.literal(RegistrarActionsResponseCodes.Ok),
|
|
1903
|
+
registrarActions: import_v48.default.array(makeNamedRegistrarActionSchema(valueLabel))
|
|
1904
|
+
});
|
|
1905
|
+
var makeRegistrarActionsResponseErrorSchema = (_valueLabel = "Registrar Actions Response Error") => import_v48.default.strictObject({
|
|
1906
|
+
responseCode: import_v48.default.literal(RegistrarActionsResponseCodes.Error),
|
|
1907
|
+
error: ErrorResponseSchema
|
|
1908
|
+
});
|
|
1909
|
+
var makeRegistrarActionsResponseSchema = (valueLabel = "Registrar Actions Response") => import_v48.default.discriminatedUnion("responseCode", [
|
|
1910
|
+
makeRegistrarActionsResponseOkSchema(valueLabel),
|
|
1911
|
+
makeRegistrarActionsResponseErrorSchema(valueLabel)
|
|
1912
|
+
]);
|
|
1913
|
+
|
|
1914
|
+
// src/api/deserialize.ts
|
|
1915
|
+
function deserializeErrorResponse(maybeErrorResponse) {
|
|
1916
|
+
const parsed = ErrorResponseSchema.safeParse(maybeErrorResponse);
|
|
1917
|
+
if (parsed.error) {
|
|
1918
|
+
throw new Error(`Cannot deserialize ErrorResponse:
|
|
1919
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1920
|
+
`);
|
|
1921
|
+
}
|
|
1922
|
+
return parsed.data;
|
|
1923
|
+
}
|
|
1924
|
+
function deserializeIndexingStatusResponse(maybeResponse) {
|
|
1925
|
+
const parsed = makeIndexingStatusResponseSchema().safeParse(maybeResponse);
|
|
1926
|
+
if (parsed.error) {
|
|
1927
|
+
throw new Error(`Cannot deserialize IndexingStatusResponse:
|
|
1928
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1929
|
+
`);
|
|
1930
|
+
}
|
|
1931
|
+
return parsed.data;
|
|
1932
|
+
}
|
|
1933
|
+
function deserializeRegistrarActionsResponse(maybeResponse) {
|
|
1934
|
+
const parsed = makeRegistrarActionsResponseSchema().safeParse(maybeResponse);
|
|
1935
|
+
if (parsed.error) {
|
|
1936
|
+
throw new Error(
|
|
1937
|
+
`Cannot deserialize RegistrarActionsResponse:
|
|
1938
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1939
|
+
`
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
return parsed.data;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
// src/api/registrar-actions/filters.ts
|
|
1946
|
+
function byParentNode(parentNode) {
|
|
1947
|
+
if (typeof parentNode === "undefined") {
|
|
1948
|
+
return void 0;
|
|
1949
|
+
}
|
|
1950
|
+
return {
|
|
1951
|
+
filterType: RegistrarActionsFilterTypes.BySubregistryNode,
|
|
1952
|
+
value: parentNode
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
function withReferral(withReferral2) {
|
|
1956
|
+
if (!withReferral2) {
|
|
1957
|
+
return void 0;
|
|
1958
|
+
}
|
|
1959
|
+
return {
|
|
1960
|
+
filterType: RegistrarActionsFilterTypes.WithEncodedReferral
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
var registrarActionsFilter = {
|
|
1964
|
+
byParentNode,
|
|
1965
|
+
withReferral
|
|
1966
|
+
};
|
|
1967
|
+
|
|
1968
|
+
// src/ensindexer/config/deserialize.ts
|
|
1969
|
+
var import_v410 = require("zod/v4");
|
|
1970
|
+
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
1971
|
+
const schema = makeENSIndexerPublicConfigSchema(valueLabel);
|
|
1972
|
+
const parsed = schema.safeParse(maybeConfig);
|
|
1973
|
+
if (parsed.error) {
|
|
1974
|
+
throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
|
|
1975
|
+
${(0, import_v410.prettifyError)(parsed.error)}
|
|
1976
|
+
`);
|
|
1977
|
+
}
|
|
1978
|
+
return parsed.data;
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
// src/ensindexer/config/label-utils.ts
|
|
1982
|
+
var import_viem13 = require("viem");
|
|
1983
|
+
function labelHashToBytes(labelHash) {
|
|
1984
|
+
try {
|
|
1985
|
+
if (labelHash.length !== 66) {
|
|
1986
|
+
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
1987
|
+
}
|
|
1988
|
+
if (labelHash !== labelHash.toLowerCase()) {
|
|
1989
|
+
throw new Error("Labelhash must be in lowercase");
|
|
1990
|
+
}
|
|
1991
|
+
if (!labelHash.startsWith("0x")) {
|
|
1992
|
+
throw new Error("Labelhash must be 0x-prefixed");
|
|
1993
|
+
}
|
|
1994
|
+
const bytes = (0, import_viem13.hexToBytes)(labelHash);
|
|
1995
|
+
if (bytes.length !== 32) {
|
|
1996
|
+
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
1997
|
+
}
|
|
1998
|
+
return bytes;
|
|
1999
|
+
} catch (e) {
|
|
2000
|
+
if (e instanceof Error) {
|
|
2001
|
+
throw e;
|
|
2002
|
+
}
|
|
2003
|
+
throw new Error("Invalid hex format");
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
// src/ensindexer/config/labelset-utils.ts
|
|
2008
|
+
function buildLabelSetId(maybeLabelSetId) {
|
|
2009
|
+
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
2010
|
+
}
|
|
2011
|
+
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
2012
|
+
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
2013
|
+
}
|
|
2014
|
+
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
2015
|
+
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
2016
|
+
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
2017
|
+
}
|
|
2018
|
+
return { labelSetId, labelSetVersion };
|
|
2019
|
+
}
|
|
2020
|
+
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
2021
|
+
if (clientSet.labelSetId === void 0) {
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
2025
|
+
throw new Error(
|
|
2026
|
+
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
2027
|
+
);
|
|
2028
|
+
}
|
|
2029
|
+
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
2030
|
+
throw new Error(
|
|
2031
|
+
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
2032
|
+
);
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
// src/ensindexer/config/parsing.ts
|
|
2037
|
+
function parseNonNegativeInteger(maybeNumber) {
|
|
2038
|
+
const trimmed = maybeNumber.trim();
|
|
2039
|
+
if (!trimmed) {
|
|
2040
|
+
throw new Error("Input cannot be empty");
|
|
2041
|
+
}
|
|
2042
|
+
if (trimmed === "-0") {
|
|
2043
|
+
throw new Error("Negative zero is not a valid non-negative integer");
|
|
2044
|
+
}
|
|
2045
|
+
const num = Number(maybeNumber);
|
|
2046
|
+
if (Number.isNaN(num)) {
|
|
2047
|
+
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
2048
|
+
}
|
|
2049
|
+
if (!Number.isFinite(num)) {
|
|
2050
|
+
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
2051
|
+
}
|
|
2052
|
+
if (!Number.isInteger(num)) {
|
|
2053
|
+
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
2054
|
+
}
|
|
2055
|
+
if (num < 0) {
|
|
2056
|
+
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
2057
|
+
}
|
|
2058
|
+
return num;
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
// src/ensindexer/config/serialize.ts
|
|
2062
|
+
function serializeIndexedChainIds(indexedChainIds) {
|
|
2063
|
+
return Array.from(indexedChainIds);
|
|
2064
|
+
}
|
|
2065
|
+
function serializeENSIndexerPublicConfig(config) {
|
|
2066
|
+
const {
|
|
2067
|
+
labelSet,
|
|
2068
|
+
indexedChainIds,
|
|
2069
|
+
databaseSchemaName,
|
|
2070
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
2071
|
+
namespace,
|
|
2072
|
+
plugins,
|
|
2073
|
+
versionInfo
|
|
2074
|
+
} = config;
|
|
2075
|
+
return {
|
|
2076
|
+
labelSet,
|
|
2077
|
+
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
2078
|
+
databaseSchemaName,
|
|
2079
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
2080
|
+
namespace,
|
|
2081
|
+
plugins,
|
|
2082
|
+
versionInfo
|
|
2083
|
+
};
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
// src/ensindexer/indexing-status/deserialize.ts
|
|
2087
|
+
var import_v411 = require("zod/v4");
|
|
2088
|
+
function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
2089
|
+
const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
|
|
2090
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
2091
|
+
if (parsed.error) {
|
|
2092
|
+
throw new Error(
|
|
2093
|
+
`Cannot deserialize into ChainIndexingStatusSnapshot:
|
|
2094
|
+
${(0, import_v411.prettifyError)(parsed.error)}
|
|
2095
|
+
`
|
|
2096
|
+
);
|
|
2097
|
+
}
|
|
2098
|
+
return parsed.data;
|
|
2099
|
+
}
|
|
2100
|
+
function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
2101
|
+
const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
|
|
2102
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
2103
|
+
if (parsed.error) {
|
|
2104
|
+
throw new Error(
|
|
2105
|
+
`Cannot deserialize into OmnichainIndexingStatusSnapshot:
|
|
2106
|
+
${(0, import_v411.prettifyError)(parsed.error)}
|
|
2107
|
+
`
|
|
2108
|
+
);
|
|
2109
|
+
}
|
|
2110
|
+
return parsed.data;
|
|
2111
|
+
}
|
|
2112
|
+
function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
2113
|
+
const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
|
|
2114
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
2115
|
+
if (parsed.error) {
|
|
2116
|
+
throw new Error(
|
|
2117
|
+
`Cannot deserialize into CrossChainIndexingStatusSnapshot:
|
|
2118
|
+
${(0, import_v411.prettifyError)(parsed.error)}
|
|
2119
|
+
`
|
|
2120
|
+
);
|
|
2121
|
+
}
|
|
2122
|
+
return parsed.data;
|
|
2123
|
+
}
|
|
2124
|
+
function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
|
|
2125
|
+
const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
|
|
2126
|
+
const parsed = schema.safeParse(maybeProjection);
|
|
2127
|
+
if (parsed.error) {
|
|
2128
|
+
throw new Error(
|
|
2129
|
+
`Cannot deserialize into RealtimeIndexingStatusProjection:
|
|
2130
|
+
${(0, import_v411.prettifyError)(parsed.error)}
|
|
2131
|
+
`
|
|
2132
|
+
);
|
|
2133
|
+
}
|
|
2134
|
+
return parsed.data;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
// src/ensindexer/indexing-status/projection.ts
|
|
2138
|
+
function createRealtimeIndexingStatusProjection(snapshot, now) {
|
|
2139
|
+
const projectedAt = Math.max(now, snapshot.snapshotTime);
|
|
2140
|
+
return {
|
|
2141
|
+
projectedAt,
|
|
2142
|
+
worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
|
|
2143
|
+
snapshot
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
// src/ensindexer/indexing-status/serialize.ts
|
|
2148
|
+
function serializeCrossChainIndexingStatusSnapshotOmnichain({
|
|
2149
|
+
strategy,
|
|
2150
|
+
slowestChainIndexingCursor,
|
|
2151
|
+
snapshotTime,
|
|
2152
|
+
omnichainSnapshot
|
|
2153
|
+
}) {
|
|
2154
|
+
return {
|
|
2155
|
+
strategy,
|
|
2156
|
+
slowestChainIndexingCursor,
|
|
2157
|
+
snapshotTime,
|
|
2158
|
+
omnichainSnapshot: serializeOmnichainIndexingStatusSnapshot(omnichainSnapshot)
|
|
2159
|
+
};
|
|
2160
|
+
}
|
|
2161
|
+
function serializeRealtimeIndexingStatusProjection(indexingProjection) {
|
|
2162
|
+
return {
|
|
2163
|
+
projectedAt: indexingProjection.projectedAt,
|
|
2164
|
+
worstCaseDistance: indexingProjection.worstCaseDistance,
|
|
2165
|
+
snapshot: serializeCrossChainIndexingStatusSnapshotOmnichain(indexingProjection.snapshot)
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
function serializeChainIndexingSnapshots(chains) {
|
|
2169
|
+
const serializedSnapshots = {};
|
|
2170
|
+
for (const [chainId, snapshot] of chains.entries()) {
|
|
2171
|
+
serializedSnapshots[serializeChainId(chainId)] = snapshot;
|
|
2172
|
+
}
|
|
2173
|
+
return serializedSnapshots;
|
|
2174
|
+
}
|
|
2175
|
+
function serializeOmnichainIndexingStatusSnapshot(indexingStatus) {
|
|
2176
|
+
switch (indexingStatus.omnichainStatus) {
|
|
2177
|
+
case OmnichainIndexingStatusIds.Unstarted:
|
|
2178
|
+
return {
|
|
2179
|
+
omnichainStatus: OmnichainIndexingStatusIds.Unstarted,
|
|
2180
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
2181
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
2182
|
+
};
|
|
2183
|
+
case OmnichainIndexingStatusIds.Backfill:
|
|
2184
|
+
return {
|
|
2185
|
+
omnichainStatus: OmnichainIndexingStatusIds.Backfill,
|
|
2186
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
2187
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
2188
|
+
};
|
|
2189
|
+
case OmnichainIndexingStatusIds.Completed: {
|
|
2190
|
+
return {
|
|
2191
|
+
omnichainStatus: OmnichainIndexingStatusIds.Completed,
|
|
2192
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
2193
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2196
|
+
case OmnichainIndexingStatusIds.Following:
|
|
2197
|
+
return {
|
|
2198
|
+
omnichainStatus: OmnichainIndexingStatusIds.Following,
|
|
2199
|
+
chains: serializeChainIndexingSnapshots(indexingStatus.chains),
|
|
2200
|
+
omnichainIndexingCursor: indexingStatus.omnichainIndexingCursor
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
// src/api/registrar-actions/prerequisites.ts
|
|
2206
|
+
var registrarActionsPrerequisites = Object.freeze({
|
|
2207
|
+
/**
|
|
2208
|
+
* Required plugins to enable Registrar Actions API routes.
|
|
2209
|
+
*
|
|
2210
|
+
* 1. `registrars` plugin is required so that data in the `registrarActions`
|
|
2211
|
+
* table is populated.
|
|
2212
|
+
* 2. `subgraph`, `basenames`, and `lineanames` are required to get the data
|
|
2213
|
+
* for the name associated with each registrar action.
|
|
2214
|
+
* 3. In theory not all of `subgraph`, `basenames`, and `lineanames` plugins
|
|
2215
|
+
* might be required. Ex: At least one, but the current logic in
|
|
2216
|
+
* the `registrars` plugin always indexes registrar actions across
|
|
2217
|
+
* Ethnames (subgraph), Basenames, and Lineanames and therefore we need to
|
|
2218
|
+
* ensure each value in the registrar actions table has
|
|
2219
|
+
* an associated record in the domains table.
|
|
2220
|
+
*/
|
|
2221
|
+
requiredPlugins: [
|
|
2222
|
+
"subgraph" /* Subgraph */,
|
|
2223
|
+
"basenames" /* Basenames */,
|
|
2224
|
+
"lineanames" /* Lineanames */,
|
|
2225
|
+
"registrars" /* Registrars */
|
|
2226
|
+
],
|
|
2227
|
+
/**
|
|
2228
|
+
* Check if provided ENSApiPublicConfig supports the Registrar Actions API.
|
|
2229
|
+
*/
|
|
2230
|
+
hasEnsIndexerConfigSupport(config) {
|
|
2231
|
+
return registrarActionsPrerequisites.requiredPlugins.every(
|
|
2232
|
+
(plugin) => config.plugins.includes(plugin)
|
|
2233
|
+
);
|
|
2234
|
+
},
|
|
2235
|
+
/**
|
|
2236
|
+
* Required Indexing Status IDs
|
|
2237
|
+
*
|
|
2238
|
+
* Database indexes are created by the time the omnichain indexing status
|
|
2239
|
+
* is either `completed` or `following`.
|
|
2240
|
+
*/
|
|
2241
|
+
supportedIndexingStatusIds: [
|
|
2242
|
+
OmnichainIndexingStatusIds.Completed,
|
|
2243
|
+
OmnichainIndexingStatusIds.Following
|
|
2244
|
+
],
|
|
2245
|
+
/**
|
|
2246
|
+
* Check if provided indexing status supports the Registrar Actions API.
|
|
2247
|
+
*/
|
|
2248
|
+
hasIndexingStatusSupport(omnichainIndexingStatusId) {
|
|
2249
|
+
return registrarActionsPrerequisites.supportedIndexingStatusIds.some(
|
|
2250
|
+
(supportedIndexingStatusId) => supportedIndexingStatusId === omnichainIndexingStatusId
|
|
2251
|
+
);
|
|
2252
|
+
}
|
|
2253
|
+
});
|
|
2254
|
+
|
|
2255
|
+
// src/registrars/ethnames-subregistry.ts
|
|
2256
|
+
var import_datasources8 = require("@ensnode/datasources");
|
|
2257
|
+
function getEthnamesSubregistryId(namespace) {
|
|
2258
|
+
const datasource = (0, import_datasources8.maybeGetDatasource)(namespace, import_datasources8.DatasourceNames.ENSRoot);
|
|
2259
|
+
if (!datasource) {
|
|
2260
|
+
throw new Error(`Datasource not found for ${namespace} ${import_datasources8.DatasourceNames.ENSRoot}`);
|
|
2261
|
+
}
|
|
2262
|
+
const address = datasource.contracts.BaseRegistrar?.address;
|
|
2263
|
+
if (address === void 0 || Array.isArray(address)) {
|
|
2264
|
+
throw new Error(`BaseRegistrar contract not found or has multiple addresses for ${namespace}`);
|
|
2265
|
+
}
|
|
2266
|
+
return {
|
|
2267
|
+
chainId: datasource.chain.id,
|
|
2268
|
+
address
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
2271
|
+
|
|
2272
|
+
// src/api/serialize.ts
|
|
2273
|
+
function serializeIndexingStatusResponse(response) {
|
|
2274
|
+
switch (response.responseCode) {
|
|
2275
|
+
case IndexingStatusResponseCodes.Ok:
|
|
2276
|
+
return {
|
|
2277
|
+
responseCode: response.responseCode,
|
|
2278
|
+
realtimeProjection: serializeRealtimeIndexingStatusProjection(response.realtimeProjection)
|
|
2279
|
+
};
|
|
2280
|
+
case IndexingStatusResponseCodes.Error:
|
|
2281
|
+
return response;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
function serializeNamedRegistrarAction({
|
|
2285
|
+
action,
|
|
2286
|
+
name
|
|
2287
|
+
}) {
|
|
2288
|
+
return {
|
|
2289
|
+
action: serializeRegistrarAction(action),
|
|
2290
|
+
name
|
|
2291
|
+
};
|
|
2292
|
+
}
|
|
2293
|
+
function serializeRegistrarActionsResponse(response) {
|
|
2294
|
+
switch (response.responseCode) {
|
|
2295
|
+
case RegistrarActionsResponseCodes.Ok:
|
|
2296
|
+
return {
|
|
2297
|
+
responseCode: response.responseCode,
|
|
2298
|
+
registrarActions: response.registrarActions.map(serializeNamedRegistrarAction)
|
|
2299
|
+
};
|
|
2300
|
+
case RegistrarActionsResponseCodes.Error:
|
|
2301
|
+
return response;
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
// src/client-error.ts
|
|
2306
|
+
var ClientError = class _ClientError extends Error {
|
|
2307
|
+
details;
|
|
2308
|
+
constructor(message, details) {
|
|
2309
|
+
super(message);
|
|
2310
|
+
this.name = "ClientError";
|
|
2311
|
+
this.details = details;
|
|
2312
|
+
}
|
|
2313
|
+
static fromErrorResponse({ message, details }) {
|
|
2314
|
+
return new _ClientError(message, details);
|
|
2315
|
+
}
|
|
2316
|
+
};
|
|
2317
|
+
|
|
2318
|
+
// src/ensanalytics/deserialize.ts
|
|
2319
|
+
var import_v413 = require("zod/v4");
|
|
2320
|
+
|
|
2321
|
+
// src/ensanalytics/zod-schemas.ts
|
|
2322
|
+
var import_v412 = __toESM(require("zod/v4"), 1);
|
|
2323
|
+
|
|
2324
|
+
// src/ensanalytics/types.ts
|
|
2325
|
+
var ITEMS_PER_PAGE_DEFAULT = 25;
|
|
2326
|
+
var ITEMS_PER_PAGE_MAX = 100;
|
|
2327
|
+
var PaginatedAggregatedReferrersResponseCodes = {
|
|
2328
|
+
/**
|
|
2329
|
+
* Represents that the aggregated referrers data is available.
|
|
2330
|
+
* @note The response may contain an empty array for the first page if there are no qualified referrers.
|
|
2331
|
+
* When the array is empty, total will be 0, page will be 1, and both hasNext and hasPrev will be false.
|
|
2332
|
+
*/
|
|
2333
|
+
Ok: "ok",
|
|
2334
|
+
/**
|
|
2335
|
+
* Represents that the aggregated referrers data is not available.
|
|
2336
|
+
*/
|
|
2337
|
+
Error: "error"
|
|
2338
|
+
};
|
|
2339
|
+
|
|
2340
|
+
// src/ensanalytics/zod-schemas.ts
|
|
2341
|
+
var makeAggregatedReferrerMetricsSchema = (valueLabel = "AggregatedReferrerMetrics") => import_v412.default.object({
|
|
2342
|
+
referrer: makeLowercaseAddressSchema(`${valueLabel}.referrer`),
|
|
2343
|
+
totalReferrals: makePositiveIntegerSchema(`${valueLabel}.totalReferrals`),
|
|
2344
|
+
totalIncrementalDuration: makeDurationSchema(`${valueLabel}.totalIncrementalDuration`)
|
|
2345
|
+
});
|
|
2346
|
+
var makeAggregatedReferrerMetricsContributionSchema = (valueLabel = "AggregatedReferrerMetricsContribution") => makeAggregatedReferrerMetricsSchema(valueLabel).extend({
|
|
2347
|
+
totalReferralsContribution: import_v412.default.number({
|
|
2348
|
+
error: `${valueLabel}.totalReferralsContribution must be a number`
|
|
2349
|
+
}).min(0, `${valueLabel}.totalReferralsContribution must be >= 0`).max(1, `${valueLabel}.totalReferralsContribution must be <= 1`),
|
|
2350
|
+
totalIncrementalDurationContribution: import_v412.default.number({
|
|
2351
|
+
error: `${valueLabel}.totalIncrementalDurationContribution must be a number`
|
|
2352
|
+
}).min(0, `${valueLabel}.totalIncrementalDurationContribution must be >= 0`).max(1, `${valueLabel}.totalIncrementalDurationContribution must be <= 1`)
|
|
2353
|
+
});
|
|
2354
|
+
var makePaginationParamsSchema = (valueLabel = "PaginationParams") => import_v412.default.object({
|
|
2355
|
+
page: makePositiveIntegerSchema(`${valueLabel}.page`).default(1),
|
|
2356
|
+
itemsPerPage: makePositiveIntegerSchema(`${valueLabel}.itemsPerPage`).max(ITEMS_PER_PAGE_MAX, `${valueLabel}.itemsPerPage must not exceed ${ITEMS_PER_PAGE_MAX}`).default(ITEMS_PER_PAGE_DEFAULT)
|
|
2357
|
+
});
|
|
2358
|
+
var makePaginatedAggregatedReferrersSchema = (valueLabel = "PaginatedAggregatedReferrers") => import_v412.default.object({
|
|
2359
|
+
referrers: import_v412.default.array(
|
|
2360
|
+
makeAggregatedReferrerMetricsContributionSchema(`${valueLabel}.referrers[item]`)
|
|
2361
|
+
),
|
|
2362
|
+
total: makeNonNegativeIntegerSchema(`${valueLabel}.total`),
|
|
2363
|
+
paginationParams: makePaginationParamsSchema(`${valueLabel}.paginationParams`),
|
|
2364
|
+
hasNext: import_v412.default.boolean(),
|
|
2365
|
+
hasPrev: import_v412.default.boolean(),
|
|
2366
|
+
updatedAt: makeUnixTimestampSchema(`${valueLabel}.updatedAt`)
|
|
2367
|
+
}).check((ctx) => {
|
|
2368
|
+
const { paginationParams, hasNext, hasPrev, total } = ctx.value;
|
|
2369
|
+
const expectedHasPrev = paginationParams.page > 1;
|
|
2370
|
+
if (hasPrev !== expectedHasPrev) {
|
|
2371
|
+
ctx.issues.push({
|
|
2372
|
+
code: "custom",
|
|
2373
|
+
message: `${valueLabel}.hasPrev must be ${expectedHasPrev} when page is ${paginationParams.page}`,
|
|
2374
|
+
input: ctx.value
|
|
2375
|
+
});
|
|
2376
|
+
}
|
|
2377
|
+
const endIndex = paginationParams.page * paginationParams.itemsPerPage;
|
|
2378
|
+
const expectedHasNext = endIndex < total;
|
|
2379
|
+
if (hasNext !== expectedHasNext) {
|
|
2380
|
+
ctx.issues.push({
|
|
2381
|
+
code: "custom",
|
|
2382
|
+
message: `${valueLabel}.hasNext must be ${expectedHasNext} when page=${paginationParams.page}, itemsPerPage=${paginationParams.itemsPerPage}, total=${total}`,
|
|
2383
|
+
input: ctx.value
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
});
|
|
2387
|
+
var makePaginatedAggregatedReferrersResponseOkSchema = (valueLabel = "PaginatedAggregatedReferrersResponse") => import_v412.default.object({
|
|
2388
|
+
responseCode: import_v412.default.literal(PaginatedAggregatedReferrersResponseCodes.Ok),
|
|
2389
|
+
data: makePaginatedAggregatedReferrersSchema(`${valueLabel}.data`)
|
|
2390
|
+
});
|
|
2391
|
+
var makePaginatedAggregatedReferrersResponseErrorSchema = (_valueLabel = "PaginatedAggregatedReferrersResponse") => import_v412.default.object({
|
|
2392
|
+
responseCode: import_v412.default.literal(PaginatedAggregatedReferrersResponseCodes.Error),
|
|
2393
|
+
error: import_v412.default.string(),
|
|
2394
|
+
errorMessage: import_v412.default.string()
|
|
2395
|
+
});
|
|
2396
|
+
var makePaginatedAggregatedReferrersResponseSchema = (valueLabel = "PaginatedAggregatedReferrersResponse") => import_v412.default.union([
|
|
2397
|
+
makePaginatedAggregatedReferrersResponseOkSchema(valueLabel),
|
|
2398
|
+
makePaginatedAggregatedReferrersResponseErrorSchema(valueLabel)
|
|
2399
|
+
]);
|
|
2400
|
+
|
|
2401
|
+
// src/ensanalytics/deserialize.ts
|
|
2402
|
+
function deserializePaginatedAggregatedReferrersResponse(maybeResponse, valueLabel) {
|
|
2403
|
+
const schema = makePaginatedAggregatedReferrersResponseSchema(valueLabel);
|
|
2404
|
+
const parsed = schema.safeParse(maybeResponse);
|
|
2405
|
+
if (parsed.error) {
|
|
2406
|
+
throw new Error(
|
|
2407
|
+
`Cannot deserialize PaginatedAggregatedReferrersResponse:
|
|
2408
|
+
${(0, import_v413.prettifyError)(parsed.error)}
|
|
2409
|
+
`
|
|
2410
|
+
);
|
|
2411
|
+
}
|
|
2412
|
+
return parsed.data;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// src/ensanalytics/serialize.ts
|
|
2416
|
+
function serializePaginatedAggregatedReferrersResponse(response) {
|
|
2417
|
+
switch (response.responseCode) {
|
|
2418
|
+
case PaginatedAggregatedReferrersResponseCodes.Ok:
|
|
2419
|
+
return response;
|
|
2420
|
+
case PaginatedAggregatedReferrersResponseCodes.Error:
|
|
2421
|
+
return response;
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
// src/ensapi/config/deserialize.ts
|
|
2426
|
+
var import_v415 = require("zod/v4");
|
|
2427
|
+
|
|
2428
|
+
// src/ensapi/config/zod-schemas.ts
|
|
2429
|
+
var import_v414 = require("zod/v4");
|
|
2430
|
+
var TheGraphCannotFallbackReasonSchema = import_v414.z.enum({
|
|
2431
|
+
NotSubgraphCompatible: "not-subgraph-compatible",
|
|
2432
|
+
NoApiKey: "no-api-key",
|
|
2433
|
+
NoSubgraphUrl: "no-subgraph-url"
|
|
2434
|
+
});
|
|
2435
|
+
var TheGraphFallbackSchema = import_v414.z.strictObject({
|
|
2436
|
+
canFallback: import_v414.z.boolean(),
|
|
2437
|
+
reason: TheGraphCannotFallbackReasonSchema.nullable()
|
|
2438
|
+
});
|
|
2439
|
+
function makeENSApiPublicConfigSchema(valueLabel) {
|
|
2440
|
+
const label = valueLabel ?? "ENSApiPublicConfig";
|
|
2441
|
+
return import_v414.z.strictObject({
|
|
2442
|
+
version: import_v414.z.string().min(1, `${label}.version must be a non-empty string`),
|
|
2443
|
+
theGraphFallback: TheGraphFallbackSchema,
|
|
2444
|
+
ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
// src/ensapi/config/deserialize.ts
|
|
2449
|
+
function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
|
|
2450
|
+
const schema = makeENSApiPublicConfigSchema(valueLabel);
|
|
2451
|
+
try {
|
|
2452
|
+
return schema.parse(maybeConfig);
|
|
2453
|
+
} catch (error) {
|
|
2454
|
+
if (error instanceof import_v415.ZodError) {
|
|
2455
|
+
throw new Error(`Cannot deserialize ENSApiPublicConfig:
|
|
2456
|
+
${(0, import_v415.prettifyError)(error)}
|
|
2457
|
+
`);
|
|
2458
|
+
}
|
|
2459
|
+
throw error;
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
// src/ensapi/config/serialize.ts
|
|
2464
|
+
function serializeENSApiPublicConfig(config) {
|
|
2465
|
+
const { version, theGraphFallback, ensIndexerPublicConfig } = config;
|
|
2466
|
+
return {
|
|
2467
|
+
version,
|
|
2468
|
+
theGraphFallback,
|
|
2469
|
+
ensIndexerPublicConfig: serializeENSIndexerPublicConfig(ensIndexerPublicConfig)
|
|
2470
|
+
};
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
// src/client.ts
|
|
2474
|
+
var DEFAULT_ENSNODE_API_URL = "https://api.alpha.ensnode.io";
|
|
2475
|
+
var ENSNodeClient = class _ENSNodeClient {
|
|
2476
|
+
options;
|
|
2477
|
+
static defaultOptions() {
|
|
2478
|
+
return {
|
|
2479
|
+
url: new URL(DEFAULT_ENSNODE_API_URL)
|
|
2480
|
+
};
|
|
2481
|
+
}
|
|
2482
|
+
constructor(options = {}) {
|
|
2483
|
+
this.options = {
|
|
2484
|
+
..._ENSNodeClient.defaultOptions(),
|
|
2485
|
+
...options
|
|
2486
|
+
};
|
|
2487
|
+
}
|
|
2488
|
+
getOptions() {
|
|
2489
|
+
return Object.freeze({
|
|
2490
|
+
url: new URL(this.options.url.href)
|
|
2491
|
+
});
|
|
2492
|
+
}
|
|
2493
|
+
/**
|
|
2494
|
+
* Resolves records for an ENS name (Forward Resolution).
|
|
2495
|
+
*
|
|
2496
|
+
* The returned `name` field, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
|
|
2497
|
+
* If the name record returned by the resolver is not normalized, `null` is returned as if no name record was set.
|
|
2498
|
+
*
|
|
2499
|
+
* @param name The ENS Name whose records to resolve
|
|
2500
|
+
* @param selection selection of Resolver records
|
|
2501
|
+
* @param options additional options
|
|
2502
|
+
* @param options.accelerate whether to attempt Protocol Acceleration (default false)
|
|
2503
|
+
* @param options.trace whether to include a trace in the response (default false)
|
|
2504
|
+
* @returns ResolveRecordsResponse<SELECTION>
|
|
2505
|
+
* @throws If the request fails or the ENSNode API returns an error response
|
|
2506
|
+
*
|
|
2507
|
+
* @example
|
|
2508
|
+
* ```typescript
|
|
2509
|
+
* const { records } = await client.resolveRecords("jesse.base.eth", {
|
|
2510
|
+
* addresses: [60],
|
|
2511
|
+
* texts: ["avatar", "com.twitter"]
|
|
2512
|
+
* });
|
|
2513
|
+
*
|
|
2514
|
+
* console.log(records);
|
|
2515
|
+
* // {
|
|
2516
|
+
* // addresses: {
|
|
2517
|
+
* // 60: "0xabcd..."
|
|
2518
|
+
* // },
|
|
2519
|
+
* // texts: {
|
|
2520
|
+
* // avatar: "https://example.com/image.jpg",
|
|
2521
|
+
* // "com.twitter": null, // if not set, for example
|
|
2522
|
+
* // }
|
|
2523
|
+
* // }
|
|
2524
|
+
* ```
|
|
2525
|
+
*/
|
|
2526
|
+
async resolveRecords(name, selection, options) {
|
|
2527
|
+
const url = new URL(`/api/resolve/records/${encodeURIComponent(name)}`, this.options.url);
|
|
2528
|
+
if (selection.name) {
|
|
2529
|
+
url.searchParams.set("name", "true");
|
|
2530
|
+
}
|
|
2531
|
+
if (selection.addresses && selection.addresses.length > 0) {
|
|
2532
|
+
url.searchParams.set("addresses", selection.addresses.join(","));
|
|
2533
|
+
}
|
|
2534
|
+
if (selection.texts && selection.texts.length > 0) {
|
|
2535
|
+
url.searchParams.set("texts", selection.texts.join(","));
|
|
2536
|
+
}
|
|
2537
|
+
if (options?.trace) url.searchParams.set("trace", "true");
|
|
2538
|
+
if (options?.accelerate) url.searchParams.set("accelerate", "true");
|
|
2539
|
+
const response = await fetch(url);
|
|
2540
|
+
if (!response.ok) {
|
|
2541
|
+
const error = await response.json();
|
|
2542
|
+
throw ClientError.fromErrorResponse(error);
|
|
2543
|
+
}
|
|
2544
|
+
const data = await response.json();
|
|
2545
|
+
return data;
|
|
2546
|
+
}
|
|
2547
|
+
/**
|
|
2548
|
+
* Resolves the primary name of a specified address (Reverse Resolution) on a specific chain.
|
|
2549
|
+
*
|
|
2550
|
+
* If the chainId-specific Primary Name is not defined, but the `address` specifies a valid
|
|
2551
|
+
* [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name), the Default
|
|
2552
|
+
* Name will be returned. You _may_ query the Default EVM Chain Id (`0`) in order to determine the
|
|
2553
|
+
* `address`'s Default Name directly.
|
|
2554
|
+
*
|
|
2555
|
+
* The returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
|
|
2556
|
+
* If the primary name set for the address is not normalized, `null` is returned as if no primary name was set.
|
|
2557
|
+
*
|
|
2558
|
+
* @param address The Address whose Primary Name to resolve
|
|
2559
|
+
* @param chainId The chain id within which to query the address' ENSIP-19 Multichain Primary Name
|
|
2560
|
+
* @param options additional options
|
|
2561
|
+
* @param options.accelerate whether to attempt Protocol Acceleration (default false)
|
|
2562
|
+
* @param options.trace whether to include a trace in the response (default false)
|
|
2563
|
+
* @returns ResolvePrimaryNameResponse
|
|
2564
|
+
* @throws If the request fails or the ENSNode API returns an error response
|
|
2565
|
+
*
|
|
2566
|
+
* @example
|
|
2567
|
+
* ```typescript
|
|
2568
|
+
* // Resolve the address' Primary Name on Ethereum Mainnet
|
|
2569
|
+
* const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 1);
|
|
2570
|
+
* // name === 'gregskril.eth'
|
|
2571
|
+
*
|
|
2572
|
+
* // Resolve the address' Primary Name on Base
|
|
2573
|
+
* const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 8453);
|
|
2574
|
+
* // name === 'greg.base.eth'
|
|
2575
|
+
*
|
|
2576
|
+
* // Resolve the address' Default Primary Name
|
|
2577
|
+
* const { name } = await client.resolvePrimaryName("0x179A862703a4adfb29896552DF9e307980D19285", 0);
|
|
2578
|
+
* // name === 'gregskril.eth'
|
|
2579
|
+
* ```
|
|
2580
|
+
*/
|
|
2581
|
+
async resolvePrimaryName(address, chainId, options) {
|
|
2582
|
+
const url = new URL(`/api/resolve/primary-name/${address}/${chainId}`, this.options.url);
|
|
2583
|
+
if (options?.trace) url.searchParams.set("trace", "true");
|
|
2584
|
+
if (options?.accelerate) url.searchParams.set("accelerate", "true");
|
|
2585
|
+
const response = await fetch(url);
|
|
2586
|
+
if (!response.ok) {
|
|
2587
|
+
const error = await response.json();
|
|
2588
|
+
throw ClientError.fromErrorResponse(error);
|
|
2589
|
+
}
|
|
2590
|
+
const data = await response.json();
|
|
2591
|
+
return data;
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Resolves the primary names of a specified address across multiple chains.
|
|
2595
|
+
*
|
|
2596
|
+
* For each Primary Name, if the chainId-specific Primary Name is not defined, but the `address`
|
|
2597
|
+
* specifies a valid [ENSIP-19 Default Name](https://docs.ens.domains/ensip/19/#default-primary-name),
|
|
2598
|
+
* the Default Name will be returned. You _may not_ query the Default EVM Chain Id (`0`) directly,
|
|
2599
|
+
* and should rely on the aforementioned per-chain defaulting behavior.
|
|
2600
|
+
*
|
|
2601
|
+
* Each returned Primary Name, if set, is guaranteed to be a [Normalized Name](https://ensnode.io/docs/reference/terminology#normalized-name).
|
|
2602
|
+
* If the primary name set for the address on any chain is not normalized, `null` is returned for
|
|
2603
|
+
* that chain as if no primary name was set.
|
|
2604
|
+
*
|
|
2605
|
+
* @param address The Address whose Primary Names to resolve
|
|
2606
|
+
* @param options additional options
|
|
2607
|
+
* @param options.chainIds The set of chain ids within which to query the address' ENSIP-19
|
|
2608
|
+
* Multichain Primary Name (default: all ENSIP-19 supported chains)
|
|
2609
|
+
* @param options.accelerate whether to attempt Protocol Acceleration (default: true)
|
|
2610
|
+
* @param options.trace whether to include a trace in the response (default: false)
|
|
2611
|
+
* @returns ResolvePrimaryNamesResponse
|
|
2612
|
+
* @throws If the request fails or the ENSNode API returns an error response
|
|
2613
|
+
*
|
|
2614
|
+
* @example
|
|
2615
|
+
* ```typescript
|
|
2616
|
+
* // Resolve the address' Primary Names on all ENSIP-19 supported chain ids
|
|
2617
|
+
* const { names } = await client.resolvePrimaryNames("0x179A862703a4adfb29896552DF9e307980D19285");
|
|
2618
|
+
*
|
|
2619
|
+
* console.log(names);
|
|
2620
|
+
* // {
|
|
2621
|
+
* // "1": "gregskril.eth", // Default Primary Name
|
|
2622
|
+
* // "10": "gregskril.eth", // Default Primary Name
|
|
2623
|
+
* // "8453": "greg.base.eth", // Base-specific Primary Name!
|
|
2624
|
+
* // "42161": "gregskril.eth", // Default Primary Name
|
|
2625
|
+
* // "59144": "gregskril.eth", // Default Primary Name
|
|
2626
|
+
* // "534352": "gregskril.eth" // Default Primary Name
|
|
2627
|
+
* // }
|
|
2628
|
+
*
|
|
2629
|
+
* // Resolve the address' Primary Names on specific chain Ids
|
|
2630
|
+
* const { names } = await client.resolvePrimaryNames("0xabcd...", [1, 8453]);
|
|
2631
|
+
*
|
|
2632
|
+
* console.log(names);
|
|
2633
|
+
* // {
|
|
2634
|
+
* // "1": "gregskril.eth",
|
|
2635
|
+
* // "8453": "greg.base.eth", // base-specific Primary Name!
|
|
2636
|
+
* // }
|
|
2637
|
+
* ```
|
|
2638
|
+
*/
|
|
2639
|
+
async resolvePrimaryNames(address, options) {
|
|
2640
|
+
const url = new URL(`/api/resolve/primary-names/${address}`, this.options.url);
|
|
2641
|
+
if (options?.chainIds) url.searchParams.set("chainIds", options.chainIds.join(","));
|
|
2642
|
+
if (options?.trace) url.searchParams.set("trace", "true");
|
|
2643
|
+
if (options?.accelerate) url.searchParams.set("accelerate", "true");
|
|
2644
|
+
const response = await fetch(url);
|
|
2645
|
+
if (!response.ok) {
|
|
2646
|
+
const error = await response.json();
|
|
2647
|
+
throw ClientError.fromErrorResponse(error);
|
|
2648
|
+
}
|
|
2649
|
+
const data = await response.json();
|
|
2650
|
+
return data;
|
|
2651
|
+
}
|
|
2652
|
+
/**
|
|
2653
|
+
* Fetch ENSNode Config
|
|
2654
|
+
*
|
|
2655
|
+
* Fetch the ENSNode's configuration.
|
|
2656
|
+
*
|
|
2657
|
+
* @returns {ConfigResponse}
|
|
2658
|
+
*
|
|
2659
|
+
* @throws if the ENSNode request fails
|
|
2660
|
+
* @throws if the ENSNode API returns an error response
|
|
2661
|
+
* @throws if the ENSNode response breaks required invariants
|
|
2662
|
+
*/
|
|
2663
|
+
async config() {
|
|
2664
|
+
const url = new URL(`/api/config`, this.options.url);
|
|
2665
|
+
const response = await fetch(url);
|
|
2666
|
+
let responseData;
|
|
2667
|
+
try {
|
|
2668
|
+
responseData = await response.json();
|
|
2669
|
+
} catch {
|
|
2670
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
2671
|
+
}
|
|
2672
|
+
if (!response.ok) {
|
|
2673
|
+
const errorResponse = deserializeErrorResponse(responseData);
|
|
2674
|
+
throw new Error(`Fetching ENSNode Config Failed: ${errorResponse.message}`);
|
|
2675
|
+
}
|
|
2676
|
+
return deserializeENSApiPublicConfig(responseData);
|
|
2677
|
+
}
|
|
2678
|
+
/**
|
|
2679
|
+
* Fetch ENSNode Indexing Status
|
|
2680
|
+
*
|
|
2681
|
+
* @returns {IndexingStatusResponse}
|
|
2682
|
+
*
|
|
2683
|
+
* @throws if the ENSNode request fails
|
|
2684
|
+
* @throws if the ENSNode API returns an error response
|
|
2685
|
+
* @throws if the ENSNode response breaks required invariants
|
|
2686
|
+
*/
|
|
2687
|
+
async indexingStatus() {
|
|
2688
|
+
const url = new URL(`/api/indexing-status`, this.options.url);
|
|
2689
|
+
const response = await fetch(url);
|
|
2690
|
+
let responseData;
|
|
2691
|
+
try {
|
|
2692
|
+
responseData = await response.json();
|
|
2693
|
+
} catch {
|
|
2694
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
2695
|
+
}
|
|
2696
|
+
if (!response.ok) {
|
|
2697
|
+
let errorResponse;
|
|
2698
|
+
try {
|
|
2699
|
+
errorResponse = deserializeErrorResponse(responseData);
|
|
2700
|
+
} catch {
|
|
2701
|
+
console.log("Indexing Status API: handling a known indexing status server error.");
|
|
2702
|
+
}
|
|
2703
|
+
if (typeof errorResponse !== "undefined") {
|
|
2704
|
+
throw new Error(`Fetching ENSNode Indexing Status Failed: ${errorResponse.message}`);
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
return deserializeIndexingStatusResponse(responseData);
|
|
2708
|
+
}
|
|
2709
|
+
/**
|
|
2710
|
+
* Fetch Paginated Aggregated Referrers
|
|
2711
|
+
*
|
|
2712
|
+
* Retrieves a paginated list of aggregated referrer metrics with contribution percentages.
|
|
2713
|
+
* Each referrer's contribution is calculated as a percentage of the grand totals across all referrers.
|
|
2714
|
+
*
|
|
2715
|
+
* @param request - Pagination parameters
|
|
2716
|
+
* @param request.page - The page number to retrieve (1-indexed, default: 1)
|
|
2717
|
+
* @param request.itemsPerPage - Number of items per page (default: 25, max: 100)
|
|
2718
|
+
* @returns {PaginatedAggregatedReferrersResponse}
|
|
2719
|
+
*
|
|
2720
|
+
* @throws if the ENSNode request fails
|
|
2721
|
+
* @throws if the ENSNode API returns an error response
|
|
2722
|
+
* @throws if the ENSNode response breaks required invariants
|
|
2723
|
+
*
|
|
2724
|
+
* @example
|
|
2725
|
+
* ```typescript
|
|
2726
|
+
* // Get first page with default page size (25 items)
|
|
2727
|
+
* const response = await client.getAggregatedReferrers();
|
|
2728
|
+
* if (response.responseCode === 'ok') {
|
|
2729
|
+
* console.log(response.data.referrers);
|
|
2730
|
+
* console.log(`Page ${response.data.paginationParams.page} of ${Math.ceil(response.data.total / response.data.paginationParams.itemsPerPage)}`);
|
|
2731
|
+
* }
|
|
2732
|
+
* ```
|
|
2733
|
+
*
|
|
2734
|
+
* @example
|
|
2735
|
+
* ```typescript
|
|
2736
|
+
* // Get second page with 50 items per page
|
|
2737
|
+
* const response = await client.getAggregatedReferrers({ page: 2, itemsPerPage: 50 });
|
|
2738
|
+
* ```
|
|
2739
|
+
*/
|
|
2740
|
+
async getAggregatedReferrers(request) {
|
|
2741
|
+
const url = new URL(`/ensanalytics/aggregated-referrers`, this.options.url);
|
|
2742
|
+
if (request?.page) url.searchParams.set("page", request.page.toString());
|
|
2743
|
+
if (request?.itemsPerPage)
|
|
2744
|
+
url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
|
|
2745
|
+
const response = await fetch(url);
|
|
2746
|
+
let responseData;
|
|
2747
|
+
try {
|
|
2748
|
+
responseData = await response.json();
|
|
2749
|
+
} catch {
|
|
2750
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
2751
|
+
}
|
|
2752
|
+
return deserializePaginatedAggregatedReferrersResponse(
|
|
2753
|
+
responseData
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Fetch ENSNode Registrar Actions
|
|
2758
|
+
*
|
|
2759
|
+
* @param {RegistrarActionsRequestFilter} request.filter is
|
|
2760
|
+
* an optional request filter configuration.
|
|
2761
|
+
* @param {number} request.limit sets the maximum count of results in the response.
|
|
2762
|
+
* @param {RegistrarActionsRequestOrder} request.order sets the order of
|
|
2763
|
+
* results in the response by field and direction.
|
|
2764
|
+
* @returns {RegistrarActionsResponse}
|
|
2765
|
+
*
|
|
2766
|
+
* @throws if the ENSNode request fails
|
|
2767
|
+
* @throws if the ENSNode API returns an error response
|
|
2768
|
+
* @throws if the ENSNode response breaks required invariants
|
|
2769
|
+
*
|
|
2770
|
+
* @example
|
|
2771
|
+
* ```ts
|
|
2772
|
+
* import {
|
|
2773
|
+
* registrarActionsFilter,,
|
|
2774
|
+
* ENSNodeClient,
|
|
2775
|
+
* } from "@ensnode/ensnode-sdk";
|
|
2776
|
+
* import { namehash } from "viem/ens";
|
|
2777
|
+
*
|
|
2778
|
+
* const client: ENSNodeClient;
|
|
2779
|
+
*
|
|
2780
|
+
* // get latest registrar action records across all indexed subregistries
|
|
2781
|
+
* // NOTE: when no `limit` value is passed,
|
|
2782
|
+
* // the default RESPONSE_ITEMS_PER_PAGE_DEFAULT applies.
|
|
2783
|
+
* const registrarActions = await client.registrarActions();
|
|
2784
|
+
*
|
|
2785
|
+
* // get latest 5 registrar action records across all indexed subregistries
|
|
2786
|
+
* // NOTE: when a `limit` value is passed, it must be lower than or equal to
|
|
2787
|
+
* // the RESPONSE_ITEMS_PER_PAGE_MAX value.
|
|
2788
|
+
* const registrarActions = await client.registrarActions({
|
|
2789
|
+
* limit: 5,
|
|
2790
|
+
* });
|
|
2791
|
+
*
|
|
2792
|
+
* // get latest registrar action records associated with
|
|
2793
|
+
* // subregistry managing `eth` name
|
|
2794
|
+
* await client.registrarActions({
|
|
2795
|
+
* filters: [registrarActionsFilter.byParentNode(namehash('eth'))],
|
|
2796
|
+
* });
|
|
2797
|
+
*
|
|
2798
|
+
* // get latest registrar action records which include referral info
|
|
2799
|
+
* await client.registrarActions({
|
|
2800
|
+
* filters: [registrarActionsFilter.withReferral(true)],
|
|
2801
|
+
* });
|
|
2802
|
+
*
|
|
2803
|
+
* // get latest 10 registrar action records associated with
|
|
2804
|
+
* // subregistry managing `base.eth` name
|
|
2805
|
+
* await client.registrarActions({
|
|
2806
|
+
* filters: [registrarActionsFilter.byParentNode(namehash('base.eth'))],
|
|
2807
|
+
* limit: 10
|
|
2808
|
+
* });
|
|
2809
|
+
* ```
|
|
2810
|
+
*/
|
|
2811
|
+
async registrarActions(request = {}) {
|
|
2812
|
+
const buildUrlPath = (filters) => {
|
|
2813
|
+
const bySubregistryNodeFilter = filters?.find(
|
|
2814
|
+
(f) => f.filterType === RegistrarActionsFilterTypes.BySubregistryNode
|
|
2815
|
+
);
|
|
2816
|
+
return bySubregistryNodeFilter ? new URL(`/api/registrar-actions/${bySubregistryNodeFilter.value}`, this.options.url) : new URL(`/api/registrar-actions`, this.options.url);
|
|
2817
|
+
};
|
|
2818
|
+
const buildWithReferralArg = (filters) => {
|
|
2819
|
+
const withReferralFilter = filters?.find(
|
|
2820
|
+
(f) => f.filterType === RegistrarActionsFilterTypes.WithEncodedReferral
|
|
2821
|
+
);
|
|
2822
|
+
return withReferralFilter ? { key: "withReferral", value: "true" } : null;
|
|
2823
|
+
};
|
|
2824
|
+
const buildOrderArg = (order) => {
|
|
2825
|
+
switch (order) {
|
|
2826
|
+
case RegistrarActionsOrders.LatestRegistrarActions: {
|
|
2827
|
+
const [field, direction] = order.split("=");
|
|
2828
|
+
return {
|
|
2829
|
+
key: `sort[${field}]`,
|
|
2830
|
+
value: `${direction}`
|
|
2831
|
+
};
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
};
|
|
2835
|
+
const url = buildUrlPath(request.filters);
|
|
2836
|
+
if (request.order) {
|
|
2837
|
+
const orderArgs = buildOrderArg(request.order);
|
|
2838
|
+
url.searchParams.set(orderArgs.key, orderArgs.value);
|
|
2839
|
+
}
|
|
2840
|
+
if (request.itemsPerPage) {
|
|
2841
|
+
url.searchParams.set("itemsPerPage", request.itemsPerPage.toString());
|
|
2842
|
+
}
|
|
2843
|
+
const referralArg = buildWithReferralArg(request.filters);
|
|
2844
|
+
if (referralArg) {
|
|
2845
|
+
url.searchParams.set(referralArg.key, referralArg.value);
|
|
2846
|
+
}
|
|
2847
|
+
const response = await fetch(url);
|
|
2848
|
+
let responseData;
|
|
2849
|
+
try {
|
|
2850
|
+
responseData = await response.json();
|
|
2851
|
+
} catch {
|
|
2852
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
2853
|
+
}
|
|
2854
|
+
if (!response.ok) {
|
|
2855
|
+
let errorResponse;
|
|
2856
|
+
try {
|
|
2857
|
+
errorResponse = deserializeErrorResponse(responseData);
|
|
2858
|
+
} catch {
|
|
2859
|
+
console.log("Registrar Actions API: handling a known server error.");
|
|
2860
|
+
}
|
|
2861
|
+
if (typeof errorResponse !== "undefined") {
|
|
2862
|
+
throw new Error(`Fetching ENSNode Registrar Actions Failed: ${errorResponse.message}`);
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
return deserializeRegistrarActionsResponse(responseData);
|
|
2866
|
+
}
|
|
2867
|
+
};
|
|
2868
|
+
|
|
2869
|
+
// src/identity/identity.ts
|
|
2870
|
+
var import_datasources9 = require("@ensnode/datasources");
|
|
2871
|
+
|
|
2872
|
+
// src/identity/types.ts
|
|
2873
|
+
var ResolutionStatusIds = {
|
|
2874
|
+
/**
|
|
2875
|
+
* Represents that the `Identity` is not resolved yet.
|
|
2876
|
+
*/
|
|
2877
|
+
Unresolved: "unresolved",
|
|
2878
|
+
/**
|
|
2879
|
+
* Represents that resolution of the `Identity` resulted in a named identity.
|
|
2880
|
+
*/
|
|
2881
|
+
Named: "named",
|
|
2882
|
+
/**
|
|
2883
|
+
* Represents that resolution of the `Identity` resulted in an unnamed identity.
|
|
2884
|
+
*/
|
|
2885
|
+
Unnamed: "unnamed",
|
|
2886
|
+
/**
|
|
2887
|
+
* Represents that attempted resolution of the `Identity` resulted in an error
|
|
2888
|
+
* and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
|
|
2889
|
+
*/
|
|
2890
|
+
Unknown: "unknown"
|
|
2891
|
+
};
|
|
2892
|
+
|
|
2893
|
+
// src/identity/identity.ts
|
|
2894
|
+
function buildUnresolvedIdentity(address, namespaceId, chainId) {
|
|
2895
|
+
return {
|
|
2896
|
+
resolutionStatus: ResolutionStatusIds.Unresolved,
|
|
2897
|
+
chainId: chainId ?? (0, import_datasources9.getENSRootChainId)(namespaceId),
|
|
2898
|
+
address
|
|
2899
|
+
};
|
|
2900
|
+
}
|
|
2901
|
+
function isResolvedIdentity(identity) {
|
|
2902
|
+
return identity.resolutionStatus !== ResolutionStatusIds.Unresolved;
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
// src/resolution/ensip19-chainid.ts
|
|
2906
|
+
var import_chains2 = require("viem/chains");
|
|
2907
|
+
var import_datasources10 = require("@ensnode/datasources");
|
|
2908
|
+
var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
|
|
2909
|
+
const ensRootChainId = (0, import_datasources10.getENSRootChainId)(namespaceId);
|
|
2910
|
+
return chainId === ensRootChainId ? import_chains2.mainnet.id : chainId;
|
|
2911
|
+
};
|
|
2912
|
+
var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
|
|
2913
|
+
return chainId === DEFAULT_EVM_CHAIN_ID ? (0, import_datasources10.getENSRootChainId)(namespaceId) : chainId;
|
|
2914
|
+
};
|
|
2915
|
+
|
|
2916
|
+
// src/resolution/resolver-records-selection.ts
|
|
2917
|
+
var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
|
|
2918
|
+
|
|
2919
|
+
// src/tracing/index.ts
|
|
2920
|
+
var TraceableENSProtocol = /* @__PURE__ */ ((TraceableENSProtocol2) => {
|
|
2921
|
+
TraceableENSProtocol2["ForwardResolution"] = "forward-resolution";
|
|
2922
|
+
TraceableENSProtocol2["ReverseResolution"] = "reverse-resolution";
|
|
2923
|
+
return TraceableENSProtocol2;
|
|
2924
|
+
})(TraceableENSProtocol || {});
|
|
2925
|
+
var ForwardResolutionProtocolStep = /* @__PURE__ */ ((ForwardResolutionProtocolStep2) => {
|
|
2926
|
+
ForwardResolutionProtocolStep2["Operation"] = "forward-resolution";
|
|
2927
|
+
ForwardResolutionProtocolStep2["FindResolver"] = "find-resolver";
|
|
2928
|
+
ForwardResolutionProtocolStep2["ActiveResolverExists"] = "active-resolver-exists";
|
|
2929
|
+
ForwardResolutionProtocolStep2["AccelerateENSIP19ReverseResolver"] = "accelerate-ensip-19-reverse-resolver";
|
|
2930
|
+
ForwardResolutionProtocolStep2["AccelerateKnownOffchainLookupResolver"] = "accelerate-known-offchain-lookup-resolver";
|
|
2931
|
+
ForwardResolutionProtocolStep2["AccelerateKnownOnchainStaticResolver"] = "accelerate-known-onchain-static-resolver";
|
|
2932
|
+
ForwardResolutionProtocolStep2["RequireResolver"] = "require-resolver";
|
|
2933
|
+
ForwardResolutionProtocolStep2["ExecuteResolveCalls"] = "execute-resolve-calls";
|
|
2934
|
+
return ForwardResolutionProtocolStep2;
|
|
2935
|
+
})(ForwardResolutionProtocolStep || {});
|
|
2936
|
+
var ReverseResolutionProtocolStep = /* @__PURE__ */ ((ReverseResolutionProtocolStep2) => {
|
|
2937
|
+
ReverseResolutionProtocolStep2["Operation"] = "reverse-resolution";
|
|
2938
|
+
ReverseResolutionProtocolStep2["ResolveReverseName"] = "resolve-reverse-name";
|
|
2939
|
+
ReverseResolutionProtocolStep2["NameRecordExists"] = "name-record-exists-check";
|
|
2940
|
+
ReverseResolutionProtocolStep2["ForwardResolveAddressRecord"] = "forward-resolve-address-record";
|
|
2941
|
+
ReverseResolutionProtocolStep2["VerifyResolvedAddressMatchesAddress"] = "verify-resolved-address-matches-address";
|
|
2942
|
+
return ReverseResolutionProtocolStep2;
|
|
2943
|
+
})(ReverseResolutionProtocolStep || {});
|
|
2944
|
+
var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|
|
2945
|
+
var ATTR_PROTOCOL_NAME = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol`;
|
|
2946
|
+
var ATTR_PROTOCOL_STEP = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step`;
|
|
2947
|
+
var ATTR_PROTOCOL_STEP_RESULT = `${PROTOCOL_ATTRIBUTE_PREFIX}.protocol.step.result`;
|
|
2948
|
+
//# sourceMappingURL=index.cjs.map
|