@secondlayer/shared 11.7.0 → 11.7.1

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.
@@ -284,21 +284,6 @@ interface MagicLinksTable {
284
284
  failed_attempts: Generated<number>;
285
285
  created_at: Generated<Date>;
286
286
  }
287
- /** One-shot hashed tokens that attach a play ghost to an email at claim. */
288
- interface ClaimTokensTable {
289
- id: Generated<string>;
290
- account_id: string;
291
- token_hash: string;
292
- created_at: Generated<Date>;
293
- expires_at: Date;
294
- used_at: Date | null;
295
- }
296
- /** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
297
- interface PlayProvisionsTable {
298
- ip_hash: string;
299
- day: string;
300
- count: Generated<number>;
301
- }
302
287
  interface SubgraphProcessingStatsTable {
303
288
  id: Generated<string>;
304
289
  subgraph_name: string;
@@ -760,8 +745,6 @@ interface Database {
760
745
  accounts: AccountsTable;
761
746
  sessions: SessionsTable;
762
747
  magic_links: MagicLinksTable;
763
- claim_tokens: ClaimTokensTable;
764
- play_provisions: PlayProvisionsTable;
765
748
  subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
766
749
  subgraph_processing_stats: SubgraphProcessingStatsTable;
767
750
  subgraph_gaps: SubgraphGapsTable;
@@ -770,7 +753,6 @@ interface Database {
770
753
  processed_stripe_events: ProcessedStripeEventsTable;
771
754
  account_spend_caps: AccountSpendCapsTable;
772
755
  account_credits: AccountCreditsTable;
773
- hosted_meter_days: HostedMeterDaysTable;
774
756
  webhooks: WebhooksTable;
775
757
  webhook_outbox: WebhookOutboxTable;
776
758
  webhook_deliveries: WebhookDeliveriesTable;
@@ -801,6 +783,8 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ waitlists: WaitlistsTable;
787
+ waitlist_signups: WaitlistSignupsTable;
804
788
  }
805
789
  interface ServiceHeartbeatsTable {
806
790
  name: string;
@@ -829,15 +813,6 @@ interface AccountCreditsTable {
829
813
  refill_last_at: Date | null;
830
814
  updated_at: Generated<Date>;
831
815
  }
832
- /** Daily idempotency ledger for hosted subgraph running + storage meters. */
833
- interface HostedMeterDaysTable {
834
- day: string;
835
- account_id: string;
836
- subgraph_name: string;
837
- kind: string;
838
- usd_micros: string | number | bigint;
839
- billed_at: Generated<Date>;
840
- }
841
816
  /**
842
817
  * Archive fetch charge log (design-f089 gate). Append-only: one row per
843
818
  * priced attempt to fetch a partition object. `usd_micros` is 0 for
@@ -941,6 +916,27 @@ interface TriggerEvaluatorStateTable {
941
916
  last_settlement_scan_at: ColumnType<Date | null, Date | null | undefined, Date | null>;
942
917
  updated_at: Generated<Date>;
943
918
  }
919
+ /** A public waitlist page: what it is for and whether it takes signups. */
920
+ interface WaitlistsTable {
921
+ slug: string;
922
+ title: string;
923
+ description: string;
924
+ url: string;
925
+ opened_at: Generated<Date>;
926
+ /** Null while the list is open. */
927
+ closed_at: Date | null;
928
+ }
929
+ /**
930
+ * One signup per (list, contact, token). `answers` holds the list's own
931
+ * questions, validated per list by the API before insert.
932
+ */
933
+ interface WaitlistSignupsTable {
934
+ id: Generated<string>;
935
+ list: string;
936
+ contact: string;
937
+ answers: Record<string, unknown>;
938
+ created_at: Generated<Date>;
939
+ }
944
940
  /**
945
941
  * Contract registry queries — backing for trait-based discovery. Populated from
946
942
  * contract deploys; ABI fetched async; standards inferred by static analysis.
@@ -284,21 +284,6 @@ interface MagicLinksTable {
284
284
  failed_attempts: Generated<number>;
285
285
  created_at: Generated<Date>;
286
286
  }
287
- /** One-shot hashed tokens that attach a play ghost to an email at claim. */
288
- interface ClaimTokensTable {
289
- id: Generated<string>;
290
- account_id: string;
291
- token_hash: string;
292
- created_at: Generated<Date>;
293
- expires_at: Date;
294
- used_at: Date | null;
295
- }
296
- /** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
297
- interface PlayProvisionsTable {
298
- ip_hash: string;
299
- day: string;
300
- count: Generated<number>;
301
- }
302
287
  interface SubgraphProcessingStatsTable {
303
288
  id: Generated<string>;
304
289
  subgraph_name: string;
@@ -760,8 +745,6 @@ interface Database {
760
745
  accounts: AccountsTable;
761
746
  sessions: SessionsTable;
762
747
  magic_links: MagicLinksTable;
763
- claim_tokens: ClaimTokensTable;
764
- play_provisions: PlayProvisionsTable;
765
748
  subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
766
749
  subgraph_processing_stats: SubgraphProcessingStatsTable;
767
750
  subgraph_gaps: SubgraphGapsTable;
@@ -770,7 +753,6 @@ interface Database {
770
753
  processed_stripe_events: ProcessedStripeEventsTable;
771
754
  account_spend_caps: AccountSpendCapsTable;
772
755
  account_credits: AccountCreditsTable;
773
- hosted_meter_days: HostedMeterDaysTable;
774
756
  webhooks: WebhooksTable;
775
757
  webhook_outbox: WebhookOutboxTable;
776
758
  webhook_deliveries: WebhookDeliveriesTable;
@@ -801,6 +783,8 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ waitlists: WaitlistsTable;
787
+ waitlist_signups: WaitlistSignupsTable;
804
788
  }
805
789
  interface ServiceHeartbeatsTable {
806
790
  name: string;
@@ -829,15 +813,6 @@ interface AccountCreditsTable {
829
813
  refill_last_at: Date | null;
830
814
  updated_at: Generated<Date>;
831
815
  }
832
- /** Daily idempotency ledger for hosted subgraph running + storage meters. */
833
- interface HostedMeterDaysTable {
834
- day: string;
835
- account_id: string;
836
- subgraph_name: string;
837
- kind: string;
838
- usd_micros: string | number | bigint;
839
- billed_at: Generated<Date>;
840
- }
841
816
  /**
842
817
  * Archive fetch charge log (design-f089 gate). Append-only: one row per
843
818
  * priced attempt to fetch a partition object. `usd_micros` is 0 for
@@ -940,6 +915,27 @@ interface TriggerEvaluatorStateTable {
940
915
  last_settlement_scan_at: ColumnType<Date | null, Date | null | undefined, Date | null>;
941
916
  updated_at: Generated<Date>;
942
917
  }
918
+ /** A public waitlist page: what it is for and whether it takes signups. */
919
+ interface WaitlistsTable {
920
+ slug: string;
921
+ title: string;
922
+ description: string;
923
+ url: string;
924
+ opened_at: Generated<Date>;
925
+ /** Null while the list is open. */
926
+ closed_at: Date | null;
927
+ }
928
+ /**
929
+ * One signup per (list, contact, token). `answers` holds the list's own
930
+ * questions, validated per list by the API before insert.
931
+ */
932
+ interface WaitlistSignupsTable {
933
+ id: Generated<string>;
934
+ list: string;
935
+ contact: string;
936
+ answers: Record<string, unknown>;
937
+ created_at: Generated<Date>;
938
+ }
943
939
  declare const INSTANCE_NETWORKS: readonly ["mainnet", "testnet", "devnet"];
944
940
  type InstanceNetwork = (typeof INSTANCE_NETWORKS)[number];
945
941
  type InstanceRow = {
@@ -284,21 +284,6 @@ interface MagicLinksTable {
284
284
  failed_attempts: Generated<number>;
285
285
  created_at: Generated<Date>;
286
286
  }
287
- /** One-shot hashed tokens that attach a play ghost to an email at claim. */
288
- interface ClaimTokensTable {
289
- id: Generated<string>;
290
- account_id: string;
291
- token_hash: string;
292
- created_at: Generated<Date>;
293
- expires_at: Date;
294
- used_at: Date | null;
295
- }
296
- /** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
297
- interface PlayProvisionsTable {
298
- ip_hash: string;
299
- day: string;
300
- count: Generated<number>;
301
- }
302
287
  interface SubgraphProcessingStatsTable {
303
288
  id: Generated<string>;
304
289
  subgraph_name: string;
@@ -760,8 +745,6 @@ interface Database {
760
745
  accounts: AccountsTable;
761
746
  sessions: SessionsTable;
762
747
  magic_links: MagicLinksTable;
763
- claim_tokens: ClaimTokensTable;
764
- play_provisions: PlayProvisionsTable;
765
748
  subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
766
749
  subgraph_processing_stats: SubgraphProcessingStatsTable;
767
750
  subgraph_gaps: SubgraphGapsTable;
@@ -770,7 +753,6 @@ interface Database {
770
753
  processed_stripe_events: ProcessedStripeEventsTable;
771
754
  account_spend_caps: AccountSpendCapsTable;
772
755
  account_credits: AccountCreditsTable;
773
- hosted_meter_days: HostedMeterDaysTable;
774
756
  webhooks: WebhooksTable;
775
757
  webhook_outbox: WebhookOutboxTable;
776
758
  webhook_deliveries: WebhookDeliveriesTable;
@@ -801,6 +783,8 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ waitlists: WaitlistsTable;
787
+ waitlist_signups: WaitlistSignupsTable;
804
788
  }
805
789
  interface ServiceHeartbeatsTable {
806
790
  name: string;
@@ -829,15 +813,6 @@ interface AccountCreditsTable {
829
813
  refill_last_at: Date | null;
830
814
  updated_at: Generated<Date>;
831
815
  }
832
- /** Daily idempotency ledger for hosted subgraph running + storage meters. */
833
- interface HostedMeterDaysTable {
834
- day: string;
835
- account_id: string;
836
- subgraph_name: string;
837
- kind: string;
838
- usd_micros: string | number | bigint;
839
- billed_at: Generated<Date>;
840
- }
841
816
  /**
842
817
  * Archive fetch charge log (design-f089 gate). Append-only: one row per
843
818
  * priced attempt to fetch a partition object. `usd_micros` is 0 for
@@ -940,6 +915,27 @@ interface TriggerEvaluatorStateTable {
940
915
  last_settlement_scan_at: ColumnType<Date | null, Date | null | undefined, Date | null>;
941
916
  updated_at: Generated<Date>;
942
917
  }
918
+ /** A public waitlist page: what it is for and whether it takes signups. */
919
+ interface WaitlistsTable {
920
+ slug: string;
921
+ title: string;
922
+ description: string;
923
+ url: string;
924
+ opened_at: Generated<Date>;
925
+ /** Null while the list is open. */
926
+ closed_at: Date | null;
927
+ }
928
+ /**
929
+ * One signup per (list, contact, token). `answers` holds the list's own
930
+ * questions, validated per list by the API before insert.
931
+ */
932
+ interface WaitlistSignupsTable {
933
+ id: Generated<string>;
934
+ list: string;
935
+ contact: string;
936
+ answers: Record<string, unknown>;
937
+ created_at: Generated<Date>;
938
+ }
943
939
  interface Gap {
944
940
  gapStart: number;
945
941
  gapEnd: number;
@@ -991,7 +987,7 @@ type BrokenLink = {
991
987
  * concern, and scanning eight million rows every cycle is not.
992
988
  */
993
989
  declare function findBrokenLinks(db: Kysely<Database>, opts?: {
994
- window?: number
990
+ window?: number | null
995
991
  limit?: number
996
992
  }): Promise<BrokenLink[]>;
997
993
  export { findGaps, findBrokenLinks, countMissingBlocks, computeContiguousTip, checkChainDataIntegrity, Gap, ChainDataIntegrity, BrokenLink };
@@ -93,14 +93,15 @@ async function computeContiguousTip(db, fromHeight) {
93
93
  return Number(rows[0]?.tip ?? fromHeight);
94
94
  }
95
95
  async function findBrokenLinks(db, opts = {}) {
96
- const windowSize = opts.window ?? 1e4;
96
+ const windowSize = opts.window === undefined ? 1e4 : opts.window;
97
97
  const limitClause = opts.limit ? sql`LIMIT ${opts.limit}` : sql``;
98
+ const windowClause = windowSize === null ? sql`` : sql`AND height > (SELECT MAX(height) - ${windowSize} FROM blocks WHERE canonical = true)`;
98
99
  const { rows } = await sql`
99
100
  WITH recent AS (
100
101
  SELECT height, hash, parent_hash
101
102
  FROM blocks
102
103
  WHERE canonical = true
103
- AND height > (SELECT MAX(height) - ${windowSize} FROM blocks WHERE canonical = true)
104
+ ${windowClause}
104
105
  )
105
106
  SELECT b.height, b.hash, p.hash AS expected_parent, b.parent_hash AS stored_parent
106
107
  FROM recent b
@@ -124,5 +125,5 @@ export {
124
125
  checkChainDataIntegrity
125
126
  };
126
127
 
127
- //# debugId=FFA2BEF866239EA364756E2164756E21
128
+ //# debugId=956E0AF2AC54818A64756E2164756E21
128
129
  //# sourceMappingURL=integrity.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/db/queries/integrity.ts"],
4
4
  "sourcesContent": [
5
- "import { type Kysely, sql } from \"kysely\";\nimport type { Database } from \"../types.ts\";\n\nexport interface Gap {\n\tgapStart: number;\n\tgapEnd: number;\n\tsize: number;\n}\n\nexport async function findGaps(\n\tdb: Kysely<Database>,\n\tlimit?: number,\n): Promise<Gap[]> {\n\tconst limitClause = limit ? sql`LIMIT ${limit}` : sql``;\n\tconst { rows } = await sql<{\n\t\tgap_start: string;\n\t\tgap_end: string;\n\t\tsize: string;\n\t}>`\n SELECT gap_start, gap_end, gap_end - gap_start + 1 AS size\n FROM (\n SELECT height + 1 AS gap_start, next_height - 1 AS gap_end\n FROM (\n SELECT height, LEAD(height) OVER (ORDER BY height) AS next_height\n FROM blocks WHERE canonical = true\n ) sub\n WHERE next_height - height > 1\n ) gaps\n ORDER BY gap_start\n ${limitClause}\n `.execute(db);\n\n\treturn rows.map((r) => ({\n\t\tgapStart: Number(r.gap_start),\n\t\tgapEnd: Number(r.gap_end),\n\t\tsize: Number(r.size),\n\t}));\n}\n\nexport async function countMissingBlocks(\n\tdb: Kysely<Database>,\n): Promise<number> {\n\tconst { rows } = await sql<{ total: string }>`\n SELECT COALESCE(SUM(next_height - height - 1), 0) AS total\n FROM (\n SELECT height, LEAD(height) OVER (ORDER BY height) AS next_height\n FROM blocks WHERE canonical = true\n ) sub\n WHERE next_height - height > 1\n `.execute(db);\n\n\treturn Number(rows[0]?.total ?? 0);\n}\n\nexport interface ChainDataIntegrity {\n\tok: boolean;\n\tmaxHeight: number;\n\tsampleHeight: number | null;\n\tsampleBlocks: number;\n\treason: string | null;\n}\n\n/**\n * Cheap sanity check that the `blocks` table actually holds the history its tip\n * implies. Catches a wrong/empty Postgres volume — e.g. a container recreated\n * against a fresh volume — being silently served: if the tip is high but a\n * window of blocks well below it is missing, the data isn't what the tip claims.\n *\n * Below `checkFloor` we can't distinguish a fresh install from an empty volume,\n * so we report ok — a genuinely new DB legitimately has little history. Two\n * indexed lookups, safe to run on every startup / health poll.\n */\nexport async function checkChainDataIntegrity(\n\tdb: Kysely<Database>,\n\topts?: { checkFloor?: number; lookback?: number },\n): Promise<ChainDataIntegrity> {\n\tconst checkFloor = opts?.checkFloor ?? 1_000_000;\n\tconst lookback = opts?.lookback ?? 500_000;\n\n\tconst { rows: tipRows } = await sql<{ max: string | null }>`\n\t\tSELECT MAX(height) AS max FROM blocks WHERE canonical = true\n\t`.execute(db);\n\tconst maxHeight = Number(tipRows[0]?.max ?? 0);\n\n\tif (maxHeight < checkFloor) {\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmaxHeight,\n\t\t\tsampleHeight: null,\n\t\t\tsampleBlocks: 0,\n\t\t\treason: null,\n\t\t};\n\t}\n\n\tconst sampleHeight = maxHeight - lookback;\n\tconst { rows: sampleRows } = await sql<{ n: string }>`\n\t\tSELECT count(*) AS n FROM blocks\n\t\tWHERE canonical = true AND height >= ${sampleHeight} AND height < ${sampleHeight + 1000}\n\t`.execute(db);\n\tconst sampleBlocks = Number(sampleRows[0]?.n ?? 0);\n\n\treturn {\n\t\tok: sampleBlocks > 0,\n\t\tmaxHeight,\n\t\tsampleHeight,\n\t\tsampleBlocks,\n\t\treason:\n\t\t\tsampleBlocks > 0\n\t\t\t\t? null\n\t\t\t\t: `tip is ${maxHeight} but no canonical blocks near ${sampleHeight} — wrong or empty volume?`,\n\t};\n}\n\nexport async function computeContiguousTip(\n\tdb: Kysely<Database>,\n\tfromHeight: number,\n): Promise<number> {\n\tconst { rows } = await sql<{ tip: string }>`\n SELECT COALESCE(MAX(height), ${fromHeight}) AS tip\n FROM (\n SELECT height, height - ROW_NUMBER() OVER (ORDER BY height) AS grp\n FROM blocks WHERE canonical = true AND height >= ${fromHeight}\n ) sub\n WHERE grp = (\n SELECT height - ROW_NUMBER() OVER (ORDER BY height)\n FROM blocks WHERE canonical = true AND height = ${fromHeight}\n )\n `.execute(db);\n\n\treturn Number(rows[0]?.tip ?? fromHeight);\n}\n\nexport type BrokenLink = {\n\theight: number;\n\thash: string;\n\texpectedParent: string;\n\tstoredParent: string;\n};\n\n/**\n * Canonical heights whose block does not descend from the canonical block\n * below it.\n *\n * `findGaps` asks \"is every height present?\", which a chain sitting on a losing\n * fork answers yes to. On 2026-07-30 a reorg at 8,663,166 was resolved the\n * wrong way: we adopted a block that mainnet orphaned, its true successors were\n * swept non-canonical, and later blocks were inserted canonical on top. Every\n * height existed. Nothing was \"missing\". The chain simply did not join up, and\n * no check asked that question — so we served a broken chain for seventeen\n * hours and only noticed because subgraphs stopped moving.\n *\n * Scoped to a recent window by default: an unlinked height is an active-repair\n * concern, and scanning eight million rows every cycle is not.\n */\nexport async function findBrokenLinks(\n\tdb: Kysely<Database>,\n\topts: { window?: number; limit?: number } = {},\n): Promise<BrokenLink[]> {\n\tconst windowSize = opts.window ?? 10_000;\n\tconst limitClause = opts.limit ? sql`LIMIT ${opts.limit}` : sql``;\n\tconst { rows } = await sql<{\n\t\theight: string | number;\n\t\thash: string;\n\t\texpected_parent: string;\n\t\tstored_parent: string;\n\t}>`\n\t\tWITH recent AS (\n\t\t\tSELECT height, hash, parent_hash\n\t\t\tFROM blocks\n\t\t\tWHERE canonical = true\n\t\t\t\tAND height > (SELECT MAX(height) - ${windowSize} FROM blocks WHERE canonical = true)\n\t\t)\n\t\tSELECT b.height, b.hash, p.hash AS expected_parent, b.parent_hash AS stored_parent\n\t\tFROM recent b\n\t\tJOIN recent p ON p.height = b.height - 1\n\t\tWHERE b.parent_hash <> p.hash\n\t\tORDER BY b.height\n\t\t${limitClause}\n\t`.execute(db);\n\treturn rows.map((r) => ({\n\t\theight: Number(r.height),\n\t\thash: r.hash,\n\t\texpectedParent: r.expected_parent,\n\t\tstoredParent: r.stored_parent,\n\t}));\n}\n"
5
+ "import { type Kysely, sql } from \"kysely\";\nimport type { Database } from \"../types.ts\";\n\nexport interface Gap {\n\tgapStart: number;\n\tgapEnd: number;\n\tsize: number;\n}\n\nexport async function findGaps(\n\tdb: Kysely<Database>,\n\tlimit?: number,\n): Promise<Gap[]> {\n\tconst limitClause = limit ? sql`LIMIT ${limit}` : sql``;\n\tconst { rows } = await sql<{\n\t\tgap_start: string;\n\t\tgap_end: string;\n\t\tsize: string;\n\t}>`\n SELECT gap_start, gap_end, gap_end - gap_start + 1 AS size\n FROM (\n SELECT height + 1 AS gap_start, next_height - 1 AS gap_end\n FROM (\n SELECT height, LEAD(height) OVER (ORDER BY height) AS next_height\n FROM blocks WHERE canonical = true\n ) sub\n WHERE next_height - height > 1\n ) gaps\n ORDER BY gap_start\n ${limitClause}\n `.execute(db);\n\n\treturn rows.map((r) => ({\n\t\tgapStart: Number(r.gap_start),\n\t\tgapEnd: Number(r.gap_end),\n\t\tsize: Number(r.size),\n\t}));\n}\n\nexport async function countMissingBlocks(\n\tdb: Kysely<Database>,\n): Promise<number> {\n\tconst { rows } = await sql<{ total: string }>`\n SELECT COALESCE(SUM(next_height - height - 1), 0) AS total\n FROM (\n SELECT height, LEAD(height) OVER (ORDER BY height) AS next_height\n FROM blocks WHERE canonical = true\n ) sub\n WHERE next_height - height > 1\n `.execute(db);\n\n\treturn Number(rows[0]?.total ?? 0);\n}\n\nexport interface ChainDataIntegrity {\n\tok: boolean;\n\tmaxHeight: number;\n\tsampleHeight: number | null;\n\tsampleBlocks: number;\n\treason: string | null;\n}\n\n/**\n * Cheap sanity check that the `blocks` table actually holds the history its tip\n * implies. Catches a wrong/empty Postgres volume — e.g. a container recreated\n * against a fresh volume — being silently served: if the tip is high but a\n * window of blocks well below it is missing, the data isn't what the tip claims.\n *\n * Below `checkFloor` we can't distinguish a fresh install from an empty volume,\n * so we report ok — a genuinely new DB legitimately has little history. Two\n * indexed lookups, safe to run on every startup / health poll.\n */\nexport async function checkChainDataIntegrity(\n\tdb: Kysely<Database>,\n\topts?: { checkFloor?: number; lookback?: number },\n): Promise<ChainDataIntegrity> {\n\tconst checkFloor = opts?.checkFloor ?? 1_000_000;\n\tconst lookback = opts?.lookback ?? 500_000;\n\n\tconst { rows: tipRows } = await sql<{ max: string | null }>`\n\t\tSELECT MAX(height) AS max FROM blocks WHERE canonical = true\n\t`.execute(db);\n\tconst maxHeight = Number(tipRows[0]?.max ?? 0);\n\n\tif (maxHeight < checkFloor) {\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmaxHeight,\n\t\t\tsampleHeight: null,\n\t\t\tsampleBlocks: 0,\n\t\t\treason: null,\n\t\t};\n\t}\n\n\tconst sampleHeight = maxHeight - lookback;\n\tconst { rows: sampleRows } = await sql<{ n: string }>`\n\t\tSELECT count(*) AS n FROM blocks\n\t\tWHERE canonical = true AND height >= ${sampleHeight} AND height < ${sampleHeight + 1000}\n\t`.execute(db);\n\tconst sampleBlocks = Number(sampleRows[0]?.n ?? 0);\n\n\treturn {\n\t\tok: sampleBlocks > 0,\n\t\tmaxHeight,\n\t\tsampleHeight,\n\t\tsampleBlocks,\n\t\treason:\n\t\t\tsampleBlocks > 0\n\t\t\t\t? null\n\t\t\t\t: `tip is ${maxHeight} but no canonical blocks near ${sampleHeight} — wrong or empty volume?`,\n\t};\n}\n\nexport async function computeContiguousTip(\n\tdb: Kysely<Database>,\n\tfromHeight: number,\n): Promise<number> {\n\tconst { rows } = await sql<{ tip: string }>`\n SELECT COALESCE(MAX(height), ${fromHeight}) AS tip\n FROM (\n SELECT height, height - ROW_NUMBER() OVER (ORDER BY height) AS grp\n FROM blocks WHERE canonical = true AND height >= ${fromHeight}\n ) sub\n WHERE grp = (\n SELECT height - ROW_NUMBER() OVER (ORDER BY height)\n FROM blocks WHERE canonical = true AND height = ${fromHeight}\n )\n `.execute(db);\n\n\treturn Number(rows[0]?.tip ?? fromHeight);\n}\n\nexport type BrokenLink = {\n\theight: number;\n\thash: string;\n\texpectedParent: string;\n\tstoredParent: string;\n};\n\n/**\n * Canonical heights whose block does not descend from the canonical block\n * below it.\n *\n * `findGaps` asks \"is every height present?\", which a chain sitting on a losing\n * fork answers yes to. On 2026-07-30 a reorg at 8,663,166 was resolved the\n * wrong way: we adopted a block that mainnet orphaned, its true successors were\n * swept non-canonical, and later blocks were inserted canonical on top. Every\n * height existed. Nothing was \"missing\". The chain simply did not join up, and\n * no check asked that question — so we served a broken chain for seventeen\n * hours and only noticed because subgraphs stopped moving.\n *\n * Scoped to a recent window by default: an unlinked height is an active-repair\n * concern, and scanning eight million rows every cycle is not.\n */\nexport async function findBrokenLinks(\n\tdb: Kysely<Database>,\n\t/** Heights below the tip to scan; `null` scans the whole chain. */\n\topts: { window?: number | null; limit?: number } = {},\n): Promise<BrokenLink[]> {\n\tconst windowSize = opts.window === undefined ? 10_000 : opts.window;\n\tconst limitClause = opts.limit ? sql`LIMIT ${opts.limit}` : sql``;\n\tconst windowClause =\n\t\twindowSize === null\n\t\t\t? sql``\n\t\t\t: sql`AND height > (SELECT MAX(height) - ${windowSize} FROM blocks WHERE canonical = true)`;\n\tconst { rows } = await sql<{\n\t\theight: string | number;\n\t\thash: string;\n\t\texpected_parent: string;\n\t\tstored_parent: string;\n\t}>`\n\t\tWITH recent AS (\n\t\t\tSELECT height, hash, parent_hash\n\t\t\tFROM blocks\n\t\t\tWHERE canonical = true\n\t\t\t\t${windowClause}\n\t\t)\n\t\tSELECT b.height, b.hash, p.hash AS expected_parent, b.parent_hash AS stored_parent\n\t\tFROM recent b\n\t\tJOIN recent p ON p.height = b.height - 1\n\t\tWHERE b.parent_hash <> p.hash\n\t\tORDER BY b.height\n\t\t${limitClause}\n\t`.execute(db);\n\treturn rows.map((r) => ({\n\t\theight: Number(r.height),\n\t\thash: r.hash,\n\t\texpectedParent: r.expected_parent,\n\t\tstoredParent: r.stored_parent,\n\t}));\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AASA,eAAsB,QAAQ,CAC7B,IACA,OACiB;AAAA,EACjB,MAAM,cAAc,QAAQ,YAAY,UAAU;AAAA,EAClD,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAelB;AAAA,IACF,QAAQ,EAAE;AAAA,EAEb,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACvB,UAAU,OAAO,EAAE,SAAS;AAAA,IAC5B,QAAQ,OAAO,EAAE,OAAO;AAAA,IACxB,MAAM,OAAO,EAAE,IAAI;AAAA,EACpB,EAAE;AAAA;AAGH,eAAsB,kBAAkB,CACvC,IACkB;AAAA,EAClB,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOpB,QAAQ,EAAE;AAAA,EAEb,OAAO,OAAO,KAAK,IAAI,SAAS,CAAC;AAAA;AAqBlC,eAAsB,uBAAuB,CAC5C,IACA,MAC8B;AAAA,EAC9B,MAAM,aAAa,MAAM,cAAc;AAAA,EACvC,MAAM,WAAW,MAAM,YAAY;AAAA,EAEnC,QAAQ,MAAM,YAAY,MAAM;AAAA;AAAA,GAE9B,QAAQ,EAAE;AAAA,EACZ,MAAM,YAAY,OAAO,QAAQ,IAAI,OAAO,CAAC;AAAA,EAE7C,IAAI,YAAY,YAAY;AAAA,IAC3B,OAAO;AAAA,MACN,IAAI;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACT;AAAA,EACD;AAAA,EAEA,MAAM,eAAe,YAAY;AAAA,EACjC,QAAQ,MAAM,eAAe,MAAM;AAAA;AAAA,yCAEK,6BAA6B,eAAe;AAAA,GAClF,QAAQ,EAAE;AAAA,EACZ,MAAM,eAAe,OAAO,WAAW,IAAI,KAAK,CAAC;AAAA,EAEjD,OAAO;AAAA,IACN,IAAI,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QACC,eAAe,IACZ,OACA,UAAU,0CAA0C;AAAA,EACzD;AAAA;AAGD,eAAsB,oBAAoB,CACzC,IACA,YACkB;AAAA,EAClB,QAAQ,SAAS,MAAM;AAAA,mCACW;AAAA;AAAA;AAAA,yDAGsB;AAAA;AAAA;AAAA;AAAA,wDAID;AAAA;AAAA,IAEpD,QAAQ,EAAE;AAAA,EAEb,OAAO,OAAO,KAAK,IAAI,OAAO,UAAU;AAAA;AAyBzC,eAAsB,eAAe,CACpC,IACA,OAA4C,CAAC,GACrB;AAAA,EACxB,MAAM,aAAa,KAAK,UAAU;AAAA,EAClC,MAAM,cAAc,KAAK,QAAQ,YAAY,KAAK,UAAU;AAAA,EAC5D,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,yCAUiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOrC;AAAA,GACD,QAAQ,EAAE;AAAA,EACZ,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACvB,QAAQ,OAAO,EAAE,MAAM;AAAA,IACvB,MAAM,EAAE;AAAA,IACR,gBAAgB,EAAE;AAAA,IAClB,cAAc,EAAE;AAAA,EACjB,EAAE;AAAA;",
8
- "debugId": "FFA2BEF866239EA364756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AASA,eAAsB,QAAQ,CAC7B,IACA,OACiB;AAAA,EACjB,MAAM,cAAc,QAAQ,YAAY,UAAU;AAAA,EAClD,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAelB;AAAA,IACF,QAAQ,EAAE;AAAA,EAEb,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACvB,UAAU,OAAO,EAAE,SAAS;AAAA,IAC5B,QAAQ,OAAO,EAAE,OAAO;AAAA,IACxB,MAAM,OAAO,EAAE,IAAI;AAAA,EACpB,EAAE;AAAA;AAGH,eAAsB,kBAAkB,CACvC,IACkB;AAAA,EAClB,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOpB,QAAQ,EAAE;AAAA,EAEb,OAAO,OAAO,KAAK,IAAI,SAAS,CAAC;AAAA;AAqBlC,eAAsB,uBAAuB,CAC5C,IACA,MAC8B;AAAA,EAC9B,MAAM,aAAa,MAAM,cAAc;AAAA,EACvC,MAAM,WAAW,MAAM,YAAY;AAAA,EAEnC,QAAQ,MAAM,YAAY,MAAM;AAAA;AAAA,GAE9B,QAAQ,EAAE;AAAA,EACZ,MAAM,YAAY,OAAO,QAAQ,IAAI,OAAO,CAAC;AAAA,EAE7C,IAAI,YAAY,YAAY;AAAA,IAC3B,OAAO;AAAA,MACN,IAAI;AAAA,MACJ;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,MACd,QAAQ;AAAA,IACT;AAAA,EACD;AAAA,EAEA,MAAM,eAAe,YAAY;AAAA,EACjC,QAAQ,MAAM,eAAe,MAAM;AAAA;AAAA,yCAEK,6BAA6B,eAAe;AAAA,GAClF,QAAQ,EAAE;AAAA,EACZ,MAAM,eAAe,OAAO,WAAW,IAAI,KAAK,CAAC;AAAA,EAEjD,OAAO;AAAA,IACN,IAAI,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QACC,eAAe,IACZ,OACA,UAAU,0CAA0C;AAAA,EACzD;AAAA;AAGD,eAAsB,oBAAoB,CACzC,IACA,YACkB;AAAA,EAClB,QAAQ,SAAS,MAAM;AAAA,mCACW;AAAA;AAAA;AAAA,yDAGsB;AAAA;AAAA;AAAA;AAAA,wDAID;AAAA;AAAA,IAEpD,QAAQ,EAAE;AAAA,EAEb,OAAO,OAAO,KAAK,IAAI,OAAO,UAAU;AAAA;AAyBzC,eAAsB,eAAe,CACpC,IAEA,OAAmD,CAAC,GAC5B;AAAA,EACxB,MAAM,aAAa,KAAK,WAAW,YAAY,MAAS,KAAK;AAAA,EAC7D,MAAM,cAAc,KAAK,QAAQ,YAAY,KAAK,UAAU;AAAA,EAC5D,MAAM,eACL,eAAe,OACZ,QACA,yCAAyC;AAAA,EAC7C,QAAQ,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAUlB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOF;AAAA,GACD,QAAQ,EAAE;AAAA,EACZ,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACvB,QAAQ,OAAO,EAAE,MAAM;AAAA,IACvB,MAAM,EAAE;AAAA,IACR,gBAAgB,EAAE;AAAA,IAClB,cAAc,EAAE;AAAA,EACjB,EAAE;AAAA;",
8
+ "debugId": "956E0AF2AC54818A64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -284,21 +284,6 @@ interface MagicLinksTable {
284
284
  failed_attempts: Generated<number>;
285
285
  created_at: Generated<Date>;
286
286
  }
287
- /** One-shot hashed tokens that attach a play ghost to an email at claim. */
288
- interface ClaimTokensTable {
289
- id: Generated<string>;
290
- account_id: string;
291
- token_hash: string;
292
- created_at: Generated<Date>;
293
- expires_at: Date;
294
- used_at: Date | null;
295
- }
296
- /** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
297
- interface PlayProvisionsTable {
298
- ip_hash: string;
299
- day: string;
300
- count: Generated<number>;
301
- }
302
287
  interface SubgraphProcessingStatsTable {
303
288
  id: Generated<string>;
304
289
  subgraph_name: string;
@@ -760,8 +745,6 @@ interface Database {
760
745
  accounts: AccountsTable;
761
746
  sessions: SessionsTable;
762
747
  magic_links: MagicLinksTable;
763
- claim_tokens: ClaimTokensTable;
764
- play_provisions: PlayProvisionsTable;
765
748
  subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
766
749
  subgraph_processing_stats: SubgraphProcessingStatsTable;
767
750
  subgraph_gaps: SubgraphGapsTable;
@@ -770,7 +753,6 @@ interface Database {
770
753
  processed_stripe_events: ProcessedStripeEventsTable;
771
754
  account_spend_caps: AccountSpendCapsTable;
772
755
  account_credits: AccountCreditsTable;
773
- hosted_meter_days: HostedMeterDaysTable;
774
756
  webhooks: WebhooksTable;
775
757
  webhook_outbox: WebhookOutboxTable;
776
758
  webhook_deliveries: WebhookDeliveriesTable;
@@ -801,6 +783,8 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ waitlists: WaitlistsTable;
787
+ waitlist_signups: WaitlistSignupsTable;
804
788
  }
805
789
  interface ServiceHeartbeatsTable {
806
790
  name: string;
@@ -829,15 +813,6 @@ interface AccountCreditsTable {
829
813
  refill_last_at: Date | null;
830
814
  updated_at: Generated<Date>;
831
815
  }
832
- /** Daily idempotency ledger for hosted subgraph running + storage meters. */
833
- interface HostedMeterDaysTable {
834
- day: string;
835
- account_id: string;
836
- subgraph_name: string;
837
- kind: string;
838
- usd_micros: string | number | bigint;
839
- billed_at: Generated<Date>;
840
- }
841
816
  /**
842
817
  * Archive fetch charge log (design-f089 gate). Append-only: one row per
843
818
  * priced attempt to fetch a partition object. `usd_micros` is 0 for
@@ -940,6 +915,27 @@ interface TriggerEvaluatorStateTable {
940
915
  last_settlement_scan_at: ColumnType<Date | null, Date | null | undefined, Date | null>;
941
916
  updated_at: Generated<Date>;
942
917
  }
918
+ /** A public waitlist page: what it is for and whether it takes signups. */
919
+ interface WaitlistsTable {
920
+ slug: string;
921
+ title: string;
922
+ description: string;
923
+ url: string;
924
+ opened_at: Generated<Date>;
925
+ /** Null while the list is open. */
926
+ closed_at: Date | null;
927
+ }
928
+ /**
929
+ * One signup per (list, contact, token). `answers` holds the list's own
930
+ * questions, validated per list by the API before insert.
931
+ */
932
+ interface WaitlistSignupsTable {
933
+ id: Generated<string>;
934
+ list: string;
935
+ contact: string;
936
+ answers: Record<string, unknown>;
937
+ created_at: Generated<Date>;
938
+ }
943
939
  interface GapRange {
944
940
  start: number;
945
941
  end: number;
@@ -284,21 +284,6 @@ interface MagicLinksTable {
284
284
  failed_attempts: Generated<number>;
285
285
  created_at: Generated<Date>;
286
286
  }
287
- /** One-shot hashed tokens that attach a play ghost to an email at claim. */
288
- interface ClaimTokensTable {
289
- id: Generated<string>;
290
- account_id: string;
291
- token_hash: string;
292
- created_at: Generated<Date>;
293
- expires_at: Date;
294
- used_at: Date | null;
295
- }
296
- /** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
297
- interface PlayProvisionsTable {
298
- ip_hash: string;
299
- day: string;
300
- count: Generated<number>;
301
- }
302
287
  interface SubgraphProcessingStatsTable {
303
288
  id: Generated<string>;
304
289
  subgraph_name: string;
@@ -760,8 +745,6 @@ interface Database {
760
745
  accounts: AccountsTable;
761
746
  sessions: SessionsTable;
762
747
  magic_links: MagicLinksTable;
763
- claim_tokens: ClaimTokensTable;
764
- play_provisions: PlayProvisionsTable;
765
748
  subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
766
749
  subgraph_processing_stats: SubgraphProcessingStatsTable;
767
750
  subgraph_gaps: SubgraphGapsTable;
@@ -770,7 +753,6 @@ interface Database {
770
753
  processed_stripe_events: ProcessedStripeEventsTable;
771
754
  account_spend_caps: AccountSpendCapsTable;
772
755
  account_credits: AccountCreditsTable;
773
- hosted_meter_days: HostedMeterDaysTable;
774
756
  webhooks: WebhooksTable;
775
757
  webhook_outbox: WebhookOutboxTable;
776
758
  webhook_deliveries: WebhookDeliveriesTable;
@@ -801,6 +783,8 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ waitlists: WaitlistsTable;
787
+ waitlist_signups: WaitlistSignupsTable;
804
788
  }
805
789
  interface ServiceHeartbeatsTable {
806
790
  name: string;
@@ -829,15 +813,6 @@ interface AccountCreditsTable {
829
813
  refill_last_at: Date | null;
830
814
  updated_at: Generated<Date>;
831
815
  }
832
- /** Daily idempotency ledger for hosted subgraph running + storage meters. */
833
- interface HostedMeterDaysTable {
834
- day: string;
835
- account_id: string;
836
- subgraph_name: string;
837
- kind: string;
838
- usd_micros: string | number | bigint;
839
- billed_at: Generated<Date>;
840
- }
841
816
  /**
842
817
  * Archive fetch charge log (design-f089 gate). Append-only: one row per
843
818
  * priced attempt to fetch a partition object. `usd_micros` is 0 for
@@ -941,6 +916,27 @@ interface TriggerEvaluatorStateTable {
941
916
  last_settlement_scan_at: ColumnType<Date | null, Date | null | undefined, Date | null>;
942
917
  updated_at: Generated<Date>;
943
918
  }
919
+ /** A public waitlist page: what it is for and whether it takes signups. */
920
+ interface WaitlistsTable {
921
+ slug: string;
922
+ title: string;
923
+ description: string;
924
+ url: string;
925
+ opened_at: Generated<Date>;
926
+ /** Null while the list is open. */
927
+ closed_at: Date | null;
928
+ }
929
+ /**
930
+ * One signup per (list, contact, token). `answers` holds the list's own
931
+ * questions, validated per list by the API before insert.
932
+ */
933
+ interface WaitlistSignupsTable {
934
+ id: Generated<string>;
935
+ list: string;
936
+ contact: string;
937
+ answers: Record<string, unknown>;
938
+ created_at: Generated<Date>;
939
+ }
944
940
  declare function isActiveSubgraphOperationConflict(err: unknown): boolean;
945
941
  declare function createSubgraphOperation(db: Kysely<Database>, data: {
946
942
  subgraphId: string
@@ -284,21 +284,6 @@ interface MagicLinksTable {
284
284
  failed_attempts: Generated<number>;
285
285
  created_at: Generated<Date>;
286
286
  }
287
- /** One-shot hashed tokens that attach a play ghost to an email at claim. */
288
- interface ClaimTokensTable {
289
- id: Generated<string>;
290
- account_id: string;
291
- token_hash: string;
292
- created_at: Generated<Date>;
293
- expires_at: Date;
294
- used_at: Date | null;
295
- }
296
- /** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
297
- interface PlayProvisionsTable {
298
- ip_hash: string;
299
- day: string;
300
- count: Generated<number>;
301
- }
302
287
  interface SubgraphProcessingStatsTable {
303
288
  id: Generated<string>;
304
289
  subgraph_name: string;
@@ -760,8 +745,6 @@ interface Database {
760
745
  accounts: AccountsTable;
761
746
  sessions: SessionsTable;
762
747
  magic_links: MagicLinksTable;
763
- claim_tokens: ClaimTokensTable;
764
- play_provisions: PlayProvisionsTable;
765
748
  subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
766
749
  subgraph_processing_stats: SubgraphProcessingStatsTable;
767
750
  subgraph_gaps: SubgraphGapsTable;
@@ -770,7 +753,6 @@ interface Database {
770
753
  processed_stripe_events: ProcessedStripeEventsTable;
771
754
  account_spend_caps: AccountSpendCapsTable;
772
755
  account_credits: AccountCreditsTable;
773
- hosted_meter_days: HostedMeterDaysTable;
774
756
  webhooks: WebhooksTable;
775
757
  webhook_outbox: WebhookOutboxTable;
776
758
  webhook_deliveries: WebhookDeliveriesTable;
@@ -801,6 +783,8 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ waitlists: WaitlistsTable;
787
+ waitlist_signups: WaitlistSignupsTable;
804
788
  }
805
789
  interface ServiceHeartbeatsTable {
806
790
  name: string;
@@ -829,15 +813,6 @@ interface AccountCreditsTable {
829
813
  refill_last_at: Date | null;
830
814
  updated_at: Generated<Date>;
831
815
  }
832
- /** Daily idempotency ledger for hosted subgraph running + storage meters. */
833
- interface HostedMeterDaysTable {
834
- day: string;
835
- account_id: string;
836
- subgraph_name: string;
837
- kind: string;
838
- usd_micros: string | number | bigint;
839
- billed_at: Generated<Date>;
840
- }
841
816
  /**
842
817
  * Archive fetch charge log (design-f089 gate). Append-only: one row per
843
818
  * priced attempt to fetch a partition object. `usd_micros` is 0 for
@@ -941,6 +916,27 @@ interface TriggerEvaluatorStateTable {
941
916
  last_settlement_scan_at: ColumnType<Date | null, Date | null | undefined, Date | null>;
942
917
  updated_at: Generated<Date>;
943
918
  }
919
+ /** A public waitlist page: what it is for and whether it takes signups. */
920
+ interface WaitlistsTable {
921
+ slug: string;
922
+ title: string;
923
+ description: string;
924
+ url: string;
925
+ opened_at: Generated<Date>;
926
+ /** Null while the list is open. */
927
+ closed_at: Date | null;
928
+ }
929
+ /**
930
+ * One signup per (list, contact, token). `answers` holds the list's own
931
+ * questions, validated per list by the API before insert.
932
+ */
933
+ interface WaitlistSignupsTable {
934
+ id: Generated<string>;
935
+ list: string;
936
+ contact: string;
937
+ answers: Record<string, unknown>;
938
+ created_at: Generated<Date>;
939
+ }
944
940
  /**
945
941
  * Convert a subgraph name to its PostgreSQL schema name (legacy form).
946
942
  * Pre shared-rip every tenant DB had its own schema namespace so disambiguation
@@ -972,11 +968,6 @@ declare function registerSubgraph(db: Kysely<Database>, data: {
972
968
  declare function getSubgraph(db: Kysely<Database>, name: string, accountId?: string): Promise<Subgraph | null>;
973
969
  declare function listSubgraphs(db: Kysely<Database>, accountId?: string): Promise<Subgraph[]>;
974
970
  declare function updateSubgraphStatus(db: Kysely<Database>, name: string, status: string, lastProcessedBlock?: number): Promise<void>;
975
- /** Account-scoped pause. Only active/reindexing rows flip; name-only
976
- * {@link updateSubgraphStatus} is unsafe on platform (name, account_id). */
977
- declare function pauseSubgraph(db: Kysely<Database>, name: string, accountId: string): Promise<void>;
978
- /** Resume every paused subgraph for an account (claim / Stripe top-up). */
979
- declare function resumePausedSubgraphs(db: Kysely<Database>, accountId: string): Promise<number>;
980
971
  /** Live-walk ERROR write (f069): a block whose handlers ALL failed
981
972
  * (`processed === 0 && errors > 0`, `block-processor.ts`'s `applyProgress`)
982
973
  * is stamped 'error' and its height is recorded as processed, same as
@@ -1052,4 +1043,4 @@ declare function recordLiveProgress(db: Kysely<Database>, name: string, lastProc
1052
1043
  * forward write between the rewind and the fork block's reprocess. Do not
1053
1044
  * call this from the live catch-up path. */
1054
1045
  declare function rewindLiveProgress(db: Kysely<Database>, name: string, lastProcessedBlock: number): Promise<void>;
1055
- export { updateSubgraphStatus, updateSubgraphHandlerPath, updateSubgraphExpiry, rewindLiveProgress, resumePausedSubgraphs, registerSubgraph, recordSubgraphProcessed, recordLiveProgress, recordLiveError, pgSchemaNameFor, pgSchemaName, pauseSubgraph, localSubgraphAccountId, listSubgraphs, getSubgraph, deleteSubgraph };
1046
+ export { updateSubgraphStatus, updateSubgraphHandlerPath, updateSubgraphExpiry, rewindLiveProgress, registerSubgraph, recordSubgraphProcessed, recordLiveProgress, recordLiveError, pgSchemaNameFor, pgSchemaName, localSubgraphAccountId, listSubgraphs, getSubgraph, deleteSubgraph };
@@ -139,13 +139,6 @@ async function updateSubgraphStatus(db, name, status, lastProcessedBlock) {
139
139
  updated_at: new Date
140
140
  }).where("name", "=", name).execute();
141
141
  }
142
- async function pauseSubgraph(db, name, accountId) {
143
- await db.updateTable("subgraphs").set({ status: "paused", updated_at: new Date }).where("name", "=", name).where("account_id", "=", accountId).where("status", "in", ["active", "reindexing"]).execute();
144
- }
145
- async function resumePausedSubgraphs(db, accountId) {
146
- const res = await db.updateTable("subgraphs").set({ status: "active", updated_at: new Date }).where("account_id", "=", accountId).where("status", "=", "paused").executeTakeFirst();
147
- return Number(res.numUpdatedRows ?? 0);
148
- }
149
142
  async function recordLiveError(db, name, blockHeight) {
150
143
  const result = await db.updateTable("subgraphs").set({
151
144
  status: "error",
@@ -208,19 +201,17 @@ export {
208
201
  updateSubgraphHandlerPath,
209
202
  updateSubgraphExpiry,
210
203
  rewindLiveProgress,
211
- resumePausedSubgraphs,
212
204
  registerSubgraph,
213
205
  recordSubgraphProcessed,
214
206
  recordLiveProgress,
215
207
  recordLiveError,
216
208
  pgSchemaNameFor,
217
209
  pgSchemaName,
218
- pauseSubgraph,
219
210
  localSubgraphAccountId,
220
211
  listSubgraphs,
221
212
  getSubgraph,
222
213
  deleteSubgraph
223
214
  };
224
215
 
225
- //# debugId=4A4D32D3E754A61364756E2164756E21
216
+ //# debugId=EEA4A11D75AFDFDE64756E2164756E21
226
217
  //# sourceMappingURL=subgraphs.js.map