@ensnode/ensnode-sdk 0.0.0-next-20260130072518 → 0.0.0-next-20260131065208
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 +1563 -1445
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1836 -1704
- package/dist/index.d.ts +1836 -1704
- package/dist/index.js +981 -863
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -113,6 +113,9 @@ __export(index_exports, {
|
|
|
113
113
|
deserializeErrorResponse: () => deserializeErrorResponse,
|
|
114
114
|
deserializeIndexingStatusResponse: () => deserializeIndexingStatusResponse,
|
|
115
115
|
deserializeOmnichainIndexingStatusSnapshot: () => deserializeOmnichainIndexingStatusSnapshot,
|
|
116
|
+
deserializePriceDai: () => deserializePriceDai,
|
|
117
|
+
deserializePriceEth: () => deserializePriceEth,
|
|
118
|
+
deserializePriceUsdc: () => deserializePriceUsdc,
|
|
116
119
|
deserializeRealtimeIndexingStatusProjection: () => deserializeRealtimeIndexingStatusProjection,
|
|
117
120
|
deserializeRegistrarActionsResponse: () => deserializeRegistrarActionsResponse,
|
|
118
121
|
deserializeUnixTimestamp: () => deserializeUnixTimestamp,
|
|
@@ -206,14 +209,19 @@ __export(index_exports, {
|
|
|
206
209
|
nameTokensPrerequisites: () => nameTokensPrerequisites,
|
|
207
210
|
parseAccountId: () => parseAccountId,
|
|
208
211
|
parseAssetId: () => parseAssetId,
|
|
212
|
+
parseDai: () => parseDai,
|
|
213
|
+
parseEth: () => parseEth,
|
|
209
214
|
parseNonNegativeInteger: () => parseNonNegativeInteger,
|
|
210
215
|
parseReverseName: () => parseReverseName,
|
|
216
|
+
parseUsdc: () => parseUsdc,
|
|
211
217
|
priceDai: () => priceDai,
|
|
212
218
|
priceEth: () => priceEth,
|
|
213
219
|
priceUsdc: () => priceUsdc,
|
|
214
220
|
registrarActionsFilter: () => registrarActionsFilter,
|
|
215
221
|
registrarActionsPrerequisites: () => registrarActionsPrerequisites,
|
|
216
222
|
reverseName: () => reverseName,
|
|
223
|
+
scaleBigintByNumber: () => scaleBigintByNumber,
|
|
224
|
+
scalePrice: () => scalePrice,
|
|
217
225
|
serializeAssetId: () => serializeAssetId,
|
|
218
226
|
serializeChainId: () => serializeChainId,
|
|
219
227
|
serializeChainIndexingSnapshots: () => serializeChainIndexingSnapshots,
|
|
@@ -230,7 +238,9 @@ __export(index_exports, {
|
|
|
230
238
|
serializeNamedRegistrarAction: () => serializeNamedRegistrarAction,
|
|
231
239
|
serializeOmnichainIndexingStatusSnapshot: () => serializeOmnichainIndexingStatusSnapshot,
|
|
232
240
|
serializePrice: () => serializePrice,
|
|
241
|
+
serializePriceDai: () => serializePriceDai,
|
|
233
242
|
serializePriceEth: () => serializePriceEth,
|
|
243
|
+
serializePriceUsdc: () => serializePriceUsdc,
|
|
234
244
|
serializeRealtimeIndexingStatusProjection: () => serializeRealtimeIndexingStatusProjection,
|
|
235
245
|
serializeRegisteredNameTokens: () => serializeRegisteredNameTokens,
|
|
236
246
|
serializeRegistrarAction: () => serializeRegistrarAction,
|
|
@@ -247,81 +257,17 @@ __export(index_exports, {
|
|
|
247
257
|
module.exports = __toCommonJS(index_exports);
|
|
248
258
|
|
|
249
259
|
// src/ensapi/config/deserialize.ts
|
|
250
|
-
var
|
|
260
|
+
var import_v45 = require("zod/v4");
|
|
251
261
|
|
|
252
262
|
// src/ensapi/config/zod-schemas.ts
|
|
253
|
-
var
|
|
263
|
+
var import_v44 = require("zod/v4");
|
|
254
264
|
|
|
255
265
|
// src/ensindexer/config/zod-schemas.ts
|
|
256
|
-
var import_v43 = require("zod/v4");
|
|
257
|
-
|
|
258
|
-
// src/shared/account-id.ts
|
|
259
|
-
var import_viem = require("viem");
|
|
260
|
-
var accountIdEqual = (a, b) => {
|
|
261
|
-
return a.chainId === b.chainId && (0, import_viem.isAddressEqual)(a.address, b.address);
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
// src/shared/address.ts
|
|
265
|
-
function asLowerCaseAddress(address) {
|
|
266
|
-
return address.toLowerCase();
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// src/shared/cache/lru-cache.ts
|
|
270
|
-
var LruCache = class {
|
|
271
|
-
_cache = /* @__PURE__ */ new Map();
|
|
272
|
-
_capacity;
|
|
273
|
-
/**
|
|
274
|
-
* Create a new LRU cache with the given capacity.
|
|
275
|
-
*
|
|
276
|
-
* @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
|
|
277
|
-
* @throws Error if capacity is not a non-negative integer.
|
|
278
|
-
*/
|
|
279
|
-
constructor(capacity) {
|
|
280
|
-
if (!Number.isInteger(capacity)) {
|
|
281
|
-
throw new Error(
|
|
282
|
-
`LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
if (capacity < 0) {
|
|
286
|
-
throw new Error(
|
|
287
|
-
`LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
this._capacity = capacity;
|
|
291
|
-
}
|
|
292
|
-
set(key, value) {
|
|
293
|
-
this._cache.set(key, value);
|
|
294
|
-
if (this._cache.size > this._capacity) {
|
|
295
|
-
const oldestKey = this._cache.keys().next().value;
|
|
296
|
-
this._cache.delete(oldestKey);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
get(key) {
|
|
300
|
-
const value = this._cache.get(key);
|
|
301
|
-
if (value) {
|
|
302
|
-
this._cache.delete(key);
|
|
303
|
-
this._cache.set(key, value);
|
|
304
|
-
}
|
|
305
|
-
return value;
|
|
306
|
-
}
|
|
307
|
-
clear() {
|
|
308
|
-
this._cache.clear();
|
|
309
|
-
}
|
|
310
|
-
get size() {
|
|
311
|
-
return this._cache.size;
|
|
312
|
-
}
|
|
313
|
-
get capacity() {
|
|
314
|
-
return this._capacity;
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
// src/shared/cache/swr-cache.ts
|
|
319
|
-
var import_date_fns = require("date-fns");
|
|
320
|
-
var import_getUnixTime = require("date-fns/getUnixTime");
|
|
321
|
-
|
|
322
|
-
// src/shared/deserialize.ts
|
|
323
266
|
var import_v42 = require("zod/v4");
|
|
324
267
|
|
|
268
|
+
// src/shared/collections.ts
|
|
269
|
+
var uniq = (arr) => [...new Set(arr)];
|
|
270
|
+
|
|
325
271
|
// src/shared/zod-schemas.ts
|
|
326
272
|
var import_caip = require("caip");
|
|
327
273
|
var import_viem8 = require("viem");
|
|
@@ -351,23 +297,23 @@ var bigintToCoinType = (value) => {
|
|
|
351
297
|
};
|
|
352
298
|
|
|
353
299
|
// src/ens/constants.ts
|
|
354
|
-
var
|
|
355
|
-
var ROOT_NODE = (0,
|
|
356
|
-
var ETH_NODE = (0,
|
|
357
|
-
var BASENAMES_NODE = (0,
|
|
358
|
-
var LINEANAMES_NODE = (0,
|
|
359
|
-
var ADDR_REVERSE_NODE = (0,
|
|
360
|
-
var NODE_ANY =
|
|
300
|
+
var import_viem = require("viem");
|
|
301
|
+
var ROOT_NODE = (0, import_viem.namehash)("");
|
|
302
|
+
var ETH_NODE = (0, import_viem.namehash)("eth");
|
|
303
|
+
var BASENAMES_NODE = (0, import_viem.namehash)("base.eth");
|
|
304
|
+
var LINEANAMES_NODE = (0, import_viem.namehash)("linea.eth");
|
|
305
|
+
var ADDR_REVERSE_NODE = (0, import_viem.namehash)("addr.reverse");
|
|
306
|
+
var NODE_ANY = import_viem.zeroHash;
|
|
361
307
|
var ROOT_RESOURCE = 0n;
|
|
362
308
|
|
|
363
309
|
// src/ens/dns-encoded-name.ts
|
|
364
|
-
var
|
|
310
|
+
var import_viem2 = require("viem");
|
|
365
311
|
function decodeDNSEncodedLiteralName(packet) {
|
|
366
312
|
return decodeDNSEncodedName(packet);
|
|
367
313
|
}
|
|
368
314
|
function decodeDNSEncodedName(packet) {
|
|
369
315
|
const segments = [];
|
|
370
|
-
const bytes = (0,
|
|
316
|
+
const bytes = (0, import_viem2.hexToBytes)(packet);
|
|
371
317
|
if (bytes.length === 0) throw new Error(`Packet is empty.`);
|
|
372
318
|
let offset = 0;
|
|
373
319
|
while (offset < bytes.length) {
|
|
@@ -381,7 +327,7 @@ function decodeDNSEncodedName(packet) {
|
|
|
381
327
|
);
|
|
382
328
|
}
|
|
383
329
|
if (len === 0) break;
|
|
384
|
-
const segment = (0,
|
|
330
|
+
const segment = (0, import_viem2.bytesToString)(bytes.subarray(offset + 1, offset + len + 1));
|
|
385
331
|
segments.push(segment);
|
|
386
332
|
offset += len + 1;
|
|
387
333
|
}
|
|
@@ -391,10 +337,10 @@ function decodeDNSEncodedName(packet) {
|
|
|
391
337
|
}
|
|
392
338
|
|
|
393
339
|
// src/ens/labelhash.ts
|
|
394
|
-
var
|
|
340
|
+
var import_viem3 = require("viem");
|
|
395
341
|
function isLabelHash(maybeLabelHash) {
|
|
396
342
|
const expectedLength = maybeLabelHash.length === 66;
|
|
397
|
-
const expectedEncoding = (0,
|
|
343
|
+
const expectedEncoding = (0, import_viem3.isHex)(maybeLabelHash);
|
|
398
344
|
const expectedCasing = maybeLabelHash === maybeLabelHash.toLowerCase();
|
|
399
345
|
return expectedLength && expectedEncoding && expectedCasing;
|
|
400
346
|
}
|
|
@@ -456,11 +402,18 @@ var beautifyName = (name) => {
|
|
|
456
402
|
};
|
|
457
403
|
|
|
458
404
|
// src/ens/parse-reverse-name.ts
|
|
459
|
-
var
|
|
405
|
+
var import_viem4 = require("viem");
|
|
406
|
+
|
|
407
|
+
// src/shared/address.ts
|
|
408
|
+
function asLowerCaseAddress(address) {
|
|
409
|
+
return address.toLowerCase();
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// src/ens/parse-reverse-name.ts
|
|
460
413
|
var REVERSE_NAME_REGEX = /^([0-9a-fA-F]+)\.([0-9a-f]{1,64}|addr|default)\.reverse$/;
|
|
461
414
|
var parseAddressLabel = (addressLabel) => {
|
|
462
415
|
const maybeAddress = `0x${addressLabel}`;
|
|
463
|
-
if (!(0,
|
|
416
|
+
if (!(0, import_viem4.isAddress)(maybeAddress)) {
|
|
464
417
|
throw new Error(`Invalid EVM address "${maybeAddress}"`);
|
|
465
418
|
}
|
|
466
419
|
return asLowerCaseAddress(maybeAddress);
|
|
@@ -468,7 +421,7 @@ var parseAddressLabel = (addressLabel) => {
|
|
|
468
421
|
var parseCoinTypeLabel = (coinTypeLabel) => {
|
|
469
422
|
if (coinTypeLabel === "default") return DEFAULT_EVM_COIN_TYPE;
|
|
470
423
|
if (coinTypeLabel === "addr") return ETH_COIN_TYPE;
|
|
471
|
-
return bigintToCoinType((0,
|
|
424
|
+
return bigintToCoinType((0, import_viem4.hexToBigInt)(`0x${coinTypeLabel}`));
|
|
472
425
|
};
|
|
473
426
|
function parseReverseName(name) {
|
|
474
427
|
const match = name.match(REVERSE_NAME_REGEX);
|
|
@@ -505,13 +458,59 @@ function reverseName(address, coinType) {
|
|
|
505
458
|
}
|
|
506
459
|
|
|
507
460
|
// src/ens/subname-helpers.ts
|
|
508
|
-
var
|
|
509
|
-
var makeSubdomainNode = (labelHash, node) => (0,
|
|
510
|
-
var uint256ToHex32 = (num) => (0,
|
|
461
|
+
var import_viem5 = require("viem");
|
|
462
|
+
var makeSubdomainNode = (labelHash, node) => (0, import_viem5.keccak256)((0, import_viem5.concat)([node, labelHash]));
|
|
463
|
+
var uint256ToHex32 = (num) => (0, import_viem5.toHex)(num, { size: 32 });
|
|
511
464
|
|
|
512
465
|
// src/ens/types.ts
|
|
513
466
|
var import_datasources = require("@ensnode/datasources");
|
|
514
467
|
|
|
468
|
+
// src/shared/currencies.ts
|
|
469
|
+
var import_viem6 = require("viem");
|
|
470
|
+
|
|
471
|
+
// src/shared/numbers.ts
|
|
472
|
+
function bigIntToNumber(n) {
|
|
473
|
+
if (n < Number.MIN_SAFE_INTEGER) {
|
|
474
|
+
throw new Error(
|
|
475
|
+
`The bigint '${n.toString()}' value is too low to be to converted into a number.'`
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
if (n > Number.MAX_SAFE_INTEGER) {
|
|
479
|
+
throw new Error(
|
|
480
|
+
`The bigint '${n.toString()}' value is too high to be to converted into a number.'`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
return Number(n);
|
|
484
|
+
}
|
|
485
|
+
function scaleBigintByNumber(value, scaleFactor) {
|
|
486
|
+
if (value < 0n) {
|
|
487
|
+
throw new Error(`scaleBigintByNumber: value must be non-negative, got: ${value.toString()}`);
|
|
488
|
+
}
|
|
489
|
+
if (!Number.isFinite(scaleFactor)) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`scaleBigintByNumber: scaleFactor must be a finite number, got: ${scaleFactor}`
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
if (scaleFactor < 0) {
|
|
495
|
+
throw new Error(`scaleBigintByNumber: scaleFactor must be non-negative, got: ${scaleFactor}`);
|
|
496
|
+
}
|
|
497
|
+
if (scaleFactor >= 1e21) {
|
|
498
|
+
throw new Error(`scaleBigintByNumber: scaleFactor must be less than 1e21, got: ${scaleFactor}`);
|
|
499
|
+
}
|
|
500
|
+
if (value === 0n || scaleFactor === 0) {
|
|
501
|
+
return 0n;
|
|
502
|
+
}
|
|
503
|
+
if (scaleFactor === 1) {
|
|
504
|
+
return value;
|
|
505
|
+
}
|
|
506
|
+
const fixedStr = scaleFactor.toFixed(20);
|
|
507
|
+
const [integerPart, decimalPart = ""] = fixedStr.split(".");
|
|
508
|
+
const trimmedDecimal = decimalPart.replace(/0+$/, "") || "0";
|
|
509
|
+
const numerator = BigInt(integerPart + trimmedDecimal);
|
|
510
|
+
const denominator = 10n ** BigInt(trimmedDecimal.length);
|
|
511
|
+
return value * numerator / denominator;
|
|
512
|
+
}
|
|
513
|
+
|
|
515
514
|
// src/shared/currencies.ts
|
|
516
515
|
var CurrencyIds = {
|
|
517
516
|
ETH: "ETH",
|
|
@@ -580,6 +579,43 @@ function addPrices(...prices) {
|
|
|
580
579
|
}
|
|
581
580
|
);
|
|
582
581
|
}
|
|
582
|
+
function scalePrice(price, scaleFactor) {
|
|
583
|
+
const scaledAmount = scaleBigintByNumber(price.amount, scaleFactor);
|
|
584
|
+
return {
|
|
585
|
+
...price,
|
|
586
|
+
amount: scaledAmount
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
function validateAmountToParse(value) {
|
|
590
|
+
const trimmed = value.trim();
|
|
591
|
+
if (trimmed === "") {
|
|
592
|
+
throw new Error("amount must be a non-negative decimal string");
|
|
593
|
+
}
|
|
594
|
+
if (value !== trimmed) {
|
|
595
|
+
throw new Error("amount must not have leading or trailing whitespace");
|
|
596
|
+
}
|
|
597
|
+
if (trimmed.startsWith("-")) {
|
|
598
|
+
throw new Error("amount must be a non-negative decimal string");
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
function parseEth(value) {
|
|
602
|
+
validateAmountToParse(value);
|
|
603
|
+
const currencyInfo2 = getCurrencyInfo(CurrencyIds.ETH);
|
|
604
|
+
const amount = (0, import_viem6.parseUnits)(value, currencyInfo2.decimals);
|
|
605
|
+
return priceEth(amount);
|
|
606
|
+
}
|
|
607
|
+
function parseUsdc(value) {
|
|
608
|
+
validateAmountToParse(value);
|
|
609
|
+
const currencyInfo2 = getCurrencyInfo(CurrencyIds.USDC);
|
|
610
|
+
const amount = (0, import_viem6.parseUnits)(value, currencyInfo2.decimals);
|
|
611
|
+
return priceUsdc(amount);
|
|
612
|
+
}
|
|
613
|
+
function parseDai(value) {
|
|
614
|
+
validateAmountToParse(value);
|
|
615
|
+
const currencyInfo2 = getCurrencyInfo(CurrencyIds.DAI);
|
|
616
|
+
const amount = (0, import_viem6.parseUnits)(value, currencyInfo2.decimals);
|
|
617
|
+
return priceDai(amount);
|
|
618
|
+
}
|
|
583
619
|
|
|
584
620
|
// src/shared/interpretation/reinterpretation.ts
|
|
585
621
|
var import_viem7 = require("viem");
|
|
@@ -675,6 +711,8 @@ var makePriceCurrencySchema = (currency, valueLabel = "Price Currency") => impor
|
|
|
675
711
|
})
|
|
676
712
|
});
|
|
677
713
|
var makePriceEthSchema = (valueLabel = "Price ETH") => makePriceCurrencySchema(CurrencyIds.ETH, valueLabel).transform((v) => v);
|
|
714
|
+
var makePriceUsdcSchema = (valueLabel = "Price USDC") => makePriceCurrencySchema(CurrencyIds.USDC, valueLabel).transform((v) => v);
|
|
715
|
+
var makePriceDaiSchema = (valueLabel = "Price DAI") => makePriceCurrencySchema(CurrencyIds.DAI, valueLabel).transform((v) => v);
|
|
678
716
|
var makeAccountIdSchema = (valueLabel = "AccountId") => import_v4.z.strictObject({
|
|
679
717
|
chainId: makeChainIdSchema(`${valueLabel} chain ID`),
|
|
680
718
|
address: makeLowercaseAddressSchema(`${valueLabel} address`)
|
|
@@ -720,64 +758,341 @@ var makeReinterpretedNameSchema = (valueLabel = "Reinterpreted Name") => import_
|
|
|
720
758
|
}
|
|
721
759
|
}).transform(reinterpretName);
|
|
722
760
|
|
|
723
|
-
// src/
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
761
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
762
|
+
var import_datasources3 = require("@ensnode/datasources");
|
|
763
|
+
|
|
764
|
+
// src/ensindexer/config/types.ts
|
|
765
|
+
var PluginName = /* @__PURE__ */ ((PluginName2) => {
|
|
766
|
+
PluginName2["Subgraph"] = "subgraph";
|
|
767
|
+
PluginName2["Basenames"] = "basenames";
|
|
768
|
+
PluginName2["Lineanames"] = "lineanames";
|
|
769
|
+
PluginName2["ThreeDNS"] = "threedns";
|
|
770
|
+
PluginName2["ProtocolAcceleration"] = "protocol-acceleration";
|
|
771
|
+
PluginName2["Registrars"] = "registrars";
|
|
772
|
+
PluginName2["TokenScope"] = "tokenscope";
|
|
773
|
+
PluginName2["ENSv2"] = "ensv2";
|
|
774
|
+
return PluginName2;
|
|
775
|
+
})(PluginName || {});
|
|
776
|
+
|
|
777
|
+
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
778
|
+
function isSubgraphCompatible(config) {
|
|
779
|
+
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
780
|
+
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
781
|
+
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
782
|
+
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === import_datasources3.ENSNamespaceIds.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
783
|
+
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
733
784
|
}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
785
|
+
|
|
786
|
+
// src/ensindexer/config/validations.ts
|
|
787
|
+
function invariant_ensDbVersionIsSameAsEnsIndexerVersion(ctx) {
|
|
788
|
+
const versionInfo = ctx.value;
|
|
789
|
+
if (versionInfo.ensDb !== versionInfo.ensIndexer) {
|
|
790
|
+
ctx.issues.push({
|
|
791
|
+
code: "custom",
|
|
792
|
+
input: versionInfo,
|
|
793
|
+
message: "`ensDb` version must be same as `ensIndexer` version"
|
|
794
|
+
});
|
|
741
795
|
}
|
|
742
|
-
return parsed.data;
|
|
743
796
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
797
|
+
|
|
798
|
+
// src/ensindexer/config/zod-schemas.ts
|
|
799
|
+
var makeIndexedChainIdsSchema = (valueLabel = "Indexed Chain IDs") => import_v42.z.array(makeChainIdSchema(valueLabel), {
|
|
800
|
+
error: `${valueLabel} must be an array.`
|
|
801
|
+
}).min(1, { error: `${valueLabel} list must include at least one element.` }).transform((v) => new Set(v));
|
|
802
|
+
var makePluginsListSchema = (valueLabel = "Plugins") => import_v42.z.array(import_v42.z.string(), {
|
|
803
|
+
error: `${valueLabel} must be a list of strings.`
|
|
804
|
+
}).min(1, {
|
|
805
|
+
error: `${valueLabel} must be a list of strings with at least one string value`
|
|
806
|
+
}).refine((arr) => arr.length === uniq(arr).length, {
|
|
807
|
+
error: `${valueLabel} cannot contain duplicate values.`
|
|
808
|
+
});
|
|
809
|
+
var makeDatabaseSchemaNameSchema = (valueLabel = "Database schema name") => import_v42.z.string({ error: `${valueLabel} must be a string` }).trim().nonempty({
|
|
810
|
+
error: `${valueLabel} is required and must be a non-empty string.`
|
|
811
|
+
});
|
|
812
|
+
var makeLabelSetIdSchema = (valueLabel) => {
|
|
813
|
+
return import_v42.z.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-]+$/, {
|
|
814
|
+
error: `${valueLabel} can only contain lowercase letters (a-z) and hyphens (-)`
|
|
815
|
+
});
|
|
816
|
+
};
|
|
817
|
+
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
818
|
+
return import_v42.z.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
819
|
+
};
|
|
820
|
+
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
821
|
+
let valueLabelLabelSetId = valueLabel;
|
|
822
|
+
let valueLabelLabelSetVersion = valueLabel;
|
|
823
|
+
if (valueLabel === "LABEL_SET") {
|
|
824
|
+
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
825
|
+
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
826
|
+
} else {
|
|
827
|
+
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
828
|
+
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
751
829
|
}
|
|
752
|
-
return
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
830
|
+
return import_v42.z.object({
|
|
831
|
+
labelSetId: makeLabelSetIdSchema(valueLabelLabelSetId),
|
|
832
|
+
labelSetVersion: makeLabelSetVersionSchema(valueLabelLabelSetVersion)
|
|
833
|
+
});
|
|
834
|
+
};
|
|
835
|
+
var makeNonEmptyStringSchema = (valueLabel = "Value") => import_v42.z.string().nonempty({ error: `${valueLabel} must be a non-empty string.` });
|
|
836
|
+
var makeENSIndexerVersionInfoSchema = (valueLabel = "Value") => import_v42.z.strictObject(
|
|
837
|
+
{
|
|
838
|
+
nodejs: makeNonEmptyStringSchema(),
|
|
839
|
+
ponder: makeNonEmptyStringSchema(),
|
|
840
|
+
ensDb: makeNonEmptyStringSchema(),
|
|
841
|
+
ensIndexer: makeNonEmptyStringSchema(),
|
|
842
|
+
ensNormalize: makeNonEmptyStringSchema(),
|
|
843
|
+
ensRainbow: makeNonEmptyStringSchema(),
|
|
844
|
+
ensRainbowSchema: makePositiveIntegerSchema()
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
|
|
761
848
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
${
|
|
770
|
-
|
|
849
|
+
).check(invariant_ensDbVersionIsSameAsEnsIndexerVersion);
|
|
850
|
+
function invariant_isSubgraphCompatibleRequirements(ctx) {
|
|
851
|
+
const { value: config } = ctx;
|
|
852
|
+
if (config.isSubgraphCompatible && !isSubgraphCompatible(config)) {
|
|
853
|
+
ctx.issues.push({
|
|
854
|
+
code: "custom",
|
|
855
|
+
input: config,
|
|
856
|
+
message: `'isSubgraphCompatible' requires only the '${"subgraph" /* Subgraph */}' plugin to be active and labelSet must be {labelSetId: "subgraph", labelSetVersion: 0}`
|
|
857
|
+
});
|
|
771
858
|
}
|
|
772
|
-
return parsed.data;
|
|
773
859
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
`)
|
|
860
|
+
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => import_v42.z.object({
|
|
861
|
+
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
862
|
+
indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
|
|
863
|
+
isSubgraphCompatible: import_v42.z.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
864
|
+
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
865
|
+
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
866
|
+
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
867
|
+
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
868
|
+
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
869
|
+
|
|
870
|
+
// src/shared/config/thegraph.ts
|
|
871
|
+
var import_v43 = require("zod/v4");
|
|
872
|
+
var TheGraphCannotFallbackReasonSchema = import_v43.z.enum({
|
|
873
|
+
NotSubgraphCompatible: "not-subgraph-compatible",
|
|
874
|
+
NoApiKey: "no-api-key",
|
|
875
|
+
NoSubgraphUrl: "no-subgraph-url"
|
|
876
|
+
});
|
|
877
|
+
var TheGraphFallbackSchema = import_v43.z.discriminatedUnion("canFallback", [
|
|
878
|
+
import_v43.z.strictObject({
|
|
879
|
+
canFallback: import_v43.z.literal(true),
|
|
880
|
+
url: import_v43.z.string()
|
|
881
|
+
}),
|
|
882
|
+
import_v43.z.strictObject({
|
|
883
|
+
canFallback: import_v43.z.literal(false),
|
|
884
|
+
reason: TheGraphCannotFallbackReasonSchema
|
|
885
|
+
})
|
|
886
|
+
]);
|
|
887
|
+
|
|
888
|
+
// src/ensapi/config/zod-schemas.ts
|
|
889
|
+
function makeENSApiPublicConfigSchema(valueLabel) {
|
|
890
|
+
const label = valueLabel ?? "ENSApiPublicConfig";
|
|
891
|
+
return import_v44.z.strictObject({
|
|
892
|
+
version: import_v44.z.string().min(1, `${label}.version must be a non-empty string`),
|
|
893
|
+
theGraphFallback: TheGraphFallbackSchema,
|
|
894
|
+
ensIndexerPublicConfig: makeENSIndexerPublicConfigSchema(`${label}.ensIndexerPublicConfig`)
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// src/ensapi/config/deserialize.ts
|
|
899
|
+
function deserializeENSApiPublicConfig(maybeConfig, valueLabel) {
|
|
900
|
+
const schema = makeENSApiPublicConfigSchema(valueLabel);
|
|
901
|
+
try {
|
|
902
|
+
return schema.parse(maybeConfig);
|
|
903
|
+
} catch (error) {
|
|
904
|
+
if (error instanceof import_v45.ZodError) {
|
|
905
|
+
throw new Error(`Cannot deserialize ENSApiPublicConfig:
|
|
906
|
+
${(0, import_v45.prettifyError)(error)}
|
|
907
|
+
`);
|
|
908
|
+
}
|
|
909
|
+
throw error;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
// src/ensindexer/config/deserialize.ts
|
|
914
|
+
var import_v46 = require("zod/v4");
|
|
915
|
+
function deserializeENSIndexerPublicConfig(maybeConfig, valueLabel) {
|
|
916
|
+
const schema = makeENSIndexerPublicConfigSchema(valueLabel);
|
|
917
|
+
const parsed = schema.safeParse(maybeConfig);
|
|
918
|
+
if (parsed.error) {
|
|
919
|
+
throw new Error(`Cannot deserialize ENSIndexerPublicConfig:
|
|
920
|
+
${(0, import_v46.prettifyError)(parsed.error)}
|
|
921
|
+
`);
|
|
922
|
+
}
|
|
923
|
+
return parsed.data;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// src/ensindexer/config/label-utils.ts
|
|
927
|
+
var import_viem9 = require("viem");
|
|
928
|
+
function labelHashToBytes(labelHash) {
|
|
929
|
+
try {
|
|
930
|
+
if (labelHash.length !== 66) {
|
|
931
|
+
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
932
|
+
}
|
|
933
|
+
if (labelHash !== labelHash.toLowerCase()) {
|
|
934
|
+
throw new Error("Labelhash must be in lowercase");
|
|
935
|
+
}
|
|
936
|
+
if (!labelHash.startsWith("0x")) {
|
|
937
|
+
throw new Error("Labelhash must be 0x-prefixed");
|
|
938
|
+
}
|
|
939
|
+
const bytes = (0, import_viem9.hexToBytes)(labelHash);
|
|
940
|
+
if (bytes.length !== 32) {
|
|
941
|
+
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
942
|
+
}
|
|
943
|
+
return bytes;
|
|
944
|
+
} catch (e) {
|
|
945
|
+
if (e instanceof Error) {
|
|
946
|
+
throw e;
|
|
947
|
+
}
|
|
948
|
+
throw new Error("Invalid hex format");
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/ensindexer/config/labelset-utils.ts
|
|
953
|
+
function buildLabelSetId(maybeLabelSetId) {
|
|
954
|
+
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
955
|
+
}
|
|
956
|
+
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
957
|
+
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
958
|
+
}
|
|
959
|
+
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
960
|
+
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
961
|
+
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
962
|
+
}
|
|
963
|
+
return { labelSetId, labelSetVersion };
|
|
964
|
+
}
|
|
965
|
+
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
966
|
+
if (clientSet.labelSetId === void 0) {
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
970
|
+
throw new Error(
|
|
971
|
+
`Server label set ID "${serverSet.labelSetId}" does not match client's requested label set ID "${clientSet.labelSetId}".`
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
if (clientSet.labelSetVersion !== void 0 && serverSet.highestLabelSetVersion < clientSet.labelSetVersion) {
|
|
975
|
+
throw new Error(
|
|
976
|
+
`Server highest label set version ${serverSet.highestLabelSetVersion} is less than client's requested version ${clientSet.labelSetVersion} for label set ID "${clientSet.labelSetId}".`
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/ensindexer/config/parsing.ts
|
|
982
|
+
function parseNonNegativeInteger(maybeNumber) {
|
|
983
|
+
const trimmed = maybeNumber.trim();
|
|
984
|
+
if (!trimmed) {
|
|
985
|
+
throw new Error("Input cannot be empty");
|
|
986
|
+
}
|
|
987
|
+
if (trimmed === "-0") {
|
|
988
|
+
throw new Error("Negative zero is not a valid non-negative integer");
|
|
989
|
+
}
|
|
990
|
+
const num = Number(maybeNumber);
|
|
991
|
+
if (Number.isNaN(num)) {
|
|
992
|
+
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
993
|
+
}
|
|
994
|
+
if (!Number.isFinite(num)) {
|
|
995
|
+
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
996
|
+
}
|
|
997
|
+
if (!Number.isInteger(num)) {
|
|
998
|
+
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
999
|
+
}
|
|
1000
|
+
if (num < 0) {
|
|
1001
|
+
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
1002
|
+
}
|
|
1003
|
+
return num;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// src/ensindexer/config/serialize.ts
|
|
1007
|
+
function serializeIndexedChainIds(indexedChainIds) {
|
|
1008
|
+
return Array.from(indexedChainIds);
|
|
1009
|
+
}
|
|
1010
|
+
function serializeENSIndexerPublicConfig(config) {
|
|
1011
|
+
const {
|
|
1012
|
+
labelSet,
|
|
1013
|
+
indexedChainIds,
|
|
1014
|
+
databaseSchemaName,
|
|
1015
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1016
|
+
namespace,
|
|
1017
|
+
plugins,
|
|
1018
|
+
versionInfo
|
|
1019
|
+
} = config;
|
|
1020
|
+
return {
|
|
1021
|
+
labelSet,
|
|
1022
|
+
indexedChainIds: serializeIndexedChainIds(indexedChainIds),
|
|
1023
|
+
databaseSchemaName,
|
|
1024
|
+
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1025
|
+
namespace,
|
|
1026
|
+
plugins,
|
|
1027
|
+
versionInfo
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// src/ensindexer/indexing-status/deserialize.ts
|
|
1032
|
+
var import_v49 = require("zod/v4");
|
|
1033
|
+
|
|
1034
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1035
|
+
var import_v48 = require("zod/v4");
|
|
1036
|
+
|
|
1037
|
+
// src/shared/deserialize.ts
|
|
1038
|
+
var import_v47 = require("zod/v4");
|
|
1039
|
+
function deserializeChainId(maybeChainId, valueLabel) {
|
|
1040
|
+
const schema = makeChainIdStringSchema(valueLabel);
|
|
1041
|
+
const parsed = schema.safeParse(maybeChainId);
|
|
1042
|
+
if (parsed.error) {
|
|
1043
|
+
throw new Error(`Cannot deserialize ChainId:
|
|
1044
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1045
|
+
`);
|
|
1046
|
+
}
|
|
1047
|
+
return parsed.data;
|
|
1048
|
+
}
|
|
1049
|
+
function deserializeDatetime(maybeDatetime, valueLabel) {
|
|
1050
|
+
const schema = makeDatetimeSchema(valueLabel);
|
|
1051
|
+
const parsed = schema.safeParse(maybeDatetime);
|
|
1052
|
+
if (parsed.error) {
|
|
1053
|
+
throw new Error(`Cannot deserialize Datetime:
|
|
1054
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1055
|
+
`);
|
|
1056
|
+
}
|
|
1057
|
+
return parsed.data;
|
|
1058
|
+
}
|
|
1059
|
+
function deserializeUnixTimestamp(maybeTimestamp, valueLabel) {
|
|
1060
|
+
const schema = makeUnixTimestampSchema(valueLabel);
|
|
1061
|
+
const parsed = schema.safeParse(maybeTimestamp);
|
|
1062
|
+
if (parsed.error) {
|
|
1063
|
+
throw new Error(`Cannot deserialize Unix Timestamp:
|
|
1064
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1065
|
+
`);
|
|
1066
|
+
}
|
|
1067
|
+
return parsed.data;
|
|
1068
|
+
}
|
|
1069
|
+
function deserializeUrl(maybeUrl, valueLabel) {
|
|
1070
|
+
const schema = makeUrlSchema(valueLabel);
|
|
1071
|
+
const parsed = schema.safeParse(maybeUrl);
|
|
1072
|
+
if (parsed.error) {
|
|
1073
|
+
throw new Error(`Cannot deserialize URL:
|
|
1074
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1075
|
+
`);
|
|
1076
|
+
}
|
|
1077
|
+
return parsed.data;
|
|
1078
|
+
}
|
|
1079
|
+
function deserializeBlockNumber(maybeBlockNumber, valueLabel) {
|
|
1080
|
+
const schema = makeBlockNumberSchema(valueLabel);
|
|
1081
|
+
const parsed = schema.safeParse(maybeBlockNumber);
|
|
1082
|
+
if (parsed.error) {
|
|
1083
|
+
throw new Error(`Cannot deserialize BlockNumber:
|
|
1084
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1085
|
+
`);
|
|
1086
|
+
}
|
|
1087
|
+
return parsed.data;
|
|
1088
|
+
}
|
|
1089
|
+
function deserializeBlockrange(maybeBlockrange, valueLabel) {
|
|
1090
|
+
const schema = makeBlockrangeSchema(valueLabel);
|
|
1091
|
+
const parsed = schema.safeParse(maybeBlockrange);
|
|
1092
|
+
if (parsed.error) {
|
|
1093
|
+
throw new Error(`Cannot deserialize Blockrange:
|
|
1094
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1095
|
+
`);
|
|
781
1096
|
}
|
|
782
1097
|
return parsed.data;
|
|
783
1098
|
}
|
|
@@ -786,7 +1101,7 @@ function deserializeBlockRef(maybeBlockRef, valueLabel) {
|
|
|
786
1101
|
const parsed = schema.safeParse(maybeBlockRef);
|
|
787
1102
|
if (parsed.error) {
|
|
788
1103
|
throw new Error(`Cannot deserialize BlockRef:
|
|
789
|
-
${(0,
|
|
1104
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
790
1105
|
`);
|
|
791
1106
|
}
|
|
792
1107
|
return parsed.data;
|
|
@@ -796,7 +1111,7 @@ function deserializeDuration(maybeDuration, valueLabel) {
|
|
|
796
1111
|
const parsed = schema.safeParse(maybeDuration);
|
|
797
1112
|
if (parsed.error) {
|
|
798
1113
|
throw new RangeError(`Cannot deserialize Duration:
|
|
799
|
-
${(0,
|
|
1114
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
800
1115
|
`);
|
|
801
1116
|
}
|
|
802
1117
|
return parsed.data;
|
|
@@ -806,1234 +1121,698 @@ function parseAccountId(maybeAccountId, valueLabel) {
|
|
|
806
1121
|
const parsed = schema.safeParse(maybeAccountId);
|
|
807
1122
|
if (parsed.error) {
|
|
808
1123
|
throw new RangeError(`Cannot deserialize AccountId:
|
|
809
|
-
${(0,
|
|
1124
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
810
1125
|
`);
|
|
811
1126
|
}
|
|
812
1127
|
return parsed.data;
|
|
813
1128
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
1129
|
+
function deserializePriceEth(maybePrice, valueLabel) {
|
|
1130
|
+
const schema = makePriceEthSchema(valueLabel);
|
|
1131
|
+
const parsed = schema.safeParse(maybePrice);
|
|
1132
|
+
if (parsed.error) {
|
|
1133
|
+
throw new Error(`Cannot deserialize PriceEth:
|
|
1134
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1135
|
+
`);
|
|
1136
|
+
}
|
|
1137
|
+
return parsed.data;
|
|
818
1138
|
}
|
|
819
|
-
function
|
|
820
|
-
|
|
1139
|
+
function deserializePriceUsdc(maybePrice, valueLabel) {
|
|
1140
|
+
const schema = makePriceUsdcSchema(valueLabel);
|
|
1141
|
+
const parsed = schema.safeParse(maybePrice);
|
|
1142
|
+
if (parsed.error) {
|
|
1143
|
+
throw new Error(`Cannot deserialize PriceUsdc:
|
|
1144
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1145
|
+
`);
|
|
1146
|
+
}
|
|
1147
|
+
return parsed.data;
|
|
821
1148
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
() => this.revalidate(),
|
|
830
|
-
(0, import_date_fns.secondsToMilliseconds)(options.proactiveRevalidationInterval)
|
|
831
|
-
);
|
|
832
|
-
}
|
|
833
|
-
if (options.proactivelyInitialize) this.revalidate();
|
|
834
|
-
}
|
|
835
|
-
cache = null;
|
|
836
|
-
inProgressRevalidate = null;
|
|
837
|
-
backgroundInterval = null;
|
|
838
|
-
async revalidate() {
|
|
839
|
-
if (!this.inProgressRevalidate) {
|
|
840
|
-
this.inProgressRevalidate = this.options.fn().then((result) => {
|
|
841
|
-
this.cache = {
|
|
842
|
-
result,
|
|
843
|
-
updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
|
|
844
|
-
};
|
|
845
|
-
}).catch((error) => {
|
|
846
|
-
if (!this.cache) {
|
|
847
|
-
this.cache = {
|
|
848
|
-
// ensure thrown value is always an Error instance
|
|
849
|
-
result: error instanceof Error ? error : new Error(String(error)),
|
|
850
|
-
updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
}).finally(() => {
|
|
854
|
-
this.inProgressRevalidate = null;
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
return this.inProgressRevalidate;
|
|
1149
|
+
function deserializePriceDai(maybePrice, valueLabel) {
|
|
1150
|
+
const schema = makePriceDaiSchema(valueLabel);
|
|
1151
|
+
const parsed = schema.safeParse(maybePrice);
|
|
1152
|
+
if (parsed.error) {
|
|
1153
|
+
throw new Error(`Cannot deserialize PriceDai:
|
|
1154
|
+
${(0, import_v47.prettifyError)(parsed.error)}
|
|
1155
|
+
`);
|
|
858
1156
|
}
|
|
1157
|
+
return parsed.data;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/ensindexer/indexing-status/types.ts
|
|
1161
|
+
var ChainIndexingConfigTypeIds = {
|
|
859
1162
|
/**
|
|
860
|
-
*
|
|
861
|
-
*
|
|
862
|
-
* @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
|
|
863
|
-
* has never successfully returned.
|
|
1163
|
+
* Represents that indexing of the chain should be performed for an indefinite range.
|
|
864
1164
|
*/
|
|
865
|
-
|
|
866
|
-
if (!this.cache) await this.revalidate();
|
|
867
|
-
if (!this.cache) throw new Error("never");
|
|
868
|
-
if (durationBetween(this.cache.updatedAt, (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())) > this.options.ttl) {
|
|
869
|
-
this.revalidate();
|
|
870
|
-
}
|
|
871
|
-
return this.cache.result;
|
|
872
|
-
}
|
|
1165
|
+
Indefinite: "indefinite",
|
|
873
1166
|
/**
|
|
874
|
-
*
|
|
1167
|
+
* Represents that indexing of the chain should be performed for a definite range.
|
|
875
1168
|
*/
|
|
876
|
-
|
|
877
|
-
if (this.backgroundInterval) {
|
|
878
|
-
clearInterval(this.backgroundInterval);
|
|
879
|
-
this.backgroundInterval = null;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
1169
|
+
Definite: "definite"
|
|
882
1170
|
};
|
|
883
|
-
|
|
884
|
-
// src/shared/cache/ttl-cache.ts
|
|
885
|
-
var import_getUnixTime2 = require("date-fns/getUnixTime");
|
|
886
|
-
var TtlCache = class {
|
|
887
|
-
_cache = /* @__PURE__ */ new Map();
|
|
888
|
-
_ttl;
|
|
1171
|
+
var ChainIndexingStatusIds = {
|
|
889
1172
|
/**
|
|
890
|
-
*
|
|
1173
|
+
* Represents that indexing of the chain is not ready to begin yet because:
|
|
1174
|
+
* - ENSIndexer is in its initialization phase and the data to build a
|
|
1175
|
+
* "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
|
|
1176
|
+
* - ENSIndexer is using an omnichain indexing strategy and the
|
|
1177
|
+
* `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
|
|
1178
|
+
* {@link ChainIndexingSnapshot}.
|
|
1179
|
+
*/
|
|
1180
|
+
Queued: "chain-queued",
|
|
1181
|
+
/**
|
|
1182
|
+
* Represents that indexing of the chain is in progress and under a special
|
|
1183
|
+
* "backfill" phase that optimizes for accelerated indexing until reaching the
|
|
1184
|
+
* "fixed target" `backfillEndBlock`.
|
|
1185
|
+
*/
|
|
1186
|
+
Backfill: "chain-backfill",
|
|
1187
|
+
/**
|
|
1188
|
+
* Represents that the "backfill" phase of indexing the chain is completed
|
|
1189
|
+
* and that the chain is configured to be indexed for an indefinite range.
|
|
1190
|
+
* Therefore, indexing of the chain remains indefinitely in progress where
|
|
1191
|
+
* ENSIndexer will continuously work to discover and index new blocks as they
|
|
1192
|
+
* are added to the chain across time.
|
|
1193
|
+
*/
|
|
1194
|
+
Following: "chain-following",
|
|
1195
|
+
/**
|
|
1196
|
+
* Represents that indexing of the chain is completed as the chain is configured
|
|
1197
|
+
* to be indexed for a definite range and the indexing of all blocks through
|
|
1198
|
+
* that definite range is completed.
|
|
1199
|
+
*/
|
|
1200
|
+
Completed: "chain-completed"
|
|
1201
|
+
};
|
|
1202
|
+
var OmnichainIndexingStatusIds = {
|
|
1203
|
+
/**
|
|
1204
|
+
* Represents that omnichain indexing is not ready to begin yet because
|
|
1205
|
+
* ENSIndexer is in its initialization phase and the data to build a "true"
|
|
1206
|
+
* {@link OmnichainIndexingStatusSnapshot} is still being loaded.
|
|
1207
|
+
*/
|
|
1208
|
+
Unstarted: "omnichain-unstarted",
|
|
1209
|
+
/**
|
|
1210
|
+
* Represents that omnichain indexing is in an overall "backfill" status because
|
|
1211
|
+
* - At least one indexed chain has a `chainStatus` of
|
|
1212
|
+
* {@link ChainIndexingStatusIds.Backfill}; and
|
|
1213
|
+
* - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
|
|
1214
|
+
*/
|
|
1215
|
+
Backfill: "omnichain-backfill",
|
|
1216
|
+
/**
|
|
1217
|
+
* Represents that omnichain indexing is in an overall "following" status because
|
|
1218
|
+
* at least one indexed chain has a `chainStatus` of
|
|
1219
|
+
* {@link ChainIndexingStatusIds.Following}.
|
|
1220
|
+
*/
|
|
1221
|
+
Following: "omnichain-following",
|
|
1222
|
+
/**
|
|
1223
|
+
* Represents that omnichain indexing has completed because all indexed chains have
|
|
1224
|
+
* a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
|
|
1225
|
+
*/
|
|
1226
|
+
Completed: "omnichain-completed"
|
|
1227
|
+
};
|
|
1228
|
+
var CrossChainIndexingStrategyIds = {
|
|
1229
|
+
/**
|
|
1230
|
+
* Represents that the indexing of events across all indexed chains will
|
|
1231
|
+
* proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
|
|
1232
|
+
* and block number.
|
|
891
1233
|
*
|
|
892
|
-
*
|
|
1234
|
+
* This strategy is "deterministic" in that the order of processing cross-chain indexed
|
|
1235
|
+
* events and each resulting indexed data state transition recorded in ENSDb is always
|
|
1236
|
+
* the same for each ENSIndexer instance operating with an equivalent
|
|
1237
|
+
* `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
|
|
1238
|
+
* - increased indexing latency that must wait for the slowest indexed chain to
|
|
1239
|
+
* add new blocks or to discover new blocks through the configured RPCs.
|
|
1240
|
+
* - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
|
|
1241
|
+
* will be affected.
|
|
893
1242
|
*/
|
|
894
|
-
|
|
895
|
-
|
|
1243
|
+
Omnichain: "omnichain"
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
// src/shared/block-ref.ts
|
|
1247
|
+
function isBefore(blockA, blockB) {
|
|
1248
|
+
return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
|
|
1249
|
+
}
|
|
1250
|
+
function isEqualTo(blockA, blockB) {
|
|
1251
|
+
return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
|
|
1252
|
+
}
|
|
1253
|
+
function isBeforeOrEqualTo(blockA, blockB) {
|
|
1254
|
+
return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
// src/ensindexer/indexing-status/helpers.ts
|
|
1258
|
+
function getOmnichainIndexingStatus(chains) {
|
|
1259
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
|
|
1260
|
+
return OmnichainIndexingStatusIds.Following;
|
|
896
1261
|
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
for (const [key, entry] of this._cache.entries()) {
|
|
900
|
-
if (entry.expiresAt <= now) {
|
|
901
|
-
this._cache.delete(key);
|
|
902
|
-
}
|
|
903
|
-
}
|
|
1262
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
|
|
1263
|
+
return OmnichainIndexingStatusIds.Backfill;
|
|
904
1264
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
const expiresAt = addDuration((0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date()), this._ttl);
|
|
908
|
-
this._cache.set(key, { value, expiresAt });
|
|
1265
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
|
|
1266
|
+
return OmnichainIndexingStatusIds.Unstarted;
|
|
909
1267
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const entry = this._cache.get(key);
|
|
913
|
-
if (!entry) {
|
|
914
|
-
return void 0;
|
|
915
|
-
}
|
|
916
|
-
if (entry.expiresAt <= (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date())) {
|
|
917
|
-
this._cache.delete(key);
|
|
918
|
-
return void 0;
|
|
919
|
-
}
|
|
920
|
-
return entry.value;
|
|
1268
|
+
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
|
|
1269
|
+
return OmnichainIndexingStatusIds.Completed;
|
|
921
1270
|
}
|
|
922
|
-
|
|
923
|
-
|
|
1271
|
+
throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
|
|
1272
|
+
}
|
|
1273
|
+
function getTimestampForLowestOmnichainStartBlock(chains) {
|
|
1274
|
+
const earliestKnownBlockTimestamps = chains.map(
|
|
1275
|
+
(chain) => chain.config.startBlock.timestamp
|
|
1276
|
+
);
|
|
1277
|
+
return Math.min(...earliestKnownBlockTimestamps);
|
|
1278
|
+
}
|
|
1279
|
+
function getTimestampForHighestOmnichainKnownBlock(chains) {
|
|
1280
|
+
const latestKnownBlockTimestamps = [];
|
|
1281
|
+
for (const chain of chains) {
|
|
1282
|
+
switch (chain.chainStatus) {
|
|
1283
|
+
case ChainIndexingStatusIds.Queued:
|
|
1284
|
+
if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
|
|
1285
|
+
latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
|
|
1286
|
+
}
|
|
1287
|
+
break;
|
|
1288
|
+
case ChainIndexingStatusIds.Backfill:
|
|
1289
|
+
latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
|
|
1290
|
+
break;
|
|
1291
|
+
case ChainIndexingStatusIds.Completed:
|
|
1292
|
+
latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
|
|
1293
|
+
break;
|
|
1294
|
+
case ChainIndexingStatusIds.Following:
|
|
1295
|
+
latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
|
|
1296
|
+
break;
|
|
1297
|
+
}
|
|
924
1298
|
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1299
|
+
return Math.max(...latestKnownBlockTimestamps);
|
|
1300
|
+
}
|
|
1301
|
+
function getOmnichainIndexingCursor(chains) {
|
|
1302
|
+
if (chains.length === 0) {
|
|
1303
|
+
throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
|
|
928
1304
|
}
|
|
929
|
-
|
|
930
|
-
|
|
1305
|
+
if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
|
|
1306
|
+
const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1307
|
+
return Math.min(...earliestStartBlockTimestamps) - 1;
|
|
931
1308
|
}
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
if (!entry) {
|
|
936
|
-
return false;
|
|
937
|
-
}
|
|
938
|
-
if (entry.expiresAt <= (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date())) {
|
|
939
|
-
this._cache.delete(key);
|
|
940
|
-
return false;
|
|
941
|
-
}
|
|
942
|
-
return true;
|
|
1309
|
+
const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
|
|
1310
|
+
if (latestIndexedBlockTimestamps.length < 1) {
|
|
1311
|
+
throw new Error("latestIndexedBlockTimestamps array must include at least one element");
|
|
943
1312
|
}
|
|
944
|
-
|
|
945
|
-
|
|
1313
|
+
return Math.max(...latestIndexedBlockTimestamps);
|
|
1314
|
+
}
|
|
1315
|
+
function createIndexingConfig(startBlock, endBlock) {
|
|
1316
|
+
if (endBlock) {
|
|
1317
|
+
return {
|
|
1318
|
+
configType: ChainIndexingConfigTypeIds.Definite,
|
|
1319
|
+
startBlock,
|
|
1320
|
+
endBlock
|
|
1321
|
+
};
|
|
946
1322
|
}
|
|
947
|
-
};
|
|
948
|
-
|
|
949
|
-
// src/shared/collections.ts
|
|
950
|
-
var uniq = (arr) => [...new Set(arr)];
|
|
951
|
-
|
|
952
|
-
// src/shared/datasource-contract.ts
|
|
953
|
-
var import_datasources3 = require("@ensnode/datasources");
|
|
954
|
-
var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
955
|
-
const datasource = (0, import_datasources3.maybeGetDatasource)(namespaceId, datasourceName);
|
|
956
|
-
if (!datasource) return void 0;
|
|
957
|
-
const address = datasource.contracts[contractName]?.address;
|
|
958
|
-
if (address === void 0 || Array.isArray(address)) return void 0;
|
|
959
1323
|
return {
|
|
960
|
-
|
|
961
|
-
|
|
1324
|
+
configType: ChainIndexingConfigTypeIds.Indefinite,
|
|
1325
|
+
startBlock
|
|
962
1326
|
};
|
|
963
|
-
};
|
|
964
|
-
var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
965
|
-
const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
|
|
966
|
-
if (!contract) {
|
|
967
|
-
throw new Error(
|
|
968
|
-
`Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
|
|
969
|
-
);
|
|
970
|
-
}
|
|
971
|
-
return contract;
|
|
972
|
-
};
|
|
973
|
-
var makeContractMatcher = (namespace, b) => (datasourceName, contractName) => {
|
|
974
|
-
const a = maybeGetDatasourceContract(namespace, datasourceName, contractName);
|
|
975
|
-
return a && accountIdEqual(a, b);
|
|
976
|
-
};
|
|
977
|
-
|
|
978
|
-
// src/shared/interpretation/interpret-address.ts
|
|
979
|
-
var import_viem9 = require("viem");
|
|
980
|
-
var interpretAddress = (owner) => (0, import_viem9.isAddressEqual)(import_viem9.zeroAddress, owner) ? null : owner;
|
|
981
|
-
|
|
982
|
-
// src/shared/interpretation/interpret-record-values.ts
|
|
983
|
-
var import_viem10 = require("viem");
|
|
984
|
-
|
|
985
|
-
// src/shared/null-bytes.ts
|
|
986
|
-
var hasNullByte = (value) => value.indexOf("\0") !== -1;
|
|
987
|
-
var stripNullBytes = (value) => value.replaceAll("\0", "");
|
|
988
|
-
|
|
989
|
-
// src/shared/interpretation/interpret-record-values.ts
|
|
990
|
-
function interpretNameRecordValue(value) {
|
|
991
|
-
if (value === "") return null;
|
|
992
|
-
if (!isNormalizedName(value)) return null;
|
|
993
|
-
return value;
|
|
994
1327
|
}
|
|
995
|
-
function
|
|
996
|
-
|
|
997
|
-
if (value === "") return null;
|
|
998
|
-
if (value === "0x") return null;
|
|
999
|
-
if (!(0, import_viem10.isAddress)(value)) return value;
|
|
1000
|
-
if ((0, import_viem10.isAddressEqual)(value, import_viem10.zeroAddress)) return null;
|
|
1001
|
-
return asLowerCaseAddress(value);
|
|
1328
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
|
|
1329
|
+
return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
|
|
1002
1330
|
}
|
|
1003
|
-
function
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1331
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
|
|
1332
|
+
const atLeastOneChainInTargetStatus = chains.some(
|
|
1333
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1334
|
+
);
|
|
1335
|
+
const otherChainsHaveValidStatuses = chains.every(
|
|
1336
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1337
|
+
);
|
|
1338
|
+
return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
|
|
1007
1339
|
}
|
|
1008
|
-
function
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1340
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
|
|
1341
|
+
const allChainsHaveValidStatuses = chains.every(
|
|
1342
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1343
|
+
);
|
|
1344
|
+
return allChainsHaveValidStatuses;
|
|
1012
1345
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
1019
|
-
var import_viem12 = require("viem");
|
|
1020
|
-
var import_ens5 = require("viem/ens");
|
|
1021
|
-
|
|
1022
|
-
// src/shared/labelhash.ts
|
|
1023
|
-
var import_viem11 = require("viem");
|
|
1024
|
-
var labelhashLiteralLabel = (label) => (0, import_viem11.keccak256)((0, import_viem11.stringToBytes)(label));
|
|
1025
|
-
|
|
1026
|
-
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
1027
|
-
function literalLabelToInterpretedLabel(label) {
|
|
1028
|
-
if (isNormalizedLabel(label)) return label;
|
|
1029
|
-
return encodeLabelHash(labelhashLiteralLabel(label));
|
|
1346
|
+
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
|
|
1347
|
+
const allChainsHaveValidStatuses = chains.some(
|
|
1348
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1349
|
+
);
|
|
1350
|
+
return allChainsHaveValidStatuses;
|
|
1030
1351
|
}
|
|
1031
|
-
function
|
|
1032
|
-
|
|
1352
|
+
function sortChainStatusesByStartBlockAsc(chains) {
|
|
1353
|
+
chains.sort(
|
|
1354
|
+
([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
|
|
1355
|
+
);
|
|
1356
|
+
return chains;
|
|
1033
1357
|
}
|
|
1034
|
-
function
|
|
1035
|
-
|
|
1358
|
+
function getLatestIndexedBlockRef(indexingStatus, chainId) {
|
|
1359
|
+
const chainIndexingStatus = indexingStatus.omnichainSnapshot.chains.get(chainId);
|
|
1360
|
+
if (chainIndexingStatus === void 0) {
|
|
1361
|
+
return null;
|
|
1362
|
+
}
|
|
1363
|
+
if (chainIndexingStatus.chainStatus === ChainIndexingStatusIds.Queued) {
|
|
1364
|
+
return null;
|
|
1365
|
+
}
|
|
1366
|
+
return chainIndexingStatus.latestIndexedBlock;
|
|
1036
1367
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1368
|
+
|
|
1369
|
+
// src/ensindexer/indexing-status/validations.ts
|
|
1370
|
+
function invariant_chainSnapshotQueuedBlocks(ctx) {
|
|
1371
|
+
const { config } = ctx.value;
|
|
1372
|
+
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
|
|
1376
|
+
ctx.issues.push({
|
|
1377
|
+
code: "custom",
|
|
1378
|
+
input: ctx.value,
|
|
1379
|
+
message: "`config.startBlock` must be before or same as `config.endBlock`."
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1039
1382
|
}
|
|
1040
|
-
function
|
|
1041
|
-
|
|
1383
|
+
function invariant_chainSnapshotBackfillBlocks(ctx) {
|
|
1384
|
+
const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
|
|
1385
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1386
|
+
ctx.issues.push({
|
|
1387
|
+
code: "custom",
|
|
1388
|
+
input: ctx.value,
|
|
1389
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
|
|
1393
|
+
ctx.issues.push({
|
|
1394
|
+
code: "custom",
|
|
1395
|
+
input: ctx.value,
|
|
1396
|
+
message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
|
|
1403
|
+
ctx.issues.push({
|
|
1404
|
+
code: "custom",
|
|
1405
|
+
input: ctx.value,
|
|
1406
|
+
message: "`backfillEndBlock` must be the same as `config.endBlock`."
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1042
1409
|
}
|
|
1043
|
-
function
|
|
1044
|
-
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1410
|
+
function invariant_chainSnapshotCompletedBlocks(ctx) {
|
|
1411
|
+
const { config, latestIndexedBlock } = ctx.value;
|
|
1412
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1413
|
+
ctx.issues.push({
|
|
1414
|
+
code: "custom",
|
|
1415
|
+
input: ctx.value,
|
|
1416
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
|
|
1420
|
+
ctx.issues.push({
|
|
1421
|
+
code: "custom",
|
|
1422
|
+
input: ctx.value,
|
|
1423
|
+
message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1050
1426
|
}
|
|
1051
|
-
function
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1427
|
+
function invariant_chainSnapshotFollowingBlocks(ctx) {
|
|
1428
|
+
const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
|
|
1429
|
+
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1430
|
+
ctx.issues.push({
|
|
1431
|
+
code: "custom",
|
|
1432
|
+
input: ctx.value,
|
|
1433
|
+
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
|
|
1437
|
+
ctx.issues.push({
|
|
1438
|
+
code: "custom",
|
|
1439
|
+
input: ctx.value,
|
|
1440
|
+
message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
|
|
1441
|
+
});
|
|
1055
1442
|
}
|
|
1056
|
-
return isNormalizedLabel(label);
|
|
1057
1443
|
}
|
|
1058
|
-
function
|
|
1059
|
-
|
|
1444
|
+
function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
|
|
1445
|
+
const snapshot = ctx.value;
|
|
1446
|
+
const chains = Array.from(snapshot.chains.values());
|
|
1447
|
+
const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
|
|
1448
|
+
const actualOmnichainStatus = snapshot.omnichainStatus;
|
|
1449
|
+
if (expectedOmnichainStatus !== actualOmnichainStatus) {
|
|
1450
|
+
ctx.issues.push({
|
|
1451
|
+
code: "custom",
|
|
1452
|
+
input: snapshot,
|
|
1453
|
+
message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
|
|
1454
|
+
});
|
|
1455
|
+
}
|
|
1060
1456
|
}
|
|
1061
|
-
function
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1457
|
+
function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
|
|
1458
|
+
const snapshot = ctx.value;
|
|
1459
|
+
const queuedChains = Array.from(snapshot.chains.values()).filter(
|
|
1460
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
|
|
1461
|
+
);
|
|
1462
|
+
if (queuedChains.length === 0) {
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
|
|
1466
|
+
const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
|
|
1467
|
+
if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
|
|
1468
|
+
ctx.issues.push({
|
|
1469
|
+
code: "custom",
|
|
1470
|
+
input: snapshot,
|
|
1471
|
+
message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
|
|
1472
|
+
});
|
|
1473
|
+
}
|
|
1072
1474
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1475
|
+
function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
|
|
1476
|
+
const snapshot = ctx.value;
|
|
1477
|
+
const backfillChains = Array.from(snapshot.chains.values()).filter(
|
|
1478
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1479
|
+
);
|
|
1480
|
+
if (backfillChains.length === 0) {
|
|
1481
|
+
return;
|
|
1080
1482
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1483
|
+
const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
|
|
1484
|
+
const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
|
|
1485
|
+
if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
|
|
1486
|
+
ctx.issues.push({
|
|
1487
|
+
code: "custom",
|
|
1488
|
+
input: snapshot,
|
|
1489
|
+
message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
|
|
1490
|
+
});
|
|
1085
1491
|
}
|
|
1086
|
-
return Number(n);
|
|
1087
1492
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
}
|
|
1108
|
-
function serializePrice(price) {
|
|
1109
|
-
return {
|
|
1110
|
-
currency: price.currency,
|
|
1111
|
-
amount: price.amount.toString()
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
function serializePriceEth(price) {
|
|
1115
|
-
return serializePrice(price);
|
|
1116
|
-
}
|
|
1117
|
-
function formatAccountId(accountId) {
|
|
1118
|
-
return import_caip2.AccountId.format({
|
|
1119
|
-
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
1120
|
-
address: accountId.address
|
|
1121
|
-
}).toLowerCase();
|
|
1122
|
-
}
|
|
1123
|
-
function formatAssetId({
|
|
1124
|
-
assetNamespace,
|
|
1125
|
-
contract: { chainId, address },
|
|
1126
|
-
tokenId
|
|
1127
|
-
}) {
|
|
1128
|
-
return import_caip2.AssetId.format({
|
|
1129
|
-
chainId: { namespace: "eip155", reference: chainId.toString() },
|
|
1130
|
-
assetName: { namespace: assetNamespace, reference: address },
|
|
1131
|
-
tokenId: uint256ToHex32(tokenId)
|
|
1132
|
-
}).toLowerCase();
|
|
1493
|
+
function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
|
|
1494
|
+
const snapshot = ctx.value;
|
|
1495
|
+
const indexedChains = Array.from(snapshot.chains.values()).filter(
|
|
1496
|
+
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1497
|
+
);
|
|
1498
|
+
if (indexedChains.length === 0) {
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
const indexedChainLatestIndexedBlocks = indexedChains.map(
|
|
1502
|
+
(chain) => chain.latestIndexedBlock.timestamp
|
|
1503
|
+
);
|
|
1504
|
+
const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
|
|
1505
|
+
if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
|
|
1506
|
+
ctx.issues.push({
|
|
1507
|
+
code: "custom",
|
|
1508
|
+
input: snapshot,
|
|
1509
|
+
message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1133
1512
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1513
|
+
function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
|
|
1514
|
+
const chains = ctx.value;
|
|
1515
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
|
|
1516
|
+
Array.from(chains.values())
|
|
1517
|
+
);
|
|
1518
|
+
if (hasValidChains === false) {
|
|
1519
|
+
ctx.issues.push({
|
|
1520
|
+
code: "custom",
|
|
1521
|
+
input: chains,
|
|
1522
|
+
message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1144
1525
|
}
|
|
1145
|
-
function
|
|
1146
|
-
|
|
1526
|
+
function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
|
|
1527
|
+
const chains = ctx.value;
|
|
1528
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
|
|
1529
|
+
Array.from(chains.values())
|
|
1530
|
+
);
|
|
1531
|
+
if (hasValidChains === false) {
|
|
1532
|
+
ctx.issues.push({
|
|
1533
|
+
code: "custom",
|
|
1534
|
+
input: chains,
|
|
1535
|
+
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".`
|
|
1536
|
+
});
|
|
1537
|
+
}
|
|
1147
1538
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
PluginName2["TokenScope"] = "tokenscope";
|
|
1161
|
-
PluginName2["ENSv2"] = "ensv2";
|
|
1162
|
-
return PluginName2;
|
|
1163
|
-
})(PluginName || {});
|
|
1164
|
-
|
|
1165
|
-
// src/ensindexer/config/is-subgraph-compatible.ts
|
|
1166
|
-
function isSubgraphCompatible(config) {
|
|
1167
|
-
const onlySubgraphPluginActivated = config.plugins.length === 1 && config.plugins[0] === "subgraph" /* Subgraph */;
|
|
1168
|
-
const isSubgraphLabelSet = config.labelSet.labelSetId === "subgraph" && config.labelSet.labelSetVersion === 0;
|
|
1169
|
-
const isEnsTestEnvLabelSet = config.labelSet.labelSetId === "ens-test-env" && config.labelSet.labelSetVersion === 0;
|
|
1170
|
-
const labelSetIsSubgraphCompatible = isSubgraphLabelSet || config.namespace === import_datasources5.ENSNamespaceIds.EnsTestEnv && isEnsTestEnvLabelSet;
|
|
1171
|
-
return onlySubgraphPluginActivated && labelSetIsSubgraphCompatible;
|
|
1539
|
+
function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
|
|
1540
|
+
const chains = ctx.value;
|
|
1541
|
+
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
|
|
1542
|
+
Array.from(chains.values())
|
|
1543
|
+
);
|
|
1544
|
+
if (hasValidChains === false) {
|
|
1545
|
+
ctx.issues.push({
|
|
1546
|
+
code: "custom",
|
|
1547
|
+
input: chains,
|
|
1548
|
+
message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
|
|
1549
|
+
});
|
|
1550
|
+
}
|
|
1172
1551
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1552
|
+
function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
|
|
1553
|
+
const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
|
|
1554
|
+
const { omnichainIndexingCursor } = omnichainSnapshot;
|
|
1555
|
+
if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
|
|
1556
|
+
console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
|
|
1557
|
+
slowestChainIndexingCursor,
|
|
1558
|
+
omnichainIndexingCursor
|
|
1559
|
+
});
|
|
1178
1560
|
ctx.issues.push({
|
|
1179
1561
|
code: "custom",
|
|
1180
|
-
input:
|
|
1181
|
-
message:
|
|
1562
|
+
input: ctx.value,
|
|
1563
|
+
message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
|
|
1182
1564
|
});
|
|
1183
1565
|
}
|
|
1184
1566
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
};
|
|
1205
|
-
var makeLabelSetVersionSchema = (valueLabel) => {
|
|
1206
|
-
return import_v43.z.coerce.number({ error: `${valueLabel} must be an integer.` }).pipe(makeNonNegativeIntegerSchema(valueLabel));
|
|
1207
|
-
};
|
|
1208
|
-
var makeFullyPinnedLabelSetSchema = (valueLabel = "Label set") => {
|
|
1209
|
-
let valueLabelLabelSetId = valueLabel;
|
|
1210
|
-
let valueLabelLabelSetVersion = valueLabel;
|
|
1211
|
-
if (valueLabel === "LABEL_SET") {
|
|
1212
|
-
valueLabelLabelSetId = "LABEL_SET_ID";
|
|
1213
|
-
valueLabelLabelSetVersion = "LABEL_SET_VERSION";
|
|
1214
|
-
} else {
|
|
1215
|
-
valueLabelLabelSetId = `${valueLabel}.labelSetId`;
|
|
1216
|
-
valueLabelLabelSetVersion = `${valueLabel}.labelSetVersion`;
|
|
1567
|
+
function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
|
|
1568
|
+
const { snapshotTime, omnichainSnapshot } = ctx.value;
|
|
1569
|
+
const chains = Array.from(omnichainSnapshot.chains.values());
|
|
1570
|
+
const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1571
|
+
const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
|
|
1572
|
+
const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
|
|
1573
|
+
const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
|
|
1574
|
+
const highestKnownBlockTimestamp = Math.max(
|
|
1575
|
+
...startBlockTimestamps,
|
|
1576
|
+
...endBlockTimestamps,
|
|
1577
|
+
...backfillEndBlockTimestamps,
|
|
1578
|
+
...latestKnownBlockTimestamps
|
|
1579
|
+
);
|
|
1580
|
+
if (snapshotTime < highestKnownBlockTimestamp) {
|
|
1581
|
+
ctx.issues.push({
|
|
1582
|
+
code: "custom",
|
|
1583
|
+
input: ctx.value,
|
|
1584
|
+
message: `'snapshotTime' (${snapshotTime}) must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
|
|
1585
|
+
});
|
|
1217
1586
|
}
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
ensDb: makeNonEmptyStringSchema(),
|
|
1229
|
-
ensIndexer: makeNonEmptyStringSchema(),
|
|
1230
|
-
ensNormalize: makeNonEmptyStringSchema(),
|
|
1231
|
-
ensRainbow: makeNonEmptyStringSchema(),
|
|
1232
|
-
ensRainbowSchema: makePositiveIntegerSchema()
|
|
1233
|
-
},
|
|
1234
|
-
{
|
|
1235
|
-
error: `${valueLabel} must be a valid ENSIndexerVersionInfo object.`
|
|
1587
|
+
}
|
|
1588
|
+
function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
|
|
1589
|
+
const projection = ctx.value;
|
|
1590
|
+
const { snapshot, projectedAt } = projection;
|
|
1591
|
+
if (snapshot.snapshotTime > projectedAt) {
|
|
1592
|
+
ctx.issues.push({
|
|
1593
|
+
code: "custom",
|
|
1594
|
+
input: projection,
|
|
1595
|
+
message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
|
|
1596
|
+
});
|
|
1236
1597
|
}
|
|
1237
|
-
|
|
1238
|
-
function
|
|
1239
|
-
const
|
|
1240
|
-
|
|
1598
|
+
}
|
|
1599
|
+
function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
|
|
1600
|
+
const projection = ctx.value;
|
|
1601
|
+
const { projectedAt, snapshot, worstCaseDistance } = projection;
|
|
1602
|
+
const { omnichainSnapshot } = snapshot;
|
|
1603
|
+
const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
|
|
1604
|
+
if (worstCaseDistance !== expectedWorstCaseDistance) {
|
|
1241
1605
|
ctx.issues.push({
|
|
1242
1606
|
code: "custom",
|
|
1243
|
-
input:
|
|
1244
|
-
message: `
|
|
1607
|
+
input: projection,
|
|
1608
|
+
message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
|
|
1245
1609
|
});
|
|
1246
1610
|
}
|
|
1247
1611
|
}
|
|
1248
|
-
var makeENSIndexerPublicConfigSchema = (valueLabel = "ENSIndexerPublicConfig") => import_v43.z.object({
|
|
1249
|
-
labelSet: makeFullyPinnedLabelSetSchema(`${valueLabel}.labelSet`),
|
|
1250
|
-
indexedChainIds: makeIndexedChainIdsSchema(`${valueLabel}.indexedChainIds`),
|
|
1251
|
-
isSubgraphCompatible: import_v43.z.boolean({ error: `${valueLabel}.isSubgraphCompatible` }),
|
|
1252
|
-
namespace: makeENSNamespaceIdSchema(`${valueLabel}.namespace`),
|
|
1253
|
-
plugins: makePluginsListSchema(`${valueLabel}.plugins`),
|
|
1254
|
-
databaseSchemaName: makeDatabaseSchemaNameSchema(`${valueLabel}.databaseSchemaName`),
|
|
1255
|
-
versionInfo: makeENSIndexerVersionInfoSchema(`${valueLabel}.versionInfo`)
|
|
1256
|
-
}).check(invariant_isSubgraphCompatibleRequirements);
|
|
1257
1612
|
|
|
1258
|
-
// src/
|
|
1259
|
-
var
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
NoSubgraphUrl: "no-subgraph-url"
|
|
1264
|
-
});
|
|
1265
|
-
var TheGraphFallbackSchema = import_v44.z.discriminatedUnion("canFallback", [
|
|
1266
|
-
import_v44.z.strictObject({
|
|
1267
|
-
canFallback: import_v44.z.literal(true),
|
|
1268
|
-
url: import_v44.z.string()
|
|
1613
|
+
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1614
|
+
var makeChainIndexingConfigSchema = (valueLabel = "Value") => import_v48.z.discriminatedUnion("configType", [
|
|
1615
|
+
import_v48.z.strictObject({
|
|
1616
|
+
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1617
|
+
startBlock: makeBlockRefSchema(valueLabel)
|
|
1269
1618
|
}),
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1619
|
+
import_v48.z.strictObject({
|
|
1620
|
+
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1621
|
+
startBlock: makeBlockRefSchema(valueLabel),
|
|
1622
|
+
endBlock: makeBlockRefSchema(valueLabel)
|
|
1273
1623
|
})
|
|
1274
1624
|
]);
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1625
|
+
var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1626
|
+
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Queued),
|
|
1627
|
+
config: makeChainIndexingConfigSchema(valueLabel)
|
|
1628
|
+
}).check(invariant_chainSnapshotQueuedBlocks);
|
|
1629
|
+
var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1630
|
+
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Backfill),
|
|
1631
|
+
config: makeChainIndexingConfigSchema(valueLabel),
|
|
1632
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1633
|
+
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
1634
|
+
}).check(invariant_chainSnapshotBackfillBlocks);
|
|
1635
|
+
var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1636
|
+
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Completed),
|
|
1637
|
+
config: import_v48.z.strictObject({
|
|
1638
|
+
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1639
|
+
startBlock: makeBlockRefSchema(valueLabel),
|
|
1640
|
+
endBlock: makeBlockRefSchema(valueLabel)
|
|
1641
|
+
}),
|
|
1642
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel)
|
|
1643
|
+
}).check(invariant_chainSnapshotCompletedBlocks);
|
|
1644
|
+
var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1645
|
+
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Following),
|
|
1646
|
+
config: import_v48.z.strictObject({
|
|
1647
|
+
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1648
|
+
startBlock: makeBlockRefSchema(valueLabel)
|
|
1649
|
+
}),
|
|
1650
|
+
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1651
|
+
latestKnownBlock: makeBlockRefSchema(valueLabel)
|
|
1652
|
+
}).check(invariant_chainSnapshotFollowingBlocks);
|
|
1653
|
+
var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => import_v48.z.discriminatedUnion("chainStatus", [
|
|
1654
|
+
makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
|
|
1655
|
+
makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1656
|
+
makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1657
|
+
makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1658
|
+
]);
|
|
1659
|
+
var makeChainIndexingStatusesSchema = (valueLabel = "Value") => import_v48.z.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
|
|
1660
|
+
error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
|
|
1661
|
+
}).transform((serializedChainsIndexingStatus) => {
|
|
1662
|
+
const chainsIndexingStatus = /* @__PURE__ */ new Map();
|
|
1663
|
+
for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
|
|
1664
|
+
chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
|
|
1298
1665
|
}
|
|
1299
|
-
|
|
1666
|
+
return chainsIndexingStatus;
|
|
1667
|
+
});
|
|
1668
|
+
var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1669
|
+
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Unstarted),
|
|
1670
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
|
|
1671
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1672
|
+
});
|
|
1673
|
+
var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1674
|
+
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Backfill),
|
|
1675
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
|
|
1676
|
+
(chains) => chains
|
|
1677
|
+
),
|
|
1678
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1679
|
+
});
|
|
1680
|
+
var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1681
|
+
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Completed),
|
|
1682
|
+
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
|
|
1683
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1684
|
+
});
|
|
1685
|
+
var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1686
|
+
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Following),
|
|
1687
|
+
chains: makeChainIndexingStatusesSchema(valueLabel),
|
|
1688
|
+
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1689
|
+
});
|
|
1690
|
+
var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => import_v48.z.discriminatedUnion("omnichainStatus", [
|
|
1691
|
+
makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
|
|
1692
|
+
makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1693
|
+
makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1694
|
+
makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1695
|
+
]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
|
|
1696
|
+
invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
|
|
1697
|
+
).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
|
|
1698
|
+
var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => import_v48.z.strictObject({
|
|
1699
|
+
strategy: import_v48.z.literal(CrossChainIndexingStrategyIds.Omnichain),
|
|
1700
|
+
slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
|
|
1701
|
+
snapshotTime: makeUnixTimestampSchema(valueLabel),
|
|
1702
|
+
omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
|
|
1703
|
+
}).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
|
|
1704
|
+
var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => import_v48.z.discriminatedUnion("strategy", [
|
|
1705
|
+
makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
|
|
1706
|
+
]);
|
|
1707
|
+
var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => import_v48.z.strictObject({
|
|
1708
|
+
projectedAt: makeUnixTimestampSchema(valueLabel),
|
|
1709
|
+
worstCaseDistance: makeDurationSchema(valueLabel),
|
|
1710
|
+
snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
|
|
1711
|
+
}).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
|
|
1300
1712
|
|
|
1301
|
-
// src/ensindexer/
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
const
|
|
1305
|
-
const parsed = schema.safeParse(maybeConfig);
|
|
1713
|
+
// src/ensindexer/indexing-status/deserialize.ts
|
|
1714
|
+
function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1715
|
+
const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
|
|
1716
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
1306
1717
|
if (parsed.error) {
|
|
1307
|
-
throw new Error(
|
|
1308
|
-
|
|
1309
|
-
|
|
1718
|
+
throw new Error(
|
|
1719
|
+
`Cannot deserialize into ChainIndexingStatusSnapshot:
|
|
1720
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1721
|
+
`
|
|
1722
|
+
);
|
|
1310
1723
|
}
|
|
1311
1724
|
return parsed.data;
|
|
1312
1725
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
try {
|
|
1318
|
-
if (labelHash.length !== 66) {
|
|
1319
|
-
throw new Error(`Invalid labelHash length ${labelHash.length} characters (expected 66)`);
|
|
1320
|
-
}
|
|
1321
|
-
if (labelHash !== labelHash.toLowerCase()) {
|
|
1322
|
-
throw new Error("Labelhash must be in lowercase");
|
|
1323
|
-
}
|
|
1324
|
-
if (!labelHash.startsWith("0x")) {
|
|
1325
|
-
throw new Error("Labelhash must be 0x-prefixed");
|
|
1326
|
-
}
|
|
1327
|
-
const bytes = (0, import_viem13.hexToBytes)(labelHash);
|
|
1328
|
-
if (bytes.length !== 32) {
|
|
1329
|
-
throw new Error(`Invalid labelHash length ${bytes.length} bytes (expected 32)`);
|
|
1330
|
-
}
|
|
1331
|
-
return bytes;
|
|
1332
|
-
} catch (e) {
|
|
1333
|
-
if (e instanceof Error) {
|
|
1334
|
-
throw e;
|
|
1335
|
-
}
|
|
1336
|
-
throw new Error("Invalid hex format");
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
// src/ensindexer/config/labelset-utils.ts
|
|
1341
|
-
function buildLabelSetId(maybeLabelSetId) {
|
|
1342
|
-
return makeLabelSetIdSchema("LabelSetId").parse(maybeLabelSetId);
|
|
1343
|
-
}
|
|
1344
|
-
function buildLabelSetVersion(maybeLabelSetVersion) {
|
|
1345
|
-
return makeLabelSetVersionSchema("LabelSetVersion").parse(maybeLabelSetVersion);
|
|
1346
|
-
}
|
|
1347
|
-
function buildEnsRainbowClientLabelSet(labelSetId, labelSetVersion) {
|
|
1348
|
-
if (labelSetVersion !== void 0 && labelSetId === void 0) {
|
|
1349
|
-
throw new Error("When a labelSetVersion is defined, labelSetId must also be defined.");
|
|
1350
|
-
}
|
|
1351
|
-
return { labelSetId, labelSetVersion };
|
|
1352
|
-
}
|
|
1353
|
-
function validateSupportedLabelSetAndVersion(serverSet, clientSet) {
|
|
1354
|
-
if (clientSet.labelSetId === void 0) {
|
|
1355
|
-
return;
|
|
1356
|
-
}
|
|
1357
|
-
if (serverSet.labelSetId !== clientSet.labelSetId) {
|
|
1726
|
+
function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1727
|
+
const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
|
|
1728
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
1729
|
+
if (parsed.error) {
|
|
1358
1730
|
throw new Error(
|
|
1359
|
-
`
|
|
1731
|
+
`Cannot deserialize into OmnichainIndexingStatusSnapshot:
|
|
1732
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1733
|
+
`
|
|
1360
1734
|
);
|
|
1361
1735
|
}
|
|
1362
|
-
|
|
1736
|
+
return parsed.data;
|
|
1737
|
+
}
|
|
1738
|
+
function deserializeCrossChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1739
|
+
const schema = makeCrossChainIndexingStatusSnapshotSchema(valueLabel);
|
|
1740
|
+
const parsed = schema.safeParse(maybeSnapshot);
|
|
1741
|
+
if (parsed.error) {
|
|
1363
1742
|
throw new Error(
|
|
1364
|
-
`
|
|
1743
|
+
`Cannot deserialize into CrossChainIndexingStatusSnapshot:
|
|
1744
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1745
|
+
`
|
|
1365
1746
|
);
|
|
1366
1747
|
}
|
|
1748
|
+
return parsed.data;
|
|
1367
1749
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
}
|
|
1378
|
-
const num = Number(maybeNumber);
|
|
1379
|
-
if (Number.isNaN(num)) {
|
|
1380
|
-
throw new Error(`"${maybeNumber}" is not a valid number`);
|
|
1381
|
-
}
|
|
1382
|
-
if (!Number.isFinite(num)) {
|
|
1383
|
-
throw new Error(`"${maybeNumber}" is not a finite number`);
|
|
1384
|
-
}
|
|
1385
|
-
if (!Number.isInteger(num)) {
|
|
1386
|
-
throw new Error(`"${maybeNumber}" is not an integer`);
|
|
1387
|
-
}
|
|
1388
|
-
if (num < 0) {
|
|
1389
|
-
throw new Error(`"${maybeNumber}" is not a non-negative integer`);
|
|
1750
|
+
function deserializeRealtimeIndexingStatusProjection(maybeProjection, valueLabel) {
|
|
1751
|
+
const schema = makeRealtimeIndexingStatusProjectionSchema(valueLabel);
|
|
1752
|
+
const parsed = schema.safeParse(maybeProjection);
|
|
1753
|
+
if (parsed.error) {
|
|
1754
|
+
throw new Error(
|
|
1755
|
+
`Cannot deserialize into RealtimeIndexingStatusProjection:
|
|
1756
|
+
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1757
|
+
`
|
|
1758
|
+
);
|
|
1390
1759
|
}
|
|
1391
|
-
return
|
|
1760
|
+
return parsed.data;
|
|
1392
1761
|
}
|
|
1393
1762
|
|
|
1394
|
-
// src/ensindexer/
|
|
1395
|
-
function
|
|
1396
|
-
|
|
1397
|
-
}
|
|
1398
|
-
function serializeENSIndexerPublicConfig(config) {
|
|
1399
|
-
const {
|
|
1400
|
-
labelSet,
|
|
1401
|
-
indexedChainIds,
|
|
1402
|
-
databaseSchemaName,
|
|
1403
|
-
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1404
|
-
namespace,
|
|
1405
|
-
plugins,
|
|
1406
|
-
versionInfo
|
|
1407
|
-
} = config;
|
|
1763
|
+
// src/ensindexer/indexing-status/projection.ts
|
|
1764
|
+
function createRealtimeIndexingStatusProjection(snapshot, now) {
|
|
1765
|
+
const projectedAt = Math.max(now, snapshot.snapshotTime);
|
|
1408
1766
|
return {
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
isSubgraphCompatible: isSubgraphCompatible2,
|
|
1413
|
-
namespace,
|
|
1414
|
-
plugins,
|
|
1415
|
-
versionInfo
|
|
1767
|
+
projectedAt,
|
|
1768
|
+
worstCaseDistance: projectedAt - snapshot.slowestChainIndexingCursor,
|
|
1769
|
+
snapshot
|
|
1416
1770
|
};
|
|
1417
1771
|
}
|
|
1418
1772
|
|
|
1419
|
-
// src/
|
|
1420
|
-
var
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
var import_v48 = require("zod/v4");
|
|
1424
|
-
|
|
1425
|
-
// src/ensindexer/indexing-status/types.ts
|
|
1426
|
-
var ChainIndexingConfigTypeIds = {
|
|
1427
|
-
/**
|
|
1428
|
-
* Represents that indexing of the chain should be performed for an indefinite range.
|
|
1429
|
-
*/
|
|
1430
|
-
Indefinite: "indefinite",
|
|
1431
|
-
/**
|
|
1432
|
-
* Represents that indexing of the chain should be performed for a definite range.
|
|
1433
|
-
*/
|
|
1434
|
-
Definite: "definite"
|
|
1435
|
-
};
|
|
1436
|
-
var ChainIndexingStatusIds = {
|
|
1437
|
-
/**
|
|
1438
|
-
* Represents that indexing of the chain is not ready to begin yet because:
|
|
1439
|
-
* - ENSIndexer is in its initialization phase and the data to build a
|
|
1440
|
-
* "true" {@link ChainIndexingSnapshot} for the chain is still being loaded; or
|
|
1441
|
-
* - ENSIndexer is using an omnichain indexing strategy and the
|
|
1442
|
-
* `omnichainIndexingCursor` is <= `config.startBlock.timestamp` for the chain's
|
|
1443
|
-
* {@link ChainIndexingSnapshot}.
|
|
1444
|
-
*/
|
|
1445
|
-
Queued: "chain-queued",
|
|
1446
|
-
/**
|
|
1447
|
-
* Represents that indexing of the chain is in progress and under a special
|
|
1448
|
-
* "backfill" phase that optimizes for accelerated indexing until reaching the
|
|
1449
|
-
* "fixed target" `backfillEndBlock`.
|
|
1450
|
-
*/
|
|
1451
|
-
Backfill: "chain-backfill",
|
|
1452
|
-
/**
|
|
1453
|
-
* Represents that the "backfill" phase of indexing the chain is completed
|
|
1454
|
-
* and that the chain is configured to be indexed for an indefinite range.
|
|
1455
|
-
* Therefore, indexing of the chain remains indefinitely in progress where
|
|
1456
|
-
* ENSIndexer will continuously work to discover and index new blocks as they
|
|
1457
|
-
* are added to the chain across time.
|
|
1458
|
-
*/
|
|
1459
|
-
Following: "chain-following",
|
|
1460
|
-
/**
|
|
1461
|
-
* Represents that indexing of the chain is completed as the chain is configured
|
|
1462
|
-
* to be indexed for a definite range and the indexing of all blocks through
|
|
1463
|
-
* that definite range is completed.
|
|
1464
|
-
*/
|
|
1465
|
-
Completed: "chain-completed"
|
|
1466
|
-
};
|
|
1467
|
-
var OmnichainIndexingStatusIds = {
|
|
1468
|
-
/**
|
|
1469
|
-
* Represents that omnichain indexing is not ready to begin yet because
|
|
1470
|
-
* ENSIndexer is in its initialization phase and the data to build a "true"
|
|
1471
|
-
* {@link OmnichainIndexingStatusSnapshot} is still being loaded.
|
|
1472
|
-
*/
|
|
1473
|
-
Unstarted: "omnichain-unstarted",
|
|
1474
|
-
/**
|
|
1475
|
-
* Represents that omnichain indexing is in an overall "backfill" status because
|
|
1476
|
-
* - At least one indexed chain has a `chainStatus` of
|
|
1477
|
-
* {@link ChainIndexingStatusIds.Backfill}; and
|
|
1478
|
-
* - No indexed chain has a `chainStatus` of {@link ChainIndexingStatusIds.Following}.
|
|
1479
|
-
*/
|
|
1480
|
-
Backfill: "omnichain-backfill",
|
|
1481
|
-
/**
|
|
1482
|
-
* Represents that omnichain indexing is in an overall "following" status because
|
|
1483
|
-
* at least one indexed chain has a `chainStatus` of
|
|
1484
|
-
* {@link ChainIndexingStatusIds.Following}.
|
|
1485
|
-
*/
|
|
1486
|
-
Following: "omnichain-following",
|
|
1487
|
-
/**
|
|
1488
|
-
* Represents that omnichain indexing has completed because all indexed chains have
|
|
1489
|
-
* a `chainStatus` of {@link ChainIndexingStatusIds.Completed}.
|
|
1490
|
-
*/
|
|
1491
|
-
Completed: "omnichain-completed"
|
|
1492
|
-
};
|
|
1493
|
-
var CrossChainIndexingStrategyIds = {
|
|
1494
|
-
/**
|
|
1495
|
-
* Represents that the indexing of events across all indexed chains will
|
|
1496
|
-
* proceed in a deterministic "omnichain" ordering by block timestamp, chain ID,
|
|
1497
|
-
* and block number.
|
|
1498
|
-
*
|
|
1499
|
-
* This strategy is "deterministic" in that the order of processing cross-chain indexed
|
|
1500
|
-
* events and each resulting indexed data state transition recorded in ENSDb is always
|
|
1501
|
-
* the same for each ENSIndexer instance operating with an equivalent
|
|
1502
|
-
* `ENSIndexerConfig` and ENSIndexer version. However it also has the drawbacks of:
|
|
1503
|
-
* - increased indexing latency that must wait for the slowest indexed chain to
|
|
1504
|
-
* add new blocks or to discover new blocks through the configured RPCs.
|
|
1505
|
-
* - if any indexed chain gets "stuck" due to chain or RPC failures, all indexed chains
|
|
1506
|
-
* will be affected.
|
|
1507
|
-
*/
|
|
1508
|
-
Omnichain: "omnichain"
|
|
1509
|
-
};
|
|
1510
|
-
|
|
1511
|
-
// src/shared/block-ref.ts
|
|
1512
|
-
function isBefore(blockA, blockB) {
|
|
1513
|
-
return blockA.number < blockB.number && blockA.timestamp < blockB.timestamp;
|
|
1514
|
-
}
|
|
1515
|
-
function isEqualTo(blockA, blockB) {
|
|
1516
|
-
return blockA.number === blockB.number && blockA.timestamp === blockB.timestamp;
|
|
1517
|
-
}
|
|
1518
|
-
function isBeforeOrEqualTo(blockA, blockB) {
|
|
1519
|
-
return isBefore(blockA, blockB) || isEqualTo(blockA, blockB);
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
// src/ensindexer/indexing-status/helpers.ts
|
|
1523
|
-
function getOmnichainIndexingStatus(chains) {
|
|
1524
|
-
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains)) {
|
|
1525
|
-
return OmnichainIndexingStatusIds.Following;
|
|
1526
|
-
}
|
|
1527
|
-
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains)) {
|
|
1528
|
-
return OmnichainIndexingStatusIds.Backfill;
|
|
1529
|
-
}
|
|
1530
|
-
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains)) {
|
|
1531
|
-
return OmnichainIndexingStatusIds.Unstarted;
|
|
1532
|
-
}
|
|
1533
|
-
if (checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains)) {
|
|
1534
|
-
return OmnichainIndexingStatusIds.Completed;
|
|
1535
|
-
}
|
|
1536
|
-
throw new Error(`Unable to determine omnichain indexing status for provided chains.`);
|
|
1537
|
-
}
|
|
1538
|
-
function getTimestampForLowestOmnichainStartBlock(chains) {
|
|
1539
|
-
const earliestKnownBlockTimestamps = chains.map(
|
|
1540
|
-
(chain) => chain.config.startBlock.timestamp
|
|
1541
|
-
);
|
|
1542
|
-
return Math.min(...earliestKnownBlockTimestamps);
|
|
1543
|
-
}
|
|
1544
|
-
function getTimestampForHighestOmnichainKnownBlock(chains) {
|
|
1545
|
-
const latestKnownBlockTimestamps = [];
|
|
1546
|
-
for (const chain of chains) {
|
|
1547
|
-
switch (chain.chainStatus) {
|
|
1548
|
-
case ChainIndexingStatusIds.Queued:
|
|
1549
|
-
if (chain.config.configType === ChainIndexingConfigTypeIds.Definite && chain.config.endBlock) {
|
|
1550
|
-
latestKnownBlockTimestamps.push(chain.config.endBlock.timestamp);
|
|
1551
|
-
}
|
|
1552
|
-
break;
|
|
1553
|
-
case ChainIndexingStatusIds.Backfill:
|
|
1554
|
-
latestKnownBlockTimestamps.push(chain.backfillEndBlock.timestamp);
|
|
1555
|
-
break;
|
|
1556
|
-
case ChainIndexingStatusIds.Completed:
|
|
1557
|
-
latestKnownBlockTimestamps.push(chain.latestIndexedBlock.timestamp);
|
|
1558
|
-
break;
|
|
1559
|
-
case ChainIndexingStatusIds.Following:
|
|
1560
|
-
latestKnownBlockTimestamps.push(chain.latestKnownBlock.timestamp);
|
|
1561
|
-
break;
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
|
-
return Math.max(...latestKnownBlockTimestamps);
|
|
1565
|
-
}
|
|
1566
|
-
function getOmnichainIndexingCursor(chains) {
|
|
1567
|
-
if (chains.length === 0) {
|
|
1568
|
-
throw new Error(`Unable to determine omnichain indexing cursor when no chains were provided.`);
|
|
1569
|
-
}
|
|
1570
|
-
if (getOmnichainIndexingStatus(chains) === OmnichainIndexingStatusIds.Unstarted) {
|
|
1571
|
-
const earliestStartBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1572
|
-
return Math.min(...earliestStartBlockTimestamps) - 1;
|
|
1573
|
-
}
|
|
1574
|
-
const latestIndexedBlockTimestamps = chains.filter((chain) => chain.chainStatus !== ChainIndexingStatusIds.Queued).map((chain) => chain.latestIndexedBlock.timestamp);
|
|
1575
|
-
if (latestIndexedBlockTimestamps.length < 1) {
|
|
1576
|
-
throw new Error("latestIndexedBlockTimestamps array must include at least one element");
|
|
1577
|
-
}
|
|
1578
|
-
return Math.max(...latestIndexedBlockTimestamps);
|
|
1579
|
-
}
|
|
1580
|
-
function createIndexingConfig(startBlock, endBlock) {
|
|
1581
|
-
if (endBlock) {
|
|
1582
|
-
return {
|
|
1583
|
-
configType: ChainIndexingConfigTypeIds.Definite,
|
|
1584
|
-
startBlock,
|
|
1585
|
-
endBlock
|
|
1586
|
-
};
|
|
1587
|
-
}
|
|
1588
|
-
return {
|
|
1589
|
-
configType: ChainIndexingConfigTypeIds.Indefinite,
|
|
1590
|
-
startBlock
|
|
1591
|
-
};
|
|
1592
|
-
}
|
|
1593
|
-
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(chains) {
|
|
1594
|
-
return chains.every((chain) => chain.chainStatus === ChainIndexingStatusIds.Queued);
|
|
1595
|
-
}
|
|
1596
|
-
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(chains) {
|
|
1597
|
-
const atLeastOneChainInTargetStatus = chains.some(
|
|
1598
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1599
|
-
);
|
|
1600
|
-
const otherChainsHaveValidStatuses = chains.every(
|
|
1601
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued || chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1602
|
-
);
|
|
1603
|
-
return atLeastOneChainInTargetStatus && otherChainsHaveValidStatuses;
|
|
1604
|
-
}
|
|
1605
|
-
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(chains) {
|
|
1606
|
-
const allChainsHaveValidStatuses = chains.every(
|
|
1607
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Completed
|
|
1608
|
-
);
|
|
1609
|
-
return allChainsHaveValidStatuses;
|
|
1610
|
-
}
|
|
1611
|
-
function checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotFollowing(chains) {
|
|
1612
|
-
const allChainsHaveValidStatuses = chains.some(
|
|
1613
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1614
|
-
);
|
|
1615
|
-
return allChainsHaveValidStatuses;
|
|
1616
|
-
}
|
|
1617
|
-
function sortChainStatusesByStartBlockAsc(chains) {
|
|
1618
|
-
chains.sort(
|
|
1619
|
-
([, chainA], [, chainB]) => chainA.config.startBlock.timestamp - chainB.config.startBlock.timestamp
|
|
1620
|
-
);
|
|
1621
|
-
return chains;
|
|
1622
|
-
}
|
|
1623
|
-
function getLatestIndexedBlockRef(indexingStatus, chainId) {
|
|
1624
|
-
const chainIndexingStatus = indexingStatus.omnichainSnapshot.chains.get(chainId);
|
|
1625
|
-
if (chainIndexingStatus === void 0) {
|
|
1626
|
-
return null;
|
|
1627
|
-
}
|
|
1628
|
-
if (chainIndexingStatus.chainStatus === ChainIndexingStatusIds.Queued) {
|
|
1629
|
-
return null;
|
|
1630
|
-
}
|
|
1631
|
-
return chainIndexingStatus.latestIndexedBlock;
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
// src/ensindexer/indexing-status/validations.ts
|
|
1635
|
-
function invariant_chainSnapshotQueuedBlocks(ctx) {
|
|
1636
|
-
const { config } = ctx.value;
|
|
1637
|
-
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1638
|
-
return;
|
|
1639
|
-
}
|
|
1640
|
-
if (config.endBlock && isBeforeOrEqualTo(config.startBlock, config.endBlock) === false) {
|
|
1641
|
-
ctx.issues.push({
|
|
1642
|
-
code: "custom",
|
|
1643
|
-
input: ctx.value,
|
|
1644
|
-
message: "`config.startBlock` must be before or same as `config.endBlock`."
|
|
1645
|
-
});
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
function invariant_chainSnapshotBackfillBlocks(ctx) {
|
|
1649
|
-
const { config, latestIndexedBlock, backfillEndBlock } = ctx.value;
|
|
1650
|
-
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1651
|
-
ctx.issues.push({
|
|
1652
|
-
code: "custom",
|
|
1653
|
-
input: ctx.value,
|
|
1654
|
-
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1655
|
-
});
|
|
1656
|
-
}
|
|
1657
|
-
if (isBeforeOrEqualTo(latestIndexedBlock, backfillEndBlock) === false) {
|
|
1658
|
-
ctx.issues.push({
|
|
1659
|
-
code: "custom",
|
|
1660
|
-
input: ctx.value,
|
|
1661
|
-
message: "`latestIndexedBlock` must be before or same as `backfillEndBlock`."
|
|
1662
|
-
});
|
|
1663
|
-
}
|
|
1664
|
-
if (config.configType === ChainIndexingConfigTypeIds.Indefinite) {
|
|
1665
|
-
return;
|
|
1666
|
-
}
|
|
1667
|
-
if (config.endBlock && isEqualTo(backfillEndBlock, config.endBlock) === false) {
|
|
1668
|
-
ctx.issues.push({
|
|
1669
|
-
code: "custom",
|
|
1670
|
-
input: ctx.value,
|
|
1671
|
-
message: "`backfillEndBlock` must be the same as `config.endBlock`."
|
|
1672
|
-
});
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
function invariant_chainSnapshotCompletedBlocks(ctx) {
|
|
1676
|
-
const { config, latestIndexedBlock } = ctx.value;
|
|
1677
|
-
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1678
|
-
ctx.issues.push({
|
|
1679
|
-
code: "custom",
|
|
1680
|
-
input: ctx.value,
|
|
1681
|
-
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
if (isBeforeOrEqualTo(latestIndexedBlock, config.endBlock) === false) {
|
|
1685
|
-
ctx.issues.push({
|
|
1686
|
-
code: "custom",
|
|
1687
|
-
input: ctx.value,
|
|
1688
|
-
message: "`latestIndexedBlock` must be before or same as `config.endBlock`."
|
|
1689
|
-
});
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
function invariant_chainSnapshotFollowingBlocks(ctx) {
|
|
1693
|
-
const { config, latestIndexedBlock, latestKnownBlock } = ctx.value;
|
|
1694
|
-
if (isBeforeOrEqualTo(config.startBlock, latestIndexedBlock) === false) {
|
|
1695
|
-
ctx.issues.push({
|
|
1696
|
-
code: "custom",
|
|
1697
|
-
input: ctx.value,
|
|
1698
|
-
message: "`config.startBlock` must be before or same as `latestIndexedBlock`."
|
|
1699
|
-
});
|
|
1700
|
-
}
|
|
1701
|
-
if (isBeforeOrEqualTo(latestIndexedBlock, latestKnownBlock) === false) {
|
|
1702
|
-
ctx.issues.push({
|
|
1703
|
-
code: "custom",
|
|
1704
|
-
input: ctx.value,
|
|
1705
|
-
message: "`latestIndexedBlock` must be before or same as `latestKnownBlock`."
|
|
1706
|
-
});
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
function invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot(ctx) {
|
|
1710
|
-
const snapshot = ctx.value;
|
|
1711
|
-
const chains = Array.from(snapshot.chains.values());
|
|
1712
|
-
const expectedOmnichainStatus = getOmnichainIndexingStatus(chains);
|
|
1713
|
-
const actualOmnichainStatus = snapshot.omnichainStatus;
|
|
1714
|
-
if (expectedOmnichainStatus !== actualOmnichainStatus) {
|
|
1715
|
-
ctx.issues.push({
|
|
1716
|
-
code: "custom",
|
|
1717
|
-
input: snapshot,
|
|
1718
|
-
message: `'${actualOmnichainStatus}' is an invalid omnichainStatus. Expected '${expectedOmnichainStatus}' based on the statuses of individual chains.`
|
|
1719
|
-
});
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
function invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains(ctx) {
|
|
1723
|
-
const snapshot = ctx.value;
|
|
1724
|
-
const queuedChains = Array.from(snapshot.chains.values()).filter(
|
|
1725
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Queued
|
|
1726
|
-
);
|
|
1727
|
-
if (queuedChains.length === 0) {
|
|
1728
|
-
return;
|
|
1729
|
-
}
|
|
1730
|
-
const queuedChainStartBlocks = queuedChains.map((chain) => chain.config.startBlock.timestamp);
|
|
1731
|
-
const queuedChainEarliestStartBlock = Math.min(...queuedChainStartBlocks);
|
|
1732
|
-
if (snapshot.omnichainIndexingCursor >= queuedChainEarliestStartBlock) {
|
|
1733
|
-
ctx.issues.push({
|
|
1734
|
-
code: "custom",
|
|
1735
|
-
input: snapshot,
|
|
1736
|
-
message: "`omnichainIndexingCursor` must be lower than the earliest start block across all queued chains."
|
|
1737
|
-
});
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
function invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains(ctx) {
|
|
1741
|
-
const snapshot = ctx.value;
|
|
1742
|
-
const backfillChains = Array.from(snapshot.chains.values()).filter(
|
|
1743
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill
|
|
1744
|
-
);
|
|
1745
|
-
if (backfillChains.length === 0) {
|
|
1746
|
-
return;
|
|
1747
|
-
}
|
|
1748
|
-
const backfillEndBlocks = backfillChains.map((chain) => chain.backfillEndBlock.timestamp);
|
|
1749
|
-
const highestBackfillEndBlock = Math.max(...backfillEndBlocks);
|
|
1750
|
-
if (snapshot.omnichainIndexingCursor > highestBackfillEndBlock) {
|
|
1751
|
-
ctx.issues.push({
|
|
1752
|
-
code: "custom",
|
|
1753
|
-
input: snapshot,
|
|
1754
|
-
message: "`omnichainIndexingCursor` must be lower than or equal to the highest `backfillEndBlock` across all backfill chains."
|
|
1755
|
-
});
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
function invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain(ctx) {
|
|
1759
|
-
const snapshot = ctx.value;
|
|
1760
|
-
const indexedChains = Array.from(snapshot.chains.values()).filter(
|
|
1761
|
-
(chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill || chain.chainStatus === ChainIndexingStatusIds.Completed || chain.chainStatus === ChainIndexingStatusIds.Following
|
|
1762
|
-
);
|
|
1763
|
-
if (indexedChains.length === 0) {
|
|
1764
|
-
return;
|
|
1765
|
-
}
|
|
1766
|
-
const indexedChainLatestIndexedBlocks = indexedChains.map(
|
|
1767
|
-
(chain) => chain.latestIndexedBlock.timestamp
|
|
1768
|
-
);
|
|
1769
|
-
const indexedChainHighestLatestIndexedBlock = Math.max(...indexedChainLatestIndexedBlocks);
|
|
1770
|
-
if (snapshot.omnichainIndexingCursor !== indexedChainHighestLatestIndexedBlock) {
|
|
1771
|
-
ctx.issues.push({
|
|
1772
|
-
code: "custom",
|
|
1773
|
-
input: snapshot,
|
|
1774
|
-
message: "`omnichainIndexingCursor` must be same as the highest `latestIndexedBlock` across all indexed chains."
|
|
1775
|
-
});
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
function invariant_omnichainSnapshotUnstartedHasValidChains(ctx) {
|
|
1779
|
-
const chains = ctx.value;
|
|
1780
|
-
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotUnstarted(
|
|
1781
|
-
Array.from(chains.values())
|
|
1782
|
-
);
|
|
1783
|
-
if (hasValidChains === false) {
|
|
1784
|
-
ctx.issues.push({
|
|
1785
|
-
code: "custom",
|
|
1786
|
-
input: chains,
|
|
1787
|
-
message: `For omnichain status snapshot 'unstarted', all chains must have "queued" status.`
|
|
1788
|
-
});
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
function invariant_omnichainStatusSnapshotBackfillHasValidChains(ctx) {
|
|
1792
|
-
const chains = ctx.value;
|
|
1793
|
-
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotBackfill(
|
|
1794
|
-
Array.from(chains.values())
|
|
1795
|
-
);
|
|
1796
|
-
if (hasValidChains === false) {
|
|
1797
|
-
ctx.issues.push({
|
|
1798
|
-
code: "custom",
|
|
1799
|
-
input: chains,
|
|
1800
|
-
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".`
|
|
1801
|
-
});
|
|
1802
|
-
}
|
|
1803
|
-
}
|
|
1804
|
-
function invariant_omnichainStatusSnapshotCompletedHasValidChains(ctx) {
|
|
1805
|
-
const chains = ctx.value;
|
|
1806
|
-
const hasValidChains = checkChainIndexingStatusSnapshotsForOmnichainStatusSnapshotCompleted(
|
|
1807
|
-
Array.from(chains.values())
|
|
1808
|
-
);
|
|
1809
|
-
if (hasValidChains === false) {
|
|
1810
|
-
ctx.issues.push({
|
|
1811
|
-
code: "custom",
|
|
1812
|
-
input: chains,
|
|
1813
|
-
message: `For omnichain status snapshot 'completed', all chains must have "completed" status.`
|
|
1814
|
-
});
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
function invariant_slowestChainEqualsToOmnichainSnapshotTime(ctx) {
|
|
1818
|
-
const { slowestChainIndexingCursor, omnichainSnapshot } = ctx.value;
|
|
1819
|
-
const { omnichainIndexingCursor } = omnichainSnapshot;
|
|
1820
|
-
if (slowestChainIndexingCursor !== omnichainIndexingCursor) {
|
|
1821
|
-
console.log("invariant_slowestChainEqualsToOmnichainSnapshotTime", {
|
|
1822
|
-
slowestChainIndexingCursor,
|
|
1823
|
-
omnichainIndexingCursor
|
|
1824
|
-
});
|
|
1825
|
-
ctx.issues.push({
|
|
1826
|
-
code: "custom",
|
|
1827
|
-
input: ctx.value,
|
|
1828
|
-
message: `'slowestChainIndexingCursor' must be equal to 'omnichainSnapshot.omnichainIndexingCursor'`
|
|
1829
|
-
});
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
|
-
function invariant_snapshotTimeIsTheHighestKnownBlockTimestamp(ctx) {
|
|
1833
|
-
const { snapshotTime, omnichainSnapshot } = ctx.value;
|
|
1834
|
-
const chains = Array.from(omnichainSnapshot.chains.values());
|
|
1835
|
-
const startBlockTimestamps = chains.map((chain) => chain.config.startBlock.timestamp);
|
|
1836
|
-
const endBlockTimestamps = chains.map((chain) => chain.config).filter((chainConfig) => chainConfig.configType === ChainIndexingConfigTypeIds.Definite).map((chainConfig) => chainConfig.endBlock.timestamp);
|
|
1837
|
-
const backfillEndBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Backfill).map((chain) => chain.backfillEndBlock.timestamp);
|
|
1838
|
-
const latestKnownBlockTimestamps = chains.filter((chain) => chain.chainStatus === ChainIndexingStatusIds.Following).map((chain) => chain.latestKnownBlock.timestamp);
|
|
1839
|
-
const highestKnownBlockTimestamp = Math.max(
|
|
1840
|
-
...startBlockTimestamps,
|
|
1841
|
-
...endBlockTimestamps,
|
|
1842
|
-
...backfillEndBlockTimestamps,
|
|
1843
|
-
...latestKnownBlockTimestamps
|
|
1844
|
-
);
|
|
1845
|
-
if (snapshotTime < highestKnownBlockTimestamp) {
|
|
1846
|
-
ctx.issues.push({
|
|
1847
|
-
code: "custom",
|
|
1848
|
-
input: ctx.value,
|
|
1849
|
-
message: `'snapshotTime' (${snapshotTime}) must be greater than or equal to the "highest known block timestamp" (${highestKnownBlockTimestamp})`
|
|
1850
|
-
});
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
function invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime(ctx) {
|
|
1854
|
-
const projection = ctx.value;
|
|
1855
|
-
const { snapshot, projectedAt } = projection;
|
|
1856
|
-
if (snapshot.snapshotTime > projectedAt) {
|
|
1857
|
-
ctx.issues.push({
|
|
1858
|
-
code: "custom",
|
|
1859
|
-
input: projection,
|
|
1860
|
-
message: "`projectedAt` must be after or same as `snapshot.snapshotTime`."
|
|
1861
|
-
});
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
function invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect(ctx) {
|
|
1865
|
-
const projection = ctx.value;
|
|
1866
|
-
const { projectedAt, snapshot, worstCaseDistance } = projection;
|
|
1867
|
-
const { omnichainSnapshot } = snapshot;
|
|
1868
|
-
const expectedWorstCaseDistance = projectedAt - omnichainSnapshot.omnichainIndexingCursor;
|
|
1869
|
-
if (worstCaseDistance !== expectedWorstCaseDistance) {
|
|
1870
|
-
ctx.issues.push({
|
|
1871
|
-
code: "custom",
|
|
1872
|
-
input: projection,
|
|
1873
|
-
message: "`worstCaseDistance` must be the exact difference between `projectedAt` and `snapshot.omnichainIndexingCursor`."
|
|
1874
|
-
});
|
|
1875
|
-
}
|
|
1876
|
-
}
|
|
1877
|
-
|
|
1878
|
-
// src/ensindexer/indexing-status/zod-schemas.ts
|
|
1879
|
-
var makeChainIndexingConfigSchema = (valueLabel = "Value") => import_v48.z.discriminatedUnion("configType", [
|
|
1880
|
-
import_v48.z.strictObject({
|
|
1881
|
-
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1882
|
-
startBlock: makeBlockRefSchema(valueLabel)
|
|
1883
|
-
}),
|
|
1884
|
-
import_v48.z.strictObject({
|
|
1885
|
-
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1886
|
-
startBlock: makeBlockRefSchema(valueLabel),
|
|
1887
|
-
endBlock: makeBlockRefSchema(valueLabel)
|
|
1888
|
-
})
|
|
1889
|
-
]);
|
|
1890
|
-
var makeChainIndexingStatusSnapshotQueuedSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1891
|
-
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Queued),
|
|
1892
|
-
config: makeChainIndexingConfigSchema(valueLabel)
|
|
1893
|
-
}).check(invariant_chainSnapshotQueuedBlocks);
|
|
1894
|
-
var makeChainIndexingStatusSnapshotBackfillSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1895
|
-
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Backfill),
|
|
1896
|
-
config: makeChainIndexingConfigSchema(valueLabel),
|
|
1897
|
-
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1898
|
-
backfillEndBlock: makeBlockRefSchema(valueLabel)
|
|
1899
|
-
}).check(invariant_chainSnapshotBackfillBlocks);
|
|
1900
|
-
var makeChainIndexingStatusSnapshotCompletedSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1901
|
-
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Completed),
|
|
1902
|
-
config: import_v48.z.strictObject({
|
|
1903
|
-
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Definite),
|
|
1904
|
-
startBlock: makeBlockRefSchema(valueLabel),
|
|
1905
|
-
endBlock: makeBlockRefSchema(valueLabel)
|
|
1906
|
-
}),
|
|
1907
|
-
latestIndexedBlock: makeBlockRefSchema(valueLabel)
|
|
1908
|
-
}).check(invariant_chainSnapshotCompletedBlocks);
|
|
1909
|
-
var makeChainIndexingStatusSnapshotFollowingSchema = (valueLabel = "Value") => import_v48.z.strictObject({
|
|
1910
|
-
chainStatus: import_v48.z.literal(ChainIndexingStatusIds.Following),
|
|
1911
|
-
config: import_v48.z.strictObject({
|
|
1912
|
-
configType: import_v48.z.literal(ChainIndexingConfigTypeIds.Indefinite),
|
|
1913
|
-
startBlock: makeBlockRefSchema(valueLabel)
|
|
1914
|
-
}),
|
|
1915
|
-
latestIndexedBlock: makeBlockRefSchema(valueLabel),
|
|
1916
|
-
latestKnownBlock: makeBlockRefSchema(valueLabel)
|
|
1917
|
-
}).check(invariant_chainSnapshotFollowingBlocks);
|
|
1918
|
-
var makeChainIndexingStatusSnapshotSchema = (valueLabel = "Value") => import_v48.z.discriminatedUnion("chainStatus", [
|
|
1919
|
-
makeChainIndexingStatusSnapshotQueuedSchema(valueLabel),
|
|
1920
|
-
makeChainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1921
|
-
makeChainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1922
|
-
makeChainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1923
|
-
]);
|
|
1924
|
-
var makeChainIndexingStatusesSchema = (valueLabel = "Value") => import_v48.z.record(makeChainIdStringSchema(), makeChainIndexingStatusSnapshotSchema(valueLabel), {
|
|
1925
|
-
error: "Chains indexing statuses must be an object mapping valid chain IDs to their indexing status snapshots."
|
|
1926
|
-
}).transform((serializedChainsIndexingStatus) => {
|
|
1927
|
-
const chainsIndexingStatus = /* @__PURE__ */ new Map();
|
|
1928
|
-
for (const [chainIdString, chainStatus] of Object.entries(serializedChainsIndexingStatus)) {
|
|
1929
|
-
chainsIndexingStatus.set(deserializeChainId(chainIdString), chainStatus);
|
|
1930
|
-
}
|
|
1931
|
-
return chainsIndexingStatus;
|
|
1932
|
-
});
|
|
1933
|
-
var makeOmnichainIndexingStatusSnapshotUnstartedSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1934
|
-
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Unstarted),
|
|
1935
|
-
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainSnapshotUnstartedHasValidChains).transform((chains) => chains),
|
|
1936
|
-
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1937
|
-
});
|
|
1938
|
-
var makeOmnichainIndexingStatusSnapshotBackfillSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1939
|
-
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Backfill),
|
|
1940
|
-
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotBackfillHasValidChains).transform(
|
|
1941
|
-
(chains) => chains
|
|
1942
|
-
),
|
|
1943
|
-
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1944
|
-
});
|
|
1945
|
-
var makeOmnichainIndexingStatusSnapshotCompletedSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1946
|
-
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Completed),
|
|
1947
|
-
chains: makeChainIndexingStatusesSchema(valueLabel).check(invariant_omnichainStatusSnapshotCompletedHasValidChains).transform((chains) => chains),
|
|
1948
|
-
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1949
|
-
});
|
|
1950
|
-
var makeOmnichainIndexingStatusSnapshotFollowingSchema = (valueLabel) => import_v48.z.strictObject({
|
|
1951
|
-
omnichainStatus: import_v48.z.literal(OmnichainIndexingStatusIds.Following),
|
|
1952
|
-
chains: makeChainIndexingStatusesSchema(valueLabel),
|
|
1953
|
-
omnichainIndexingCursor: makeUnixTimestampSchema(valueLabel)
|
|
1954
|
-
});
|
|
1955
|
-
var makeOmnichainIndexingStatusSnapshotSchema = (valueLabel = "Omnichain Indexing Snapshot") => import_v48.z.discriminatedUnion("omnichainStatus", [
|
|
1956
|
-
makeOmnichainIndexingStatusSnapshotUnstartedSchema(valueLabel),
|
|
1957
|
-
makeOmnichainIndexingStatusSnapshotBackfillSchema(valueLabel),
|
|
1958
|
-
makeOmnichainIndexingStatusSnapshotCompletedSchema(valueLabel),
|
|
1959
|
-
makeOmnichainIndexingStatusSnapshotFollowingSchema(valueLabel)
|
|
1960
|
-
]).check(invariant_omnichainSnapshotStatusIsConsistentWithChainSnapshot).check(invariant_omnichainIndexingCursorLowerThanEarliestStartBlockAcrossQueuedChains).check(
|
|
1961
|
-
invariant_omnichainIndexingCursorLowerThanOrEqualToLatestBackfillEndBlockAcrossBackfillChains
|
|
1962
|
-
).check(invariant_omnichainIndexingCursorIsEqualToHighestLatestIndexedBlockAcrossIndexedChain);
|
|
1963
|
-
var makeCrossChainIndexingStatusSnapshotOmnichainSchema = (valueLabel = "Cross-chain Indexing Status Snapshot Omnichain") => import_v48.z.strictObject({
|
|
1964
|
-
strategy: import_v48.z.literal(CrossChainIndexingStrategyIds.Omnichain),
|
|
1965
|
-
slowestChainIndexingCursor: makeUnixTimestampSchema(valueLabel),
|
|
1966
|
-
snapshotTime: makeUnixTimestampSchema(valueLabel),
|
|
1967
|
-
omnichainSnapshot: makeOmnichainIndexingStatusSnapshotSchema(valueLabel)
|
|
1968
|
-
}).check(invariant_slowestChainEqualsToOmnichainSnapshotTime).check(invariant_snapshotTimeIsTheHighestKnownBlockTimestamp);
|
|
1969
|
-
var makeCrossChainIndexingStatusSnapshotSchema = (valueLabel = "Cross-chain Indexing Status Snapshot") => import_v48.z.discriminatedUnion("strategy", [
|
|
1970
|
-
makeCrossChainIndexingStatusSnapshotOmnichainSchema(valueLabel)
|
|
1971
|
-
]);
|
|
1972
|
-
var makeRealtimeIndexingStatusProjectionSchema = (valueLabel = "Realtime Indexing Status Projection") => import_v48.z.strictObject({
|
|
1973
|
-
projectedAt: makeUnixTimestampSchema(valueLabel),
|
|
1974
|
-
worstCaseDistance: makeDurationSchema(valueLabel),
|
|
1975
|
-
snapshot: makeCrossChainIndexingStatusSnapshotSchema(valueLabel)
|
|
1976
|
-
}).check(invariant_realtimeIndexingStatusProjectionProjectedAtIsAfterOrEqualToSnapshotTime).check(invariant_realtimeIndexingStatusProjectionWorstCaseDistanceIsCorrect);
|
|
1977
|
-
|
|
1978
|
-
// src/ensindexer/indexing-status/deserialize.ts
|
|
1979
|
-
function deserializeChainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1980
|
-
const schema = makeChainIndexingStatusSnapshotSchema(valueLabel);
|
|
1981
|
-
const parsed = schema.safeParse(maybeSnapshot);
|
|
1982
|
-
if (parsed.error) {
|
|
1983
|
-
throw new Error(
|
|
1984
|
-
`Cannot deserialize into ChainIndexingStatusSnapshot:
|
|
1985
|
-
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1986
|
-
`
|
|
1987
|
-
);
|
|
1988
|
-
}
|
|
1989
|
-
return parsed.data;
|
|
1990
|
-
}
|
|
1991
|
-
function deserializeOmnichainIndexingStatusSnapshot(maybeSnapshot, valueLabel) {
|
|
1992
|
-
const schema = makeOmnichainIndexingStatusSnapshotSchema(valueLabel);
|
|
1993
|
-
const parsed = schema.safeParse(maybeSnapshot);
|
|
1994
|
-
if (parsed.error) {
|
|
1995
|
-
throw new Error(
|
|
1996
|
-
`Cannot deserialize into OmnichainIndexingStatusSnapshot:
|
|
1997
|
-
${(0, import_v49.prettifyError)(parsed.error)}
|
|
1998
|
-
`
|
|
1999
|
-
);
|
|
2000
|
-
}
|
|
2001
|
-
return parsed.data;
|
|
1773
|
+
// src/shared/serialize.ts
|
|
1774
|
+
var import_caip2 = require("caip");
|
|
1775
|
+
function serializeChainId(chainId) {
|
|
1776
|
+
return chainId.toString();
|
|
2002
1777
|
}
|
|
2003
|
-
function
|
|
2004
|
-
|
|
2005
|
-
const parsed = schema.safeParse(maybeSnapshot);
|
|
2006
|
-
if (parsed.error) {
|
|
2007
|
-
throw new Error(
|
|
2008
|
-
`Cannot deserialize into CrossChainIndexingStatusSnapshot:
|
|
2009
|
-
${(0, import_v49.prettifyError)(parsed.error)}
|
|
2010
|
-
`
|
|
2011
|
-
);
|
|
2012
|
-
}
|
|
2013
|
-
return parsed.data;
|
|
1778
|
+
function serializeDatetime(datetime) {
|
|
1779
|
+
return datetime.toISOString();
|
|
2014
1780
|
}
|
|
2015
|
-
function
|
|
2016
|
-
|
|
2017
|
-
const parsed = schema.safeParse(maybeProjection);
|
|
2018
|
-
if (parsed.error) {
|
|
2019
|
-
throw new Error(
|
|
2020
|
-
`Cannot deserialize into RealtimeIndexingStatusProjection:
|
|
2021
|
-
${(0, import_v49.prettifyError)(parsed.error)}
|
|
2022
|
-
`
|
|
2023
|
-
);
|
|
2024
|
-
}
|
|
2025
|
-
return parsed.data;
|
|
1781
|
+
function serializeUrl(url) {
|
|
1782
|
+
return url.toString();
|
|
2026
1783
|
}
|
|
2027
|
-
|
|
2028
|
-
// src/ensindexer/indexing-status/projection.ts
|
|
2029
|
-
function createRealtimeIndexingStatusProjection(snapshot, now) {
|
|
2030
|
-
const projectedAt = Math.max(now, snapshot.snapshotTime);
|
|
1784
|
+
function serializePrice(price) {
|
|
2031
1785
|
return {
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
snapshot
|
|
1786
|
+
currency: price.currency,
|
|
1787
|
+
amount: price.amount.toString()
|
|
2035
1788
|
};
|
|
2036
1789
|
}
|
|
1790
|
+
function serializePriceEth(price) {
|
|
1791
|
+
return serializePrice(price);
|
|
1792
|
+
}
|
|
1793
|
+
function serializePriceUsdc(price) {
|
|
1794
|
+
return serializePrice(price);
|
|
1795
|
+
}
|
|
1796
|
+
function serializePriceDai(price) {
|
|
1797
|
+
return serializePrice(price);
|
|
1798
|
+
}
|
|
1799
|
+
function formatAccountId(accountId) {
|
|
1800
|
+
return import_caip2.AccountId.format({
|
|
1801
|
+
chainId: { namespace: "eip155", reference: accountId.chainId.toString() },
|
|
1802
|
+
address: accountId.address
|
|
1803
|
+
}).toLowerCase();
|
|
1804
|
+
}
|
|
1805
|
+
function formatAssetId({
|
|
1806
|
+
assetNamespace,
|
|
1807
|
+
contract: { chainId, address },
|
|
1808
|
+
tokenId
|
|
1809
|
+
}) {
|
|
1810
|
+
return import_caip2.AssetId.format({
|
|
1811
|
+
chainId: { namespace: "eip155", reference: chainId.toString() },
|
|
1812
|
+
assetName: { namespace: assetNamespace, reference: address },
|
|
1813
|
+
tokenId: uint256ToHex32(tokenId)
|
|
1814
|
+
}).toLowerCase();
|
|
1815
|
+
}
|
|
2037
1816
|
|
|
2038
1817
|
// src/ensindexer/indexing-status/serialize.ts
|
|
2039
1818
|
function serializeCrossChainIndexingStatusSnapshotOmnichain({
|
|
@@ -2172,21 +1951,61 @@ function serializeIndexingStatusResponse(response) {
|
|
|
2172
1951
|
var import_v416 = require("zod/v4");
|
|
2173
1952
|
|
|
2174
1953
|
// src/api/name-tokens/zod-schemas.ts
|
|
2175
|
-
var
|
|
1954
|
+
var import_viem14 = require("viem");
|
|
2176
1955
|
var import_v415 = require("zod/v4");
|
|
2177
1956
|
|
|
2178
1957
|
// src/tokenscope/assets.ts
|
|
2179
|
-
var
|
|
1958
|
+
var import_viem13 = require("viem");
|
|
2180
1959
|
var import_v413 = require("zod/v4");
|
|
2181
1960
|
|
|
2182
1961
|
// src/tokenscope/zod-schemas.ts
|
|
2183
1962
|
var import_caip3 = require("caip");
|
|
2184
|
-
var
|
|
1963
|
+
var import_viem12 = require("viem");
|
|
2185
1964
|
var import_v412 = require("zod/v4");
|
|
2186
1965
|
|
|
1966
|
+
// src/shared/types.ts
|
|
1967
|
+
var AssetNamespaces = {
|
|
1968
|
+
ERC721: "erc721",
|
|
1969
|
+
ERC1155: "erc1155"
|
|
1970
|
+
};
|
|
1971
|
+
|
|
1972
|
+
// src/tokenscope/name-token.ts
|
|
1973
|
+
var import_viem11 = require("viem");
|
|
1974
|
+
var import_datasources5 = require("@ensnode/datasources");
|
|
1975
|
+
|
|
1976
|
+
// src/shared/account-id.ts
|
|
1977
|
+
var import_viem10 = require("viem");
|
|
1978
|
+
var accountIdEqual = (a, b) => {
|
|
1979
|
+
return a.chainId === b.chainId && (0, import_viem10.isAddressEqual)(a.address, b.address);
|
|
1980
|
+
};
|
|
1981
|
+
|
|
1982
|
+
// src/shared/datasource-contract.ts
|
|
1983
|
+
var import_datasources4 = require("@ensnode/datasources");
|
|
1984
|
+
var maybeGetDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
1985
|
+
const datasource = (0, import_datasources4.maybeGetDatasource)(namespaceId, datasourceName);
|
|
1986
|
+
if (!datasource) return void 0;
|
|
1987
|
+
const address = datasource.contracts[contractName]?.address;
|
|
1988
|
+
if (address === void 0 || Array.isArray(address)) return void 0;
|
|
1989
|
+
return {
|
|
1990
|
+
chainId: datasource.chain.id,
|
|
1991
|
+
address
|
|
1992
|
+
};
|
|
1993
|
+
};
|
|
1994
|
+
var getDatasourceContract = (namespaceId, datasourceName, contractName) => {
|
|
1995
|
+
const contract = maybeGetDatasourceContract(namespaceId, datasourceName, contractName);
|
|
1996
|
+
if (!contract) {
|
|
1997
|
+
throw new Error(
|
|
1998
|
+
`Expected contract not found for ${namespaceId} ${datasourceName} ${contractName}`
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
return contract;
|
|
2002
|
+
};
|
|
2003
|
+
var makeContractMatcher = (namespace, b) => (datasourceName, contractName) => {
|
|
2004
|
+
const a = maybeGetDatasourceContract(namespace, datasourceName, contractName);
|
|
2005
|
+
return a && accountIdEqual(a, b);
|
|
2006
|
+
};
|
|
2007
|
+
|
|
2187
2008
|
// src/tokenscope/name-token.ts
|
|
2188
|
-
var import_viem14 = require("viem");
|
|
2189
|
-
var import_datasources6 = require("@ensnode/datasources");
|
|
2190
2009
|
var NameTokenOwnershipTypes = {
|
|
2191
2010
|
/**
|
|
2192
2011
|
* Name Token is owned by NameWrapper account.
|
|
@@ -2217,12 +2036,12 @@ function serializeNameToken(nameToken) {
|
|
|
2217
2036
|
function getNameWrapperAccounts(namespaceId) {
|
|
2218
2037
|
const ethnamesNameWrapperAccount = getDatasourceContract(
|
|
2219
2038
|
namespaceId,
|
|
2220
|
-
|
|
2039
|
+
import_datasources5.DatasourceNames.ENSRoot,
|
|
2221
2040
|
"NameWrapper"
|
|
2222
2041
|
);
|
|
2223
2042
|
const lineanamesNameWrapperAccount = maybeGetDatasourceContract(
|
|
2224
2043
|
namespaceId,
|
|
2225
|
-
|
|
2044
|
+
import_datasources5.DatasourceNames.Lineanames,
|
|
2226
2045
|
"NameWrapper"
|
|
2227
2046
|
);
|
|
2228
2047
|
const nameWrapperAccounts = [
|
|
@@ -2245,7 +2064,7 @@ function getNameTokenOwnership(namespaceId, name, owner) {
|
|
|
2245
2064
|
owner
|
|
2246
2065
|
};
|
|
2247
2066
|
}
|
|
2248
|
-
if ((0,
|
|
2067
|
+
if ((0, import_viem11.isAddressEqual)(owner.address, import_viem11.zeroAddress)) {
|
|
2249
2068
|
return {
|
|
2250
2069
|
ownershipType: NameTokenOwnershipTypes.Burned,
|
|
2251
2070
|
owner
|
|
@@ -2300,7 +2119,7 @@ var makeAssetIdStringSchema = (valueLabel = "Asset ID String Schema") => import_
|
|
|
2300
2119
|
}, makeAssetIdSchema(valueLabel));
|
|
2301
2120
|
function invariant_nameTokenOwnershipHasNonZeroAddressOwner(ctx) {
|
|
2302
2121
|
const ownership = ctx.value;
|
|
2303
|
-
if (ctx.value.owner.address ===
|
|
2122
|
+
if (ctx.value.owner.address === import_viem12.zeroAddress) {
|
|
2304
2123
|
ctx.issues.push({
|
|
2305
2124
|
code: "custom",
|
|
2306
2125
|
input: ctx.value,
|
|
@@ -2326,7 +2145,7 @@ var makeNameTokenOwnershipUnknownSchema = (valueLabel = "Name Token Ownership Un
|
|
|
2326
2145
|
}).check(invariant_nameTokenOwnershipHasNonZeroAddressOwner);
|
|
2327
2146
|
function invariant_nameTokenOwnershipHasZeroAddressOwner(ctx) {
|
|
2328
2147
|
const ownership = ctx.value;
|
|
2329
|
-
if (ctx.value.owner.address !==
|
|
2148
|
+
if (ctx.value.owner.address !== import_viem12.zeroAddress) {
|
|
2330
2149
|
ctx.issues.push({
|
|
2331
2150
|
code: "custom",
|
|
2332
2151
|
input: ctx.value,
|
|
@@ -2504,11 +2323,11 @@ var NFTTransferTypes = {
|
|
|
2504
2323
|
};
|
|
2505
2324
|
var getNFTTransferType = (from, to, allowMintedRemint, metadata, currentlyIndexedOwner) => {
|
|
2506
2325
|
const isIndexed = currentlyIndexedOwner !== void 0;
|
|
2507
|
-
const isIndexedAsMinted = isIndexed && !(0,
|
|
2508
|
-
const isMint = (0,
|
|
2509
|
-
const isBurn = (0,
|
|
2510
|
-
const isSelfTransfer = (0,
|
|
2511
|
-
if (isIndexed && !(0,
|
|
2326
|
+
const isIndexedAsMinted = isIndexed && !(0, import_viem13.isAddressEqual)(currentlyIndexedOwner, import_viem13.zeroAddress);
|
|
2327
|
+
const isMint = (0, import_viem13.isAddressEqual)(from, import_viem13.zeroAddress);
|
|
2328
|
+
const isBurn = (0, import_viem13.isAddressEqual)(to, import_viem13.zeroAddress);
|
|
2329
|
+
const isSelfTransfer = (0, import_viem13.isAddressEqual)(from, to);
|
|
2330
|
+
if (isIndexed && !(0, import_viem13.isAddressEqual)(currentlyIndexedOwner, from)) {
|
|
2512
2331
|
if (isMint && allowMintedRemint) {
|
|
2513
2332
|
} else {
|
|
2514
2333
|
throw new Error(
|
|
@@ -2641,7 +2460,7 @@ var makeRegisteredNameTokenSchema = (valueLabel = "Registered Name Token", seria
|
|
|
2641
2460
|
accurateAsOf: makeUnixTimestampSchema(`${valueLabel}.accurateAsOf`)
|
|
2642
2461
|
}).check(function invariant_nameIsAssociatedWithDomainId(ctx) {
|
|
2643
2462
|
const { name, domainId } = ctx.value;
|
|
2644
|
-
if ((0,
|
|
2463
|
+
if ((0, import_viem14.namehash)(name) !== domainId) {
|
|
2645
2464
|
ctx.issues.push({
|
|
2646
2465
|
code: "custom",
|
|
2647
2466
|
input: ctx.value,
|
|
@@ -2793,41 +2612,41 @@ function serializeNameTokensResponse(response) {
|
|
|
2793
2612
|
var import_v420 = require("zod/v4");
|
|
2794
2613
|
|
|
2795
2614
|
// src/api/registrar-actions/zod-schemas.ts
|
|
2796
|
-
var
|
|
2615
|
+
var import_ens7 = require("viem/ens");
|
|
2797
2616
|
var import_v419 = require("zod/v4");
|
|
2798
2617
|
|
|
2799
2618
|
// src/registrars/zod-schemas.ts
|
|
2800
2619
|
var import_v417 = require("zod/v4");
|
|
2801
2620
|
|
|
2802
2621
|
// src/registrars/encoded-referrer.ts
|
|
2803
|
-
var
|
|
2622
|
+
var import_viem15 = require("viem");
|
|
2804
2623
|
var ENCODED_REFERRER_BYTE_OFFSET = 12;
|
|
2805
2624
|
var ENCODED_REFERRER_BYTE_LENGTH = 32;
|
|
2806
|
-
var EXPECTED_ENCODED_REFERRER_PADDING = (0,
|
|
2625
|
+
var EXPECTED_ENCODED_REFERRER_PADDING = (0, import_viem15.pad)("0x", {
|
|
2807
2626
|
size: ENCODED_REFERRER_BYTE_OFFSET,
|
|
2808
2627
|
dir: "left"
|
|
2809
2628
|
});
|
|
2810
|
-
var ZERO_ENCODED_REFERRER = (0,
|
|
2629
|
+
var ZERO_ENCODED_REFERRER = (0, import_viem15.pad)("0x", {
|
|
2811
2630
|
size: ENCODED_REFERRER_BYTE_LENGTH,
|
|
2812
2631
|
dir: "left"
|
|
2813
2632
|
});
|
|
2814
2633
|
function buildEncodedReferrer(address) {
|
|
2815
2634
|
const lowercaseAddress = address.toLowerCase();
|
|
2816
|
-
return (0,
|
|
2635
|
+
return (0, import_viem15.pad)(lowercaseAddress, { size: ENCODED_REFERRER_BYTE_LENGTH, dir: "left" });
|
|
2817
2636
|
}
|
|
2818
2637
|
function decodeEncodedReferrer(encodedReferrer) {
|
|
2819
|
-
if ((0,
|
|
2638
|
+
if ((0, import_viem15.size)(encodedReferrer) !== ENCODED_REFERRER_BYTE_LENGTH) {
|
|
2820
2639
|
throw new Error(
|
|
2821
2640
|
`Encoded referrer value must be represented by ${ENCODED_REFERRER_BYTE_LENGTH} bytes.`
|
|
2822
2641
|
);
|
|
2823
2642
|
}
|
|
2824
|
-
const padding = (0,
|
|
2643
|
+
const padding = (0, import_viem15.slice)(encodedReferrer, 0, ENCODED_REFERRER_BYTE_OFFSET);
|
|
2825
2644
|
if (padding !== EXPECTED_ENCODED_REFERRER_PADDING) {
|
|
2826
|
-
return
|
|
2645
|
+
return import_viem15.zeroAddress;
|
|
2827
2646
|
}
|
|
2828
|
-
const decodedReferrer = (0,
|
|
2647
|
+
const decodedReferrer = (0, import_viem15.slice)(encodedReferrer, ENCODED_REFERRER_BYTE_OFFSET);
|
|
2829
2648
|
try {
|
|
2830
|
-
return (0,
|
|
2649
|
+
return (0, import_viem15.getAddress)(decodedReferrer);
|
|
2831
2650
|
} catch {
|
|
2832
2651
|
throw new Error(`Decoded referrer value must be a valid EVM address.`);
|
|
2833
2652
|
}
|
|
@@ -3062,7 +2881,7 @@ var RegistrarActionsResponseCodes = {
|
|
|
3062
2881
|
function invariant_registrationLifecycleNodeMatchesName(ctx) {
|
|
3063
2882
|
const { name, action } = ctx.value;
|
|
3064
2883
|
const expectedNode = action.registrationLifecycle.node;
|
|
3065
|
-
const actualNode = (0,
|
|
2884
|
+
const actualNode = (0, import_ens7.namehash)(name);
|
|
3066
2885
|
if (actualNode !== expectedNode) {
|
|
3067
2886
|
ctx.issues.push({
|
|
3068
2887
|
code: "custom",
|
|
@@ -3219,11 +3038,11 @@ var registrarActionsPrerequisites = Object.freeze({
|
|
|
3219
3038
|
});
|
|
3220
3039
|
|
|
3221
3040
|
// src/registrars/basenames-subregistry.ts
|
|
3222
|
-
var
|
|
3041
|
+
var import_datasources6 = require("@ensnode/datasources");
|
|
3223
3042
|
function getBasenamesSubregistryId(namespace) {
|
|
3224
|
-
const datasource = (0,
|
|
3043
|
+
const datasource = (0, import_datasources6.maybeGetDatasource)(namespace, import_datasources6.DatasourceNames.Basenames);
|
|
3225
3044
|
if (!datasource) {
|
|
3226
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
3045
|
+
throw new Error(`Datasource not found for ${namespace} ${import_datasources6.DatasourceNames.Basenames}`);
|
|
3227
3046
|
}
|
|
3228
3047
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
3229
3048
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -3236,12 +3055,12 @@ function getBasenamesSubregistryId(namespace) {
|
|
|
3236
3055
|
}
|
|
3237
3056
|
function getBasenamesSubregistryManagedName(namespaceId) {
|
|
3238
3057
|
switch (namespaceId) {
|
|
3239
|
-
case
|
|
3058
|
+
case import_datasources6.ENSNamespaceIds.Mainnet:
|
|
3240
3059
|
return "base.eth";
|
|
3241
|
-
case
|
|
3242
|
-
case
|
|
3060
|
+
case import_datasources6.ENSNamespaceIds.Sepolia:
|
|
3061
|
+
case import_datasources6.ENSNamespaceIds.SepoliaV2:
|
|
3243
3062
|
return "basetest.eth";
|
|
3244
|
-
case
|
|
3063
|
+
case import_datasources6.ENSNamespaceIds.EnsTestEnv:
|
|
3245
3064
|
throw new Error(
|
|
3246
3065
|
`No registrar managed name is known for the 'basenames' subregistry within the "${namespaceId}" namespace.`
|
|
3247
3066
|
);
|
|
@@ -3249,11 +3068,11 @@ function getBasenamesSubregistryManagedName(namespaceId) {
|
|
|
3249
3068
|
}
|
|
3250
3069
|
|
|
3251
3070
|
// src/registrars/ethnames-subregistry.ts
|
|
3252
|
-
var
|
|
3071
|
+
var import_datasources7 = require("@ensnode/datasources");
|
|
3253
3072
|
function getEthnamesSubregistryId(namespace) {
|
|
3254
|
-
const datasource = (0,
|
|
3073
|
+
const datasource = (0, import_datasources7.maybeGetDatasource)(namespace, import_datasources7.DatasourceNames.ENSRoot);
|
|
3255
3074
|
if (!datasource) {
|
|
3256
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
3075
|
+
throw new Error(`Datasource not found for ${namespace} ${import_datasources7.DatasourceNames.ENSRoot}`);
|
|
3257
3076
|
}
|
|
3258
3077
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
3259
3078
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -3266,20 +3085,20 @@ function getEthnamesSubregistryId(namespace) {
|
|
|
3266
3085
|
}
|
|
3267
3086
|
function getEthnamesSubregistryManagedName(namespaceId) {
|
|
3268
3087
|
switch (namespaceId) {
|
|
3269
|
-
case
|
|
3270
|
-
case
|
|
3271
|
-
case
|
|
3272
|
-
case
|
|
3088
|
+
case import_datasources7.ENSNamespaceIds.Mainnet:
|
|
3089
|
+
case import_datasources7.ENSNamespaceIds.Sepolia:
|
|
3090
|
+
case import_datasources7.ENSNamespaceIds.SepoliaV2:
|
|
3091
|
+
case import_datasources7.ENSNamespaceIds.EnsTestEnv:
|
|
3273
3092
|
return "eth";
|
|
3274
3093
|
}
|
|
3275
3094
|
}
|
|
3276
3095
|
|
|
3277
3096
|
// src/registrars/lineanames-subregistry.ts
|
|
3278
|
-
var
|
|
3097
|
+
var import_datasources8 = require("@ensnode/datasources");
|
|
3279
3098
|
function getLineanamesSubregistryId(namespace) {
|
|
3280
|
-
const datasource = (0,
|
|
3099
|
+
const datasource = (0, import_datasources8.maybeGetDatasource)(namespace, import_datasources8.DatasourceNames.Lineanames);
|
|
3281
3100
|
if (!datasource) {
|
|
3282
|
-
throw new Error(`Datasource not found for ${namespace} ${
|
|
3101
|
+
throw new Error(`Datasource not found for ${namespace} ${import_datasources8.DatasourceNames.Lineanames}`);
|
|
3283
3102
|
}
|
|
3284
3103
|
const address = datasource.contracts.BaseRegistrar?.address;
|
|
3285
3104
|
if (address === void 0 || Array.isArray(address)) {
|
|
@@ -3292,12 +3111,12 @@ function getLineanamesSubregistryId(namespace) {
|
|
|
3292
3111
|
}
|
|
3293
3112
|
function getLineanamesSubregistryManagedName(namespaceId) {
|
|
3294
3113
|
switch (namespaceId) {
|
|
3295
|
-
case
|
|
3114
|
+
case import_datasources8.ENSNamespaceIds.Mainnet:
|
|
3296
3115
|
return "linea.eth";
|
|
3297
|
-
case
|
|
3298
|
-
case
|
|
3116
|
+
case import_datasources8.ENSNamespaceIds.Sepolia:
|
|
3117
|
+
case import_datasources8.ENSNamespaceIds.SepoliaV2:
|
|
3299
3118
|
return "linea-sepolia.eth";
|
|
3300
|
-
case
|
|
3119
|
+
case import_datasources8.ENSNamespaceIds.EnsTestEnv:
|
|
3301
3120
|
throw new Error(
|
|
3302
3121
|
`No registrar managed name is known for the 'Lineanames' subregistry within the "${namespaceId}" namespace.`
|
|
3303
3122
|
);
|
|
@@ -3404,15 +3223,15 @@ var ClientError = class _ClientError extends Error {
|
|
|
3404
3223
|
};
|
|
3405
3224
|
|
|
3406
3225
|
// src/deployments.ts
|
|
3407
|
-
var
|
|
3226
|
+
var import_datasources9 = require("@ensnode/datasources");
|
|
3408
3227
|
var DEFAULT_ENSNODE_API_URL_MAINNET = "https://api.alpha.ensnode.io";
|
|
3409
3228
|
var DEFAULT_ENSNODE_API_URL_SEPOLIA = "https://api.alpha-sepolia.ensnode.io";
|
|
3410
3229
|
var getDefaultEnsNodeUrl = (namespace) => {
|
|
3411
|
-
const effectiveNamespace = namespace ??
|
|
3230
|
+
const effectiveNamespace = namespace ?? import_datasources9.ENSNamespaceIds.Mainnet;
|
|
3412
3231
|
switch (effectiveNamespace) {
|
|
3413
|
-
case
|
|
3232
|
+
case import_datasources9.ENSNamespaceIds.Mainnet:
|
|
3414
3233
|
return new URL(DEFAULT_ENSNODE_API_URL_MAINNET);
|
|
3415
|
-
case
|
|
3234
|
+
case import_datasources9.ENSNamespaceIds.Sepolia:
|
|
3416
3235
|
return new URL(DEFAULT_ENSNODE_API_URL_SEPOLIA);
|
|
3417
3236
|
default:
|
|
3418
3237
|
throw new Error(
|
|
@@ -3831,136 +3650,435 @@ var ENSNodeClient = class _ENSNodeClient {
|
|
|
3831
3650
|
return deserializeRegistrarActionsResponse(responseData);
|
|
3832
3651
|
}
|
|
3833
3652
|
/**
|
|
3834
|
-
* Fetch Name Tokens for requested name.
|
|
3835
|
-
*
|
|
3836
|
-
* @param request.name - Name for which Name Tokens will be fetched.
|
|
3837
|
-
* @returns {NameTokensResponse}
|
|
3838
|
-
*
|
|
3839
|
-
* @throws if the ENSNode request fails
|
|
3840
|
-
* @throws if the ENSNode API returns an error response
|
|
3841
|
-
* @throws if the ENSNode response breaks required invariants
|
|
3842
|
-
*
|
|
3843
|
-
* @example
|
|
3844
|
-
* ```ts
|
|
3845
|
-
* import {
|
|
3846
|
-
* ENSNodeClient,
|
|
3847
|
-
* } from "@ensnode/ensnode-sdk";
|
|
3848
|
-
* import { namehash } from "viem/ens";
|
|
3849
|
-
*
|
|
3850
|
-
* const client: ENSNodeClient;
|
|
3851
|
-
*
|
|
3852
|
-
* // get latest name token records from the indexed subregistry based on the requested name
|
|
3853
|
-
* const response = await client.nameTokens({
|
|
3854
|
-
* name: "vitalik.eth"
|
|
3855
|
-
* });
|
|
3653
|
+
* Fetch Name Tokens for requested name.
|
|
3654
|
+
*
|
|
3655
|
+
* @param request.name - Name for which Name Tokens will be fetched.
|
|
3656
|
+
* @returns {NameTokensResponse}
|
|
3657
|
+
*
|
|
3658
|
+
* @throws if the ENSNode request fails
|
|
3659
|
+
* @throws if the ENSNode API returns an error response
|
|
3660
|
+
* @throws if the ENSNode response breaks required invariants
|
|
3661
|
+
*
|
|
3662
|
+
* @example
|
|
3663
|
+
* ```ts
|
|
3664
|
+
* import {
|
|
3665
|
+
* ENSNodeClient,
|
|
3666
|
+
* } from "@ensnode/ensnode-sdk";
|
|
3667
|
+
* import { namehash } from "viem/ens";
|
|
3668
|
+
*
|
|
3669
|
+
* const client: ENSNodeClient;
|
|
3670
|
+
*
|
|
3671
|
+
* // get latest name token records from the indexed subregistry based on the requested name
|
|
3672
|
+
* const response = await client.nameTokens({
|
|
3673
|
+
* name: "vitalik.eth"
|
|
3674
|
+
* });
|
|
3675
|
+
*
|
|
3676
|
+
* const response = await client.nameTokens({
|
|
3677
|
+
* domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
|
|
3678
|
+
* })
|
|
3679
|
+
* ```
|
|
3680
|
+
*/
|
|
3681
|
+
async nameTokens(request) {
|
|
3682
|
+
const url = new URL(`/api/name-tokens`, this.options.url);
|
|
3683
|
+
if (request.name !== void 0) {
|
|
3684
|
+
url.searchParams.set("name", request.name);
|
|
3685
|
+
} else if (request.domainId !== void 0) {
|
|
3686
|
+
url.searchParams.set("domainId", request.domainId);
|
|
3687
|
+
}
|
|
3688
|
+
const response = await fetch(url);
|
|
3689
|
+
let responseData;
|
|
3690
|
+
try {
|
|
3691
|
+
responseData = await response.json();
|
|
3692
|
+
} catch {
|
|
3693
|
+
throw new Error("Malformed response data: invalid JSON");
|
|
3694
|
+
}
|
|
3695
|
+
if (!response.ok) {
|
|
3696
|
+
let errorResponse;
|
|
3697
|
+
try {
|
|
3698
|
+
errorResponse = deserializeErrorResponse(responseData);
|
|
3699
|
+
} catch {
|
|
3700
|
+
console.log("Name Tokens API: handling a known server error.");
|
|
3701
|
+
}
|
|
3702
|
+
if (typeof errorResponse !== "undefined") {
|
|
3703
|
+
throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
return deserializedNameTokensResponse(responseData);
|
|
3707
|
+
}
|
|
3708
|
+
};
|
|
3709
|
+
|
|
3710
|
+
// src/ensv2/ids-lib.ts
|
|
3711
|
+
var import_viem16 = require("viem");
|
|
3712
|
+
var makeRegistryId = (accountId) => formatAccountId(accountId);
|
|
3713
|
+
var makeENSv1DomainId = (node) => node;
|
|
3714
|
+
var makeENSv2DomainId = (registry, canonicalId) => formatAssetId({
|
|
3715
|
+
assetNamespace: AssetNamespaces.ERC1155,
|
|
3716
|
+
contract: registry,
|
|
3717
|
+
tokenId: canonicalId
|
|
3718
|
+
});
|
|
3719
|
+
var maskLower32Bits = (num) => num ^ num & 0xffffffffn;
|
|
3720
|
+
var getCanonicalId = (input) => {
|
|
3721
|
+
if (typeof input === "bigint") return maskLower32Bits(input);
|
|
3722
|
+
return getCanonicalId((0, import_viem16.hexToBigInt)(input));
|
|
3723
|
+
};
|
|
3724
|
+
var makePermissionsId = (contract) => formatAccountId(contract);
|
|
3725
|
+
var makePermissionsResourceId = (contract, resource) => `${makePermissionsId(contract)}/${resource}`;
|
|
3726
|
+
var makePermissionsUserId = (contract, resource, user) => `${makePermissionsId(contract)}/${resource}/${user}`;
|
|
3727
|
+
var makeResolverId = (contract) => formatAccountId(contract);
|
|
3728
|
+
var makeResolverRecordsId = (resolver, node) => `${makeResolverId(resolver)}/${node}`;
|
|
3729
|
+
var makeLatestRegistrationId = (domainId) => `${domainId}/latest`;
|
|
3730
|
+
var makeRegistrationId = (domainId, index = 0) => `${domainId}/${index}`;
|
|
3731
|
+
var makeLatestRenewalId = (domainId, registrationIndex) => `${makeRegistrationId(domainId, registrationIndex)}/latest`;
|
|
3732
|
+
var makeRenewalId = (domainId, registrationIndex, index = 0) => `${makeRegistrationId(domainId, registrationIndex)}/${index}`;
|
|
3733
|
+
|
|
3734
|
+
// src/identity/identity.ts
|
|
3735
|
+
var import_datasources10 = require("@ensnode/datasources");
|
|
3736
|
+
|
|
3737
|
+
// src/identity/types.ts
|
|
3738
|
+
var ResolutionStatusIds = {
|
|
3739
|
+
/**
|
|
3740
|
+
* Represents that the `Identity` is not resolved yet.
|
|
3741
|
+
*/
|
|
3742
|
+
Unresolved: "unresolved",
|
|
3743
|
+
/**
|
|
3744
|
+
* Represents that resolution of the `Identity` resulted in a named identity.
|
|
3745
|
+
*/
|
|
3746
|
+
Named: "named",
|
|
3747
|
+
/**
|
|
3748
|
+
* Represents that resolution of the `Identity` resulted in an unnamed identity.
|
|
3749
|
+
*/
|
|
3750
|
+
Unnamed: "unnamed",
|
|
3751
|
+
/**
|
|
3752
|
+
* Represents that attempted resolution of the `Identity` resulted in an error
|
|
3753
|
+
* and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
|
|
3754
|
+
*/
|
|
3755
|
+
Unknown: "unknown"
|
|
3756
|
+
};
|
|
3757
|
+
|
|
3758
|
+
// src/identity/identity.ts
|
|
3759
|
+
function buildUnresolvedIdentity(address, namespaceId, chainId) {
|
|
3760
|
+
return {
|
|
3761
|
+
resolutionStatus: ResolutionStatusIds.Unresolved,
|
|
3762
|
+
chainId: chainId ?? (0, import_datasources10.getENSRootChainId)(namespaceId),
|
|
3763
|
+
address
|
|
3764
|
+
};
|
|
3765
|
+
}
|
|
3766
|
+
function isResolvedIdentity(identity) {
|
|
3767
|
+
return identity.resolutionStatus !== ResolutionStatusIds.Unresolved;
|
|
3768
|
+
}
|
|
3769
|
+
|
|
3770
|
+
// src/resolution/ensip19-chainid.ts
|
|
3771
|
+
var import_chains = require("viem/chains");
|
|
3772
|
+
var import_datasources11 = require("@ensnode/datasources");
|
|
3773
|
+
var getResolvePrimaryNameChainIdParam = (chainId, namespaceId) => {
|
|
3774
|
+
const ensRootChainId = (0, import_datasources11.getENSRootChainId)(namespaceId);
|
|
3775
|
+
return chainId === ensRootChainId ? import_chains.mainnet.id : chainId;
|
|
3776
|
+
};
|
|
3777
|
+
var translateDefaultableChainIdToChainId = (chainId, namespaceId) => {
|
|
3778
|
+
return chainId === DEFAULT_EVM_CHAIN_ID ? (0, import_datasources11.getENSRootChainId)(namespaceId) : chainId;
|
|
3779
|
+
};
|
|
3780
|
+
|
|
3781
|
+
// src/resolution/resolver-records-selection.ts
|
|
3782
|
+
var isSelectionEmpty = (selection) => !selection.name && !selection.addresses?.length && !selection.texts?.length;
|
|
3783
|
+
|
|
3784
|
+
// src/shared/cache/lru-cache.ts
|
|
3785
|
+
var LruCache = class {
|
|
3786
|
+
_cache = /* @__PURE__ */ new Map();
|
|
3787
|
+
_capacity;
|
|
3788
|
+
/**
|
|
3789
|
+
* Create a new LRU cache with the given capacity.
|
|
3790
|
+
*
|
|
3791
|
+
* @param capacity The maximum number of items in the cache. If set to 0, the cache is effectively disabled.
|
|
3792
|
+
* @throws Error if capacity is not a non-negative integer.
|
|
3793
|
+
*/
|
|
3794
|
+
constructor(capacity) {
|
|
3795
|
+
if (!Number.isInteger(capacity)) {
|
|
3796
|
+
throw new Error(
|
|
3797
|
+
`LruCache requires capacity to be an integer but a capacity of ${capacity} was requested.`
|
|
3798
|
+
);
|
|
3799
|
+
}
|
|
3800
|
+
if (capacity < 0) {
|
|
3801
|
+
throw new Error(
|
|
3802
|
+
`LruCache requires a non-negative capacity but a capacity of ${capacity} was requested.`
|
|
3803
|
+
);
|
|
3804
|
+
}
|
|
3805
|
+
this._capacity = capacity;
|
|
3806
|
+
}
|
|
3807
|
+
set(key, value) {
|
|
3808
|
+
this._cache.set(key, value);
|
|
3809
|
+
if (this._cache.size > this._capacity) {
|
|
3810
|
+
const oldestKey = this._cache.keys().next().value;
|
|
3811
|
+
this._cache.delete(oldestKey);
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
get(key) {
|
|
3815
|
+
const value = this._cache.get(key);
|
|
3816
|
+
if (value) {
|
|
3817
|
+
this._cache.delete(key);
|
|
3818
|
+
this._cache.set(key, value);
|
|
3819
|
+
}
|
|
3820
|
+
return value;
|
|
3821
|
+
}
|
|
3822
|
+
clear() {
|
|
3823
|
+
this._cache.clear();
|
|
3824
|
+
}
|
|
3825
|
+
get size() {
|
|
3826
|
+
return this._cache.size;
|
|
3827
|
+
}
|
|
3828
|
+
get capacity() {
|
|
3829
|
+
return this._capacity;
|
|
3830
|
+
}
|
|
3831
|
+
};
|
|
3832
|
+
|
|
3833
|
+
// src/shared/cache/swr-cache.ts
|
|
3834
|
+
var import_date_fns = require("date-fns");
|
|
3835
|
+
var import_getUnixTime = require("date-fns/getUnixTime");
|
|
3836
|
+
|
|
3837
|
+
// src/shared/datetime.ts
|
|
3838
|
+
function durationBetween(start, end) {
|
|
3839
|
+
return deserializeDuration(end - start, "Duration");
|
|
3840
|
+
}
|
|
3841
|
+
function addDuration(timestamp, duration) {
|
|
3842
|
+
return deserializeUnixTimestamp(timestamp + duration, "UnixTimestamp");
|
|
3843
|
+
}
|
|
3844
|
+
|
|
3845
|
+
// src/shared/cache/swr-cache.ts
|
|
3846
|
+
var SWRCache = class {
|
|
3847
|
+
constructor(options) {
|
|
3848
|
+
this.options = options;
|
|
3849
|
+
if (options.proactiveRevalidationInterval) {
|
|
3850
|
+
this.backgroundInterval = setInterval(
|
|
3851
|
+
() => this.revalidate(),
|
|
3852
|
+
(0, import_date_fns.secondsToMilliseconds)(options.proactiveRevalidationInterval)
|
|
3853
|
+
);
|
|
3854
|
+
}
|
|
3855
|
+
if (options.proactivelyInitialize) this.revalidate();
|
|
3856
|
+
}
|
|
3857
|
+
cache = null;
|
|
3858
|
+
inProgressRevalidate = null;
|
|
3859
|
+
backgroundInterval = null;
|
|
3860
|
+
async revalidate() {
|
|
3861
|
+
if (!this.inProgressRevalidate) {
|
|
3862
|
+
this.inProgressRevalidate = this.options.fn().then((result) => {
|
|
3863
|
+
this.cache = {
|
|
3864
|
+
result,
|
|
3865
|
+
updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
|
|
3866
|
+
};
|
|
3867
|
+
}).catch((error) => {
|
|
3868
|
+
if (!this.cache) {
|
|
3869
|
+
this.cache = {
|
|
3870
|
+
// ensure thrown value is always an Error instance
|
|
3871
|
+
result: error instanceof Error ? error : new Error(String(error)),
|
|
3872
|
+
updatedAt: (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())
|
|
3873
|
+
};
|
|
3874
|
+
}
|
|
3875
|
+
}).finally(() => {
|
|
3876
|
+
this.inProgressRevalidate = null;
|
|
3877
|
+
});
|
|
3878
|
+
}
|
|
3879
|
+
return this.inProgressRevalidate;
|
|
3880
|
+
}
|
|
3881
|
+
/**
|
|
3882
|
+
* Read the most recently cached result from the `SWRCache`.
|
|
3883
|
+
*
|
|
3884
|
+
* @returns a `ValueType` that was most recently successfully returned by `fn` or `Error` if `fn`
|
|
3885
|
+
* has never successfully returned.
|
|
3886
|
+
*/
|
|
3887
|
+
async read() {
|
|
3888
|
+
if (!this.cache) await this.revalidate();
|
|
3889
|
+
if (!this.cache) throw new Error("never");
|
|
3890
|
+
if (durationBetween(this.cache.updatedAt, (0, import_getUnixTime.getUnixTime)(/* @__PURE__ */ new Date())) > this.options.ttl) {
|
|
3891
|
+
this.revalidate();
|
|
3892
|
+
}
|
|
3893
|
+
return this.cache.result;
|
|
3894
|
+
}
|
|
3895
|
+
/**
|
|
3896
|
+
* Destroys the background revalidation interval, if exists.
|
|
3897
|
+
*/
|
|
3898
|
+
destroy() {
|
|
3899
|
+
if (this.backgroundInterval) {
|
|
3900
|
+
clearInterval(this.backgroundInterval);
|
|
3901
|
+
this.backgroundInterval = null;
|
|
3902
|
+
}
|
|
3903
|
+
}
|
|
3904
|
+
};
|
|
3905
|
+
|
|
3906
|
+
// src/shared/cache/ttl-cache.ts
|
|
3907
|
+
var import_getUnixTime2 = require("date-fns/getUnixTime");
|
|
3908
|
+
var TtlCache = class {
|
|
3909
|
+
_cache = /* @__PURE__ */ new Map();
|
|
3910
|
+
_ttl;
|
|
3911
|
+
/**
|
|
3912
|
+
* Create a new TTL cache with the given TTL.
|
|
3856
3913
|
*
|
|
3857
|
-
*
|
|
3858
|
-
* domainId: "0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835" // namehash('vitalik.eth')
|
|
3859
|
-
* })
|
|
3860
|
-
* ```
|
|
3914
|
+
* @param ttl Time-to-live duration in seconds. Items expire after this duration.
|
|
3861
3915
|
*/
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3916
|
+
constructor(ttl) {
|
|
3917
|
+
this._ttl = ttl;
|
|
3918
|
+
}
|
|
3919
|
+
_cleanup() {
|
|
3920
|
+
const now = (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date());
|
|
3921
|
+
for (const [key, entry] of this._cache.entries()) {
|
|
3922
|
+
if (entry.expiresAt <= now) {
|
|
3923
|
+
this._cache.delete(key);
|
|
3924
|
+
}
|
|
3868
3925
|
}
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3926
|
+
}
|
|
3927
|
+
set(key, value) {
|
|
3928
|
+
this._cleanup();
|
|
3929
|
+
const expiresAt = addDuration((0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date()), this._ttl);
|
|
3930
|
+
this._cache.set(key, { value, expiresAt });
|
|
3931
|
+
}
|
|
3932
|
+
get(key) {
|
|
3933
|
+
this._cleanup();
|
|
3934
|
+
const entry = this._cache.get(key);
|
|
3935
|
+
if (!entry) {
|
|
3936
|
+
return void 0;
|
|
3875
3937
|
}
|
|
3876
|
-
if (
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
errorResponse = deserializeErrorResponse(responseData);
|
|
3880
|
-
} catch {
|
|
3881
|
-
console.log("Name Tokens API: handling a known server error.");
|
|
3882
|
-
}
|
|
3883
|
-
if (typeof errorResponse !== "undefined") {
|
|
3884
|
-
throw new Error(`Fetching ENSNode Name Tokens Failed: ${errorResponse.message}`);
|
|
3885
|
-
}
|
|
3938
|
+
if (entry.expiresAt <= (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date())) {
|
|
3939
|
+
this._cache.delete(key);
|
|
3940
|
+
return void 0;
|
|
3886
3941
|
}
|
|
3887
|
-
return
|
|
3942
|
+
return entry.value;
|
|
3943
|
+
}
|
|
3944
|
+
clear() {
|
|
3945
|
+
this._cache.clear();
|
|
3946
|
+
}
|
|
3947
|
+
get size() {
|
|
3948
|
+
this._cleanup();
|
|
3949
|
+
return this._cache.size;
|
|
3950
|
+
}
|
|
3951
|
+
get capacity() {
|
|
3952
|
+
return Number.MAX_SAFE_INTEGER;
|
|
3953
|
+
}
|
|
3954
|
+
has(key) {
|
|
3955
|
+
this._cleanup();
|
|
3956
|
+
const entry = this._cache.get(key);
|
|
3957
|
+
if (!entry) {
|
|
3958
|
+
return false;
|
|
3959
|
+
}
|
|
3960
|
+
if (entry.expiresAt <= (0, import_getUnixTime2.getUnixTime)(/* @__PURE__ */ new Date())) {
|
|
3961
|
+
this._cache.delete(key);
|
|
3962
|
+
return false;
|
|
3963
|
+
}
|
|
3964
|
+
return true;
|
|
3965
|
+
}
|
|
3966
|
+
delete(key) {
|
|
3967
|
+
return this._cache.delete(key);
|
|
3888
3968
|
}
|
|
3889
3969
|
};
|
|
3890
3970
|
|
|
3891
|
-
// src/
|
|
3892
|
-
var
|
|
3893
|
-
var
|
|
3894
|
-
var makeENSv1DomainId = (node) => node;
|
|
3895
|
-
var makeENSv2DomainId = (registry, canonicalId) => formatAssetId({
|
|
3896
|
-
assetNamespace: AssetNamespaces.ERC1155,
|
|
3897
|
-
contract: registry,
|
|
3898
|
-
tokenId: canonicalId
|
|
3899
|
-
});
|
|
3900
|
-
var maskLower32Bits = (num) => num ^ num & 0xffffffffn;
|
|
3901
|
-
var getCanonicalId = (input) => {
|
|
3902
|
-
if (typeof input === "bigint") return maskLower32Bits(input);
|
|
3903
|
-
return getCanonicalId((0, import_viem19.hexToBigInt)(input));
|
|
3904
|
-
};
|
|
3905
|
-
var makePermissionsId = (contract) => formatAccountId(contract);
|
|
3906
|
-
var makePermissionsResourceId = (contract, resource) => `${makePermissionsId(contract)}/${resource}`;
|
|
3907
|
-
var makePermissionsUserId = (contract, resource, user) => `${makePermissionsId(contract)}/${resource}/${user}`;
|
|
3908
|
-
var makeResolverId = (contract) => formatAccountId(contract);
|
|
3909
|
-
var makeResolverRecordsId = (resolver, node) => `${makeResolverId(resolver)}/${node}`;
|
|
3910
|
-
var makeLatestRegistrationId = (domainId) => `${domainId}/latest`;
|
|
3911
|
-
var makeRegistrationId = (domainId, index = 0) => `${domainId}/${index}`;
|
|
3912
|
-
var makeLatestRenewalId = (domainId, registrationIndex) => `${makeRegistrationId(domainId, registrationIndex)}/latest`;
|
|
3913
|
-
var makeRenewalId = (domainId, registrationIndex, index = 0) => `${makeRegistrationId(domainId, registrationIndex)}/${index}`;
|
|
3971
|
+
// src/shared/interpretation/interpret-address.ts
|
|
3972
|
+
var import_viem17 = require("viem");
|
|
3973
|
+
var interpretAddress = (owner) => (0, import_viem17.isAddressEqual)(import_viem17.zeroAddress, owner) ? null : owner;
|
|
3914
3974
|
|
|
3915
|
-
// src/
|
|
3916
|
-
var
|
|
3975
|
+
// src/shared/interpretation/interpret-record-values.ts
|
|
3976
|
+
var import_viem18 = require("viem");
|
|
3917
3977
|
|
|
3918
|
-
// src/
|
|
3919
|
-
var
|
|
3920
|
-
|
|
3921
|
-
* Represents that the `Identity` is not resolved yet.
|
|
3922
|
-
*/
|
|
3923
|
-
Unresolved: "unresolved",
|
|
3924
|
-
/**
|
|
3925
|
-
* Represents that resolution of the `Identity` resulted in a named identity.
|
|
3926
|
-
*/
|
|
3927
|
-
Named: "named",
|
|
3928
|
-
/**
|
|
3929
|
-
* Represents that resolution of the `Identity` resulted in an unnamed identity.
|
|
3930
|
-
*/
|
|
3931
|
-
Unnamed: "unnamed",
|
|
3932
|
-
/**
|
|
3933
|
-
* Represents that attempted resolution of the `Identity` resulted in an error
|
|
3934
|
-
* and therefore it is unknown if the `Identity` resolves to a named or unnamed identity.
|
|
3935
|
-
*/
|
|
3936
|
-
Unknown: "unknown"
|
|
3937
|
-
};
|
|
3978
|
+
// src/shared/null-bytes.ts
|
|
3979
|
+
var hasNullByte = (value) => value.indexOf("\0") !== -1;
|
|
3980
|
+
var stripNullBytes = (value) => value.replaceAll("\0", "");
|
|
3938
3981
|
|
|
3939
|
-
// src/
|
|
3940
|
-
function
|
|
3941
|
-
return
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
address
|
|
3945
|
-
};
|
|
3982
|
+
// src/shared/interpretation/interpret-record-values.ts
|
|
3983
|
+
function interpretNameRecordValue(value) {
|
|
3984
|
+
if (value === "") return null;
|
|
3985
|
+
if (!isNormalizedName(value)) return null;
|
|
3986
|
+
return value;
|
|
3946
3987
|
}
|
|
3947
|
-
function
|
|
3948
|
-
|
|
3988
|
+
function interpretAddressRecordValue(value) {
|
|
3989
|
+
if (hasNullByte(value)) return null;
|
|
3990
|
+
if (value === "") return null;
|
|
3991
|
+
if (value === "0x") return null;
|
|
3992
|
+
if (!(0, import_viem18.isAddress)(value)) return value;
|
|
3993
|
+
if ((0, import_viem18.isAddressEqual)(value, import_viem18.zeroAddress)) return null;
|
|
3994
|
+
return asLowerCaseAddress(value);
|
|
3995
|
+
}
|
|
3996
|
+
function interpretTextRecordKey(key) {
|
|
3997
|
+
if (hasNullByte(key)) return null;
|
|
3998
|
+
if (key === "") return null;
|
|
3999
|
+
return key;
|
|
4000
|
+
}
|
|
4001
|
+
function interpretTextRecordValue(value) {
|
|
4002
|
+
if (hasNullByte(value)) return null;
|
|
4003
|
+
if (value === "") return null;
|
|
4004
|
+
return value;
|
|
3949
4005
|
}
|
|
3950
4006
|
|
|
3951
|
-
// src/
|
|
3952
|
-
var
|
|
4007
|
+
// src/shared/interpretation/interpret-tokenid.ts
|
|
4008
|
+
var interpretTokenIdAsLabelHash = (tokenId) => uint256ToHex32(tokenId);
|
|
4009
|
+
var interpretTokenIdAsNode = (tokenId) => uint256ToHex32(tokenId);
|
|
4010
|
+
|
|
4011
|
+
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
4012
|
+
var import_viem20 = require("viem");
|
|
4013
|
+
var import_ens10 = require("viem/ens");
|
|
4014
|
+
|
|
4015
|
+
// src/shared/labelhash.ts
|
|
4016
|
+
var import_viem19 = require("viem");
|
|
4017
|
+
var labelhashLiteralLabel = (label) => (0, import_viem19.keccak256)((0, import_viem19.stringToBytes)(label));
|
|
4018
|
+
|
|
4019
|
+
// src/shared/interpretation/interpreted-names-and-labels.ts
|
|
4020
|
+
function literalLabelToInterpretedLabel(label) {
|
|
4021
|
+
if (isNormalizedLabel(label)) return label;
|
|
4022
|
+
return encodeLabelHash(labelhashLiteralLabel(label));
|
|
4023
|
+
}
|
|
4024
|
+
function literalLabelsToInterpretedName(labels) {
|
|
4025
|
+
return labels.map(literalLabelToInterpretedLabel).join(".");
|
|
4026
|
+
}
|
|
4027
|
+
function interpretedLabelsToInterpretedName(labels) {
|
|
4028
|
+
return labels.join(".");
|
|
4029
|
+
}
|
|
4030
|
+
function literalLabelsToLiteralName(labels) {
|
|
4031
|
+
return labels.join(".");
|
|
4032
|
+
}
|
|
4033
|
+
function interpretedNameToInterpretedLabels(name) {
|
|
4034
|
+
return name.split(".");
|
|
4035
|
+
}
|
|
4036
|
+
function encodedLabelToLabelhash(label) {
|
|
4037
|
+
if (label.length !== 66) return null;
|
|
4038
|
+
if (label.indexOf("[") !== 0) return null;
|
|
4039
|
+
if (label.indexOf("]") !== 65) return null;
|
|
4040
|
+
const hash = `0x${label.slice(1, 65)}`;
|
|
4041
|
+
if (!(0, import_viem20.isHex)(hash)) return null;
|
|
4042
|
+
return hash;
|
|
4043
|
+
}
|
|
4044
|
+
function isInterpetedLabel(label) {
|
|
4045
|
+
if (label.startsWith("[")) {
|
|
4046
|
+
const labelHash = encodedLabelToLabelhash(label);
|
|
4047
|
+
if (labelHash === null) return false;
|
|
4048
|
+
}
|
|
4049
|
+
return isNormalizedLabel(label);
|
|
4050
|
+
}
|
|
4051
|
+
function isInterpretedName(name) {
|
|
4052
|
+
return name.split(".").every(isInterpetedLabel);
|
|
4053
|
+
}
|
|
4054
|
+
function interpretedNameToLabelHashPath(name) {
|
|
4055
|
+
return interpretedNameToInterpretedLabels(name).map((label) => {
|
|
4056
|
+
if (!isInterpetedLabel(label)) {
|
|
4057
|
+
throw new Error(
|
|
4058
|
+
`Invariant(interpretedNameToLabelHashPath): Expected InterpretedLabel, received '${label}'.`
|
|
4059
|
+
);
|
|
4060
|
+
}
|
|
4061
|
+
const maybeLabelHash = encodedLabelToLabelhash(label);
|
|
4062
|
+
if (maybeLabelHash !== null) return maybeLabelHash;
|
|
4063
|
+
return (0, import_ens10.labelhash)(label);
|
|
4064
|
+
}).toReversed();
|
|
4065
|
+
}
|
|
4066
|
+
|
|
4067
|
+
// src/shared/root-registry.ts
|
|
3953
4068
|
var import_datasources12 = require("@ensnode/datasources");
|
|
3954
|
-
var
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
var
|
|
3959
|
-
return chainId === DEFAULT_EVM_CHAIN_ID ? (0, import_datasources12.getENSRootChainId)(namespaceId) : chainId;
|
|
3960
|
-
};
|
|
4069
|
+
var getENSv1Registry = (namespace) => getDatasourceContract(namespace, import_datasources12.DatasourceNames.ENSRoot, "ENSv1Registry");
|
|
4070
|
+
var isENSv1Registry = (namespace, contract) => accountIdEqual(getENSv1Registry(namespace), contract);
|
|
4071
|
+
var getENSv2RootRegistry = (namespace) => getDatasourceContract(namespace, import_datasources12.DatasourceNames.ENSv2Root, "RootRegistry");
|
|
4072
|
+
var getENSv2RootRegistryId = (namespace) => makeRegistryId(getENSv2RootRegistry(namespace));
|
|
4073
|
+
var isENSv2RootRegistry = (namespace, contract) => accountIdEqual(getENSv2RootRegistry(namespace), contract);
|
|
3961
4074
|
|
|
3962
|
-
// src/
|
|
3963
|
-
|
|
4075
|
+
// src/shared/url.ts
|
|
4076
|
+
function isHttpProtocol(url) {
|
|
4077
|
+
return ["http:", "https:"].includes(url.protocol);
|
|
4078
|
+
}
|
|
4079
|
+
function isWebSocketProtocol(url) {
|
|
4080
|
+
return ["ws:", "wss:"].includes(url.protocol);
|
|
4081
|
+
}
|
|
3964
4082
|
|
|
3965
4083
|
// src/tracing/ens-protocol-tracing.ts
|
|
3966
4084
|
var PROTOCOL_ATTRIBUTE_PREFIX = "ens";
|