@ensnode/ensdb-sdk 1.15.1 → 1.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 NameHash
3
+ Copyright (c) 2026 NameHash Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,4 +1,4 @@
1
- export { b as account, c as account_relations, d as domain, e as domainEvent, f as domainResolverRelation, g as domainResolverRelation_relations, h as domainType, i as event, j as internal_registrarActionMetadata, k as internal_registrarActionMetadataType, l as label, m as label_relations, n as latestRegistrationIndex, o as latestRegistrationIndex_relations, p as latestRenewalIndex, q as latestRenewalIndex_relations, r as migratedNodeByNode, s as migratedNodeByParent, t as nameSales, u as nameTokens, v as permissions, w as permissionsEvent, x as permissionsResource, y as permissionsUser, z as permissionsUserEvent, A as registrarActionRelations, B as registrarActionType, C as registrarActions, D as registration, E as registrationLifecycleRelations, F as registrationLifecycles, G as registrationType, H as registration_relations, I as registry, J as registryType, K as relations_domain, L as relations_permissions, M as relations_permissionsResource, N as relations_permissionsUser, O as relations_registry, P as renewal, Q as renewal_relations, R as resolver, S as resolverAddressRecord, T as resolverAddressRecordRelations, U as resolverEvent, V as resolverRecords, W as resolverRecords_relations, X as resolverTextRecord, Y as resolverTextRecordRelations, Z as resolver_relations, _ as reverseNameRecord, $ as subgraph_abiChanged, a0 as subgraph_abiChangedRelations, a1 as subgraph_account, a2 as subgraph_accountRelations, a3 as subgraph_addrChanged, a4 as subgraph_addrChangedRelations, a5 as subgraph_authorisationChanged, a6 as subgraph_authorisationChangedRelations, a7 as subgraph_contenthashChanged, a8 as subgraph_contenthashChangedRelations, a9 as subgraph_domain, aa as subgraph_domainRelations, ab as subgraph_expiryExtended, ac as subgraph_expiryExtendedRelations, ad as subgraph_fusesSet, ae as subgraph_fusesSetRelations, af as subgraph_interfaceChanged, ag as subgraph_interfaceChangedRelations, ah as subgraph_multicoinAddrChanged, ai as subgraph_multicoinAddrChangedRelations, aj as subgraph_nameChanged, ak as subgraph_nameChangedRelations, al as subgraph_nameRegistered, am as subgraph_nameRegisteredRelations, an as subgraph_nameRenewed, ao as subgraph_nameRenewedRelations, ap as subgraph_nameTransferred, aq as subgraph_nameTransferredRelations, ar as subgraph_nameUnwrapped, as as subgraph_nameUnwrappedRelations, at as subgraph_nameWrapped, au as subgraph_nameWrappedRelations, av as subgraph_newOwner, aw as subgraph_newOwnerRelations, ax as subgraph_newResolver, ay as subgraph_newResolverRelations, az as subgraph_newTTL, aA as subgraph_newTTLRelations, aB as subgraph_pubkeyChanged, aC as subgraph_pubkeyChangedRelations, aD as subgraph_registration, aE as subgraph_registrationRelations, aF as subgraph_resolver, aG as subgraph_resolverRelations, aH as subgraph_textChanged, aI as subgraph_textChangedRelations, aJ as subgraph_transfer, aK as subgraph_transferRelations, aL as subgraph_versionChanged, aM as subgraph_versionChangedRelations, aN as subgraph_wrappedDomain, aO as subgraph_wrappedDomainRelations, aP as subgraph_wrappedTransfer, aQ as subgraph_wrappedTransferRelations, aR as subregistries, aS as subregistryRelations } from '../index-1D8_3_7g.js';
1
+ export { C as CANONICAL_NAME_PREFIX_LENGTH, R as REGISTRATION_SORT_SENTINEL, b as account, c as account_relations, d as domain, e as domainEvent, f as domainResolverRelation, g as domainResolverRelation_relations, h as domainType, i as event, j as internal_registrarActionMetadata, k as internal_registrarActionMetadataType, l as label, m as label_relations, n as latestRegistrationIndex, o as latestRegistrationIndex_relations, p as latestRenewalIndex, q as latestRenewalIndex_relations, r as migratedNodeByNode, s as migratedNodeByParent, t as nameSales, u as nameTokens, v as permissions, w as permissionsEvent, x as permissionsResource, y as permissionsUser, z as permissionsUserEvent, A as registrarActionRelations, B as registrarActionType, D as registrarActions, E as registration, F as registrationLifecycleRelations, G as registrationLifecycles, H as registrationType, I as registration_relations, J as registry, K as registryType, L as relations_domain, M as relations_permissions, N as relations_permissionsResource, O as relations_permissionsUser, P as relations_registry, Q as renewal, S as renewal_relations, T as resolver, U as resolverAddressRecord, V as resolverAddressRecordRelations, W as resolverEvent, X as resolverRecords, Y as resolverRecords_relations, Z as resolverTextRecord, _ as resolverTextRecordRelations, $ as resolver_relations, a0 as reverseNameRecord, a1 as subgraph_abiChanged, a2 as subgraph_abiChangedRelations, a3 as subgraph_account, a4 as subgraph_accountRelations, a5 as subgraph_addrChanged, a6 as subgraph_addrChangedRelations, a7 as subgraph_authorisationChanged, a8 as subgraph_authorisationChangedRelations, a9 as subgraph_contenthashChanged, aa as subgraph_contenthashChangedRelations, ab as subgraph_domain, ac as subgraph_domainRelations, ad as subgraph_expiryExtended, ae as subgraph_expiryExtendedRelations, af as subgraph_fusesSet, ag as subgraph_fusesSetRelations, ah as subgraph_interfaceChanged, ai as subgraph_interfaceChangedRelations, aj as subgraph_multicoinAddrChanged, ak as subgraph_multicoinAddrChangedRelations, al as subgraph_nameChanged, am as subgraph_nameChangedRelations, an as subgraph_nameRegistered, ao as subgraph_nameRegisteredRelations, ap as subgraph_nameRenewed, aq as subgraph_nameRenewedRelations, ar as subgraph_nameTransferred, as as subgraph_nameTransferredRelations, at as subgraph_nameUnwrapped, au as subgraph_nameUnwrappedRelations, av as subgraph_nameWrapped, aw as subgraph_nameWrappedRelations, ax as subgraph_newOwner, ay as subgraph_newOwnerRelations, az as subgraph_newResolver, aA as subgraph_newResolverRelations, aB as subgraph_newTTL, aC as subgraph_newTTLRelations, aD as subgraph_pubkeyChanged, aE as subgraph_pubkeyChangedRelations, aF as subgraph_registration, aG as subgraph_registrationRelations, aH as subgraph_resolver, aI as subgraph_resolverRelations, aJ as subgraph_textChanged, aK as subgraph_textChangedRelations, aL as subgraph_transfer, aM as subgraph_transferRelations, aN as subgraph_versionChanged, aO as subgraph_versionChangedRelations, aP as subgraph_wrappedDomain, aQ as subgraph_wrappedDomainRelations, aR as subgraph_wrappedTransfer, aS as subgraph_wrappedTransferRelations, aT as subregistries, aU as subregistryRelations, aV as truncateCanonicalNamePrefix } from '../index-DH9e7wPl.js';
2
2
  import 'ponder';
3
3
  import 'drizzle-orm';
4
4
  import 'drizzle-orm/pg-core';
@@ -62,7 +62,13 @@ var resolver = onchainTable2(
62
62
  // keyed by (chainId, address)
63
63
  id: t.text().primaryKey().$type(),
64
64
  chainId: t.int8({ mode: "number" }).notNull().$type(),
65
- address: t.hex().notNull().$type()
65
+ address: t.hex().notNull().$type(),
66
+ /**
67
+ * Whether this Resolver implements ENSIP-10 wildcard resolution (`IExtendedResolver`,
68
+ * interfaceId `0x9061b923`), determined via a single `supportsInterface` RPC the first
69
+ * time the Resolver is observed (see `upsertResolver`).
70
+ */
71
+ isExtended: t.boolean().notNull().default(false)
66
72
  }),
67
73
  (t) => ({
68
74
  byId: uniqueIndex().on(t.chainId, t.address)
@@ -133,12 +139,12 @@ var resolverAddressRecord = onchainTable2(
133
139
  // stored as BigInt
134
140
  coinType: t.bigint().notNull(),
135
141
  /**
136
- * Represents the value of the Addresss Record specified by ((chainId, resolver, node), coinType).
142
+ * Represents the value of the Address Record specified by ((chainId, resolver, node), coinType).
137
143
  *
138
144
  * The value of this field is interpreted by `interpretAddressRecordValue` — see its implementation
139
145
  * for additional context and specific guarantees.
140
146
  */
141
- value: t.text().notNull()
147
+ value: t.hex().notNull()
142
148
  }),
143
149
  (t) => ({
144
150
  pk: primaryKey2({ columns: [t.chainId, t.address, t.node, t.coinType] })
@@ -1569,7 +1575,19 @@ var relations_registry = relations4(registry, ({ one, many }) => ({
1569
1575
  references: [permissions.chainId, permissions.address]
1570
1576
  })
1571
1577
  }));
1578
+ var REGISTRATION_SORT_SENTINEL = 2n ** 256n - 1n;
1572
1579
  var domainType = onchainEnum2("DomainType", ["ENSv1Domain", "ENSv2Domain"]);
1580
+ var CANONICAL_NAME_PREFIX_LENGTH = 64;
1581
+ function truncateCanonicalNamePrefix(name) {
1582
+ if (name === null) return null;
1583
+ let prefix = "";
1584
+ let count = 0;
1585
+ for (const codePoint of name) {
1586
+ prefix += codePoint;
1587
+ if (++count >= CANONICAL_NAME_PREFIX_LENGTH) break;
1588
+ }
1589
+ return prefix;
1590
+ }
1573
1591
  var domain = onchainTable6(
1574
1592
  "domains",
1575
1593
  (t) => ({
@@ -1601,6 +1619,18 @@ var domain = onchainTable6(
1601
1619
  * @example "vitalik.eth"
1602
1620
  */
1603
1621
  canonicalName: t.text().$type(),
1622
+ /**
1623
+ * Materialized prefix of `canonicalName` (first {@link CANONICAL_NAME_PREFIX_LENGTH} code
1624
+ * points), NULL iff `canonical = false`. Maintained by `canonicality-db-helpers.ts`.
1625
+ *
1626
+ * Powers left-anchored / substring search (`__canonical_name_prefix LIKE 'vit%'`) and NAME
1627
+ * ordering without `canonical_name`'s full-length btree size hazard. The `__` prefix marks it
1628
+ * an internal implementation detail (mirrors `Registry.__hasChildren`); query `canonical_name`
1629
+ * for exact matches and display.
1630
+ *
1631
+ * @example "vitalik.eth"
1632
+ */
1633
+ __canonicalNamePrefix: t.text("__canonical_name_prefix").$type(),
1604
1634
  /**
1605
1635
  * Materialized Canonical LabelHashPath, NULL iff `canonical = false`.
1606
1636
  * Maintained by `canonicality-db-helpers.ts`.
@@ -1629,7 +1659,29 @@ var domain = onchainTable6(
1629
1659
  *
1630
1660
  * @dev the computed Node (via `namehash`) of this Domain's Canonical Name.
1631
1661
  */
1632
- canonicalNode: t.hex().$type()
1662
+ canonicalNode: t.hex().$type(),
1663
+ /**
1664
+ * Materialized `start` of this Domain's latest Registration, or {@link REGISTRATION_SORT_SENTINEL}
1665
+ * when the Domain has no Registration. Mirror of the latest `registration.start` (see
1666
+ * `latestRegistrationIndex`), maintained inline by `registration-db-helpers.ts`.
1667
+ *
1668
+ * @dev Exists purely so REGISTRATION_TIMESTAMP-ordered find-domains queries can use the
1669
+ * `(registry_id, __latest_registration_start, id)` composite index instead of joining through
1670
+ * `latest_registration_indexes` → `registrations` and sorting. Held NOT NULL (absent → sentinel)
1671
+ * so the keyset stays a plain tuple compare with no NULL-placement special casing; see
1672
+ * find-domains-resolver-helpers.ts. Double-underscore prefix marks it as an internal
1673
+ * materialized mirror, not part of the on-chain protocol surface; the canonical (possibly null)
1674
+ * value lives on the Registration entity.
1675
+ */
1676
+ __latestRegistrationStart: t.bigint("__latest_registration_start").notNull().default(REGISTRATION_SORT_SENTINEL),
1677
+ /**
1678
+ * Materialized `expiry` of this Domain's latest Registration, or {@link REGISTRATION_SORT_SENTINEL}
1679
+ * when the Domain has no Registration or its latest Registration never expires (effectively +∞).
1680
+ * Mirror of the latest `registration.expiry`, maintained inline by `registration-db-helpers.ts`.
1681
+ *
1682
+ * @dev See `__latestRegistrationStart`. Backs REGISTRATION_EXPIRY-ordered queries.
1683
+ */
1684
+ __latestRegistrationExpiry: t.bigint("__latest_registration_expiry").notNull().default(REGISTRATION_SORT_SENTINEL)
1633
1685
  // NOTE: Domain-Resolver Relations tracked via Protocol Acceleration plugin
1634
1686
  }),
1635
1687
  (t) => ({
@@ -1641,29 +1693,40 @@ var domain = onchainTable6(
1641
1693
  // get-domain-by-interpreted-name.ts). The leading `registry_id` column also serves
1642
1694
  // `WHERE registry_id = X` lookups via prefix scan.
1643
1695
  byRegistryAndLabelHash: index5().on(t.registryId, t.labelHash),
1644
- // composite for `WHERE registry_id = X ORDER BY canonical_name LIMIT N` (Domain.subdomains
1645
- // and other find-domains queries when ordering by NAME). Uses `left(canonical_name, 256)`
1646
- // to bound the index tuple under btree's per-tuple max (~2712 bytes): 256 chars × max 4-byte
1647
- // UTF-8 = 1024 bytes, leaving ample room for the registry_id and id columns. Names beyond
1648
- // 256 chars (currently <0.0001% of mainnet) collide on the truncated prefix and tie-break by
1649
- // id; this is acceptable since such names are invariably spam. Callers MUST sort by the same
1650
- // expression for the planner to use this index for ordered scan.
1651
- byRegistryAndCanonicalNameLeft: index5().on(
1652
- t.registryId,
1653
- sql2`left(${t.canonicalName}, 256)`,
1654
- t.id
1655
- ),
1696
+ // composite for `WHERE registry_id = X ORDER BY __canonical_name_prefix LIMIT N` (Domain.subdomains
1697
+ // and other find-domains queries when ordering by NAME). The length-capped prefix keeps the
1698
+ // index tuple under btree's per-tuple max (~2712 bytes); 64 code points × max 4-byte UTF-8 =
1699
+ // 256 bytes, leaving ample room for the registry_id and id columns.
1700
+ byRegistryAndCanonicalNamePrefix: index5().on(t.registryId, t.__canonicalNamePrefix, t.id),
1656
1701
  // hash index avoids the btree 8191-byte row-size hazard for spam names
1657
1702
  byCanonicalNameExact: index5().using("hash", t.canonicalName),
1658
- // GIN trigram index for substring / similarity queries (inline `gin_trgm_ops` via `sql`
1659
- // because passing it through `.op()` gets dropped by Ponder)
1660
- byCanonicalNameFuzzy: index5().using("gin", sql2`${t.canonicalName} gin_trgm_ops`),
1703
+ // GIN trigram on the length-capped prefix for left-anchored (`LIKE 'vit%'`) and substring
1704
+ // search (inline `gin_trgm_ops` via `sql` because passing it through `.op()` gets dropped by
1705
+ // Ponder)
1706
+ byCanonicalNamePrefixFuzzy: index5().using("gin", sql2`${t.__canonicalNamePrefix} gin_trgm_ops`),
1661
1707
  // GIN containment for `cascadeLabelHeal`'s `canonical_label_hash_path @> ARRAY[lh]` lookup
1662
1708
  byCanonicalLabelHashPath: index5().using("gin", t.canonicalLabelHashPath),
1663
1709
  // hash index for resolver-record → canonical-domain joins
1664
1710
  byCanonicalNode: index5().using("hash", t.canonicalNode),
1665
1711
  // btree for ORDER BY canonical_depth (typeahead and DEPTH-ordered browse)
1666
- byCanonicalDepth: index5().on(t.canonicalDepth)
1712
+ byCanonicalDepth: index5().on(t.canonicalDepth),
1713
+ // Composites for `WHERE registry_id = X ORDER BY <latest registration value> LIMIT N`
1714
+ // (REGISTRATION_TIMESTAMP / REGISTRATION_EXPIRY ordering in find-domains queries). The latest
1715
+ // registration's start/expiry is mirrored onto the Domain row (see `__latestRegistration*`) so
1716
+ // the order is an index-ordered scan, not a join through `latest_registration_indexes` →
1717
+ // `registrations` followed by a sort. The columns are NOT NULL (absent → `REGISTRATION_SORT_SENTINEL`),
1718
+ // so a single plain composite per column serves both ASC and DESC (forward / backward scan) with
1719
+ // a plain keyset tuple — see find-domains-resolver-helpers.ts.
1720
+ byRegistryAndLatestRegistrationStart: index5().on(
1721
+ t.registryId,
1722
+ t.__latestRegistrationStart,
1723
+ t.id
1724
+ ),
1725
+ byRegistryAndLatestRegistrationExpiry: index5().on(
1726
+ t.registryId,
1727
+ t.__latestRegistrationExpiry,
1728
+ t.id
1729
+ )
1667
1730
  })
1668
1731
  );
1669
1732
  var relations_domain = relations4(domain, ({ one, many }) => ({
@@ -1715,7 +1778,7 @@ var registration = onchainTable6(
1715
1778
  start: t.bigint().notNull(),
1716
1779
  // may have an expiry
1717
1780
  expiry: t.bigint(),
1718
- // maybe have a grace period (BaseRegistrar)
1781
+ // may have a grace period (BaseRegistrar)
1719
1782
  gracePeriod: t.bigint(),
1720
1783
  // registrar AccountId
1721
1784
  registrarChainId: t.int8({ mode: "number" }).notNull().$type(),
@@ -1923,6 +1986,8 @@ var label_relations = relations4(label, ({ many }) => ({
1923
1986
  domains: many(domain)
1924
1987
  }));
1925
1988
  export {
1989
+ CANONICAL_NAME_PREFIX_LENGTH,
1990
+ REGISTRATION_SORT_SENTINEL,
1926
1991
  account,
1927
1992
  account_relations,
1928
1993
  domain,
@@ -2030,6 +2095,7 @@ export {
2030
2095
  subgraph_wrappedTransfer,
2031
2096
  subgraph_wrappedTransferRelations,
2032
2097
  subregistries,
2033
- subregistryRelations
2098
+ subregistryRelations,
2099
+ truncateCanonicalNamePrefix
2034
2100
  };
2035
2101
  //# sourceMappingURL=index.js.map