@secondlayer/shared 11.4.3 → 11.5.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.
Files changed (55) hide show
  1. package/README.md +4 -4
  2. package/dist/src/archive/derived-stage-report.d.ts +2 -2
  3. package/dist/src/archive/derived-stage-report.js.map +1 -1
  4. package/dist/src/archive/instance-diagnosis.js +2 -2
  5. package/dist/src/archive/instance-diagnosis.js.map +2 -2
  6. package/dist/src/archive/range-digest.d.ts +25 -25
  7. package/dist/src/archive/semantic-digest-builder.d.ts +25 -25
  8. package/dist/src/coverage/index.d.ts +25 -25
  9. package/dist/src/coverage/index.js.map +1 -1
  10. package/dist/src/crypto/secondlayer-webhook.d.ts +2 -2
  11. package/dist/src/crypto/secondlayer-webhook.js.map +1 -1
  12. package/dist/src/crypto/secrets.js.map +1 -1
  13. package/dist/src/db/index.d.ts +37 -37
  14. package/dist/src/db/index.js +4 -4
  15. package/dist/src/db/index.js.map +3 -3
  16. package/dist/src/db/queries/chain-reorgs.d.ts +25 -25
  17. package/dist/src/db/queries/chain-reorgs.js +4 -4
  18. package/dist/src/db/queries/chain-reorgs.js.map +3 -3
  19. package/dist/src/db/queries/contracts.d.ts +25 -25
  20. package/dist/src/db/queries/instance.d.ts +25 -25
  21. package/dist/src/db/queries/integrity.d.ts +25 -25
  22. package/dist/src/db/queries/subgraph-gaps.d.ts +25 -25
  23. package/dist/src/db/queries/subgraph-operations.d.ts +25 -25
  24. package/dist/src/db/queries/subgraphs.d.ts +25 -25
  25. package/dist/src/db/queries/subgraphs.js +4 -4
  26. package/dist/src/db/queries/subgraphs.js.map +3 -3
  27. package/dist/src/db/queries/sync-scope.d.ts +25 -25
  28. package/dist/src/db/queries/{subscriptions.d.ts → webhooks.d.ts} +58 -58
  29. package/dist/src/db/queries/{subscriptions.js → webhooks.js} +38 -38
  30. package/dist/src/db/queries/webhooks.js.map +13 -0
  31. package/dist/src/db/schema.d.ts +34 -34
  32. package/dist/src/index.d.ts +107 -107
  33. package/dist/src/index.js +51 -54
  34. package/dist/src/index.js.map +6 -6
  35. package/dist/src/leader.d.ts +4 -4
  36. package/dist/src/leader.js +3 -3
  37. package/dist/src/leader.js.map +3 -3
  38. package/dist/src/node/local-client.d.ts +25 -25
  39. package/dist/src/queue/listener.d.ts +2 -2
  40. package/dist/src/queue/listener.js.map +1 -1
  41. package/dist/src/runtime/index.js +2 -6
  42. package/dist/src/runtime/index.js.map +4 -4
  43. package/dist/src/schemas/index.d.ts +61 -61
  44. package/dist/src/schemas/index.js +48 -51
  45. package/dist/src/schemas/index.js.map +5 -5
  46. package/dist/src/schemas/subgraphs.d.ts +2 -2
  47. package/dist/src/schemas/subgraphs.js.map +1 -1
  48. package/dist/src/schemas/{subscriptions.d.ts → webhooks.d.ts} +63 -63
  49. package/dist/src/schemas/{subscriptions.js → webhooks.js} +49 -52
  50. package/dist/src/schemas/webhooks.js.map +10 -0
  51. package/migrations/0126_rename_subscriptions_to_webhooks.ts +96 -0
  52. package/migrations/0127_rename_webhook_catalog_names.ts +55 -0
  53. package/package.json +8 -8
  54. package/dist/src/db/queries/subscriptions.js.map +0 -13
  55. package/dist/src/schemas/subscriptions.js.map +0 -10
@@ -789,9 +789,9 @@ interface Database {
789
789
  account_spend_caps: AccountSpendCapsTable;
790
790
  account_credits: AccountCreditsTable;
791
791
  hosted_meter_days: HostedMeterDaysTable;
792
- subscriptions: SubscriptionsTable;
793
- subscription_outbox: SubscriptionOutboxTable;
794
- subscription_deliveries: SubscriptionDeliveriesTable;
792
+ webhooks: WebhooksTable;
793
+ webhook_outbox: WebhookOutboxTable;
794
+ webhook_deliveries: WebhookDeliveriesTable;
795
795
  trigger_evaluator_state: TriggerEvaluatorStateTable;
796
796
  decoded_events: DecodedEventsTable;
797
797
  decoder_checkpoints: DecoderCheckpointsTable;
@@ -911,31 +911,31 @@ interface ArchiveFetchesTable {
911
911
  via_allowance: Generated<boolean>;
912
912
  charged_at: Generated<Date>;
913
913
  }
914
- type SubscriptionStatus = "active" | "paused" | "error";
915
- /** Polymorphic subscription mode: `subgraph` reacts to processed table rows;
914
+ type WebhookStatus = "active" | "paused" | "error";
915
+ /** Polymorphic webhook mode: `subgraph` reacts to processed table rows;
916
916
  * `chain` reacts to raw chain events matched directly off the Index/Streams
917
917
  * clock (no subgraph). See migration 0088. */
918
- type SubscriptionKind = "subgraph" | "chain";
919
- type SubscriptionFormat = "standard-webhooks" | "inngest" | "trigger" | "cloudflare" | "cloudevents" | "raw";
920
- type SubscriptionRuntime = "inngest" | "trigger" | "cloudflare" | "node";
921
- interface SubscriptionsTable {
918
+ type WebhookKind = "subgraph" | "chain";
919
+ type WebhookFormat = "standard-webhooks" | "inngest" | "trigger" | "cloudflare" | "cloudevents" | "raw";
920
+ type WebhookRuntime = "inngest" | "trigger" | "cloudflare" | "node";
921
+ interface WebhooksTable {
922
922
  id: Generated<string>;
923
923
  account_id: string;
924
924
  project_id: string | null;
925
925
  name: string;
926
- status: ColumnType<SubscriptionStatus, SubscriptionStatus | undefined, SubscriptionStatus>;
927
- kind: ColumnType<SubscriptionKind, SubscriptionKind | undefined, SubscriptionKind>;
928
- /** Null for chain subscriptions (CHECK subscriptions_kind_shape). */
926
+ status: ColumnType<WebhookStatus, WebhookStatus | undefined, WebhookStatus>;
927
+ kind: ColumnType<WebhookKind, WebhookKind | undefined, WebhookKind>;
928
+ /** Null for chain webhooks (CHECK webhooks_kind_shape). */
929
929
  subgraph_name: string | null;
930
- /** Null for chain subscriptions (CHECK subscriptions_kind_shape). */
930
+ /** Null for chain webhooks (CHECK webhooks_kind_shape). */
931
931
  table_name: string | null;
932
932
  /** Chain-trigger filter array (the `SubgraphFilter` shape, JSON). Null for
933
- * subgraph subscriptions. Typed loosely here to avoid a shared→subgraphs
934
- * import cycle; the Zod schema in schemas/subscriptions.ts owns the shape. */
933
+ * subgraph webhooks. Typed loosely here to avoid a shared→subgraphs
934
+ * import cycle; the Zod schema in schemas/webhooks.ts owns the shape. */
935
935
  triggers: unknown | null;
936
936
  filter: Generated<unknown>;
937
- format: ColumnType<SubscriptionFormat, SubscriptionFormat | undefined, SubscriptionFormat>;
938
- runtime: SubscriptionRuntime | null;
937
+ format: ColumnType<WebhookFormat, WebhookFormat | undefined, WebhookFormat>;
938
+ runtime: WebhookRuntime | null;
939
939
  url: string;
940
940
  signing_secret_enc: Buffer;
941
941
  auth_config: Generated<unknown>;
@@ -950,15 +950,15 @@ interface SubscriptionsTable {
950
950
  created_at: Generated<Date>;
951
951
  updated_at: Generated<Date>;
952
952
  }
953
- type Subscription = Selectable<SubscriptionsTable>;
953
+ type Webhook = Selectable<WebhooksTable>;
954
954
  type OutboxStatus = "pending" | "delivered" | "dead";
955
- interface SubscriptionOutboxTable {
955
+ interface WebhookOutboxTable {
956
956
  id: Generated<string>;
957
- subscription_id: string;
958
- kind: ColumnType<SubscriptionKind, SubscriptionKind | undefined, SubscriptionKind>;
959
- /** Null for chain-subscription rows. */
957
+ webhook_id: string;
958
+ kind: ColumnType<WebhookKind, WebhookKind | undefined, WebhookKind>;
959
+ /** Null for chain-webhook rows. */
960
960
  subgraph_name: string | null;
961
- /** Null for chain-subscription rows. */
961
+ /** Null for chain-webhook rows. */
962
962
  table_name: string | null;
963
963
  block_height: number | bigint;
964
964
  tx_id: string | null;
@@ -976,12 +976,12 @@ interface SubscriptionOutboxTable {
976
976
  locked_until: Date | null;
977
977
  created_at: Generated<Date>;
978
978
  }
979
- interface SubscriptionDeliveriesTable {
979
+ interface WebhookDeliveriesTable {
980
980
  id: Generated<string>;
981
981
  /** Nullable after migration 0077 — outbox row may be cleaned up while
982
982
  * delivery telemetry is retained. */
983
983
  outbox_id: string | null;
984
- subscription_id: string;
984
+ webhook_id: string;
985
985
  attempt: number;
986
986
  status_code: number | null;
987
987
  response_headers: unknown | null;
@@ -991,7 +991,7 @@ interface SubscriptionDeliveriesTable {
991
991
  dispatched_at: Generated<Date>;
992
992
  }
993
993
  /** Single-row (id always TRUE) high-water mark for the chain-trigger evaluator.
994
- * One loop serves all chain subscriptions, so the cursor is global. */
994
+ * One loop serves all chain webhooks, so the cursor is global. */
995
995
  interface TriggerEvaluatorStateTable {
996
996
  id: Generated<boolean>;
997
997
  last_processed_block: ColumnType<bigint, bigint | number | undefined, bigint | number>;
@@ -1001,70 +1001,70 @@ interface TriggerEvaluatorStateTable {
1001
1001
  updated_at: Generated<Date>;
1002
1002
  }
1003
1003
  /**
1004
- * Subscription CRUD. `signing_secret_enc` is transparently encrypted via
1004
+ * Webhook CRUD. `signing_secret_enc` is transparently encrypted via
1005
1005
  * `encryptSecret`/`decryptSecret`. Plaintext secrets only leave via the
1006
1006
  * return value of `create` (one-time display) and `rotateSecret`.
1007
1007
  */
1008
- interface CreateSubscriptionInput {
1008
+ interface CreateWebhookInput {
1009
1009
  accountId: string;
1010
1010
  projectId?: string | null;
1011
1011
  name: string;
1012
- /** Defaults to "subgraph". Chain subscriptions set kind="chain" + triggers. */
1013
- kind?: SubscriptionKind;
1014
- /** Required for subgraph subscriptions; omitted for chain. */
1012
+ /** Defaults to "subgraph". Chain webhooks set kind="chain" + triggers. */
1013
+ kind?: WebhookKind;
1014
+ /** Required for subgraph webhooks; omitted for chain. */
1015
1015
  subgraphName?: string | null;
1016
- /** Required for subgraph subscriptions; omitted for chain. */
1016
+ /** Required for subgraph webhooks; omitted for chain. */
1017
1017
  tableName?: string | null;
1018
- /** Chain-trigger filter array. Required for chain subscriptions. */
1018
+ /** Chain-trigger filter array. Required for chain webhooks. */
1019
1019
  triggers?: unknown;
1020
1020
  filter?: unknown;
1021
- format?: SubscriptionFormat;
1022
- runtime?: SubscriptionRuntime | null;
1021
+ format?: WebhookFormat;
1022
+ runtime?: WebhookRuntime | null;
1023
1023
  url: string;
1024
1024
  authConfig?: unknown;
1025
1025
  maxRetries?: number;
1026
1026
  timeoutMs?: number;
1027
1027
  concurrency?: number;
1028
1028
  }
1029
- interface CreateSubscriptionResult {
1030
- subscription: Subscription;
1029
+ interface CreateWebhookResult {
1030
+ webhook: Webhook;
1031
1031
  /** Plaintext signing secret — surfaced once, never stored decrypted. */
1032
1032
  signingSecret: string;
1033
1033
  }
1034
- declare function createSubscription(db: Kysely<Database>, input: CreateSubscriptionInput): Promise<CreateSubscriptionResult>;
1035
- declare function listSubscriptions(db: Kysely<Database>, accountId: string, opts?: {
1034
+ declare function createWebhook(db: Kysely<Database>, input: CreateWebhookInput): Promise<CreateWebhookResult>;
1035
+ declare function listWebhooks(db: Kysely<Database>, accountId: string, opts?: {
1036
1036
  limit?: number
1037
1037
  offset?: number
1038
- }): Promise<Subscription[]>;
1038
+ }): Promise<Webhook[]>;
1039
1039
  /**
1040
- * All active chain subscriptions across every account — the input to the global
1041
- * trigger evaluator (one loop serves them all). Subgraph subscriptions are
1040
+ * All active chain webhooks across every account — the input to the global
1041
+ * trigger evaluator (one loop serves them all). Subgraph webhooks are
1042
1042
  * excluded; they emit via the subgraph flush path.
1043
1043
  */
1044
- declare function listActiveChainSubscriptions(db: Kysely<Database>): Promise<Subscription[]>;
1045
- declare function getSubscription(db: Kysely<Database>, accountId: string, id: string): Promise<Subscription | null>;
1046
- declare function getSubscriptionByName(db: Kysely<Database>, accountId: string, name: string): Promise<Subscription | null>;
1047
- interface UpdateSubscriptionInput {
1044
+ declare function listActiveChainWebhooks(db: Kysely<Database>): Promise<Webhook[]>;
1045
+ declare function getWebhook(db: Kysely<Database>, accountId: string, id: string): Promise<Webhook | null>;
1046
+ declare function getWebhookByName(db: Kysely<Database>, accountId: string, name: string): Promise<Webhook | null>;
1047
+ interface UpdateWebhookInput {
1048
1048
  name?: string;
1049
1049
  filter?: unknown;
1050
- format?: SubscriptionFormat;
1051
- runtime?: SubscriptionRuntime | null;
1050
+ format?: WebhookFormat;
1051
+ runtime?: WebhookRuntime | null;
1052
1052
  url?: string;
1053
1053
  authConfig?: unknown;
1054
1054
  maxRetries?: number;
1055
1055
  timeoutMs?: number;
1056
1056
  concurrency?: number;
1057
1057
  }
1058
- declare function updateSubscription(db: Kysely<Database>, accountId: string, id: string, patch: UpdateSubscriptionInput): Promise<Subscription | null>;
1059
- declare function toggleSubscriptionStatus(db: Kysely<Database>, accountId: string, id: string, status: SubscriptionStatus): Promise<Subscription | null>;
1060
- declare function deleteSubscription(db: Kysely<Database>, accountId: string, id: string): Promise<boolean>;
1058
+ declare function updateWebhook(db: Kysely<Database>, accountId: string, id: string, patch: UpdateWebhookInput): Promise<Webhook | null>;
1059
+ declare function toggleWebhookStatus(db: Kysely<Database>, accountId: string, id: string, status: WebhookStatus): Promise<Webhook | null>;
1060
+ declare function deleteWebhook(db: Kysely<Database>, accountId: string, id: string): Promise<boolean>;
1061
1061
  interface RotateSecretResult {
1062
- subscription: Subscription;
1062
+ webhook: Webhook;
1063
1063
  signingSecret: string;
1064
1064
  }
1065
- declare function rotateSubscriptionSecret(db: Kysely<Database>, accountId: string, id: string): Promise<RotateSecretResult | null>;
1066
- /** Decrypt a subscription's signing secret for HMAC signing at emit time. */
1067
- declare function getSubscriptionSigningSecret(sub: Subscription): string;
1068
- /** Fire `subscriptions:changed` notify so the emitter hot-reloads its cache. */
1069
- declare function notifySubscriptionsChanged(db: Kysely<Database>, accountId: string): Promise<void>;
1070
- export { updateSubscription, toggleSubscriptionStatus, rotateSubscriptionSecret, notifySubscriptionsChanged, listSubscriptions, listActiveChainSubscriptions, getSubscriptionSigningSecret, getSubscriptionByName, getSubscription, deleteSubscription, createSubscription, UpdateSubscriptionInput, RotateSecretResult, CreateSubscriptionResult, CreateSubscriptionInput };
1065
+ declare function rotateWebhookSecret(db: Kysely<Database>, accountId: string, id: string): Promise<RotateSecretResult | null>;
1066
+ /** Decrypt a webhook's signing secret for HMAC signing at emit time. */
1067
+ declare function getWebhookSigningSecret(webhook: Webhook): string;
1068
+ /** Fire `webhooks:changed` notify so the emitter hot-reloads its cache. */
1069
+ declare function notifyWebhooksChanged(db: Kysely<Database>, accountId: string): Promise<void>;
1070
+ export { updateWebhook, toggleWebhookStatus, rotateWebhookSecret, notifyWebhooksChanged, listWebhooks, listActiveChainWebhooks, getWebhookSigningSecret, getWebhookByName, getWebhook, deleteWebhook, createWebhook, UpdateWebhookInput, RotateSecretResult, CreateWebhookResult, CreateWebhookInput };
@@ -227,9 +227,9 @@ function generateSecretsKey() {
227
227
  return randomBytes2(32).toString("hex");
228
228
  }
229
229
 
230
- // src/db/queries/subscriptions.ts
230
+ // src/db/queries/webhooks.ts
231
231
  import { sql } from "kysely";
232
- async function createSubscription(db, input) {
232
+ async function createWebhook(db, input) {
233
233
  const signingSecret = generateSecret();
234
234
  const kind = input.kind ?? "subgraph";
235
235
  const row = {
@@ -251,11 +251,11 @@ async function createSubscription(db, input) {
251
251
  ...input.timeoutMs !== undefined ? { timeout_ms: input.timeoutMs } : {},
252
252
  ...input.concurrency !== undefined ? { concurrency: input.concurrency } : {}
253
253
  };
254
- const subscription = await db.insertInto("subscriptions").values(row).returningAll().executeTakeFirstOrThrow();
255
- return { subscription, signingSecret };
254
+ const webhook = await db.insertInto("webhooks").values(row).returningAll().executeTakeFirstOrThrow();
255
+ return { webhook, signingSecret };
256
256
  }
257
- async function listSubscriptions(db, accountId, opts) {
258
- let q = db.selectFrom("subscriptions").selectAll().orderBy("created_at", "desc");
257
+ async function listWebhooks(db, accountId, opts) {
258
+ let q = db.selectFrom("webhooks").selectAll().orderBy("created_at", "desc");
259
259
  if (isPlatformMode())
260
260
  q = q.where("account_id", "=", accountId);
261
261
  if (opts?.limit !== undefined)
@@ -264,22 +264,22 @@ async function listSubscriptions(db, accountId, opts) {
264
264
  q = q.offset(opts.offset);
265
265
  return q.execute();
266
266
  }
267
- async function listActiveChainSubscriptions(db) {
268
- return db.selectFrom("subscriptions").selectAll().where("kind", "=", "chain").where("status", "=", "active").execute();
267
+ async function listActiveChainWebhooks(db) {
268
+ return db.selectFrom("webhooks").selectAll().where("kind", "=", "chain").where("status", "=", "active").execute();
269
269
  }
270
- async function getSubscription(db, accountId, id) {
271
- let q = db.selectFrom("subscriptions").selectAll().where("id", "=", id);
270
+ async function getWebhook(db, accountId, id) {
271
+ let q = db.selectFrom("webhooks").selectAll().where("id", "=", id);
272
272
  if (isPlatformMode())
273
273
  q = q.where("account_id", "=", accountId);
274
274
  return await q.executeTakeFirst() ?? null;
275
275
  }
276
- async function getSubscriptionByName(db, accountId, name) {
277
- let q = db.selectFrom("subscriptions").selectAll().where("name", "=", name);
276
+ async function getWebhookByName(db, accountId, name) {
277
+ let q = db.selectFrom("webhooks").selectAll().where("name", "=", name);
278
278
  if (isPlatformMode())
279
279
  q = q.where("account_id", "=", accountId);
280
280
  return await q.executeTakeFirst() ?? null;
281
281
  }
282
- async function updateSubscription(db, accountId, id, patch) {
282
+ async function updateWebhook(db, accountId, id, patch) {
283
283
  const update = { updated_at: new Date };
284
284
  if (patch.name !== undefined)
285
285
  update.name = patch.name;
@@ -299,13 +299,13 @@ async function updateSubscription(db, accountId, id, patch) {
299
299
  update.timeout_ms = patch.timeoutMs;
300
300
  if (patch.concurrency !== undefined)
301
301
  update.concurrency = patch.concurrency;
302
- let q = db.updateTable("subscriptions").set(update).where("id", "=", id);
302
+ let q = db.updateTable("webhooks").set(update).where("id", "=", id);
303
303
  if (isPlatformMode())
304
304
  q = q.where("account_id", "=", accountId);
305
305
  return await q.returningAll().executeTakeFirst() ?? null;
306
306
  }
307
- async function toggleSubscriptionStatus(db, accountId, id, status) {
308
- let q = db.updateTable("subscriptions").set({
307
+ async function toggleWebhookStatus(db, accountId, id, status) {
308
+ let q = db.updateTable("webhooks").set({
309
309
  status,
310
310
  updated_at: new Date,
311
311
  ...status === "active" ? {
@@ -317,16 +317,16 @@ async function toggleSubscriptionStatus(db, accountId, id, status) {
317
317
  q = q.where("account_id", "=", accountId);
318
318
  return await q.returningAll().executeTakeFirst() ?? null;
319
319
  }
320
- async function deleteSubscription(db, accountId, id) {
321
- let q = db.deleteFrom("subscriptions").where("id", "=", id);
320
+ async function deleteWebhook(db, accountId, id) {
321
+ let q = db.deleteFrom("webhooks").where("id", "=", id);
322
322
  if (isPlatformMode())
323
323
  q = q.where("account_id", "=", accountId);
324
324
  const res = await q.executeTakeFirst();
325
325
  return Number(res.numDeletedRows ?? 0) > 0;
326
326
  }
327
- async function rotateSubscriptionSecret(db, accountId, id) {
327
+ async function rotateWebhookSecret(db, accountId, id) {
328
328
  const signingSecret = generateSecret();
329
- let q = db.updateTable("subscriptions").set({
329
+ let q = db.updateTable("webhooks").set({
330
330
  signing_secret_enc: encryptSecret(signingSecret),
331
331
  updated_at: new Date
332
332
  }).where("id", "=", id);
@@ -335,27 +335,27 @@ async function rotateSubscriptionSecret(db, accountId, id) {
335
335
  const row = await q.returningAll().executeTakeFirst();
336
336
  if (!row)
337
337
  return null;
338
- return { subscription: row, signingSecret };
338
+ return { webhook: row, signingSecret };
339
339
  }
340
- function getSubscriptionSigningSecret(sub) {
341
- return decryptSecret(sub.signing_secret_enc);
340
+ function getWebhookSigningSecret(webhook) {
341
+ return decryptSecret(webhook.signing_secret_enc);
342
342
  }
343
- async function notifySubscriptionsChanged(db, accountId) {
344
- await sql`SELECT pg_notify('subscriptions:changed', ${accountId})`.execute(db);
343
+ async function notifyWebhooksChanged(db, accountId) {
344
+ await sql`SELECT pg_notify('webhooks:changed', ${accountId})`.execute(db);
345
345
  }
346
346
  export {
347
- updateSubscription,
348
- toggleSubscriptionStatus,
349
- rotateSubscriptionSecret,
350
- notifySubscriptionsChanged,
351
- listSubscriptions,
352
- listActiveChainSubscriptions,
353
- getSubscriptionSigningSecret,
354
- getSubscriptionByName,
355
- getSubscription,
356
- deleteSubscription,
357
- createSubscription
347
+ updateWebhook,
348
+ toggleWebhookStatus,
349
+ rotateWebhookSecret,
350
+ notifyWebhooksChanged,
351
+ listWebhooks,
352
+ listActiveChainWebhooks,
353
+ getWebhookSigningSecret,
354
+ getWebhookByName,
355
+ getWebhook,
356
+ deleteWebhook,
357
+ createWebhook
358
358
  };
359
359
 
360
- //# debugId=A468DA6DE7BBDD4564756E2164756E21
361
- //# sourceMappingURL=subscriptions.js.map
360
+ //# debugId=8CB695561D569ACB64756E2164756E21
361
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/mode.ts", "../src/crypto/hmac.ts", "../src/crypto/secrets.ts", "../src/db/queries/webhooks.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Instance modes for the Secondlayer platform.\n *\n * - `oss`: self-hosted, single-tenant. No auth middleware, no platform routes\n * (projects, admin). Everything runs against a single `DATABASE_URL`.\n * Intended for `docker compose up`.\n *\n * - `platform`: the metered archive deployment. Magic-link auth, API keys,\n * accounts, credits, and metered `/v1` reads (Index + Streams + subgraphs)\n * against a single shared DB. No paid tier ladder — one metered `free`\n * tier plus first-party internal service credentials.\n */\n\nexport type InstanceMode = \"oss\" | \"platform\";\n\n/** What the operator wrote in the env — `archive` is the honest name for the\n * metered public-archive deployment and aliases `platform` behaviorally. */\nexport type DeclaredInstanceMode = InstanceMode | \"archive\";\n\nconst VALID_MODES: readonly DeclaredInstanceMode[] = [\n\t\"oss\",\n\t\"platform\",\n\t\"archive\",\n];\n\nfunction declaredMode(): DeclaredInstanceMode {\n\tconst raw = process.env.INSTANCE_MODE?.trim().toLowerCase();\n\tif (raw && (VALID_MODES as readonly string[]).includes(raw)) {\n\t\treturn raw as DeclaredInstanceMode;\n\t}\n\treturn \"oss\";\n}\n\n/**\n * Resolve the active instance mode from `process.env.INSTANCE_MODE`.\n * Defaults to `\"oss\"` — the safest default for self-hosters who deploy\n * without setting the variable. `archive` normalizes to `platform` here so\n * every behavioral branch stays a two-way choice; use\n * `getDeclaredInstanceMode()` for display surfaces.\n */\nexport function getInstanceMode(): InstanceMode {\n\tconst declared = declaredMode();\n\treturn declared === \"archive\" ? \"platform\" : declared;\n}\n\n/** The mode as declared in the env, for status/identity surfaces. */\nexport function getDeclaredInstanceMode(): DeclaredInstanceMode {\n\treturn declaredMode();\n}\n\n/**\n * True when public reads are credit-metered (the free window, retention, and\n * credits gates arm). Platform/archive deployments meter by default;\n * self-host never does unless the operator explicitly sets\n * `METERED_READS=true`. `METERED_READS=false` disarms a metered deployment.\n */\nexport function isMeteredReads(): boolean {\n\tconst override = process.env.METERED_READS?.trim().toLowerCase();\n\tif (override === \"true\") return true;\n\tif (override === \"false\") return false;\n\treturn getInstanceMode() === \"platform\";\n}\n\n/** True when the active mode is `\"platform\"` (shared multi-tenant). */\nexport function isPlatformMode(): boolean {\n\treturn getInstanceMode() === \"platform\";\n}\n\n/** True when the active mode is `\"oss\"` (self-hosted). */\nexport function isOssMode(): boolean {\n\treturn getInstanceMode() === \"oss\";\n}\n",
6
+ "import { createHmac, randomBytes } from \"node:crypto\";\n\n/**\n * Generate a random secret for delivery signing\n * Returns 32 bytes as a 64-character hex string\n */\nexport function generateSecret(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Sign a payload with HMAC-SHA256\n * Returns the signature as a hex string\n */\nexport function signPayload(payload: string, secret: string): string {\n\tconst hmac = createHmac(\"sha256\", secret);\n\thmac.update(payload);\n\treturn hmac.digest(\"hex\");\n}\n\n/**\n * Verify an HMAC signature\n * Uses constant-time comparison to prevent timing attacks\n */\nexport function verifySignature(\n\tpayload: string,\n\tsignature: string,\n\tsecret: string,\n): boolean {\n\tconst expectedSignature = signPayload(payload, secret);\n\n\t// Constant-time comparison\n\tif (signature.length !== expectedSignature.length) {\n\t\treturn false;\n\t}\n\n\tlet result = 0;\n\tfor (let i = 0; i < signature.length; i++) {\n\t\tresult |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n\t}\n\n\treturn result === 0;\n}\n\n/**\n * Create a Stripe-style signature header\n * Format: t=timestamp,v1=signature\n */\nexport function createSignatureHeader(\n\tpayload: string,\n\tsecret: string,\n\ttimestamp?: number,\n): string {\n\tconst ts = timestamp ?? Math.floor(Date.now() / 1000);\n\tconst signedPayload = `${ts}.${payload}`;\n\tconst signature = signPayload(signedPayload, secret);\n\n\treturn `t=${ts},v1=${signature}`;\n}\n\n/**\n * Parse and verify a Stripe-style signature header\n * Returns true if valid, false otherwise\n */\nexport function verifySignatureHeader(\n\tpayload: string,\n\theader: string,\n\tsecret: string,\n\ttoleranceSeconds = 300, // 5 minutes\n): boolean {\n\t// Parse header\n\tconst parts = header.split(\",\");\n\tconst timestamp = parts.find((p) => p.startsWith(\"t=\"))?.slice(2);\n\tconst signature = parts.find((p) => p.startsWith(\"v1=\"))?.slice(3);\n\n\tif (!timestamp || !signature) {\n\t\treturn false;\n\t}\n\n\tconst ts = Number.parseInt(timestamp, 10);\n\tif (Number.isNaN(ts)) {\n\t\treturn false;\n\t}\n\n\t// Check timestamp is within tolerance\n\tconst now = Math.floor(Date.now() / 1000);\n\tif (Math.abs(now - ts) > toleranceSeconds) {\n\t\treturn false;\n\t}\n\n\t// Verify signature\n\tconst signedPayload = `${ts}.${payload}`;\n\treturn verifySignature(signedPayload, signature, secret);\n}\n",
7
+ "import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\texistsSync,\n\topenSync,\n\treadFileSync,\n\tunlinkSync,\n} from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { getInstanceMode } from \"../mode.ts\";\n\n/**\n * AES-256-GCM symmetric envelope for encrypted secrets at rest (tenant keys,\n * webhook signing secrets, etc.).\n *\n * Ciphertext layout: `iv (12 bytes) || authTag (16 bytes) || ciphertext`\n *\n * The key comes from `SECONDLAYER_SECRETS_KEY` — 32 bytes hex. In OSS mode,\n * if the env var is unset on first use we autogenerate a key and persist it\n * to `.env.local` in the current working directory so subsequent restarts\n * pick it up without user intervention. Dedicated/platform modes throw —\n * those runtimes must provision the key explicitly.\n *\n * Rotation strategy: re-encrypt all rows with the new key and swap the env\n * var. Not zero-downtime, but acceptable at v2 scale. For real KMS (AWS\n * KMS, Vault, GCP KMS), wrap the same byte layout behind an\n * `EncryptSecret`/`DecryptSecret` interface and swap at startup.\n */\n\nconst KEY_ENV = \"SECONDLAYER_SECRETS_KEY\";\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\n\nfunction readExistingKey(envPath: string): string | null {\n\tif (!existsSync(envPath)) return null;\n\tconst contents = readFileSync(envPath, \"utf8\");\n\tconst match = contents.match(/^SECONDLAYER_SECRETS_KEY=([a-fA-F0-9]{64})/m);\n\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\treturn match ? match[1]! : null;\n}\n\n/**\n * Atomic file lock via `openSync(..., \"wx\")` — O_CREAT | O_EXCL. If two\n * processes race on cold-compose start, exactly one creates the lock\n * file; the loser polls until the winner finishes writing `.env.local`,\n * then reads the winner's key. Stale locks (process crashed mid-write)\n * are cleaned after `STALE_LOCK_MS`.\n */\nconst STALE_LOCK_MS = 10_000;\nconst POLL_MS = 25;\n\nfunction bootstrapOssKey(): string {\n\tconst envPath = resolve(process.cwd(), \".env.local\");\n\n\t// Fast path — key already on disk from a prior run.\n\tconst existing = readExistingKey(envPath);\n\tif (existing) {\n\t\tprocess.env[KEY_ENV] = existing;\n\t\treturn existing;\n\t}\n\n\tconst lockPath = `${envPath}.secret-bootstrap.lock`;\n\tlet lockFd: number | null = null;\n\ttry {\n\t\tlockFd = openSync(lockPath, \"wx\", 0o600);\n\t} catch (err) {\n\t\tconst e = err as NodeJS.ErrnoException;\n\t\tif (e.code !== \"EEXIST\") throw err;\n\t}\n\n\tif (lockFd === null) {\n\t\t// Another process is bootstrapping. Poll for its result.\n\t\tconst deadline = Date.now() + STALE_LOCK_MS;\n\t\twhile (Date.now() < deadline) {\n\t\t\tconst key = readExistingKey(envPath);\n\t\t\tif (key) {\n\t\t\t\tprocess.env[KEY_ENV] = key;\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\tBun.sleepSync(POLL_MS);\n\t\t}\n\t\t// Lock holder died mid-write — force-clean and retry once.\n\t\ttry {\n\t\t\tunlinkSync(lockPath);\n\t\t} catch {}\n\t\treturn bootstrapOssKey();\n\t}\n\n\ttry {\n\t\tconst hex = randomBytes(32).toString(\"hex\");\n\t\tconst line = `${existsSync(envPath) ? \"\\n\" : \"\"}${KEY_ENV}=${hex}\\n`;\n\t\tappendFileSync(envPath, line, { mode: 0o600 });\n\t\tprocess.env[KEY_ENV] = hex;\n\t\tconsole.log(\n\t\t\t`[secondlayer] generated ${KEY_ENV}; saved to ${envPath} (mode 0600)`,\n\t\t);\n\t\treturn hex;\n\t} finally {\n\t\tcloseSync(lockFd);\n\t\ttry {\n\t\t\tunlinkSync(lockPath);\n\t\t} catch {}\n\t}\n}\n\nfunction loadKey(): Buffer {\n\tlet hex = process.env[KEY_ENV];\n\tif (!hex) {\n\t\tif (getInstanceMode() === \"oss\") {\n\t\t\thex = bootstrapOssKey();\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`${KEY_ENV} not set. Generate one with: openssl rand -hex 32`,\n\t\t\t);\n\t\t}\n\t}\n\tconst key = Buffer.from(hex, \"hex\");\n\tif (key.length !== 32) {\n\t\tthrow new Error(`${KEY_ENV} must be 32 bytes hex (got ${key.length})`);\n\t}\n\treturn key;\n}\n\nlet _cachedKey: Buffer | null = null;\nfunction getKey(): Buffer {\n\tif (!_cachedKey) _cachedKey = loadKey();\n\treturn _cachedKey;\n}\n\n/**\n * Non-throwing check for whether a secrets key is currently resolvable —\n * same resolution order as {@link loadKey} (env var, then the OSS\n * `.env.local` fallback), but never bootstraps a new key (that would\n * generate+persist a key as a side effect of a mere existence check), never\n * throws, and never returns or logs the key itself. Used by callers that\n * need to fail loud on a missing key BEFORE attempting a decrypt (f072).\n */\nexport function secretsKeyAvailable(): boolean {\n\tif (process.env[KEY_ENV]) return true;\n\tif (getInstanceMode() === \"oss\") {\n\t\tconst envPath = resolve(process.cwd(), \".env.local\");\n\t\treturn readExistingKey(envPath) !== null;\n\t}\n\treturn false;\n}\n\nexport function encryptSecret(plaintext: string): Buffer {\n\tconst key = getKey();\n\tconst iv = randomBytes(IV_LEN);\n\tconst cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n\tconst ciphertext = Buffer.concat([\n\t\tcipher.update(plaintext, \"utf8\"),\n\t\tcipher.final(),\n\t]);\n\tconst tag = cipher.getAuthTag();\n\treturn Buffer.concat([iv, tag, ciphertext]);\n}\n\nexport function decryptSecret(envelope: Buffer): string {\n\tconst key = getKey();\n\tconst iv = envelope.subarray(0, IV_LEN);\n\tconst tag = envelope.subarray(IV_LEN, IV_LEN + TAG_LEN);\n\tconst ciphertext = envelope.subarray(IV_LEN + TAG_LEN);\n\tconst decipher = createDecipheriv(\"aes-256-gcm\", key, iv);\n\tdecipher.setAuthTag(tag);\n\treturn decipher.update(ciphertext).toString(\"utf8\") + decipher.final(\"utf8\");\n}\n\n/** Generate a fresh 32-byte hex key suitable for `SECONDLAYER_SECRETS_KEY`. */\nexport function generateSecretsKey(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n",
8
+ "import { type Kysely, sql } from \"kysely\";\nimport { generateSecret } from \"../../crypto/hmac.ts\";\nimport { decryptSecret, encryptSecret } from \"../../crypto/secrets.ts\";\nimport { isPlatformMode } from \"../../mode.ts\";\nimport type {\n\tDatabase,\n\tInsertWebhook,\n\tUpdateWebhook,\n\tWebhook,\n\tWebhookFormat,\n\tWebhookKind,\n\tWebhookRuntime,\n\tWebhookStatus,\n} from \"../types.ts\";\n\n/**\n * Webhook CRUD. `signing_secret_enc` is transparently encrypted via\n * `encryptSecret`/`decryptSecret`. Plaintext secrets only leave via the\n * return value of `create` (one-time display) and `rotateSecret`.\n */\n\nexport interface CreateWebhookInput {\n\taccountId: string;\n\tprojectId?: string | null;\n\tname: string;\n\t/** Defaults to \"subgraph\". Chain webhooks set kind=\"chain\" + triggers. */\n\tkind?: WebhookKind;\n\t/** Required for subgraph webhooks; omitted for chain. */\n\tsubgraphName?: string | null;\n\t/** Required for subgraph webhooks; omitted for chain. */\n\ttableName?: string | null;\n\t/** Chain-trigger filter array. Required for chain webhooks. */\n\ttriggers?: unknown;\n\tfilter?: unknown;\n\tformat?: WebhookFormat;\n\truntime?: WebhookRuntime | null;\n\turl: string;\n\tauthConfig?: unknown;\n\tmaxRetries?: number;\n\ttimeoutMs?: number;\n\tconcurrency?: number;\n}\n\nexport interface CreateWebhookResult {\n\twebhook: Webhook;\n\t/** Plaintext signing secret — surfaced once, never stored decrypted. */\n\tsigningSecret: string;\n}\n\nexport async function createWebhook(\n\tdb: Kysely<Database>,\n\tinput: CreateWebhookInput,\n): Promise<CreateWebhookResult> {\n\tconst signingSecret = generateSecret();\n\tconst kind: WebhookKind = input.kind ?? \"subgraph\";\n\tconst row: InsertWebhook = {\n\t\taccount_id: isPlatformMode() ? input.accountId : \"\",\n\t\tproject_id: input.projectId ?? null,\n\t\tname: input.name,\n\t\tstatus: \"active\",\n\t\tkind,\n\t\tsubgraph_name: input.subgraphName ?? null,\n\t\ttable_name: input.tableName ?? null,\n\t\ttriggers: kind === \"chain\" ? ((input.triggers ?? []) as unknown) : null,\n\t\tfilter: input.filter ?? {},\n\t\tformat: input.format ?? \"standard-webhooks\",\n\t\truntime: input.runtime ?? null,\n\t\turl: input.url,\n\t\tsigning_secret_enc: encryptSecret(signingSecret),\n\t\tauth_config: input.authConfig ?? {},\n\t\t...(input.maxRetries !== undefined\n\t\t\t? { max_retries: input.maxRetries }\n\t\t\t: {}),\n\t\t...(input.timeoutMs !== undefined ? { timeout_ms: input.timeoutMs } : {}),\n\t\t...(input.concurrency !== undefined\n\t\t\t? { concurrency: input.concurrency }\n\t\t\t: {}),\n\t};\n\tconst webhook = await db\n\t\t.insertInto(\"webhooks\")\n\t\t.values(row)\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\treturn { webhook, signingSecret };\n}\n\nexport async function listWebhooks(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\topts?: { limit?: number; offset?: number },\n): Promise<Webhook[]> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().orderBy(\"created_at\", \"desc\");\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tif (opts?.limit !== undefined) q = q.limit(opts.limit);\n\tif (opts?.offset !== undefined) q = q.offset(opts.offset);\n\treturn q.execute();\n}\n\n/**\n * All active chain webhooks across every account — the input to the global\n * trigger evaluator (one loop serves them all). Subgraph webhooks are\n * excluded; they emit via the subgraph flush path.\n */\nexport async function listActiveChainWebhooks(\n\tdb: Kysely<Database>,\n): Promise<Webhook[]> {\n\treturn db\n\t\t.selectFrom(\"webhooks\")\n\t\t.selectAll()\n\t\t.where(\"kind\", \"=\", \"chain\")\n\t\t.where(\"status\", \"=\", \"active\")\n\t\t.execute();\n}\n\nexport async function getWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<Webhook | null> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.executeTakeFirst()) ?? null;\n}\n\nexport async function getWebhookByName(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tname: string,\n): Promise<Webhook | null> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().where(\"name\", \"=\", name);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.executeTakeFirst()) ?? null;\n}\n\nexport interface UpdateWebhookInput {\n\tname?: string;\n\tfilter?: unknown;\n\tformat?: WebhookFormat;\n\truntime?: WebhookRuntime | null;\n\turl?: string;\n\tauthConfig?: unknown;\n\tmaxRetries?: number;\n\ttimeoutMs?: number;\n\tconcurrency?: number;\n}\n\nexport async function updateWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n\tpatch: UpdateWebhookInput,\n): Promise<Webhook | null> {\n\tconst update: UpdateWebhook = { updated_at: new Date() };\n\tif (patch.name !== undefined) update.name = patch.name;\n\tif (patch.filter !== undefined) update.filter = patch.filter;\n\tif (patch.format !== undefined) update.format = patch.format;\n\tif (patch.runtime !== undefined) update.runtime = patch.runtime;\n\tif (patch.url !== undefined) update.url = patch.url;\n\tif (patch.authConfig !== undefined) update.auth_config = patch.authConfig;\n\tif (patch.maxRetries !== undefined) update.max_retries = patch.maxRetries;\n\tif (patch.timeoutMs !== undefined) update.timeout_ms = patch.timeoutMs;\n\tif (patch.concurrency !== undefined) update.concurrency = patch.concurrency;\n\n\tlet q = db.updateTable(\"webhooks\").set(update).where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.returningAll().executeTakeFirst()) ?? null;\n}\n\nexport async function toggleWebhookStatus(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n\tstatus: WebhookStatus,\n): Promise<Webhook | null> {\n\tlet q = db\n\t\t.updateTable(\"webhooks\")\n\t\t.set({\n\t\t\tstatus,\n\t\t\tupdated_at: new Date(),\n\t\t\t...(status === \"active\"\n\t\t\t\t? {\n\t\t\t\t\t\tcircuit_failures: 0,\n\t\t\t\t\t\tcircuit_opened_at: null,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t})\n\t\t.where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.returningAll().executeTakeFirst()) ?? null;\n}\n\nexport async function deleteWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<boolean> {\n\tlet q = db.deleteFrom(\"webhooks\").where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tconst res = await q.executeTakeFirst();\n\treturn Number(res.numDeletedRows ?? 0) > 0;\n}\n\nexport interface RotateSecretResult {\n\twebhook: Webhook;\n\tsigningSecret: string;\n}\n\nexport async function rotateWebhookSecret(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<RotateSecretResult | null> {\n\tconst signingSecret = generateSecret();\n\tlet q = db\n\t\t.updateTable(\"webhooks\")\n\t\t.set({\n\t\t\tsigning_secret_enc: encryptSecret(signingSecret),\n\t\t\tupdated_at: new Date(),\n\t\t})\n\t\t.where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tconst row = await q.returningAll().executeTakeFirst();\n\tif (!row) return null;\n\treturn { webhook: row, signingSecret };\n}\n\n/** Decrypt a webhook's signing secret for HMAC signing at emit time. */\nexport function getWebhookSigningSecret(webhook: Webhook): string {\n\treturn decryptSecret(webhook.signing_secret_enc);\n}\n\n/** Fire `webhooks:changed` notify so the emitter hot-reloads its cache. */\nexport async function notifyWebhooksChanged(\n\tdb: Kysely<Database>,\n\taccountId: string,\n): Promise<void> {\n\tawait sql`SELECT pg_notify('webhooks:changed', ${accountId})`.execute(db);\n}\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "8CB695561D569ACB64756E2164756E21",
12
+ "names": []
13
+ }
@@ -788,9 +788,9 @@ interface Database {
788
788
  account_spend_caps: AccountSpendCapsTable;
789
789
  account_credits: AccountCreditsTable;
790
790
  hosted_meter_days: HostedMeterDaysTable;
791
- subscriptions: SubscriptionsTable;
792
- subscription_outbox: SubscriptionOutboxTable;
793
- subscription_deliveries: SubscriptionDeliveriesTable;
791
+ webhooks: WebhooksTable;
792
+ webhook_outbox: WebhookOutboxTable;
793
+ webhook_deliveries: WebhookDeliveriesTable;
794
794
  trigger_evaluator_state: TriggerEvaluatorStateTable;
795
795
  decoded_events: DecodedEventsTable;
796
796
  decoder_checkpoints: DecoderCheckpointsTable;
@@ -963,31 +963,31 @@ type SubgraphHealthSnapshot = Selectable<SubgraphHealthSnapshotsTable>;
963
963
  type InsertSubgraphHealthSnapshot = Insertable<SubgraphHealthSnapshotsTable>;
964
964
  type SubgraphGap = Selectable<SubgraphGapsTable>;
965
965
  type InsertSubgraphGap = Insertable<SubgraphGapsTable>;
966
- type SubscriptionStatus = "active" | "paused" | "error";
967
- /** Polymorphic subscription mode: `subgraph` reacts to processed table rows;
966
+ type WebhookStatus = "active" | "paused" | "error";
967
+ /** Polymorphic webhook mode: `subgraph` reacts to processed table rows;
968
968
  * `chain` reacts to raw chain events matched directly off the Index/Streams
969
969
  * clock (no subgraph). See migration 0088. */
970
- type SubscriptionKind = "subgraph" | "chain";
971
- type SubscriptionFormat = "standard-webhooks" | "inngest" | "trigger" | "cloudflare" | "cloudevents" | "raw";
972
- type SubscriptionRuntime = "inngest" | "trigger" | "cloudflare" | "node";
973
- interface SubscriptionsTable {
970
+ type WebhookKind = "subgraph" | "chain";
971
+ type WebhookFormat = "standard-webhooks" | "inngest" | "trigger" | "cloudflare" | "cloudevents" | "raw";
972
+ type WebhookRuntime = "inngest" | "trigger" | "cloudflare" | "node";
973
+ interface WebhooksTable {
974
974
  id: Generated<string>;
975
975
  account_id: string;
976
976
  project_id: string | null;
977
977
  name: string;
978
- status: ColumnType<SubscriptionStatus, SubscriptionStatus | undefined, SubscriptionStatus>;
979
- kind: ColumnType<SubscriptionKind, SubscriptionKind | undefined, SubscriptionKind>;
980
- /** Null for chain subscriptions (CHECK subscriptions_kind_shape). */
978
+ status: ColumnType<WebhookStatus, WebhookStatus | undefined, WebhookStatus>;
979
+ kind: ColumnType<WebhookKind, WebhookKind | undefined, WebhookKind>;
980
+ /** Null for chain webhooks (CHECK webhooks_kind_shape). */
981
981
  subgraph_name: string | null;
982
- /** Null for chain subscriptions (CHECK subscriptions_kind_shape). */
982
+ /** Null for chain webhooks (CHECK webhooks_kind_shape). */
983
983
  table_name: string | null;
984
984
  /** Chain-trigger filter array (the `SubgraphFilter` shape, JSON). Null for
985
- * subgraph subscriptions. Typed loosely here to avoid a shared→subgraphs
986
- * import cycle; the Zod schema in schemas/subscriptions.ts owns the shape. */
985
+ * subgraph webhooks. Typed loosely here to avoid a shared→subgraphs
986
+ * import cycle; the Zod schema in schemas/webhooks.ts owns the shape. */
987
987
  triggers: unknown | null;
988
988
  filter: Generated<unknown>;
989
- format: ColumnType<SubscriptionFormat, SubscriptionFormat | undefined, SubscriptionFormat>;
990
- runtime: SubscriptionRuntime | null;
989
+ format: ColumnType<WebhookFormat, WebhookFormat | undefined, WebhookFormat>;
990
+ runtime: WebhookRuntime | null;
991
991
  url: string;
992
992
  signing_secret_enc: Buffer;
993
993
  auth_config: Generated<unknown>;
@@ -1002,17 +1002,17 @@ interface SubscriptionsTable {
1002
1002
  created_at: Generated<Date>;
1003
1003
  updated_at: Generated<Date>;
1004
1004
  }
1005
- type Subscription = Selectable<SubscriptionsTable>;
1006
- type InsertSubscription = Insertable<SubscriptionsTable>;
1007
- type UpdateSubscription = Updateable<SubscriptionsTable>;
1005
+ type Webhook = Selectable<WebhooksTable>;
1006
+ type InsertWebhook = Insertable<WebhooksTable>;
1007
+ type UpdateWebhook = Updateable<WebhooksTable>;
1008
1008
  type OutboxStatus = "pending" | "delivered" | "dead";
1009
- interface SubscriptionOutboxTable {
1009
+ interface WebhookOutboxTable {
1010
1010
  id: Generated<string>;
1011
- subscription_id: string;
1012
- kind: ColumnType<SubscriptionKind, SubscriptionKind | undefined, SubscriptionKind>;
1013
- /** Null for chain-subscription rows. */
1011
+ webhook_id: string;
1012
+ kind: ColumnType<WebhookKind, WebhookKind | undefined, WebhookKind>;
1013
+ /** Null for chain-webhook rows. */
1014
1014
  subgraph_name: string | null;
1015
- /** Null for chain-subscription rows. */
1015
+ /** Null for chain-webhook rows. */
1016
1016
  table_name: string | null;
1017
1017
  block_height: number | bigint;
1018
1018
  tx_id: string | null;
@@ -1030,15 +1030,15 @@ interface SubscriptionOutboxTable {
1030
1030
  locked_until: Date | null;
1031
1031
  created_at: Generated<Date>;
1032
1032
  }
1033
- type SubscriptionOutbox = Selectable<SubscriptionOutboxTable>;
1034
- type InsertSubscriptionOutbox = Insertable<SubscriptionOutboxTable>;
1035
- type UpdateSubscriptionOutbox = Updateable<SubscriptionOutboxTable>;
1036
- interface SubscriptionDeliveriesTable {
1033
+ type WebhookOutbox = Selectable<WebhookOutboxTable>;
1034
+ type InsertWebhookOutbox = Insertable<WebhookOutboxTable>;
1035
+ type UpdateWebhookOutbox = Updateable<WebhookOutboxTable>;
1036
+ interface WebhookDeliveriesTable {
1037
1037
  id: Generated<string>;
1038
1038
  /** Nullable after migration 0077 — outbox row may be cleaned up while
1039
1039
  * delivery telemetry is retained. */
1040
1040
  outbox_id: string | null;
1041
- subscription_id: string;
1041
+ webhook_id: string;
1042
1042
  attempt: number;
1043
1043
  status_code: number | null;
1044
1044
  response_headers: unknown | null;
@@ -1047,10 +1047,10 @@ interface SubscriptionDeliveriesTable {
1047
1047
  duration_ms: number | null;
1048
1048
  dispatched_at: Generated<Date>;
1049
1049
  }
1050
- type SubscriptionDelivery = Selectable<SubscriptionDeliveriesTable>;
1051
- type InsertSubscriptionDelivery = Insertable<SubscriptionDeliveriesTable>;
1050
+ type WebhookDelivery = Selectable<WebhookDeliveriesTable>;
1051
+ type InsertWebhookDelivery = Insertable<WebhookDeliveriesTable>;
1052
1052
  /** Single-row (id always TRUE) high-water mark for the chain-trigger evaluator.
1053
- * One loop serves all chain subscriptions, so the cursor is global. */
1053
+ * One loop serves all chain webhooks, so the cursor is global. */
1054
1054
  interface TriggerEvaluatorStateTable {
1055
1055
  id: Generated<boolean>;
1056
1056
  last_processed_block: ColumnType<bigint, bigint | number | undefined, bigint | number>;
@@ -1060,4 +1060,4 @@ interface TriggerEvaluatorStateTable {
1060
1060
  updated_at: Generated<Date>;
1061
1061
  }
1062
1062
  type TriggerEvaluatorState = Selectable<TriggerEvaluatorStateTable>;
1063
- export { X402PaymentsTable, X402BalancesTable, UpdateTransaction, UpdateSubscriptionOutbox, UpdateSubscription, UpdateSubgraphOperation, UpdateSubgraph, UpdateIndexProgress, UpdateHostedMeterDay, UpdateEvent, UpdateContract, UpdateClaimToken, UpdateBlock, UpdateArchiveFetch, UpdateApiKey, UpdateAccountSpendCap, UpdateAccountCredits, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, SyncScopesTable, SubscriptionsTable, SubscriptionStatus, SubscriptionRuntime, SubscriptionOutboxTable, SubscriptionOutbox, SubscriptionKind, SubscriptionFormat, SubscriptionDelivery, SubscriptionDeliveriesTable, Subscription, SubgraphsTable, SubgraphViolationsTable, SubgraphTableSnapshotsTable, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGap, Subgraph, StageRunsTable, StageRegistryTable, StageKind, StageFailuresTable, StageBlockReceiptsTable, SessionsTable, Session, ServiceHeartbeatsTable, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSupplySnapshotsTable, SbtcSettlementsTable, SbtcEventsTable, SbtcEventTopic, RunStatus, RetryState, RepairMode, ProcessedStripeEventsTable, Pox5EventsTable, Pox5EventTopic, Pox4SignersDailyTable, Pox4FunctionName, Pox4CyclesDailyTable, Pox4CallsTable, PlayProvisionsTable, PlayProvision, PendingForkBlocksTable, OutboxStatus, ObserverJournalTable, ObserverJournalStatus, NativeClock, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, InstancesTable, InsertTransaction, InsertSubscriptionOutbox, InsertSubscriptionDelivery, InsertSubscription, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertPlayProvision, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertHostedMeterDay, InsertEvent, InsertContract, InsertClaimToken, InsertBlock, InsertArchiveFetch, InsertApiKey, InsertAccountSpendCap, InsertAccountCredits, InsertAccount, IndexProgressTable, IndexProgress, HostedMeterDaysTable, HostedMeterDay, FailureUnit, FailureClass, EventsTable, EventsArchiveTable, Event, DecoderCheckpointsTable, DecodedEventsTable, DeadLetterEventsTable, Database, CoverageSegmentsTable, ContractsTable, Contract, ClaimTokensTable, ClaimToken, ChainReorgsTable, ChainReadCacheTable, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, ArchiveFetchesTable, ArchiveFetch, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountCreditsTable, AccountCredits, Account };
1063
+ export { X402PaymentsTable, X402BalancesTable, WebhooksTable, WebhookStatus, WebhookRuntime, WebhookOutboxTable, WebhookOutbox, WebhookKind, WebhookFormat, WebhookDelivery, WebhookDeliveriesTable, Webhook, UpdateWebhookOutbox, UpdateWebhook, UpdateTransaction, UpdateSubgraphOperation, UpdateSubgraph, UpdateIndexProgress, UpdateHostedMeterDay, UpdateEvent, UpdateContract, UpdateClaimToken, UpdateBlock, UpdateArchiveFetch, UpdateApiKey, UpdateAccountSpendCap, UpdateAccountCredits, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, SyncScopesTable, SubgraphsTable, SubgraphViolationsTable, SubgraphTableSnapshotsTable, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGap, Subgraph, StageRunsTable, StageRegistryTable, StageKind, StageFailuresTable, StageBlockReceiptsTable, SessionsTable, Session, ServiceHeartbeatsTable, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSupplySnapshotsTable, SbtcSettlementsTable, SbtcEventsTable, SbtcEventTopic, RunStatus, RetryState, RepairMode, ProcessedStripeEventsTable, Pox5EventsTable, Pox5EventTopic, Pox4SignersDailyTable, Pox4FunctionName, Pox4CyclesDailyTable, Pox4CallsTable, PlayProvisionsTable, PlayProvision, PendingForkBlocksTable, OutboxStatus, ObserverJournalTable, ObserverJournalStatus, NativeClock, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, InstancesTable, InsertWebhookOutbox, InsertWebhookDelivery, InsertWebhook, InsertTransaction, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertPlayProvision, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertHostedMeterDay, InsertEvent, InsertContract, InsertClaimToken, InsertBlock, InsertArchiveFetch, InsertApiKey, InsertAccountSpendCap, InsertAccountCredits, InsertAccount, IndexProgressTable, IndexProgress, HostedMeterDaysTable, HostedMeterDay, FailureUnit, FailureClass, EventsTable, EventsArchiveTable, Event, DecoderCheckpointsTable, DecodedEventsTable, DeadLetterEventsTable, Database, CoverageSegmentsTable, ContractsTable, Contract, ClaimTokensTable, ClaimToken, ChainReorgsTable, ChainReadCacheTable, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, ArchiveFetchesTable, ArchiveFetch, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountCreditsTable, AccountCredits, Account };