@secondlayer/shared 13.12.0 → 13.13.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 (43) hide show
  1. package/dist/src/archive/range-digest.d.ts +53 -0
  2. package/dist/src/archive/semantic-digest-builder.d.ts +53 -0
  3. package/dist/src/coverage/index.d.ts +53 -0
  4. package/dist/src/db/index.d.ts +66 -2
  5. package/dist/src/db/index.js +5 -1
  6. package/dist/src/db/index.js.map +3 -3
  7. package/dist/src/db/queries/chain-reorgs.d.ts +53 -0
  8. package/dist/src/db/queries/chain-reorgs.js +5 -1
  9. package/dist/src/db/queries/chain-reorgs.js.map +3 -3
  10. package/dist/src/db/queries/contracts.d.ts +53 -0
  11. package/dist/src/db/queries/instance.d.ts +53 -0
  12. package/dist/src/db/queries/integrity.d.ts +53 -0
  13. package/dist/src/db/queries/subgraph-gaps.d.ts +53 -0
  14. package/dist/src/db/queries/subgraph-operations.d.ts +53 -0
  15. package/dist/src/db/queries/subgraphs.d.ts +53 -0
  16. package/dist/src/db/queries/sync-scope.d.ts +53 -0
  17. package/dist/src/db/queries/webhook-replays.d.ts +1431 -0
  18. package/dist/src/db/queries/webhook-replays.js +156 -0
  19. package/dist/src/db/queries/webhook-replays.js.map +10 -0
  20. package/dist/src/db/queries/webhooks.d.ts +53 -0
  21. package/dist/src/db/schema.d.ts +62 -2
  22. package/dist/src/email/index.d.ts +27 -6
  23. package/dist/src/email/index.js +135 -29
  24. package/dist/src/email/index.js.map +3 -3
  25. package/dist/src/index.d.ts +66 -2
  26. package/dist/src/index.js +9 -1
  27. package/dist/src/index.js.map +4 -4
  28. package/dist/src/insights/index.d.ts +70 -3
  29. package/dist/src/insights/index.js +40 -3
  30. package/dist/src/insights/index.js.map +3 -3
  31. package/dist/src/node/local-client.d.ts +53 -0
  32. package/dist/src/queue/listener.js +5 -1
  33. package/dist/src/queue/listener.js.map +3 -3
  34. package/dist/src/schemas/index.js +5 -1
  35. package/dist/src/schemas/index.js.map +3 -3
  36. package/dist/src/schemas/webhooks.d.ts +45 -1
  37. package/dist/src/schemas/webhooks.js +6 -1
  38. package/dist/src/schemas/webhooks.js.map +3 -3
  39. package/migrations/0178_insight_snooze.ts +22 -0
  40. package/migrations/0179_webhook_replays.ts +56 -0
  41. package/migrations/0180_push.ts +54 -0
  42. package/migrations/0181_push_sent.ts +30 -0
  43. package/package.json +5 -1
@@ -1,60 +1,166 @@
1
1
  // src/email/render.ts
2
+ var LOGO_URL = "https://www.secondlayer.tools/email/logo.png";
3
+ var TAGLINE = "Instant data for apps on Bitcoin";
4
+ var SANS = "Geist, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
5
+ var MONO = "'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
6
+ var LIGHT = {
7
+ paper: "#fbfaf7",
8
+ ink: "#14110d",
9
+ sub: "#63605c",
10
+ faint: "#9d9b97",
11
+ line: "#e8e6e3",
12
+ pri: "#1f45e0",
13
+ onPri: "#fbfaf7",
14
+ ok: "#128a43",
15
+ alarm: "#e3301e"
16
+ };
17
+ var DARK_STYLE = `
18
+ @media (prefers-color-scheme: dark) {
19
+ .sl-paper { background: #1e1b17 !important; }
20
+ .sl-ink { color: #e8e6e3 !important; }
21
+ .sl-sub { color: #b3b1ad !important; }
22
+ .sl-faint { color: #7c7a76 !important; }
23
+ .sl-line { border-color: #393632 !important; }
24
+ .sl-pri { background: #3a5bff !important; }
25
+ .sl-ok { color: #5cc28f !important; }
26
+ .sl-alarm { color: #ff5a47 !important; }
27
+ .sl-dot-neutral { background: #7c7a76 !important; }
28
+ .sl-dot-ok { background: #5cc28f !important; }
29
+ .sl-dot-alarm { background: #ff5a47 !important; }
30
+ }`.trim();
2
31
  function escapeHtml(value) {
3
32
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
4
33
  }
34
+ var TONE_COLOR = {
35
+ neutral: LIGHT.sub,
36
+ ok: LIGHT.ok,
37
+ alarm: LIGHT.alarm
38
+ };
39
+ var DOT_COLOR = {
40
+ neutral: LIGHT.faint,
41
+ ok: LIGHT.ok,
42
+ alarm: LIGHT.alarm
43
+ };
44
+ var TONE_CLASS = {
45
+ neutral: "sl-sub",
46
+ ok: "sl-ok",
47
+ alarm: "sl-alarm"
48
+ };
49
+ function dot(tone) {
50
+ return `<span class="sl-dot-${tone}" style="display: inline-block; width: 7px; height: 7px; border-radius: 999px; background: ${DOT_COLOR[tone]}; margin-right: 6px; vertical-align: 1px;"></span>`;
51
+ }
52
+ function statusChip(status) {
53
+ return `<span class="sl-line ${TONE_CLASS[status.tone]}" style="display: inline-block; border: 1px solid ${LIGHT.line}; border-radius: 999px; padding: 2px 8px; font-family: ${MONO}; font-size: 12px; line-height: 16px; color: ${TONE_COLOR[status.tone]}; white-space: nowrap;">${dot(status.tone)}${escapeHtml(status.text)}</span>`;
54
+ }
55
+ function preheaderHtml(preheader) {
56
+ if (!preheader)
57
+ return "";
58
+ const filler = "&#847;&zwnj;&nbsp;".repeat(60);
59
+ return `<div style="display: none; max-height: 0; overflow: hidden; mso-hide: all; opacity: 0; color: transparent;">${escapeHtml(preheader)}${filler}</div>`;
60
+ }
61
+ function figureHtml(input) {
62
+ if (!input.code && !input.facts?.length)
63
+ return "";
64
+ const title = input.figure ?? (input.code ? "sign-in code" : "details");
65
+ const line = `border-color: ${LIGHT.line}; border-style: solid; border-width: 0`;
66
+ const bar = `<tr>
67
+ <td class="sl-faint sl-line" style="padding: 8px 14px; ${line}; border-bottom-width: 1px; font-family: ${MONO}; font-size: 12px; line-height: 18px; color: ${LIGHT.faint};">${escapeHtml(title)}</td>
68
+ <td class="sl-line" align="right" style="padding: 8px 14px; ${line}; border-bottom-width: 1px;">${input.status ? statusChip(input.status) : ""}</td>
69
+ </tr>`;
70
+ let body;
71
+ if (input.code) {
72
+ body = `<tr><td colspan="2" align="center" class="sl-ink" style="padding: 24px 14px 8px; font-family: ${MONO}; font-size: 36px; line-height: 40px; font-weight: 500; letter-spacing: 0.3em; color: ${LIGHT.ink}; -webkit-user-select: all; user-select: all;">${escapeHtml(input.code)}</td></tr>
73
+ <tr><td colspan="2" align="center" class="sl-faint" style="padding: 0 14px 16px; font-family: ${MONO}; font-size: 12px; line-height: 18px; color: ${LIGHT.faint};">tap or double-click to select</td></tr>`;
74
+ } else {
75
+ const facts = input.facts ?? [];
76
+ body = facts.map((fact, i) => {
77
+ const top = i === 0 ? 12 : 2;
78
+ const bottom = i === facts.length - 1 ? 12 : 2;
79
+ const cell = `padding: ${top}px 14px ${bottom}px; font-family: ${MONO}; font-size: 13px; line-height: 20px; vertical-align: top;`;
80
+ return `<tr>
81
+ <td class="sl-faint" style="${cell} padding-right: 24px; width: 1%; color: ${LIGHT.faint}; white-space: nowrap;">${escapeHtml(fact.label.toLowerCase())}</td>
82
+ <td class="sl-ink" style="${cell} color: ${LIGHT.ink}; word-break: break-word;">${escapeHtml(fact.value)}</td>
83
+ </tr>`;
84
+ }).join(`
85
+ `);
86
+ }
87
+ return `<table role="presentation" cellpadding="0" cellspacing="0" class="sl-line" style="width: 100%; border: 1px solid ${LIGHT.line}; border-radius: 8px; border-collapse: separate; border-spacing: 0; margin: 8px 0 24px;">
88
+ ${bar}
89
+ ${body}
90
+ </table>`;
91
+ }
5
92
  function renderHtml(input) {
6
- const paragraphsHtml = input.paragraphs.map((p) => `<p style="color: #555; font-size: 14px; line-height: 1.6; margin: 0 0 16px;">${escapeHtml(p)}</p>`).join(`
7
- `);
8
- const codeHtml = input.code ? `<div style="background: #f5f5f5; border: 1px solid #e5e5e5; border-radius: 8px; padding: 20px; text-align: center; margin: 0 0 24px;">
9
- <span style="font-size: 32px; font-weight: 600; letter-spacing: 8px; color: #111;">${escapeHtml(input.code)}</span>
10
- </div>` : "";
11
- const factsHtml = input.facts?.length ? `<table role="presentation" cellpadding="0" cellspacing="0" style="width: 100%; margin: 0 0 24px; border-collapse: collapse;">
12
- ${input.facts.map((fact) => `<tr><td style="padding: 6px 0; color: #888; font-size: 13px;">${escapeHtml(fact.label)}</td><td style="padding: 6px 0; color: #111; font-size: 13px; text-align: right; font-weight: 600;">${escapeHtml(fact.value)}</td></tr>`).join(`
13
- `)}
14
- </table>` : "";
15
- const ctaHtml = input.cta ? `<a href="${escapeHtml(input.cta.url)}" style="display: inline-block; background: #111; color: #fff; text-decoration: none; padding: 10px 20px; border-radius: 6px; font-size: 14px; margin: 0 0 24px;">${escapeHtml(input.cta.label)}</a>` : "";
16
- const footnoteHtml = input.footnote ? `<p style="color: #aaa; font-size: 12px; margin: 24px 0 0;">${escapeHtml(input.footnote)}</p>` : "";
17
- return `
18
- <table role="presentation" cellpadding="0" cellspacing="0" style="width: 100%; background: #fff;">
93
+ const hasFigure = Boolean(input.code || input.facts?.length);
94
+ const statusLine = input.status && !hasFigure ? `<p class="${TONE_CLASS[input.status.tone]}" style="margin: 0 0 12px; font-size: 13px; line-height: 20px; color: ${TONE_COLOR[input.status.tone]};">${dot(input.status.tone)}${escapeHtml(input.status.text)}</p>` : "";
95
+ const paragraphsHtml = input.paragraphs.map((p) => `<p class="sl-sub" style="margin: 0 0 14px; font-size: 15px; line-height: 24px; color: ${LIGHT.sub};">${escapeHtml(p)}</p>`).join(`
96
+ `);
97
+ const quoteHtml = input.quote ? `<p class="sl-ink" style="margin: 0 0 14px; font-size: 15px; line-height: 24px; color: ${LIGHT.ink};">&ldquo;${escapeHtml(input.quote)}&rdquo;</p>` : "";
98
+ const ctaHtml = input.cta ? `<table role="presentation" cellpadding="0" cellspacing="0" style="margin: 10px 0 0;"><tr><td class="sl-pri" style="background: ${LIGHT.pri}; border-radius: 4px;"><a href="${escapeHtml(input.cta.url)}" style="display: inline-block; padding: 0 18px; height: 42px; line-height: 42px; font-family: ${SANS}; font-size: 15px; font-weight: 500; color: ${LIGHT.onPri}; text-decoration: none;">${escapeHtml(input.cta.label)}</a></td></tr></table>` : "";
99
+ const footnoteHtml = input.footnote ? `<p class="sl-faint" style="margin: 0 0 6px;">${escapeHtml(input.footnote)}</p>` : "";
100
+ return `<!doctype html>
101
+ <html lang="en">
102
+ <head>
103
+ <meta charset="utf-8">
104
+ <meta name="viewport" content="width=device-width, initial-scale=1">
105
+ <meta name="color-scheme" content="light dark">
106
+ <meta name="supported-color-schemes" content="light dark">
107
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500&family=Geist+Mono:wght@400;500&display=swap">
108
+ <style>
109
+ ${DARK_STYLE}
110
+ </style>
111
+ </head>
112
+ <body class="sl-paper" style="margin: 0; padding: 0; background: ${LIGHT.paper};">
113
+ ${preheaderHtml(input.preheader)}
114
+ <table role="presentation" cellpadding="0" cellspacing="0" class="sl-paper" style="width: 100%; background: ${LIGHT.paper};">
19
115
  <tr>
20
116
  <td align="center">
21
- <table role="presentation" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 560px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; padding: 40px 20px;">
117
+ <table role="presentation" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 560px; font-family: ${SANS}; padding: 40px 20px;">
22
118
  <tr>
23
119
  <td>
24
- <p style="color: #888; font-size: 14px; margin: 0 0 24px;">secondlayer</p>
25
- <p style="color: #111; font-size: 18px; font-weight: 600; margin: 0 0 16px;">${escapeHtml(input.heading)}</p>
120
+ <table role="presentation" cellpadding="0" cellspacing="0" style="margin: 0 0 32px;"><tr>
121
+ <td style="padding-right: 8px; vertical-align: middle;"><img src="${LOGO_URL}" width="30" height="20" alt="" style="display: block; border: 0;"></td>
122
+ <td class="sl-ink" style="vertical-align: middle; font-size: 15px; font-weight: 500; letter-spacing: -0.01em; color: ${LIGHT.ink};">secondlayer</td>
123
+ </tr></table>
124
+ ${statusLine}
125
+ <h1 class="sl-ink" style="margin: 0 0 14px; font-size: 24px; line-height: 29px; font-weight: 500; letter-spacing: -0.025em; color: ${LIGHT.ink};">${escapeHtml(input.heading)}</h1>
26
126
  ${paragraphsHtml}
27
- ${codeHtml}
28
- ${factsHtml}
127
+ ${quoteHtml}
128
+ ${figureHtml(input)}
29
129
  ${ctaHtml}
30
- ${footnoteHtml}
130
+ <div class="sl-line sl-faint" style="margin: 32px 0 0; padding: 16px 0 0; border-top: 1px solid ${LIGHT.line}; font-size: 12px; line-height: 18px; color: ${LIGHT.faint};">
131
+ ${footnoteHtml}
132
+ <p class="sl-faint" style="margin: 0;"><span class="sl-sub" style="color: ${LIGHT.sub}; font-weight: 500;">Secondlayer</span> &middot; ${TAGLINE}</p>
133
+ </div>
31
134
  </td>
32
135
  </tr>
33
136
  </table>
34
137
  </td>
35
138
  </tr>
36
- </table>`.trim();
139
+ </table>
140
+ </body>
141
+ </html>`;
37
142
  }
38
143
  function renderText(input) {
39
144
  const lines = [input.heading, ""];
40
145
  for (const p of input.paragraphs)
41
146
  lines.push(p, "");
42
- if (input.code) {
147
+ if (input.quote)
148
+ lines.push(`"${input.quote}"`, "");
149
+ if (input.status)
150
+ lines.push(input.status.text, "");
151
+ if (input.code)
43
152
  lines.push(`Code: ${input.code}`, "");
44
- }
45
153
  if (input.facts?.length) {
46
154
  for (const fact of input.facts)
47
155
  lines.push(`${fact.label}: ${fact.value}`);
48
156
  lines.push("");
49
157
  }
50
- if (input.cta) {
158
+ if (input.cta)
51
159
  lines.push(`${input.cta.label}: ${input.cta.url}`, "");
52
- }
53
- if (input.footnote) {
160
+ lines.push("--");
161
+ if (input.footnote)
54
162
  lines.push(input.footnote);
55
- }
56
- while (lines.length && lines[lines.length - 1] === "")
57
- lines.pop();
163
+ lines.push(`Secondlayer · ${TAGLINE}`);
58
164
  return lines.join(`
59
165
  `);
60
166
  }
@@ -227,5 +333,5 @@ export {
227
333
  sendEmail
228
334
  };
229
335
 
230
- //# debugId=33BAE8397C503C5864756E2164756E21
336
+ //# debugId=36F0F48E4EBB77FF64756E2164756E21
231
337
  //# sourceMappingURL=index.js.map
@@ -2,12 +2,12 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/email/render.ts", "../src/env.ts", "../src/logger.ts", "../src/email/send.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * The one HTML/text layout every customer email renders through. Table-based\n * HTML, inline styles only (email clients strip <style>), 560px max width,\n * white background, #111 text, one black button — same look as the login\n * email this was lifted from. Text is the same content, plainer.\n */\n\nexport interface FactRow {\n\tlabel: string;\n\tvalue: string;\n}\n\nexport interface EmailCta {\n\tlabel: string;\n\turl: string;\n}\n\nexport interface RenderEmailInput {\n\theading: string;\n\tparagraphs: string[];\n\t/** A code shown in a large, letter-spaced box (login codes). */\n\tcode?: string;\n\tfacts?: FactRow[];\n\tcta?: EmailCta;\n\tfootnote?: string;\n}\n\nexport interface RenderedEmail {\n\thtml: string;\n\ttext: string;\n}\n\nfunction escapeHtml(value: string): string {\n\treturn value\n\t\t.replace(/&/g, \"&amp;\")\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t.replace(/\"/g, \"&quot;\")\n\t\t.replace(/'/g, \"&#39;\");\n}\n\nfunction renderHtml(input: RenderEmailInput): string {\n\tconst paragraphsHtml = input.paragraphs\n\t\t.map(\n\t\t\t(p) =>\n\t\t\t\t`<p style=\"color: #555; font-size: 14px; line-height: 1.6; margin: 0 0 16px;\">${escapeHtml(p)}</p>`,\n\t\t)\n\t\t.join(\"\\n \");\n\n\tconst codeHtml = input.code\n\t\t? `<div style=\"background: #f5f5f5; border: 1px solid #e5e5e5; border-radius: 8px; padding: 20px; text-align: center; margin: 0 0 24px;\">\n <span style=\"font-size: 32px; font-weight: 600; letter-spacing: 8px; color: #111;\">${escapeHtml(input.code)}</span>\n </div>`\n\t\t: \"\";\n\n\tconst factsHtml = input.facts?.length\n\t\t? `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 100%; margin: 0 0 24px; border-collapse: collapse;\">\n ${input.facts\n\t\t\t.map(\n\t\t\t\t(fact) =>\n\t\t\t\t\t`<tr><td style=\"padding: 6px 0; color: #888; font-size: 13px;\">${escapeHtml(fact.label)}</td><td style=\"padding: 6px 0; color: #111; font-size: 13px; text-align: right; font-weight: 600;\">${escapeHtml(fact.value)}</td></tr>`,\n\t\t\t)\n\t\t\t.join(\"\\n \")}\n </table>`\n\t\t: \"\";\n\n\tconst ctaHtml = input.cta\n\t\t? `<a href=\"${escapeHtml(input.cta.url)}\" style=\"display: inline-block; background: #111; color: #fff; text-decoration: none; padding: 10px 20px; border-radius: 6px; font-size: 14px; margin: 0 0 24px;\">${escapeHtml(input.cta.label)}</a>`\n\t\t: \"\";\n\n\tconst footnoteHtml = input.footnote\n\t\t? `<p style=\"color: #aaa; font-size: 12px; margin: 24px 0 0;\">${escapeHtml(input.footnote)}</p>`\n\t\t: \"\";\n\n\treturn `\n<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 100%; background: #fff;\">\n <tr>\n <td align=\"center\">\n <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 100%; max-width: 560px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; padding: 40px 20px;\">\n <tr>\n <td>\n <p style=\"color: #888; font-size: 14px; margin: 0 0 24px;\">secondlayer</p>\n <p style=\"color: #111; font-size: 18px; font-weight: 600; margin: 0 0 16px;\">${escapeHtml(input.heading)}</p>\n ${paragraphsHtml}\n ${codeHtml}\n ${factsHtml}\n ${ctaHtml}\n ${footnoteHtml}\n </td>\n </tr>\n </table>\n </td>\n </tr>\n</table>`.trim();\n}\n\nfunction renderText(input: RenderEmailInput): string {\n\tconst lines: string[] = [input.heading, \"\"];\n\tfor (const p of input.paragraphs) lines.push(p, \"\");\n\tif (input.code) {\n\t\tlines.push(`Code: ${input.code}`, \"\");\n\t}\n\tif (input.facts?.length) {\n\t\tfor (const fact of input.facts) lines.push(`${fact.label}: ${fact.value}`);\n\t\tlines.push(\"\");\n\t}\n\tif (input.cta) {\n\t\tlines.push(`${input.cta.label}: ${input.cta.url}`, \"\");\n\t}\n\tif (input.footnote) {\n\t\tlines.push(input.footnote);\n\t}\n\t// Trim trailing blank lines.\n\twhile (lines.length && lines[lines.length - 1] === \"\") lines.pop();\n\treturn lines.join(\"\\n\");\n}\n\nexport function renderEmail(input: RenderEmailInput): RenderedEmail {\n\treturn { html: renderHtml(input), text: renderText(input) };\n}\n",
5
+ "/**\n * The one HTML/text layout every customer email renders through, in the\n * brand's \"Figure\" look: logo + wordmark, a 24px heading, muted prose, the\n * code or facts inside a hairline code figure whose bar names it and carries\n * a status chip, one blue button, and a hairline footer.\n *\n * Table-based HTML with inline styles (most clients strip <style>). The head\n * <style> only adds dark mode for clients that honor `prefers-color-scheme`\n * (Apple Mail, iOS); everyone else gets the light palette, which Gmail\n * inverts on its own. Geist loads where web fonts work, the system stack\n * elsewhere. Callers pass content; every color lives here.\n */\n\nexport interface FactRow {\n\tlabel: string;\n\tvalue: string;\n}\n\nexport interface EmailCta {\n\tlabel: string;\n\turl: string;\n}\n\n/** `alarm` only for failures and stops, `ok` only for success. */\nexport type EmailTone = \"neutral\" | \"ok\" | \"alarm\";\n\nexport interface EmailStatus {\n\ttone: EmailTone;\n\ttext: string;\n}\n\nexport interface RenderEmailInput {\n\theading: string;\n\t/** The inbox preview line after the subject. Not shown in the body. */\n\tpreheader?: string;\n\tparagraphs: string[];\n\t/** Someone else's words, quoted (a contact form message). */\n\tquote?: string;\n\t/** A sign-in code, shown as one selectable run of digits in the figure. */\n\tcode?: string;\n\tfacts?: FactRow[];\n\t/** The figure's title bar. Defaults to \"sign-in code\" or \"details\". */\n\tfigure?: string;\n\t/** A chip in the figure bar, or a status line when there is no figure. */\n\tstatus?: EmailStatus;\n\tcta?: EmailCta;\n\t/** Why the reader got this email and how to stop it. */\n\tfootnote?: string;\n}\n\nexport interface RenderedEmail {\n\thtml: string;\n\ttext: string;\n}\n\n// www directly: the apex 307s there, and every image fetch would pay for it.\nconst LOGO_URL = \"https://www.secondlayer.tools/email/logo.png\";\nconst TAGLINE = \"Instant data for apps on Bitcoin\";\n\nconst SANS =\n\t\"Geist, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\";\nconst MONO =\n\t\"'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\";\n\n// DESIGN.md roles. Light inline; dark via the head <style> classes below.\nconst LIGHT = {\n\tpaper: \"#fbfaf7\",\n\tink: \"#14110d\",\n\tsub: \"#63605c\",\n\tfaint: \"#9d9b97\",\n\tline: \"#e8e6e3\",\n\tpri: \"#1f45e0\",\n\tonPri: \"#fbfaf7\",\n\tok: \"#128a43\",\n\talarm: \"#e3301e\",\n};\n\nconst DARK_STYLE = `\n@media (prefers-color-scheme: dark) {\n .sl-paper { background: #1e1b17 !important; }\n .sl-ink { color: #e8e6e3 !important; }\n .sl-sub { color: #b3b1ad !important; }\n .sl-faint { color: #7c7a76 !important; }\n .sl-line { border-color: #393632 !important; }\n .sl-pri { background: #3a5bff !important; }\n .sl-ok { color: #5cc28f !important; }\n .sl-alarm { color: #ff5a47 !important; }\n .sl-dot-neutral { background: #7c7a76 !important; }\n .sl-dot-ok { background: #5cc28f !important; }\n .sl-dot-alarm { background: #ff5a47 !important; }\n}`.trim();\n\nfunction escapeHtml(value: string): string {\n\treturn value\n\t\t.replace(/&/g, \"&amp;\")\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t.replace(/\"/g, \"&quot;\")\n\t\t.replace(/'/g, \"&#39;\");\n}\n\nconst TONE_COLOR: Record<EmailTone, string> = {\n\tneutral: LIGHT.sub,\n\tok: LIGHT.ok,\n\talarm: LIGHT.alarm,\n};\nconst DOT_COLOR: Record<EmailTone, string> = {\n\tneutral: LIGHT.faint,\n\tok: LIGHT.ok,\n\talarm: LIGHT.alarm,\n};\nconst TONE_CLASS: Record<EmailTone, string> = {\n\tneutral: \"sl-sub\",\n\tok: \"sl-ok\",\n\talarm: \"sl-alarm\",\n};\n\nfunction dot(tone: EmailTone): string {\n\treturn `<span class=\"sl-dot-${tone}\" style=\"display: inline-block; width: 7px; height: 7px; border-radius: 999px; background: ${DOT_COLOR[tone]}; margin-right: 6px; vertical-align: 1px;\"></span>`;\n}\n\nfunction statusChip(status: EmailStatus): string {\n\treturn `<span class=\"sl-line ${TONE_CLASS[status.tone]}\" style=\"display: inline-block; border: 1px solid ${LIGHT.line}; border-radius: 999px; padding: 2px 8px; font-family: ${MONO}; font-size: 12px; line-height: 16px; color: ${TONE_COLOR[status.tone]}; white-space: nowrap;\">${dot(status.tone)}${escapeHtml(status.text)}</span>`;\n}\n\nfunction preheaderHtml(preheader: string | undefined): string {\n\tif (!preheader) return \"\";\n\t// Trailing joiners keep body text from leaking into the preview line.\n\tconst filler = \"&#847;&zwnj;&nbsp;\".repeat(60);\n\treturn `<div style=\"display: none; max-height: 0; overflow: hidden; mso-hide: all; opacity: 0; color: transparent;\">${escapeHtml(preheader)}${filler}</div>`;\n}\n\nfunction figureHtml(input: RenderEmailInput): string {\n\tif (!input.code && !input.facts?.length) return \"\";\n\tconst title = input.figure ?? (input.code ? \"sign-in code\" : \"details\");\n\tconst line = `border-color: ${LIGHT.line}; border-style: solid; border-width: 0`;\n\n\tconst bar = `<tr>\n <td class=\"sl-faint sl-line\" style=\"padding: 8px 14px; ${line}; border-bottom-width: 1px; font-family: ${MONO}; font-size: 12px; line-height: 18px; color: ${LIGHT.faint};\">${escapeHtml(title)}</td>\n <td class=\"sl-line\" align=\"right\" style=\"padding: 8px 14px; ${line}; border-bottom-width: 1px;\">${input.status ? statusChip(input.status) : \"\"}</td>\n </tr>`;\n\n\tlet body: string;\n\tif (input.code) {\n\t\tbody = `<tr><td colspan=\"2\" align=\"center\" class=\"sl-ink\" style=\"padding: 24px 14px 8px; font-family: ${MONO}; font-size: 36px; line-height: 40px; font-weight: 500; letter-spacing: 0.3em; color: ${LIGHT.ink}; -webkit-user-select: all; user-select: all;\">${escapeHtml(input.code)}</td></tr>\n <tr><td colspan=\"2\" align=\"center\" class=\"sl-faint\" style=\"padding: 0 14px 16px; font-family: ${MONO}; font-size: 12px; line-height: 18px; color: ${LIGHT.faint};\">tap or double-click to select</td></tr>`;\n\t} else {\n\t\tconst facts = input.facts ?? [];\n\t\tbody = facts\n\t\t\t.map((fact, i) => {\n\t\t\t\tconst top = i === 0 ? 12 : 2;\n\t\t\t\tconst bottom = i === facts.length - 1 ? 12 : 2;\n\t\t\t\tconst cell = `padding: ${top}px 14px ${bottom}px; font-family: ${MONO}; font-size: 13px; line-height: 20px; vertical-align: top;`;\n\t\t\t\treturn `<tr>\n <td class=\"sl-faint\" style=\"${cell} padding-right: 24px; width: 1%; color: ${LIGHT.faint}; white-space: nowrap;\">${escapeHtml(fact.label.toLowerCase())}</td>\n <td class=\"sl-ink\" style=\"${cell} color: ${LIGHT.ink}; word-break: break-word;\">${escapeHtml(fact.value)}</td>\n </tr>`;\n\t\t\t})\n\t\t\t.join(\"\\n \");\n\t}\n\n\treturn `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" class=\"sl-line\" style=\"width: 100%; border: 1px solid ${LIGHT.line}; border-radius: 8px; border-collapse: separate; border-spacing: 0; margin: 8px 0 24px;\">\n ${bar}\n ${body}\n </table>`;\n}\n\nfunction renderHtml(input: RenderEmailInput): string {\n\tconst hasFigure = Boolean(input.code || input.facts?.length);\n\n\tconst statusLine =\n\t\tinput.status && !hasFigure\n\t\t\t? `<p class=\"${TONE_CLASS[input.status.tone]}\" style=\"margin: 0 0 12px; font-size: 13px; line-height: 20px; color: ${TONE_COLOR[input.status.tone]};\">${dot(input.status.tone)}${escapeHtml(input.status.text)}</p>`\n\t\t\t: \"\";\n\n\tconst paragraphsHtml = input.paragraphs\n\t\t.map(\n\t\t\t(p) =>\n\t\t\t\t`<p class=\"sl-sub\" style=\"margin: 0 0 14px; font-size: 15px; line-height: 24px; color: ${LIGHT.sub};\">${escapeHtml(p)}</p>`,\n\t\t)\n\t\t.join(\"\\n \");\n\n\tconst quoteHtml = input.quote\n\t\t? `<p class=\"sl-ink\" style=\"margin: 0 0 14px; font-size: 15px; line-height: 24px; color: ${LIGHT.ink};\">&ldquo;${escapeHtml(input.quote)}&rdquo;</p>`\n\t\t: \"\";\n\n\tconst ctaHtml = input.cta\n\t\t? `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin: 10px 0 0;\"><tr><td class=\"sl-pri\" style=\"background: ${LIGHT.pri}; border-radius: 4px;\"><a href=\"${escapeHtml(input.cta.url)}\" style=\"display: inline-block; padding: 0 18px; height: 42px; line-height: 42px; font-family: ${SANS}; font-size: 15px; font-weight: 500; color: ${LIGHT.onPri}; text-decoration: none;\">${escapeHtml(input.cta.label)}</a></td></tr></table>`\n\t\t: \"\";\n\n\tconst footnoteHtml = input.footnote\n\t\t? `<p class=\"sl-faint\" style=\"margin: 0 0 6px;\">${escapeHtml(input.footnote)}</p>`\n\t\t: \"\";\n\n\treturn `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<meta name=\"supported-color-schemes\" content=\"light dark\">\n<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Geist:wght@400;500&family=Geist+Mono:wght@400;500&display=swap\">\n<style>\n${DARK_STYLE}\n</style>\n</head>\n<body class=\"sl-paper\" style=\"margin: 0; padding: 0; background: ${LIGHT.paper};\">\n${preheaderHtml(input.preheader)}\n<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" class=\"sl-paper\" style=\"width: 100%; background: ${LIGHT.paper};\">\n <tr>\n <td align=\"center\">\n <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 100%; max-width: 560px; font-family: ${SANS}; padding: 40px 20px;\">\n <tr>\n <td>\n <table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin: 0 0 32px;\"><tr>\n <td style=\"padding-right: 8px; vertical-align: middle;\"><img src=\"${LOGO_URL}\" width=\"30\" height=\"20\" alt=\"\" style=\"display: block; border: 0;\"></td>\n <td class=\"sl-ink\" style=\"vertical-align: middle; font-size: 15px; font-weight: 500; letter-spacing: -0.01em; color: ${LIGHT.ink};\">secondlayer</td>\n </tr></table>\n ${statusLine}\n <h1 class=\"sl-ink\" style=\"margin: 0 0 14px; font-size: 24px; line-height: 29px; font-weight: 500; letter-spacing: -0.025em; color: ${LIGHT.ink};\">${escapeHtml(input.heading)}</h1>\n ${paragraphsHtml}\n ${quoteHtml}\n ${figureHtml(input)}\n ${ctaHtml}\n <div class=\"sl-line sl-faint\" style=\"margin: 32px 0 0; padding: 16px 0 0; border-top: 1px solid ${LIGHT.line}; font-size: 12px; line-height: 18px; color: ${LIGHT.faint};\">\n ${footnoteHtml}\n <p class=\"sl-faint\" style=\"margin: 0;\"><span class=\"sl-sub\" style=\"color: ${LIGHT.sub}; font-weight: 500;\">Secondlayer</span> &middot; ${TAGLINE}</p>\n </div>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n</table>\n</body>\n</html>`;\n}\n\nfunction renderText(input: RenderEmailInput): string {\n\tconst lines: string[] = [input.heading, \"\"];\n\tfor (const p of input.paragraphs) lines.push(p, \"\");\n\tif (input.quote) lines.push(`\"${input.quote}\"`, \"\");\n\tif (input.status) lines.push(input.status.text, \"\");\n\tif (input.code) lines.push(`Code: ${input.code}`, \"\");\n\tif (input.facts?.length) {\n\t\tfor (const fact of input.facts) lines.push(`${fact.label}: ${fact.value}`);\n\t\tlines.push(\"\");\n\t}\n\tif (input.cta) lines.push(`${input.cta.label}: ${input.cta.url}`, \"\");\n\tlines.push(\"--\");\n\tif (input.footnote) lines.push(input.footnote);\n\tlines.push(`Secondlayer · ${TAGLINE}`);\n\treturn lines.join(\"\\n\");\n}\n\nexport function renderEmail(input: RenderEmailInput): RenderedEmail {\n\treturn { html: renderHtml(input), text: renderText(input) };\n}\n",
6
6
  "import { z } from \"zod\";\n\n// Parse comma-separated networks\nconst networksSchema = z.string().transform((val) => {\n\tconst networks = val\n\t\t.split(\",\")\n\t\t.map((n) => n.trim())\n\t\t.filter(Boolean);\n\tconst valid = [\"mainnet\", \"testnet\"];\n\tfor (const n of networks) {\n\t\tif (!valid.includes(n)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid network: ${n}. Must be one of: ${valid.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn networks as (\"mainnet\" | \"testnet\")[];\n});\n\ninterface EnvSchemaOutput {\n\tDATABASE_URL?: string;\n\t/**\n\t * Shared indexer DB (blocks/txs/events). Falls back to DATABASE_URL.\n\t * Set this alongside TARGET_DATABASE_URL to enable dual-DB mode.\n\t */\n\tSOURCE_DATABASE_URL?: string;\n\t/**\n\t * Tenant DB (subgraph schemas + subgraphs table). Falls back to DATABASE_URL.\n\t * Set this alongside SOURCE_DATABASE_URL to enable dual-DB mode.\n\t */\n\tTARGET_DATABASE_URL?: string;\n\tNETWORK?: \"mainnet\" | \"testnet\";\n\tNETWORKS?: (\"mainnet\" | \"testnet\")[];\n\tLOG_LEVEL: \"debug\" | \"info\" | \"warn\" | \"error\";\n\tNODE_ENV: \"development\" | \"production\" | \"test\";\n}\n\n// Cast needed: z.preprocess / z.default create different _input vs _output types\n// that z.ZodType<T> can't represent without explicit input type param\nconst envSchema: z.ZodType<EnvSchemaOutput> = z.object({\n\tDATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tSOURCE_DATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tTARGET_DATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tNETWORK: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\tNETWORKS: networksSchema.optional(),\n\tLOG_LEVEL: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n\tNODE_ENV: z\n\t\t.enum([\"development\", \"production\", \"test\"])\n\t\t.default(\"development\"),\n}) as unknown as z.ZodType<EnvSchemaOutput>;\n\nexport type Env = EnvSchemaOutput & {\n\tenabledNetworks: (\"mainnet\" | \"testnet\")[];\n};\n\nlet cachedEnv: Env | null = null;\n\nexport function getEnv(): Env {\n\tif (cachedEnv) {\n\t\treturn cachedEnv;\n\t}\n\n\tconst result = envSchema.safeParse(process.env);\n\n\tif (!result.success) {\n\t\tconsole.error(\"❌ Invalid environment configuration:\");\n\t\tconsole.error(z.treeifyError(result.error));\n\t\tthrow new Error(\"Invalid environment configuration\");\n\t}\n\n\t// Compute enabled networks from NETWORKS or NETWORK\n\tlet enabledNetworks: (\"mainnet\" | \"testnet\")[];\n\tif (result.data.NETWORKS && result.data.NETWORKS.length > 0) {\n\t\tenabledNetworks = result.data.NETWORKS;\n\t} else if (result.data.NETWORK) {\n\t\tenabledNetworks = [result.data.NETWORK];\n\t} else {\n\t\tenabledNetworks = [\"mainnet\"]; // Default\n\t}\n\n\tcachedEnv = { ...result.data, enabledNetworks };\n\treturn cachedEnv;\n}\n\n/**\n * True when `NODE_ENV=production`, read at RUNTIME — the single source of truth\n * for prod-vs-dev branching in this package.\n *\n * Why a helper instead of inlining `process.env.NODE_ENV === \"production\"`:\n * bunup/esbuild constant-folds the dot-access `process.env.NODE_ENV` to its\n * BUILD-time value. `@secondlayer/shared` is consumed by other services as its\n * built `dist`, so an inlined check freezes to a literal in the shipped bundle\n * (e.g. `const isProd = false`) and silently ignores the container's real\n * NODE_ENV. The bracket access below is NOT folded, so it stays a runtime read.\n * Route every prod check through here so the footgun lives in exactly one place.\n */\nexport function isProductionEnv(): boolean {\n\t// biome-ignore lint/complexity/useLiteralKeys: bracket access is deliberate — dot-access gets constant-folded by the bundler, freezing this to a build-time literal in the shipped dist.\n\treturn process.env[\"NODE_ENV\"] === \"production\";\n}\n\ntype EnvMap = NodeJS.ProcessEnv;\n\n/**\n * PoX-4 stacking decoder is ON by default — `/v1/index/stacking` is part of the\n * public surface, so the decoder that fills `pox4_calls` runs unless explicitly\n * opted out with `POX4_DECODER_ENABLED=false` (mirrors the sBTC decoder policy).\n */\nexport function isPox4DecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.POX4_DECODER_ENABLED !== \"false\";\n}\n\n/**\n * PoX-5 print-event decoder is ON by default (mirrors pox-4/sBTC policy).\n * No activation gating needed: pox-5 events cannot exist before the Epoch 4.0\n * hard fork (Bitcoin block 960,230), so pre-activation the decoder idles at\n * tip. Opt out with `POX5_DECODER_ENABLED=false`.\n */\nexport function isPox5DecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.POX5_DECODER_ENABLED !== \"false\";\n}\n\n/** Default ON. Opt out with `SBTC_DECODER_ENABLED=false`. */\nexport function isSbtcDecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.SBTC_DECODER_ENABLED !== \"false\";\n}\n\n/** Default OFF. Opt in with `BNS_DECODER_ENABLED=true`. */\nexport function isBnsDecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.BNS_DECODER_ENABLED === \"true\";\n}\n\n// Export for testing\nexport { envSchema };\n",
7
7
  "import { getEnv } from \"./env.ts\";\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n\tdebug: 0,\n\tinfo: 1,\n\twarn: 2,\n\terror: 3,\n};\n\nclass Logger {\n\tprivate _level?: LogLevel;\n\tprivate _isProduction?: boolean;\n\tprivate _initialized = false;\n\n\tprivate init() {\n\t\tif (this._initialized) return;\n\t\tthis._initialized = true;\n\t\ttry {\n\t\t\tconst env = getEnv();\n\t\t\tthis._level = env.LOG_LEVEL;\n\t\t\tthis._isProduction = env.NODE_ENV === \"production\";\n\t\t} catch {\n\t\t\t// Fallback when env is unavailable (e.g. tests without DATABASE_URL)\n\t\t\tthis._level = \"info\";\n\t\t\tthis._isProduction = false;\n\t\t}\n\t}\n\n\tprivate get level(): LogLevel {\n\t\tthis.init();\n\t\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\t\treturn this._level!;\n\t}\n\n\tprivate get isProduction(): boolean {\n\t\tthis.init();\n\t\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\t\treturn this._isProduction!;\n\t}\n\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\treturn LOG_LEVELS[level] >= LOG_LEVELS[this.level];\n\t}\n\n\tprivate formatMessage(\n\t\tlevel: LogLevel,\n\t\tmessage: string,\n\t\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\t\tmeta?: Record<string, any>,\n\t) {\n\t\tconst timestamp = new Date().toISOString();\n\n\t\tif (this.isProduction) {\n\t\t\t// JSON output for production\n\t\t\treturn JSON.stringify({\n\t\t\t\ttimestamp,\n\t\t\t\tlevel,\n\t\t\t\tmessage,\n\t\t\t\t...meta,\n\t\t\t});\n\t\t}\n\n\t\t// Human-readable output for development\n\t\tconst metaStr = meta ? ` ${JSON.stringify(meta)}` : \"\";\n\t\treturn `[${timestamp}] ${level.toUpperCase()}: ${message}${metaStr}`;\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\tdebug(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"debug\")) {\n\t\t\tconsole.debug(this.formatMessage(\"debug\", message, meta));\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\tinfo(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"info\")) {\n\t\t\tconsole.info(this.formatMessage(\"info\", message, meta));\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\twarn(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"warn\")) {\n\t\t\tconsole.warn(this.formatMessage(\"warn\", message, meta));\n\t\t}\n\t}\n\n\t// biome-ignore lint/suspicious/noExplicitAny: interop boundary or dynamic-shape value where typing adds friction without runtime safety\n\terror(message: string, meta?: Record<string, any>): void {\n\t\tif (this.shouldLog(\"error\")) {\n\t\t\tconsole.error(this.formatMessage(\"error\", message, meta));\n\t\t}\n\t}\n}\n\n// Export singleton instance\nexport const logger: Logger = new Logger();\n",
8
8
  "import { logger } from \"../logger.ts\";\n\n/**\n * The one Resend call every customer email goes through. Never throws when\n * `RESEND_API_KEY` is unset — that's a dev/CI/self-host state, not a send\n * failure — it logs a warning and reports `{ skipped: true }` so a caller\n * can still record its own \"notification sent\" bookkeeping accurately.\n */\n\nexport interface SendEmailInput {\n\tto: string;\n\tsubject: string;\n\thtml: string;\n\ttext: string;\n\t/** Where a reply goes; omitted, replies go to the From address. */\n\treplyTo?: string;\n}\n\nexport type SendEmailResult = { skipped: true } | { skipped: false };\n\nexport async function sendEmail(\n\tinput: SendEmailInput,\n): Promise<SendEmailResult> {\n\tconst apiKey = process.env.RESEND_API_KEY;\n\tif (!apiKey) {\n\t\tlogger.warn(\"RESEND_API_KEY unset — skipping email\", {\n\t\t\tsubject: input.subject,\n\t\t});\n\t\treturn { skipped: true };\n\t}\n\n\tconst from =\n\t\tprocess.env.EMAIL_FROM ?? \"secondlayer <noreply@secondlayer.tools>\";\n\n\tconst response = await fetch(\"https://api.resend.com/emails\", {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tfrom,\n\t\t\tto: [input.to],\n\t\t\tsubject: input.subject,\n\t\t\thtml: input.html,\n\t\t\ttext: input.text,\n\t\t\t...(input.replyTo ? { reply_to: [input.replyTo] } : {}),\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst body = await response.text().catch(() => \"\");\n\t\tthrow new Error(\n\t\t\t`Resend API error (${response.status}): ${body.slice(0, 200)}`,\n\t\t);\n\t}\n\n\treturn { skipped: false };\n}\n"
9
9
  ],
10
- "mappings": "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",
11
- "debugId": "33BAE8397C503C5864756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "36F0F48E4EBB77FF64756E2164756E21",
12
12
  "names": []
13
13
  }
@@ -620,6 +620,7 @@ interface InsightsTable {
620
620
  clear_streak: Generated<number>;
621
621
  resolved_at: Date | null;
622
622
  dismissed_at: Date | null;
623
+ snoozed_until: Date | null;
623
624
  }
624
625
  /** "Expected": mutes one rule for one resource until removed. */
625
626
  interface InsightMutesTable {
@@ -1113,6 +1114,7 @@ interface Database {
1113
1114
  webhooks: WebhooksTable;
1114
1115
  webhook_outbox: WebhookOutboxTable;
1115
1116
  webhook_deliveries: WebhookDeliveriesTable;
1117
+ webhook_replays: WebhookReplaysTable;
1116
1118
  trigger_evaluator_state: TriggerEvaluatorStateTable;
1117
1119
  decoded_events: DecodedEventsTable;
1118
1120
  decoder_checkpoints: DecoderCheckpointsTable;
@@ -1161,6 +1163,9 @@ interface Database {
1161
1163
  insights: InsightsTable;
1162
1164
  insight_mutes: InsightMutesTable;
1163
1165
  feedback_tickets: FeedbackTicketsTable;
1166
+ push_subscriptions: PushSubscriptionsTable;
1167
+ push_prefs: PushPrefsTable;
1168
+ push_sent: PushSentTable;
1164
1169
  }
1165
1170
  interface ServiceHeartbeatsTable {
1166
1171
  name: string;
@@ -1266,6 +1271,38 @@ interface WebhookIncidentAlertsTable {
1266
1271
  resolved_at: Date | null;
1267
1272
  }
1268
1273
  type WebhookIncidentAlert = Selectable<WebhookIncidentAlertsTable>;
1274
+ /** One browser/device push subscription; the endpoint is unique. */
1275
+ interface PushSubscriptionsTable {
1276
+ id: Generated<string>;
1277
+ account_id: string;
1278
+ endpoint: string;
1279
+ p256dh: string;
1280
+ auth: string;
1281
+ user_agent: string | null;
1282
+ created_at: Generated<Date>;
1283
+ last_success_at: Date | null;
1284
+ failed_count: Generated<number>;
1285
+ }
1286
+ type PushSubscription = Selectable<PushSubscriptionsTable>;
1287
+ /** Per-account push toggles. A missing row means the column defaults. */
1288
+ interface PushPrefsTable {
1289
+ account_id: string;
1290
+ webhook_failing: Generated<boolean>;
1291
+ subgraph_stopped: Generated<boolean>;
1292
+ subgraph_not_serving: Generated<boolean>;
1293
+ replay_done: Generated<boolean>;
1294
+ spend_cap: Generated<boolean>;
1295
+ key_repeat: Generated<boolean>;
1296
+ updated_at: Generated<Date>;
1297
+ }
1298
+ type PushPrefs = Selectable<PushPrefsTable>;
1299
+ /** A push already sent, keyed by what it was about; debounces repeat signals. */
1300
+ interface PushSentTable {
1301
+ account_id: string;
1302
+ key: string;
1303
+ kind: string;
1304
+ sent_at: Generated<Date>;
1305
+ }
1269
1306
  type CliDeviceLoginStatus = "pending" | "approved" | "denied" | "consumed";
1270
1307
  /** The product that started a CLI sign-in; null is `sl login`. */
1271
1308
  type CliDeviceProduct = "sentinel";
@@ -1460,6 +1497,8 @@ interface WebhookOutboxTable {
1460
1497
  next_attempt_at: Generated<Date>;
1461
1498
  status: ColumnType<OutboxStatus, OutboxStatus | undefined, OutboxStatus>;
1462
1499
  is_replay: Generated<boolean>;
1500
+ /** The replay that created this row; null for live rows. */
1501
+ replay_id: string | null;
1463
1502
  /** The chain block_time of the matched event/tx. Null for rows written
1464
1503
  * before this column existed, and for the settlement scan path (not yet
1465
1504
  * wired). Lets `delivered_at - block_time` measure end-to-end webhook
@@ -1475,7 +1514,28 @@ interface WebhookOutboxTable {
1475
1514
  last_error: string | null;
1476
1515
  created_at: Generated<Date>;
1477
1516
  }
1478
- type WebhookOutbox = Selectable<WebhookOutboxTable>;
1517
+ type WebhookReplayStatus = "scanning" | "running" | "done" | "failed";
1518
+ interface WebhookReplaysTable {
1519
+ id: string;
1520
+ webhook_id: string;
1521
+ from_block: number | bigint;
1522
+ to_block: number | bigint;
1523
+ status: WebhookReplayStatus;
1524
+ scanned_count: Generated<number>;
1525
+ enqueued_count: Generated<number>;
1526
+ total: number | null;
1527
+ delivered: number | null;
1528
+ gave_up: number | null;
1529
+ error: string | null;
1530
+ started_at: Generated<Date>;
1531
+ finished_at: Date | null;
1532
+ }
1533
+ type WebhookReplay = Selectable<WebhookReplaysTable>;
1534
+ /** `replay_id` is optional on the row type so hand-built rows (the test
1535
+ * delivery, fixtures) need not carry it; reads still return it. */
1536
+ type WebhookOutbox = Omit<Selectable<WebhookOutboxTable>, "replay_id"> & {
1537
+ replay_id?: string | null
1538
+ };
1479
1539
  type InsertWebhookOutbox = Insertable<WebhookOutboxTable>;
1480
1540
  type UpdateWebhookOutbox = Updateable<WebhookOutboxTable>;
1481
1541
  interface WebhookDeliveriesTable {
@@ -2642,6 +2702,7 @@ declare const TABLE_TO_DB: {
2642
2702
  webhooks: string
2643
2703
  webhook_outbox: string
2644
2704
  webhook_deliveries: string
2705
+ webhook_replays: string
2645
2706
  trigger_evaluator_state: string
2646
2707
  subgraphs: string
2647
2708
  subgraph_operations: string
@@ -2664,6 +2725,9 @@ declare const TABLE_TO_DB: {
2664
2725
  insights: string
2665
2726
  insight_mutes: string
2666
2727
  feedback_tickets: string
2728
+ push_subscriptions: string
2729
+ push_prefs: string
2730
+ push_sent: string
2667
2731
  service_heartbeats: string
2668
2732
  };
2669
2733
  /** OSS: one application URL. SOURCE_/TARGET_ are hosted split only. */
@@ -3762,4 +3826,4 @@ declare function publicKeyPemFromPrivate(privateKeyPem: string): string;
3762
3826
  declare function ed25519KeyId(publicKeyPem: string): string;
3763
3827
  declare function signEd25519(payload: string, privateKey: KeyObject): string;
3764
3828
  declare function verifyEd25519(payload: string, signatureBase64: string, publicKey: KeyObject): boolean;
3765
- export { Account, AccountBalanceAlerts, AccountBalanceAlertsTable, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiFailedRequest, ApiFailedRequestsTable, ApiKey, ApiKeyRevokedError, ApiKeysTable, ApiRequestLogRow, ApiRequestLogTable, ArchiveFetch, ArchiveFetchesTable, AuthenticationError, AuthorizationError, BILLING_PAUSED_PREFIX, Block, BlocksTable, BnsMarketplaceAction, BnsMarketplaceEventsTable, BnsNameEventTopic, BnsNameEventsTable, BnsNamesTable, BnsNamespaceEventStatus, BnsNamespaceEventsTable, BnsNamespacesTable, BurnBlockRewardSlotsTable, BurnBlockRewardsTable, CHAIN_TRIGGER_FIELDS, CHAIN_TRIGGER_TYPES, CODE_TO_STATUS, ChainApplyDeliveryOf, ChainApplyEnvelope, ChainApplyEnvelopeOf, ChainEventEnvelope, ChainFtBurnData, ChainFtMintData, ChainFtTransferData, ChainNftBurnData, ChainNftMintData, ChainNftTransferData, ChainPrintEventData, ChainReadCacheTable, ChainReorgOrphanedEntry, ChainReorgRollbackDelivery, ChainReorgRollbackEnvelope, ChainReorgsTable, ChainStxBurnData, ChainStxLockData, ChainStxMintData, ChainStxTransferData, ChainTestDelivery, ChainTxLevelEvent, ChainWebhookDelivery, ChainWebhookEnvelope, CliDeviceLogin, CliDeviceLoginStatus, CliDeviceLoginsTable, CliDeviceProduct, ContactRequest, ContactRequestsTable, Contract, ContractsTable, CoverageSegmentsTable, CreateWebhookRequest, CreateWebhookRequestSchema, CreateWebhookResponse, DB_TO_STREAMS_EVENT_TYPE, DECODED_EVENT_TYPES2 as DECODED_EVENT_TYPES, DEFAULT_BTC_CONFIRMATIONS, Database, DatabaseError, DbPlane, DbReadRow, DbSplitStatus, DeadLetterEventsTable, DeadRow, DecodedEventType2 as DecodedEventType, DecodedEventsTable, DecoderCheckpointsTable, DeliveryRow, DeploySubgraphRequest, DeploySubgraphRequestSchema, DeploySubgraphResponse, EMPTY_RANGE_EVENT_INDEX_SENTINEL, Env, ErrorCode, ErrorCodes, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, FeedbackTicket, FeedbackTicketsTable, ForbiddenError, HealthHour, HealthSnapshotPoint, INSIGHT_SEVERITIES, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountBalanceAlerts, InsertAccountCredits, InsertAccountSpendCap, InsertApiFailedRequest, InsertApiKey, InsertApiRequestLogRow, InsertArchiveFetch, InsertBlock, InsertContactRequest, InsertContract, InsertEvent, InsertFeedbackTicket, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertStateWrite, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, Insight, InsightEvidence, InsightEvidenceSchema, InsightListResponse, InsightListResponseSchema, InsightMutesTable, InsightResourceKind, InsightResourceKindSchema, InsightSchema, InsightSeverity, InsightSeveritySchema, InsightsTable, InstancesTable, KeyRotatedError, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NotFoundError, NumericAsText, OauthClient, OauthClientsTable, OauthCodesTable, OauthGrant, OauthGrantsTable, OauthRefreshRetiredTable, OauthRequestStatus, OauthRequestsTable, OauthTokenKind, OauthTokensTable, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, ParsedCreateWebhookRequest, ParsedReplayWebhookRequest, ParsedUpdateWebhookRequest, PaymentRequiredError, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5CycleSignersTable, Pox5CyclesTable, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RUNE_EVENT_TYPES, RateLimitError, ReindexResponse, RepairMode, ReplayResult, ReplayWebhookRequest, ReplayWebhookRequestSchema, RetryState, RotateSecretResponse, RunStatus, RuneApplyDeliveryOf, RuneApplyEnvelope, RuneEventType, SEVERITY_ORDER, SOURCE_READ_COLUMNS, SOURCE_READ_PKS, SOURCE_READ_TYPES, STREAMS_DB_EVENT_TYPES, STREAMS_EVENT_TYPES, STREAMS_TO_DB_EVENT_TYPES, SbtcDepositEvent, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, SbtcWithdrawalEvent, SbtcWithdrawalSweptConfirmedEvent, SecondLayerError, SentinelAccount, SentinelAccountsTable, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StateWrite, StateWritesArchiveTable, StateWritesTable, StreamsCursor, StreamsDbEventType, StreamsEventType, Subgraph, SubgraphAgentSchema, SubgraphAggregateParams, SubgraphAggregateResponse, SubgraphDetail, SubgraphErrorGroupsTable, SubgraphGap, SubgraphGapEntry, SubgraphGapRange, SubgraphGapsResponse, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphQueryParams, SubgraphSpecFormat, SubgraphSpecOptions, SubgraphSummary, SubgraphSyncInfo, SubgraphVerification, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, TABLE_TO_DB, TenantSuspendedError, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, UpdateAccountBalanceAlerts, UpdateAccountCredits, UpdateAccountSpendCap, UpdateApiKey, UpdateArchiveFetch, UpdateBlock, UpdateContract, UpdateEvent, UpdateIndexProgress, UpdateSubgraph, UpdateSubgraphOperation, UpdateTransaction, UpdateUsageLedgerRow, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, UpdateWebhookRequest, UpdateWebhookRequestSchema, UsageLedgerRow, UsageLedgerTable, VM_EVENT_TYPES, VM_NODE_TO_STORED_TYPE2 as VM_NODE_TO_STORED_TYPE, VM_STORED_TO_NODE_TYPE, ValidationError, VersionConflictError, VmEvent, VmEventType, VmEventsArchiveTable, VmEventsTable, VmNodeEventType, WEBHOOK_FORMATS, WEBHOOK_STATUSES, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookDetail, WebhookFormat, WebhookFormatSchema, WebhookIncidentAlert, WebhookIncidentAlertsTable, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookStatus, WebhookStatusSchema, WebhookSummary, WebhooksTable, applicationDatabaseUrl, assertDbSplit, billingPausedCode, blockEndCursor, bucketHourly, closeDb, closeDbOrTimeout, committedHeight, compareStreamsCursor, exports_hmac as crypto, decodeStreamsCursor, describeDbUrl, exports_ed25519 as ed25519, encodeStreamsCursor, finalizedBurnHeight, formatWebhookSchemaErrors, generateSubgraphAgentSchema, generateSubgraphMarkdown, generateSubgraphOpenApi, generateSubgraphSpec, getDb, getDbSplitStatus, getEnv, getErrorMessage, getMigrationRole, getRawClient, getSourceDb, getTargetDb, isBnsDecoderEnabled, isEmptyRangeCursor, isPox4DecoderEnabled, isPox5DecoderEnabled, isSbtcDecoderEnabled, jsonb, logger, onChainPlane, onControlPlane, parseJsonb, resolveSourceUrl, resolveTargetUrl, setMigrationRole, sql };
3829
+ export { Account, AccountBalanceAlerts, AccountBalanceAlertsTable, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiFailedRequest, ApiFailedRequestsTable, ApiKey, ApiKeyRevokedError, ApiKeysTable, ApiRequestLogRow, ApiRequestLogTable, ArchiveFetch, ArchiveFetchesTable, AuthenticationError, AuthorizationError, BILLING_PAUSED_PREFIX, Block, BlocksTable, BnsMarketplaceAction, BnsMarketplaceEventsTable, BnsNameEventTopic, BnsNameEventsTable, BnsNamesTable, BnsNamespaceEventStatus, BnsNamespaceEventsTable, BnsNamespacesTable, BurnBlockRewardSlotsTable, BurnBlockRewardsTable, CHAIN_TRIGGER_FIELDS, CHAIN_TRIGGER_TYPES, CODE_TO_STATUS, ChainApplyDeliveryOf, ChainApplyEnvelope, ChainApplyEnvelopeOf, ChainEventEnvelope, ChainFtBurnData, ChainFtMintData, ChainFtTransferData, ChainNftBurnData, ChainNftMintData, ChainNftTransferData, ChainPrintEventData, ChainReadCacheTable, ChainReorgOrphanedEntry, ChainReorgRollbackDelivery, ChainReorgRollbackEnvelope, ChainReorgsTable, ChainStxBurnData, ChainStxLockData, ChainStxMintData, ChainStxTransferData, ChainTestDelivery, ChainTxLevelEvent, ChainWebhookDelivery, ChainWebhookEnvelope, CliDeviceLogin, CliDeviceLoginStatus, CliDeviceLoginsTable, CliDeviceProduct, ContactRequest, ContactRequestsTable, Contract, ContractsTable, CoverageSegmentsTable, CreateWebhookRequest, CreateWebhookRequestSchema, CreateWebhookResponse, DB_TO_STREAMS_EVENT_TYPE, DECODED_EVENT_TYPES2 as DECODED_EVENT_TYPES, DEFAULT_BTC_CONFIRMATIONS, Database, DatabaseError, DbPlane, DbReadRow, DbSplitStatus, DeadLetterEventsTable, DeadRow, DecodedEventType2 as DecodedEventType, DecodedEventsTable, DecoderCheckpointsTable, DeliveryRow, DeploySubgraphRequest, DeploySubgraphRequestSchema, DeploySubgraphResponse, EMPTY_RANGE_EVENT_INDEX_SENTINEL, Env, ErrorCode, ErrorCodes, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, FeedbackTicket, FeedbackTicketsTable, ForbiddenError, HealthHour, HealthSnapshotPoint, INSIGHT_SEVERITIES, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountBalanceAlerts, InsertAccountCredits, InsertAccountSpendCap, InsertApiFailedRequest, InsertApiKey, InsertApiRequestLogRow, InsertArchiveFetch, InsertBlock, InsertContactRequest, InsertContract, InsertEvent, InsertFeedbackTicket, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertStateWrite, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, Insight, InsightEvidence, InsightEvidenceSchema, InsightListResponse, InsightListResponseSchema, InsightMutesTable, InsightResourceKind, InsightResourceKindSchema, InsightSchema, InsightSeverity, InsightSeveritySchema, InsightsTable, InstancesTable, KeyRotatedError, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NotFoundError, NumericAsText, OauthClient, OauthClientsTable, OauthCodesTable, OauthGrant, OauthGrantsTable, OauthRefreshRetiredTable, OauthRequestStatus, OauthRequestsTable, OauthTokenKind, OauthTokensTable, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, ParsedCreateWebhookRequest, ParsedReplayWebhookRequest, ParsedUpdateWebhookRequest, PaymentRequiredError, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5CycleSignersTable, Pox5CyclesTable, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, PushPrefs, PushPrefsTable, PushSentTable, PushSubscription, PushSubscriptionsTable, RUNE_EVENT_TYPES, RateLimitError, ReindexResponse, RepairMode, ReplayResult, ReplayWebhookRequest, ReplayWebhookRequestSchema, RetryState, RotateSecretResponse, RunStatus, RuneApplyDeliveryOf, RuneApplyEnvelope, RuneEventType, SEVERITY_ORDER, SOURCE_READ_COLUMNS, SOURCE_READ_PKS, SOURCE_READ_TYPES, STREAMS_DB_EVENT_TYPES, STREAMS_EVENT_TYPES, STREAMS_TO_DB_EVENT_TYPES, SbtcDepositEvent, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, SbtcWithdrawalEvent, SbtcWithdrawalSweptConfirmedEvent, SecondLayerError, SentinelAccount, SentinelAccountsTable, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StateWrite, StateWritesArchiveTable, StateWritesTable, StreamsCursor, StreamsDbEventType, StreamsEventType, Subgraph, SubgraphAgentSchema, SubgraphAggregateParams, SubgraphAggregateResponse, SubgraphDetail, SubgraphErrorGroupsTable, SubgraphGap, SubgraphGapEntry, SubgraphGapRange, SubgraphGapsResponse, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphQueryParams, SubgraphSpecFormat, SubgraphSpecOptions, SubgraphSummary, SubgraphSyncInfo, SubgraphVerification, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, TABLE_TO_DB, TenantSuspendedError, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, UpdateAccountBalanceAlerts, UpdateAccountCredits, UpdateAccountSpendCap, UpdateApiKey, UpdateArchiveFetch, UpdateBlock, UpdateContract, UpdateEvent, UpdateIndexProgress, UpdateSubgraph, UpdateSubgraphOperation, UpdateTransaction, UpdateUsageLedgerRow, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, UpdateWebhookRequest, UpdateWebhookRequestSchema, UsageLedgerRow, UsageLedgerTable, VM_EVENT_TYPES, VM_NODE_TO_STORED_TYPE2 as VM_NODE_TO_STORED_TYPE, VM_STORED_TO_NODE_TYPE, ValidationError, VersionConflictError, VmEvent, VmEventType, VmEventsArchiveTable, VmEventsTable, VmNodeEventType, WEBHOOK_FORMATS, WEBHOOK_STATUSES, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookDetail, WebhookFormat, WebhookFormatSchema, WebhookIncidentAlert, WebhookIncidentAlertsTable, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookReplay, WebhookReplayStatus, WebhookReplaysTable, WebhookStatus, WebhookStatusSchema, WebhookSummary, WebhooksTable, applicationDatabaseUrl, assertDbSplit, billingPausedCode, blockEndCursor, bucketHourly, closeDb, closeDbOrTimeout, committedHeight, compareStreamsCursor, exports_hmac as crypto, decodeStreamsCursor, describeDbUrl, exports_ed25519 as ed25519, encodeStreamsCursor, finalizedBurnHeight, formatWebhookSchemaErrors, generateSubgraphAgentSchema, generateSubgraphMarkdown, generateSubgraphOpenApi, generateSubgraphSpec, getDb, getDbSplitStatus, getEnv, getErrorMessage, getMigrationRole, getRawClient, getSourceDb, getTargetDb, isBnsDecoderEnabled, isEmptyRangeCursor, isPox4DecoderEnabled, isPox5DecoderEnabled, isSbtcDecoderEnabled, jsonb, logger, onChainPlane, onControlPlane, parseJsonb, resolveSourceUrl, resolveTargetUrl, setMigrationRole, sql };
package/dist/src/index.js CHANGED
@@ -855,6 +855,7 @@ var TABLE_TO_DB = {
855
855
  webhooks: "target",
856
856
  webhook_outbox: "target",
857
857
  webhook_deliveries: "target",
858
+ webhook_replays: "target",
858
859
  trigger_evaluator_state: "target",
859
860
  subgraphs: "target",
860
861
  subgraph_operations: "target",
@@ -877,6 +878,9 @@ var TABLE_TO_DB = {
877
878
  insights: "target",
878
879
  insight_mutes: "target",
879
880
  feedback_tickets: "target",
881
+ push_subscriptions: "target",
882
+ push_prefs: "target",
883
+ push_sent: "target",
880
884
  service_heartbeats: "both"
881
885
  };
882
886
 
@@ -1718,6 +1722,10 @@ var ReplayWebhookRequestSchema = z4.object({
1718
1722
  message: "fromBlock must be less than or equal to toBlock",
1719
1723
  path: ["toBlock"]
1720
1724
  });
1725
+ var RequeueDeadRequestSchema = z4.object({
1726
+ replayId: z4.string().regex(/^[0-9a-f]{16}$/, "replayId must be 16 hex characters").optional(),
1727
+ since: z4.iso.datetime({ offset: true }).optional()
1728
+ });
1721
1729
  var trigger = {
1722
1730
  stxTransfer: (f = {}) => ({
1723
1731
  type: "stx_transfer",
@@ -2408,5 +2416,5 @@ export {
2408
2416
  sql2 as sql
2409
2417
  };
2410
2418
 
2411
- //# debugId=D706D905F1A1003364756E2164756E21
2419
+ //# debugId=4C61DE1D3131B7BB64756E2164756E21
2412
2420
  //# sourceMappingURL=index.js.map