@ensnode/ensdb-sdk 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,6 +16,11 @@ __export(ensindexer_abstract_exports, {
16
16
  domainResolverRelation: () => domainResolverRelation,
17
17
  domainResolverRelation_relations: () => domainResolverRelation_relations,
18
18
  domainType: () => domainType,
19
+ efpAccountMetadata: () => efpAccountMetadata,
20
+ efpListMetadata: () => efpListMetadata,
21
+ efpListRecords: () => efpListRecords,
22
+ efpListStorageLocations: () => efpListStorageLocations,
23
+ efpLists: () => efpLists,
19
24
  event: () => event,
20
25
  internal_registrarActionMetadata: () => internal_registrarActionMetadata,
21
26
  internal_registrarActionMetadataType: () => internal_registrarActionMetadataType,
@@ -120,9 +125,141 @@ __export(ensindexer_abstract_exports, {
120
125
  truncateCanonicalNamePrefix: () => truncateCanonicalNamePrefix
121
126
  });
122
127
 
128
+ // src/ensindexer-abstract/efp.schema.ts
129
+ import { index, onchainTable } from "ponder";
130
+ var efpLists = onchainTable(
131
+ "efp_lists",
132
+ (t) => ({
133
+ /** ERC-721 token id of the list NFT (a uint256), the list's primary key. */
134
+ id: t.bigint().primaryKey().$type(),
135
+ /** Current ERC-721 owner of the list NFT. */
136
+ owner: t.hex().notNull().$type(),
137
+ /** Chain id of the `ListRegistry` NFT (Base / 8453 on mainnet; the active namespace's EFP deployment chain otherwise). */
138
+ nftChainId: t.int8({ mode: "number" }).notNull().$type(),
139
+ /** `ListRegistry` contract address on `nftChainId`. */
140
+ nftContractAddress: t.hex().notNull().$type(),
141
+ /** Raw `UpdateListStorageLocation` payload. */
142
+ listStorageLocation: t.hex(),
143
+ /** Decoded list storage location: target chain id. */
144
+ listStorageLocationChainId: t.int8({ mode: "number" }).$type(),
145
+ /** Decoded list storage location: target contract address. */
146
+ listStorageLocationContractAddress: t.hex().$type(),
147
+ /** Decoded list storage location: target slot (bytes32). */
148
+ listStorageLocationSlot: t.hex(),
149
+ /** Address allowed to post records to this list (the EFP "user"). */
150
+ user: t.hex().$type(),
151
+ /** Address allowed to administer this list (the EFP "manager"). */
152
+ manager: t.hex().$type(),
153
+ createdAt: t.bigint().notNull().$type(),
154
+ updatedAt: t.bigint().notNull().$type()
155
+ }),
156
+ (t) => ({
157
+ idx_owner: index().on(t.owner),
158
+ idx_user: index().on(t.user),
159
+ idx_manager: index().on(t.manager),
160
+ idx_storageLocation: index().on(
161
+ t.listStorageLocationChainId,
162
+ t.listStorageLocationContractAddress,
163
+ t.listStorageLocationSlot
164
+ )
165
+ // `id` is a `bigint` (Postgres `numeric`) primary key, so its implicit unique index already
166
+ // orders numerically — `efp.lists` / `Account.efp.lists` pagination needs no extra index.
167
+ })
168
+ );
169
+ var efpListStorageLocations = onchainTable("efp_list_storage_locations", (t) => ({
170
+ /** Composite key "chainId-contractAddress-slot". */
171
+ id: t.text().primaryKey(),
172
+ chainId: t.int8({ mode: "number" }).notNull().$type(),
173
+ contractAddress: t.hex().notNull().$type(),
174
+ slot: t.hex().notNull(),
175
+ /**
176
+ * Token id of the list NFT that owns this storage location's reverse mapping. The slot is
177
+ * arbitrary, attacker-settable bytes, so multiple list NFTs can point at the same
178
+ * `(chainId, contract, slot)`; this records the FIRST list to claim it (first writer wins), and
179
+ * the `UpdateListStorageLocation` handler gates every write/delete of this row on that ownership.
180
+ * A consequence: when lists share a slot, only the owner's `EfpListRecord.list` back-ref and
181
+ * `user`/`manager` role routing track that slot.
182
+ */
183
+ tokenId: t.bigint().notNull().$type(),
184
+ updatedAt: t.bigint().notNull().$type()
185
+ }));
186
+ var efpListRecords = onchainTable(
187
+ "efp_list_records",
188
+ (t) => ({
189
+ /** Composite key "chainId-contractAddress-slot-record". */
190
+ id: t.text().primaryKey(),
191
+ chainId: t.int8({ mode: "number" }).notNull().$type(),
192
+ contractAddress: t.hex().notNull().$type(),
193
+ slot: t.hex().notNull(),
194
+ /** Canonical record prefix `version | type | address` (22 bytes). */
195
+ record: t.hex().notNull(),
196
+ /** Decoded record header — version byte. */
197
+ recordVersion: t.integer().notNull(),
198
+ /** Decoded record header — type byte. */
199
+ recordType: t.integer().notNull(),
200
+ /** Decoded record data. Only address records (type 1) are indexed, so exactly a 20-byte address. */
201
+ recordData: t.hex().notNull().$type(),
202
+ /** UTF-8 tags attached to this record (a set; NULL bytes stripped). */
203
+ tags: t.text().array().notNull().default([]),
204
+ createdAt: t.bigint().notNull().$type()
205
+ }),
206
+ (t) => ({
207
+ idx_slot: index().on(t.chainId, t.contractAddress, t.slot),
208
+ idx_recordData: index().on(t.recordData)
209
+ })
210
+ );
211
+ var efpAccountMetadata = onchainTable(
212
+ "efp_account_metadata",
213
+ (t) => ({
214
+ /** Composite key "chainId-address-key". */
215
+ id: t.text().primaryKey(),
216
+ chainId: t.int8({ mode: "number" }).notNull().$type(),
217
+ contractAddress: t.hex().notNull().$type(),
218
+ /** Account whose metadata this is. */
219
+ address: t.hex().notNull().$type(),
220
+ /** Metadata key (UTF-8 string). */
221
+ key: t.text().notNull(),
222
+ /** Metadata value (raw bytes). */
223
+ value: t.hex().notNull(),
224
+ /**
225
+ * For the `primary-list` key only: the decoded token id of the account's primary list (the
226
+ * `value` is `abi.encodePacked(uint256)`, which Postgres can't compare to the numeric
227
+ * `efp_lists.id`). Decoding it at index time makes the validated follower/following social graph
228
+ * a pure SQL join. `null` for any other key, or a malformed `primary-list` value.
229
+ */
230
+ primaryListTokenId: t.bigint().$type(),
231
+ createdAt: t.bigint().notNull().$type(),
232
+ updatedAt: t.bigint().notNull().$type()
233
+ }),
234
+ (t) => ({
235
+ idx_address: index().on(t.address),
236
+ // Account-metadata lookups (primary-list validation, `metadata(key:)`) filter by `(address, key)`;
237
+ // a composite index makes that a point lookup rather than an address-partition scan.
238
+ idx_address_key: index().on(t.address, t.key),
239
+ // The followers join filters lists by `(user, primaryListTokenId)`; index it for the social graph.
240
+ idx_primaryListTokenId: index().on(t.primaryListTokenId)
241
+ })
242
+ );
243
+ var efpListMetadata = onchainTable(
244
+ "efp_list_metadata",
245
+ (t) => ({
246
+ /** Composite key "chainId-contractAddress-slot-key". */
247
+ id: t.text().primaryKey(),
248
+ chainId: t.int8({ mode: "number" }).notNull().$type(),
249
+ contractAddress: t.hex().notNull().$type(),
250
+ slot: t.hex().notNull(),
251
+ key: t.text().notNull(),
252
+ value: t.hex().notNull(),
253
+ createdAt: t.bigint().notNull().$type()
254
+ }),
255
+ (t) => ({
256
+ idx_slot: index().on(t.chainId, t.contractAddress, t.slot)
257
+ })
258
+ );
259
+
123
260
  // src/ensindexer-abstract/migrated-nodes.schema.ts
124
- import { onchainTable, primaryKey } from "ponder";
125
- var migratedNodeByParent = onchainTable(
261
+ import { onchainTable as onchainTable2, primaryKey } from "ponder";
262
+ var migratedNodeByParent = onchainTable2(
126
263
  "migrated_nodes_by_parent",
127
264
  (t) => ({
128
265
  // keyed by (parentNode, labelHash)
@@ -133,13 +270,13 @@ var migratedNodeByParent = onchainTable(
133
270
  pk: primaryKey({ columns: [t.parentNode, t.labelHash] })
134
271
  })
135
272
  );
136
- var migratedNodeByNode = onchainTable("migrated_nodes_by_node", (t) => ({
273
+ var migratedNodeByNode = onchainTable2("migrated_nodes_by_node", (t) => ({
137
274
  node: t.hex().primaryKey().$type()
138
275
  }));
139
276
 
140
277
  // src/ensindexer-abstract/protocol-acceleration.schema.ts
141
- import { index, onchainTable as onchainTable2, primaryKey as primaryKey2, relations, uniqueIndex } from "ponder";
142
- var reverseNameRecord = onchainTable2(
278
+ import { index as index2, onchainTable as onchainTable3, primaryKey as primaryKey2, relations, uniqueIndex } from "ponder";
279
+ var reverseNameRecord = onchainTable3(
143
280
  "reverse_name_records",
144
281
  (t) => ({
145
282
  // keyed by (address, coinType)
@@ -158,7 +295,7 @@ var reverseNameRecord = onchainTable2(
158
295
  pk: primaryKey2({ columns: [t.address, t.coinType] })
159
296
  })
160
297
  );
161
- var domainResolverRelation = onchainTable2(
298
+ var domainResolverRelation = onchainTable3(
162
299
  "domain_resolver_relations",
163
300
  (t) => ({
164
301
  // keyed by (chainId, address, node)
@@ -171,7 +308,7 @@ var domainResolverRelation = onchainTable2(
171
308
  }),
172
309
  (t) => ({
173
310
  pk: primaryKey2({ columns: [t.chainId, t.address, t.domainId] }),
174
- byDomain: index().on(t.domainId)
311
+ byDomain: index2().on(t.domainId)
175
312
  })
176
313
  );
177
314
  var domainResolverRelation_relations = relations(domainResolverRelation, ({ one }) => ({
@@ -180,7 +317,7 @@ var domainResolverRelation_relations = relations(domainResolverRelation, ({ one
180
317
  references: [resolver.chainId, resolver.address]
181
318
  })
182
319
  }));
183
- var resolver = onchainTable2(
320
+ var resolver = onchainTable3(
184
321
  "resolvers",
185
322
  (t) => ({
186
323
  // keyed by (chainId, address)
@@ -201,7 +338,7 @@ var resolver = onchainTable2(
201
338
  var resolver_relations = relations(resolver, ({ many }) => ({
202
339
  records: many(resolverRecords)
203
340
  }));
204
- var resolverRecords = onchainTable2(
341
+ var resolverRecords = onchainTable3(
205
342
  "resolver_records",
206
343
  (t) => ({
207
344
  // keyed by (chainId, resolver, node)
@@ -252,7 +389,7 @@ var resolverRecords_relations = relations(resolverRecords, ({ one, many }) => ({
252
389
  // resolverRecord has many text records
253
390
  textRecords: many(resolverTextRecord)
254
391
  }));
255
- var resolverAddressRecord = onchainTable2(
392
+ var resolverAddressRecord = onchainTable3(
256
393
  "resolver_address_records",
257
394
  (t) => ({
258
395
  // keyed by ((chainId, resolver, node), coinType)
@@ -275,8 +412,10 @@ var resolverAddressRecord = onchainTable2(
275
412
  (t) => ({
276
413
  pk: primaryKey2({ columns: [t.chainId, t.address, t.node, t.coinType] }),
277
414
  // supports the reverse lookup powering `Account.nameReferences`:
278
- // `WHERE value = <address> [AND coin_type = <coinType>]`
279
- byValueAndCoinType: index().on(t.value, t.coinType)
415
+ // `WHERE value = <address> [AND coin_type = <coinType>] ORDER BY (node, coinType, chainId, address)`.
416
+ // The `value` prefix seeks the filter; the remaining columns match the keyset ORDER BY tuple so
417
+ // rows are yielded already sorted, letting pagination range-scan to the cursor instead of sorting.
418
+ byValueKeyset: index2().on(t.value, t.node, t.coinType, t.chainId, t.address)
280
419
  })
281
420
  );
282
421
  var resolverAddressRecordRelations = relations(resolverAddressRecord, ({ one }) => ({
@@ -290,7 +429,7 @@ var resolverAddressRecordRelations = relations(resolverAddressRecord, ({ one })
290
429
  references: [resolverRecords.chainId, resolverRecords.address, resolverRecords.node]
291
430
  })
292
431
  }));
293
- var resolverTextRecord = onchainTable2(
432
+ var resolverTextRecord = onchainTable3(
294
433
  "resolver_text_records",
295
434
  (t) => ({
296
435
  // keyed by ((chainId, resolver, node), key)
@@ -319,8 +458,8 @@ var resolverTextRecordRelations = relations(resolverTextRecord, ({ one }) => ({
319
458
  }));
320
459
 
321
460
  // src/ensindexer-abstract/registrars.schema.ts
322
- import { index as index2, onchainEnum, onchainTable as onchainTable3, relations as relations2, uniqueIndex as uniqueIndex2 } from "ponder";
323
- var subregistries = onchainTable3(
461
+ import { index as index3, onchainEnum, onchainTable as onchainTable4, relations as relations2, uniqueIndex as uniqueIndex2 } from "ponder";
462
+ var subregistries = onchainTable4(
324
463
  "subregistries",
325
464
  (t) => ({
326
465
  /**
@@ -350,7 +489,7 @@ var subregistries = onchainTable3(
350
489
  uniqueNode: uniqueIndex2().on(t.node)
351
490
  })
352
491
  );
353
- var registrationLifecycles = onchainTable3(
492
+ var registrationLifecycles = onchainTable4(
354
493
  "registration_lifecycles",
355
494
  (t) => ({
356
495
  /**
@@ -383,14 +522,14 @@ var registrationLifecycles = onchainTable3(
383
522
  expiresAt: t.bigint().notNull()
384
523
  }),
385
524
  (t) => ({
386
- bySubregistry: index2().on(t.subregistryId)
525
+ bySubregistry: index3().on(t.subregistryId)
387
526
  })
388
527
  );
389
528
  var registrarActionType = onchainEnum("registrar_action_type", [
390
529
  "registration",
391
530
  "renewal"
392
531
  ]);
393
- var registrarActions = onchainTable3(
532
+ var registrarActions = onchainTable4(
394
533
  "registrar_actions",
395
534
  (t) => ({
396
535
  /**
@@ -639,15 +778,15 @@ var registrarActions = onchainTable3(
639
778
  eventIds: t.text().array().notNull()
640
779
  }),
641
780
  (t) => ({
642
- byDecodedReferrer: index2().on(t.decodedReferrer),
643
- byTimestamp: index2().on(t.timestamp)
781
+ byDecodedReferrer: index3().on(t.decodedReferrer),
782
+ byTimestamp: index3().on(t.timestamp)
644
783
  })
645
784
  );
646
785
  var internal_registrarActionMetadataType = onchainEnum(
647
786
  "_ensindexer_registrar_action_metadata_type",
648
787
  ["CURRENT_LOGICAL_REGISTRAR_ACTION"]
649
788
  );
650
- var internal_registrarActionMetadata = onchainTable3(
789
+ var internal_registrarActionMetadata = onchainTable4(
651
790
  "_ensindexer_registrar_action_metadata",
652
791
  (t) => ({
653
792
  /**
@@ -696,7 +835,7 @@ var registrarActionRelations = relations2(registrarActions, ({ one }) => ({
696
835
  }));
697
836
 
698
837
  // src/ensindexer-abstract/subgraph.schema.ts
699
- import { index as index3, onchainTable as onchainTable4, relations as relations3, sql } from "ponder";
838
+ import { index as index4, onchainTable as onchainTable5, relations as relations3, sql } from "ponder";
700
839
 
701
840
  // src/lib/collate.ts
702
841
  function monkeypatchCollate(col, collation) {
@@ -707,7 +846,7 @@ function monkeypatchCollate(col, collation) {
707
846
  }
708
847
 
709
848
  // src/ensindexer-abstract/subgraph.schema.ts
710
- var subgraph_domain = onchainTable4(
849
+ var subgraph_domain = onchainTable5(
711
850
  "subgraph_domains",
712
851
  (t) => ({
713
852
  // The namehash of the name
@@ -777,17 +916,17 @@ var subgraph_domain = onchainTable4(
777
916
  }),
778
917
  (t) => ({
779
918
  // uses a hash index because some name values exceed the btree max row size (8191 bytes)
780
- byExactName: index3().using("hash", t.name),
919
+ byExactName: index4().using("hash", t.name),
781
920
  // GIN trigram index for partial-match filters (_contains, _starts_with, _ends_with).
782
921
  // (inline `gin_trgm_ops` via `sql` because passing it through `.op()` gets dropped by Ponder,
783
922
  // producing `USING gin (name)` with no opclass)
784
- byFuzzyName: index3().using("gin", sql`${t.name} gin_trgm_ops`),
785
- byLabelhash: index3().on(t.labelhash),
786
- byParentId: index3().on(t.parentId),
787
- byOwnerId: index3().on(t.ownerId),
788
- byRegistrantId: index3().on(t.registrantId),
789
- byWrappedOwnerId: index3().on(t.wrappedOwnerId),
790
- byResolvedAddressId: index3().on(t.resolvedAddressId)
923
+ byFuzzyName: index4().using("gin", sql`${t.name} gin_trgm_ops`),
924
+ byLabelhash: index4().on(t.labelhash),
925
+ byParentId: index4().on(t.parentId),
926
+ byOwnerId: index4().on(t.ownerId),
927
+ byRegistrantId: index4().on(t.registrantId),
928
+ byWrappedOwnerId: index4().on(t.wrappedOwnerId),
929
+ byResolvedAddressId: index4().on(t.resolvedAddressId)
791
930
  })
792
931
  );
793
932
  monkeypatchCollate(subgraph_domain.name, '"C"');
@@ -837,7 +976,7 @@ var subgraph_domainRelations = relations3(subgraph_domain, ({ one, many }) => ({
837
976
  fusesSets: many(subgraph_fusesSet),
838
977
  expiryExtendeds: many(subgraph_expiryExtended)
839
978
  }));
840
- var subgraph_account = onchainTable4("subgraph_accounts", (t) => ({
979
+ var subgraph_account = onchainTable5("subgraph_accounts", (t) => ({
841
980
  id: t.hex().primaryKey()
842
981
  }));
843
982
  var subgraph_accountRelations = relations3(subgraph_account, ({ many }) => ({
@@ -845,7 +984,7 @@ var subgraph_accountRelations = relations3(subgraph_account, ({ many }) => ({
845
984
  wrappedDomains: many(subgraph_wrappedDomain),
846
985
  registrations: many(subgraph_registration)
847
986
  }));
848
- var subgraph_resolver = onchainTable4(
987
+ var subgraph_resolver = onchainTable5(
849
988
  "subgraph_resolvers",
850
989
  (t) => ({
851
990
  // The unique identifier for this resolver, which is a concatenation of the domain namehash and the resolver address
@@ -866,7 +1005,7 @@ var subgraph_resolver = onchainTable4(
866
1005
  coinTypes: t.bigint().array()
867
1006
  }),
868
1007
  (t) => ({
869
- byDomainId: index3().on(t.domainId)
1008
+ byDomainId: index4().on(t.domainId)
870
1009
  })
871
1010
  );
872
1011
  var subgraph_resolverRelations = relations3(subgraph_resolver, ({ one, many }) => ({
@@ -890,7 +1029,7 @@ var subgraph_resolverRelations = relations3(subgraph_resolver, ({ one, many }) =
890
1029
  authorisationChangeds: many(subgraph_authorisationChanged),
891
1030
  versionChangeds: many(subgraph_versionChanged)
892
1031
  }));
893
- var subgraph_registration = onchainTable4(
1032
+ var subgraph_registration = onchainTable5(
894
1033
  "subgraph_registrations",
895
1034
  (t) => ({
896
1035
  // The unique identifier of the registration
@@ -927,9 +1066,9 @@ var subgraph_registration = onchainTable4(
927
1066
  labelName: t.text()
928
1067
  }),
929
1068
  (t) => ({
930
- byDomainId: index3().on(t.domainId),
931
- byRegistrationDate: index3().on(t.registrationDate),
932
- byExpiryDate: index3().on(t.expiryDate)
1069
+ byDomainId: index4().on(t.domainId),
1070
+ byRegistrationDate: index4().on(t.registrationDate),
1071
+ byExpiryDate: index4().on(t.expiryDate)
933
1072
  })
934
1073
  );
935
1074
  var subgraph_registrationRelations = relations3(subgraph_registration, ({ one, many }) => ({
@@ -946,7 +1085,7 @@ var subgraph_registrationRelations = relations3(subgraph_registration, ({ one, m
946
1085
  nameReneweds: many(subgraph_nameRenewed),
947
1086
  nameTransferreds: many(subgraph_nameTransferred)
948
1087
  }));
949
- var subgraph_wrappedDomain = onchainTable4(
1088
+ var subgraph_wrappedDomain = onchainTable5(
950
1089
  "subgraph_wrapped_domains",
951
1090
  (t) => ({
952
1091
  // The unique identifier for each instance of the WrappedDomain entity
@@ -978,7 +1117,7 @@ var subgraph_wrappedDomain = onchainTable4(
978
1117
  name: t.text()
979
1118
  }),
980
1119
  (t) => ({
981
- byDomainId: index3().on(t.domainId)
1120
+ byDomainId: index4().on(t.domainId)
982
1121
  })
983
1122
  );
984
1123
  var subgraph_wrappedDomainRelations = relations3(subgraph_wrappedDomain, ({ one }) => ({
@@ -1002,11 +1141,11 @@ var domainEvent = (t) => ({
1002
1141
  });
1003
1142
  var domainEventIndex = (t) => ({
1004
1143
  // primary reverse lookup
1005
- idx: index3().on(t.domainId),
1144
+ idx: index4().on(t.domainId),
1006
1145
  // sorting index
1007
- idx_compound: index3().on(t.domainId, t.id)
1146
+ idx_compound: index4().on(t.domainId, t.id)
1008
1147
  });
1009
- var subgraph_transfer = onchainTable4(
1148
+ var subgraph_transfer = onchainTable5(
1010
1149
  "subgraph_transfers",
1011
1150
  (t) => ({
1012
1151
  ...domainEvent(t),
@@ -1014,7 +1153,7 @@ var subgraph_transfer = onchainTable4(
1014
1153
  }),
1015
1154
  domainEventIndex
1016
1155
  );
1017
- var subgraph_newOwner = onchainTable4(
1156
+ var subgraph_newOwner = onchainTable5(
1018
1157
  "subgraph_new_owners",
1019
1158
  (t) => ({
1020
1159
  ...domainEvent(t),
@@ -1023,7 +1162,7 @@ var subgraph_newOwner = onchainTable4(
1023
1162
  }),
1024
1163
  domainEventIndex
1025
1164
  );
1026
- var subgraph_newResolver = onchainTable4(
1165
+ var subgraph_newResolver = onchainTable5(
1027
1166
  "subgraph_new_resolvers",
1028
1167
  (t) => ({
1029
1168
  ...domainEvent(t),
@@ -1031,7 +1170,7 @@ var subgraph_newResolver = onchainTable4(
1031
1170
  }),
1032
1171
  domainEventIndex
1033
1172
  );
1034
- var subgraph_newTTL = onchainTable4(
1173
+ var subgraph_newTTL = onchainTable5(
1035
1174
  "subgraph_new_ttls",
1036
1175
  (t) => ({
1037
1176
  ...domainEvent(t),
@@ -1039,7 +1178,7 @@ var subgraph_newTTL = onchainTable4(
1039
1178
  }),
1040
1179
  domainEventIndex
1041
1180
  );
1042
- var subgraph_wrappedTransfer = onchainTable4(
1181
+ var subgraph_wrappedTransfer = onchainTable5(
1043
1182
  "subgraph_wrapped_transfers",
1044
1183
  (t) => ({
1045
1184
  ...domainEvent(t),
@@ -1047,7 +1186,7 @@ var subgraph_wrappedTransfer = onchainTable4(
1047
1186
  }),
1048
1187
  domainEventIndex
1049
1188
  );
1050
- var subgraph_nameWrapped = onchainTable4(
1189
+ var subgraph_nameWrapped = onchainTable5(
1051
1190
  "subgraph_name_wrapped",
1052
1191
  (t) => ({
1053
1192
  ...domainEvent(t),
@@ -1058,7 +1197,7 @@ var subgraph_nameWrapped = onchainTable4(
1058
1197
  }),
1059
1198
  domainEventIndex
1060
1199
  );
1061
- var subgraph_nameUnwrapped = onchainTable4(
1200
+ var subgraph_nameUnwrapped = onchainTable5(
1062
1201
  "subgraph_name_unwrapped",
1063
1202
  (t) => ({
1064
1203
  ...domainEvent(t),
@@ -1066,7 +1205,7 @@ var subgraph_nameUnwrapped = onchainTable4(
1066
1205
  }),
1067
1206
  domainEventIndex
1068
1207
  );
1069
- var subgraph_fusesSet = onchainTable4(
1208
+ var subgraph_fusesSet = onchainTable5(
1070
1209
  "subgraph_fuses_set",
1071
1210
  (t) => ({
1072
1211
  ...domainEvent(t),
@@ -1074,7 +1213,7 @@ var subgraph_fusesSet = onchainTable4(
1074
1213
  }),
1075
1214
  domainEventIndex
1076
1215
  );
1077
- var subgraph_expiryExtended = onchainTable4(
1216
+ var subgraph_expiryExtended = onchainTable5(
1078
1217
  "subgraph_expiry_extended",
1079
1218
  (t) => ({
1080
1219
  ...domainEvent(t),
@@ -1088,11 +1227,11 @@ var registrationEvent = (t) => ({
1088
1227
  });
1089
1228
  var registrationEventIndex = (t) => ({
1090
1229
  // primary reverse lookup
1091
- idx: index3().on(t.registrationId),
1230
+ idx: index4().on(t.registrationId),
1092
1231
  // sorting index
1093
- idx_compound: index3().on(t.registrationId, t.id)
1232
+ idx_compound: index4().on(t.registrationId, t.id)
1094
1233
  });
1095
- var subgraph_nameRegistered = onchainTable4(
1234
+ var subgraph_nameRegistered = onchainTable5(
1096
1235
  "subgraph_name_registered",
1097
1236
  (t) => ({
1098
1237
  ...registrationEvent(t),
@@ -1101,7 +1240,7 @@ var subgraph_nameRegistered = onchainTable4(
1101
1240
  }),
1102
1241
  registrationEventIndex
1103
1242
  );
1104
- var subgraph_nameRenewed = onchainTable4(
1243
+ var subgraph_nameRenewed = onchainTable5(
1105
1244
  "subgraph_name_renewed",
1106
1245
  (t) => ({
1107
1246
  ...registrationEvent(t),
@@ -1109,7 +1248,7 @@ var subgraph_nameRenewed = onchainTable4(
1109
1248
  }),
1110
1249
  registrationEventIndex
1111
1250
  );
1112
- var subgraph_nameTransferred = onchainTable4(
1251
+ var subgraph_nameTransferred = onchainTable5(
1113
1252
  "subgraph_name_transferred",
1114
1253
  (t) => ({
1115
1254
  ...registrationEvent(t),
@@ -1123,11 +1262,11 @@ var resolverEvent = (t) => ({
1123
1262
  });
1124
1263
  var resolverEventIndex = (t) => ({
1125
1264
  // primary reverse lookup
1126
- idx: index3().on(t.resolverId),
1265
+ idx: index4().on(t.resolverId),
1127
1266
  // sorting index
1128
- idx_compound: index3().on(t.resolverId, t.id)
1267
+ idx_compound: index4().on(t.resolverId, t.id)
1129
1268
  });
1130
- var subgraph_addrChanged = onchainTable4(
1269
+ var subgraph_addrChanged = onchainTable5(
1131
1270
  "subgraph_addr_changed",
1132
1271
  (t) => ({
1133
1272
  ...resolverEvent(t),
@@ -1135,7 +1274,7 @@ var subgraph_addrChanged = onchainTable4(
1135
1274
  }),
1136
1275
  resolverEventIndex
1137
1276
  );
1138
- var subgraph_multicoinAddrChanged = onchainTable4(
1277
+ var subgraph_multicoinAddrChanged = onchainTable5(
1139
1278
  "subgraph_multicoin_addr_changed",
1140
1279
  (t) => ({
1141
1280
  ...resolverEvent(t),
@@ -1144,7 +1283,7 @@ var subgraph_multicoinAddrChanged = onchainTable4(
1144
1283
  }),
1145
1284
  resolverEventIndex
1146
1285
  );
1147
- var subgraph_nameChanged = onchainTable4(
1286
+ var subgraph_nameChanged = onchainTable5(
1148
1287
  "subgraph_name_changed",
1149
1288
  (t) => ({
1150
1289
  ...resolverEvent(t),
@@ -1152,7 +1291,7 @@ var subgraph_nameChanged = onchainTable4(
1152
1291
  }),
1153
1292
  resolverEventIndex
1154
1293
  );
1155
- var subgraph_abiChanged = onchainTable4(
1294
+ var subgraph_abiChanged = onchainTable5(
1156
1295
  "subgraph_abi_changed",
1157
1296
  (t) => ({
1158
1297
  ...resolverEvent(t),
@@ -1160,7 +1299,7 @@ var subgraph_abiChanged = onchainTable4(
1160
1299
  }),
1161
1300
  resolverEventIndex
1162
1301
  );
1163
- var subgraph_pubkeyChanged = onchainTable4(
1302
+ var subgraph_pubkeyChanged = onchainTable5(
1164
1303
  "subgraph_pubkey_changed",
1165
1304
  (t) => ({
1166
1305
  ...resolverEvent(t),
@@ -1169,7 +1308,7 @@ var subgraph_pubkeyChanged = onchainTable4(
1169
1308
  }),
1170
1309
  resolverEventIndex
1171
1310
  );
1172
- var subgraph_textChanged = onchainTable4(
1311
+ var subgraph_textChanged = onchainTable5(
1173
1312
  "subgraph_text_changed",
1174
1313
  (t) => ({
1175
1314
  ...resolverEvent(t),
@@ -1178,7 +1317,7 @@ var subgraph_textChanged = onchainTable4(
1178
1317
  }),
1179
1318
  resolverEventIndex
1180
1319
  );
1181
- var subgraph_contenthashChanged = onchainTable4(
1320
+ var subgraph_contenthashChanged = onchainTable5(
1182
1321
  "subgraph_contenthash_changed",
1183
1322
  (t) => ({
1184
1323
  ...resolverEvent(t),
@@ -1186,7 +1325,7 @@ var subgraph_contenthashChanged = onchainTable4(
1186
1325
  }),
1187
1326
  resolverEventIndex
1188
1327
  );
1189
- var subgraph_interfaceChanged = onchainTable4(
1328
+ var subgraph_interfaceChanged = onchainTable5(
1190
1329
  "subgraph_interface_changed",
1191
1330
  (t) => ({
1192
1331
  ...resolverEvent(t),
@@ -1195,7 +1334,7 @@ var subgraph_interfaceChanged = onchainTable4(
1195
1334
  }),
1196
1335
  resolverEventIndex
1197
1336
  );
1198
- var subgraph_authorisationChanged = onchainTable4(
1337
+ var subgraph_authorisationChanged = onchainTable5(
1199
1338
  "subgraph_authorisation_changed",
1200
1339
  (t) => ({
1201
1340
  ...resolverEvent(t),
@@ -1205,7 +1344,7 @@ var subgraph_authorisationChanged = onchainTable4(
1205
1344
  }),
1206
1345
  resolverEventIndex
1207
1346
  );
1208
- var subgraph_versionChanged = onchainTable4(
1347
+ var subgraph_versionChanged = onchainTable5(
1209
1348
  "subgraph_version_changed",
1210
1349
  (t) => ({
1211
1350
  ...resolverEvent(t),
@@ -1399,8 +1538,8 @@ var subgraph_versionChangedRelations = relations3(subgraph_versionChanged, ({ on
1399
1538
  }));
1400
1539
 
1401
1540
  // src/ensindexer-abstract/tokenscope.schema.ts
1402
- import { index as index4, onchainTable as onchainTable5 } from "ponder";
1403
- var nameSales = onchainTable5(
1541
+ import { index as index5, onchainTable as onchainTable6 } from "ponder";
1542
+ var nameSales = onchainTable6(
1404
1543
  "name_sales",
1405
1544
  (t) => ({
1406
1545
  /**
@@ -1489,14 +1628,14 @@ var nameSales = onchainTable5(
1489
1628
  timestamp: t.bigint().notNull()
1490
1629
  }),
1491
1630
  (t) => ({
1492
- idx_domainId: index4().on(t.domainId),
1493
- idx_assetId: index4().on(t.assetId),
1494
- idx_buyer: index4().on(t.buyer),
1495
- idx_seller: index4().on(t.seller),
1496
- idx_timestamp: index4().on(t.timestamp)
1631
+ idx_domainId: index5().on(t.domainId),
1632
+ idx_assetId: index5().on(t.assetId),
1633
+ idx_buyer: index5().on(t.buyer),
1634
+ idx_seller: index5().on(t.seller),
1635
+ idx_timestamp: index5().on(t.timestamp)
1497
1636
  })
1498
1637
  );
1499
- var nameTokens = onchainTable5(
1638
+ var nameTokens = onchainTable6(
1500
1639
  "name_tokens",
1501
1640
  (t) => ({
1502
1641
  /**
@@ -1576,14 +1715,14 @@ var nameTokens = onchainTable5(
1576
1715
  mintStatus: t.text().notNull()
1577
1716
  }),
1578
1717
  (t) => ({
1579
- idx_domainId: index4().on(t.domainId),
1580
- idx_owner: index4().on(t.owner)
1718
+ idx_domainId: index5().on(t.domainId),
1719
+ idx_owner: index5().on(t.owner)
1581
1720
  })
1582
1721
  );
1583
1722
 
1584
1723
  // src/ensindexer-abstract/unigraph.schema.ts
1585
- import { index as index5, onchainEnum as onchainEnum2, onchainTable as onchainTable6, primaryKey as primaryKey3, relations as relations4, sql as sql2, uniqueIndex as uniqueIndex3 } from "ponder";
1586
- var event = onchainTable6(
1724
+ import { index as index6, onchainEnum as onchainEnum2, onchainTable as onchainTable7, primaryKey as primaryKey3, relations as relations4, sql as sql2, uniqueIndex as uniqueIndex3 } from "ponder";
1725
+ var event = onchainTable7(
1587
1726
  "events",
1588
1727
  (t) => ({
1589
1728
  // Ponder's event.id
@@ -1613,13 +1752,13 @@ var event = onchainTable6(
1613
1752
  data: t.hex().notNull()
1614
1753
  }),
1615
1754
  (t) => ({
1616
- bySelector: index5().on(t.selector),
1617
- byFrom: index5().on(t.from),
1618
- bySender: index5().on(t.sender),
1619
- byTimestamp: index5().on(t.timestamp)
1755
+ bySelector: index6().on(t.selector),
1756
+ byFrom: index6().on(t.from),
1757
+ bySender: index6().on(t.sender),
1758
+ byTimestamp: index6().on(t.timestamp)
1620
1759
  })
1621
1760
  );
1622
- var domainEvent2 = onchainTable6(
1761
+ var domainEvent2 = onchainTable7(
1623
1762
  "domain_events",
1624
1763
  (t) => ({
1625
1764
  domainId: t.text().notNull().$type(),
@@ -1627,7 +1766,7 @@ var domainEvent2 = onchainTable6(
1627
1766
  }),
1628
1767
  (t) => ({ pk: primaryKey3({ columns: [t.domainId, t.eventId] }) })
1629
1768
  );
1630
- var resolverEvent2 = onchainTable6(
1769
+ var resolverEvent2 = onchainTable7(
1631
1770
  "resolver_events",
1632
1771
  (t) => ({
1633
1772
  resolverId: t.text().notNull().$type(),
@@ -1635,7 +1774,7 @@ var resolverEvent2 = onchainTable6(
1635
1774
  }),
1636
1775
  (t) => ({ pk: primaryKey3({ columns: [t.resolverId, t.eventId] }) })
1637
1776
  );
1638
- var permissionsEvent = onchainTable6(
1777
+ var permissionsEvent = onchainTable7(
1639
1778
  "permissions_events",
1640
1779
  (t) => ({
1641
1780
  permissionsId: t.text().notNull().$type(),
@@ -1643,7 +1782,7 @@ var permissionsEvent = onchainTable6(
1643
1782
  }),
1644
1783
  (t) => ({ pk: primaryKey3({ columns: [t.permissionsId, t.eventId] }) })
1645
1784
  );
1646
- var permissionsUserEvent = onchainTable6(
1785
+ var permissionsUserEvent = onchainTable7(
1647
1786
  "permissions_user_events",
1648
1787
  (t) => ({
1649
1788
  permissionsUserId: t.text().notNull().$type(),
@@ -1651,7 +1790,7 @@ var permissionsUserEvent = onchainTable6(
1651
1790
  }),
1652
1791
  (t) => ({ pk: primaryKey3({ columns: [t.permissionsUserId, t.eventId] }) })
1653
1792
  );
1654
- var account = onchainTable6("accounts", (t) => ({
1793
+ var account = onchainTable7("accounts", (t) => ({
1655
1794
  id: t.hex().primaryKey().$type()
1656
1795
  }));
1657
1796
  var account_relations = relations4(account, ({ many }) => ({
@@ -1664,7 +1803,7 @@ var registryType = onchainEnum2("RegistryType", [
1664
1803
  "ENSv1VirtualRegistry",
1665
1804
  "ENSv2Registry"
1666
1805
  ]);
1667
- var registry = onchainTable6(
1806
+ var registry = onchainTable7(
1668
1807
  "registries",
1669
1808
  (t) => ({
1670
1809
  // see RegistryId for guarantees
@@ -1690,7 +1829,7 @@ var registry = onchainTable6(
1690
1829
  }),
1691
1830
  (t) => ({
1692
1831
  // NOTE: non-unique index because multiple rows can share (chainId, address) across virtual registries
1693
- byChainAddress: index5().on(t.chainId, t.address)
1832
+ byChainAddress: index6().on(t.chainId, t.address)
1694
1833
  })
1695
1834
  );
1696
1835
  var relations_registry = relations4(registry, ({ one, many }) => ({
@@ -1717,7 +1856,7 @@ function truncateCanonicalNamePrefix(name) {
1717
1856
  }
1718
1857
  return prefix;
1719
1858
  }
1720
- var domain = onchainTable6(
1859
+ var domain = onchainTable7(
1721
1860
  "domains",
1722
1861
  (t) => ({
1723
1862
  // see DomainId for guarantees (ENSv1DomainId: `${ENSv1RegistryId}/${node}`, ENSv2DomainId: CAIP-19)
@@ -1814,31 +1953,31 @@ var domain = onchainTable6(
1814
1953
  // NOTE: Domain-Resolver Relations tracked via Protocol Acceleration plugin
1815
1954
  }),
1816
1955
  (t) => ({
1817
- byType: index5().on(t.type),
1818
- bySubregistry: index5().on(t.subregistryId).where(sql2`${t.subregistryId} IS NOT NULL`),
1819
- byOwner: index5().on(t.ownerId),
1820
- byLabelHash: index5().on(t.labelHash),
1956
+ byType: index6().on(t.type),
1957
+ bySubregistry: index6().on(t.subregistryId).where(sql2`${t.subregistryId} IS NOT NULL`),
1958
+ byOwner: index6().on(t.ownerId),
1959
+ byLabelHash: index6().on(t.labelHash),
1821
1960
  // Composite for `(registry_id, label_hash)` lookups (namegraph walk in
1822
1961
  // get-domain-by-interpreted-name.ts). The leading `registry_id` column also serves
1823
1962
  // `WHERE registry_id = X` lookups via prefix scan.
1824
- byRegistryAndLabelHash: index5().on(t.registryId, t.labelHash),
1963
+ byRegistryAndLabelHash: index6().on(t.registryId, t.labelHash),
1825
1964
  // composite for `WHERE registry_id = X ORDER BY __canonical_name_prefix LIMIT N` (Domain.subdomains
1826
1965
  // and other find-domains queries when ordering by NAME). The length-capped prefix keeps the
1827
1966
  // index tuple under btree's per-tuple max (~2712 bytes); 64 code points × max 4-byte UTF-8 =
1828
1967
  // 256 bytes, leaving ample room for the registry_id and id columns.
1829
- byRegistryAndCanonicalNamePrefix: index5().on(t.registryId, t.__canonicalNamePrefix, t.id),
1968
+ byRegistryAndCanonicalNamePrefix: index6().on(t.registryId, t.__canonicalNamePrefix, t.id),
1830
1969
  // hash index avoids the btree 8191-byte row-size hazard for spam names
1831
- byCanonicalNameExact: index5().using("hash", t.canonicalName),
1970
+ byCanonicalNameExact: index6().using("hash", t.canonicalName),
1832
1971
  // GIN trigram on the length-capped prefix for left-anchored (`LIKE 'vit%'`) and substring
1833
1972
  // search (inline `gin_trgm_ops` via `sql` because passing it through `.op()` gets dropped by
1834
1973
  // Ponder)
1835
- byCanonicalNamePrefixFuzzy: index5().using("gin", sql2`${t.__canonicalNamePrefix} gin_trgm_ops`),
1974
+ byCanonicalNamePrefixFuzzy: index6().using("gin", sql2`${t.__canonicalNamePrefix} gin_trgm_ops`),
1836
1975
  // GIN containment for `cascadeLabelHeal`'s `canonical_label_hash_path @> ARRAY[lh]` lookup
1837
- byCanonicalLabelHashPath: index5().using("gin", t.canonicalLabelHashPath),
1976
+ byCanonicalLabelHashPath: index6().using("gin", t.canonicalLabelHashPath),
1838
1977
  // hash index for resolver-record → canonical-domain joins
1839
- byCanonicalNode: index5().using("hash", t.canonicalNode),
1978
+ byCanonicalNode: index6().using("hash", t.canonicalNode),
1840
1979
  // btree for ORDER BY canonical_depth (typeahead and DEPTH-ordered browse)
1841
- byCanonicalDepth: index5().on(t.canonicalDepth),
1980
+ byCanonicalDepth: index6().on(t.canonicalDepth),
1842
1981
  // Composites for `WHERE registry_id = X ORDER BY <latest registration value> LIMIT N`
1843
1982
  // (REGISTRATION_TIMESTAMP / REGISTRATION_EXPIRY ordering in find-domains queries). The latest
1844
1983
  // registration's start/expiry is mirrored onto the Domain row (see `__latestRegistration*`) so
@@ -1846,12 +1985,12 @@ var domain = onchainTable6(
1846
1985
  // `registrations` followed by a sort. The columns are NOT NULL (absent → `REGISTRATION_SORT_SENTINEL`),
1847
1986
  // so a single plain composite per column serves both ASC and DESC (forward / backward scan) with
1848
1987
  // a plain keyset tuple — see find-domains-resolver-helpers.ts.
1849
- byRegistryAndLatestRegistrationStart: index5().on(
1988
+ byRegistryAndLatestRegistrationStart: index6().on(
1850
1989
  t.registryId,
1851
1990
  t.__latestRegistrationStart,
1852
1991
  t.id
1853
1992
  ),
1854
- byRegistryAndLatestRegistrationExpiry: index5().on(
1993
+ byRegistryAndLatestRegistrationExpiry: index6().on(
1855
1994
  t.registryId,
1856
1995
  t.__latestRegistrationExpiry,
1857
1996
  t.id
@@ -1894,7 +2033,7 @@ var registrationType = onchainEnum2("RegistrationType", [
1894
2033
  "ENSv2RegistryRegistration",
1895
2034
  "ENSv2RegistryReservation"
1896
2035
  ]);
1897
- var registration = onchainTable6(
2036
+ var registration = onchainTable7(
1898
2037
  "registrations",
1899
2038
  (t) => ({
1900
2039
  // keyed by (domainId, registrationIndex)
@@ -1966,7 +2105,7 @@ var registration_relations = relations4(registration, ({ one, many }) => ({
1966
2105
  references: [event.id]
1967
2106
  })
1968
2107
  }));
1969
- var latestRegistrationIndex = onchainTable6("latest_registration_indexes", (t) => ({
2108
+ var latestRegistrationIndex = onchainTable7("latest_registration_indexes", (t) => ({
1970
2109
  domainId: t.text().primaryKey().$type(),
1971
2110
  registrationIndex: t.integer().notNull()
1972
2111
  }));
@@ -1977,7 +2116,7 @@ var latestRegistrationIndex_relations = relations4(latestRegistrationIndex, ({ o
1977
2116
  references: [domain.id]
1978
2117
  })
1979
2118
  }));
1980
- var renewal = onchainTable6(
2119
+ var renewal = onchainTable7(
1981
2120
  "renewals",
1982
2121
  (t) => ({
1983
2122
  // keyed by (registrationId, index)
@@ -2013,7 +2152,7 @@ var renewal_relations = relations4(renewal, ({ one }) => ({
2013
2152
  references: [event.id]
2014
2153
  })
2015
2154
  }));
2016
- var latestRenewalIndex = onchainTable6(
2155
+ var latestRenewalIndex = onchainTable7(
2017
2156
  "latest_renewal_indexes",
2018
2157
  (t) => ({
2019
2158
  domainId: t.text().notNull().$type(),
@@ -2029,7 +2168,7 @@ var latestRenewalIndex_relations = relations4(latestRenewalIndex, ({ one }) => (
2029
2168
  references: [domain.id]
2030
2169
  })
2031
2170
  }));
2032
- var permissions = onchainTable6(
2171
+ var permissions = onchainTable7(
2033
2172
  "permissions",
2034
2173
  (t) => ({
2035
2174
  id: t.text().primaryKey().$type(),
@@ -2044,7 +2183,7 @@ var relations_permissions = relations4(permissions, ({ many }) => ({
2044
2183
  resources: many(permissionsResource),
2045
2184
  users: many(permissionsUser)
2046
2185
  }));
2047
- var permissionsResource = onchainTable6(
2186
+ var permissionsResource = onchainTable7(
2048
2187
  "permissions_resources",
2049
2188
  (t) => ({
2050
2189
  id: t.text().primaryKey().$type(),
@@ -2062,7 +2201,7 @@ var relations_permissionsResource = relations4(permissionsResource, ({ one }) =>
2062
2201
  references: [permissions.chainId, permissions.address]
2063
2202
  })
2064
2203
  }));
2065
- var permissionsUser = onchainTable6(
2204
+ var permissionsUser = onchainTable7(
2066
2205
  "permissions_users",
2067
2206
  (t) => ({
2068
2207
  id: t.text().primaryKey().$type(),
@@ -2096,7 +2235,7 @@ var relations_permissionsUser = relations4(permissionsUser, ({ one }) => ({
2096
2235
  ]
2097
2236
  })
2098
2237
  }));
2099
- var label = onchainTable6(
2238
+ var label = onchainTable7(
2100
2239
  "labels",
2101
2240
  (t) => ({
2102
2241
  labelHash: t.hex().primaryKey().$type(),
@@ -2105,10 +2244,10 @@ var label = onchainTable6(
2105
2244
  (t) => ({
2106
2245
  // hash index avoids the btree 8191-byte row-size hazard for spam labels (a single label can
2107
2246
  // exceed btree's leaf-size limit)
2108
- byInterpretedExact: index5().using("hash", t.interpreted),
2247
+ byInterpretedExact: index6().using("hash", t.interpreted),
2109
2248
  // GIN trigram index for substring / similarity queries (inline `gin_trgm_ops` via `sql`
2110
2249
  // because passing it through `.op()` gets dropped by Ponder)
2111
- byInterpretedFuzzy: index5().using("gin", sql2`${t.interpreted} gin_trgm_ops`)
2250
+ byInterpretedFuzzy: index6().using("gin", sql2`${t.interpreted} gin_trgm_ops`)
2112
2251
  })
2113
2252
  );
2114
2253
  var label_relations = relations4(label, ({ many }) => ({
@@ -2242,7 +2381,7 @@ var ENSDB_SCHEMA_CHECKSUM = getDrizzleSchemaChecksum({
2242
2381
  });
2243
2382
 
2244
2383
  // src/client/ensdb-reader.ts
2245
- import { and, eq } from "drizzle-orm/sql";
2384
+ import { and, eq, sql as sql3 } from "drizzle-orm/sql";
2246
2385
  import {
2247
2386
  buildIndexingMetadataContextUninitialized,
2248
2387
  deserializeIndexingMetadataContext,
@@ -2382,6 +2521,15 @@ var EnsDbReader = class {
2382
2521
  versionInfo
2383
2522
  };
2384
2523
  }
2524
+ /**
2525
+ * Check whether a Postgres schema with the given name exists in the ENSDb instance.
2526
+ */
2527
+ async schemaExists(schemaName) {
2528
+ const result = await this.ensDb.execute(
2529
+ sql3`select 1 as exists from information_schema.schemata where schema_name = ${schemaName} limit 1`
2530
+ );
2531
+ return result.rows.length > 0;
2532
+ }
2385
2533
  /**
2386
2534
  * Get Indexing Metadata Context
2387
2535
  *
@@ -2394,7 +2542,7 @@ var EnsDbReader = class {
2394
2542
  if (!record) {
2395
2543
  return buildIndexingMetadataContextUninitialized();
2396
2544
  }
2397
- return deserializeIndexingMetadataContext(record);
2545
+ return deserializeIndexingMetadataContext(record.value);
2398
2546
  }
2399
2547
  /**
2400
2548
  * Destroy the ENSDbReader instance by closing the ENSDb connection pool.
@@ -2405,7 +2553,8 @@ var EnsDbReader = class {
2405
2553
  /**
2406
2554
  * Get ENSNode Metadata record
2407
2555
  *
2408
- * @returns selected record in ENSDb.
2556
+ * @returns the full `{ key, value }` record for the given key under this instance's
2557
+ * ENSIndexer Schema, or undefined if no such record exists.
2409
2558
  * @throws when more than one matching metadata record is found
2410
2559
  * (should be impossible given the composite PK constraint on
2411
2560
  * 'ensIndexerSchemaName' and 'key')
@@ -2421,7 +2570,7 @@ var EnsDbReader = class {
2421
2570
  return void 0;
2422
2571
  }
2423
2572
  if (result.length === 1 && result[0]) {
2424
- return result[0].value;
2573
+ return { key: result[0].key, value: result[0].value };
2425
2574
  }
2426
2575
  throw new Error(
2427
2576
  `There must be exactly one ENSNodeMetadata record for ('${this.ensIndexerSchemaName}', '${metadata2.key}') composite key`
@@ -2457,8 +2606,8 @@ var EnsDbReader = class {
2457
2606
  };
2458
2607
 
2459
2608
  // src/client/ensdb-writer.ts
2460
- import { sql as sql3 } from "drizzle-orm";
2461
2609
  import { migrate } from "drizzle-orm/node-postgres/migrator";
2610
+ import { sql as sql4 } from "drizzle-orm/sql";
2462
2611
  import {
2463
2612
  serializeIndexingMetadataContext
2464
2613
  } from "@ensnode/ensnode-sdk";
@@ -2494,30 +2643,50 @@ var EnsDbWriter = class _EnsDbWriter extends EnsDbReader {
2494
2643
  */
2495
2644
  async migrateEnsNodeSchema(migrationsDirPath) {
2496
2645
  await this.drizzleClient.transaction(async (tx) => {
2497
- await tx.execute(sql3`SELECT pg_advisory_xact_lock(${_EnsDbWriter.MIGRATION_LOCK_ID})`);
2646
+ await tx.execute(sql4`SELECT pg_advisory_xact_lock(${_EnsDbWriter.MIGRATION_LOCK_ID})`);
2498
2647
  await migrate(tx, {
2499
2648
  migrationsFolder: migrationsDirPath,
2500
2649
  migrationsSchema: "ensnode"
2501
2650
  });
2502
2651
  });
2503
2652
  }
2653
+ /**
2654
+ * Drop a Postgres schema (and everything in it) from the ENSDb instance, if it exists.
2655
+ */
2656
+ async dropSchema(schemaName) {
2657
+ await this.ensDb.execute(sql4`drop schema if exists ${sql4.identifier(schemaName)} cascade`);
2658
+ }
2659
+ /**
2660
+ * Rename a Postgres schema within the ENSDb instance.
2661
+ *
2662
+ * The Postgres schema name does not affect Ponder's build_id, so renaming a restored ENSIndexer
2663
+ * schema is safe for resume.
2664
+ */
2665
+ async renameSchema(fromSchemaName, toSchemaName) {
2666
+ await this.ensDb.execute(
2667
+ sql4`alter schema ${sql4.identifier(fromSchemaName)} rename to ${sql4.identifier(toSchemaName)}`
2668
+ );
2669
+ }
2504
2670
  /**
2505
2671
  * Upsert Indexing Metadata Context Initialized
2506
2672
  *
2507
2673
  * @throws when upsert operation failed.
2508
2674
  */
2509
2675
  async upsertIndexingMetadataContext(indexingMetadataContext) {
2510
- await this.upsertEnsNodeMetadata({
2676
+ await this.writeEnsNodeMetadata({
2511
2677
  key: EnsNodeMetadataKeys.IndexingMetadataContext,
2512
2678
  value: serializeIndexingMetadataContext(indexingMetadataContext)
2513
2679
  });
2514
2680
  }
2515
2681
  /**
2516
- * Upsert ENSNode metadata
2682
+ * Write (upsert) an ENSNode metadata record under this instance's ENSIndexer Schema.
2517
2683
  *
2518
- * @throws when upsert operation failed.
2684
+ * Re-keys the record to this writer's {@link ensIndexerSchemaName}, so metadata read from one
2685
+ * ENSIndexer Schema can be written under a different (e.g. renamed) one.
2686
+ *
2687
+ * @throws when the upsert operation failed.
2519
2688
  */
2520
- async upsertEnsNodeMetadata(metadata2) {
2689
+ async writeEnsNodeMetadata(metadata2) {
2521
2690
  await this.ensDb.insert(this.ensNodeSchema.metadata).values({
2522
2691
  ensIndexerSchemaName: this.ensIndexerSchemaName,
2523
2692
  key: metadata2.key,