@secondlayer/shared 11.15.2 → 11.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/archive/range-digest.d.ts +15 -0
- package/dist/src/archive/semantic-digest-builder.d.ts +15 -0
- package/dist/src/coverage/index.d.ts +15 -0
- package/dist/src/db/index.d.ts +20 -1
- package/dist/src/db/index.js +2 -1
- package/dist/src/db/index.js.map +3 -3
- package/dist/src/db/queries/chain-reorgs.d.ts +15 -0
- package/dist/src/db/queries/chain-reorgs.js +2 -1
- package/dist/src/db/queries/chain-reorgs.js.map +3 -3
- package/dist/src/db/queries/contracts.d.ts +15 -0
- package/dist/src/db/queries/instance.d.ts +15 -0
- package/dist/src/db/queries/integrity.d.ts +15 -0
- package/dist/src/db/queries/subgraph-gaps.d.ts +15 -0
- package/dist/src/db/queries/subgraph-operations.d.ts +15 -0
- package/dist/src/db/queries/subgraphs.d.ts +15 -0
- package/dist/src/db/queries/sync-scope.d.ts +15 -0
- package/dist/src/db/queries/webhooks.d.ts +15 -0
- package/dist/src/db/schema.d.ts +19 -1
- package/dist/src/email/index.d.ts +47 -0
- package/dist/src/email/index.js +230 -0
- package/dist/src/email/index.js.map +13 -0
- package/dist/src/index.d.ts +20 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +3 -3
- package/dist/src/node/local-client.d.ts +15 -0
- package/dist/src/queue/listener.js +2 -1
- package/dist/src/queue/listener.js.map +3 -3
- package/migrations/0147_usage_ledger_observed_quantity.ts +24 -0
- package/migrations/0148_account_balance_alerts.ts +30 -0
- package/package.json +5 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// src/email/render.ts
|
|
2
|
+
function escapeHtml(value) {
|
|
3
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
4
|
+
}
|
|
5
|
+
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;">
|
|
19
|
+
<tr>
|
|
20
|
+
<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;">
|
|
22
|
+
<tr>
|
|
23
|
+
<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>
|
|
26
|
+
${paragraphsHtml}
|
|
27
|
+
${codeHtml}
|
|
28
|
+
${factsHtml}
|
|
29
|
+
${ctaHtml}
|
|
30
|
+
${footnoteHtml}
|
|
31
|
+
</td>
|
|
32
|
+
</tr>
|
|
33
|
+
</table>
|
|
34
|
+
</td>
|
|
35
|
+
</tr>
|
|
36
|
+
</table>`.trim();
|
|
37
|
+
}
|
|
38
|
+
function renderText(input) {
|
|
39
|
+
const lines = [input.heading, ""];
|
|
40
|
+
for (const p of input.paragraphs)
|
|
41
|
+
lines.push(p, "");
|
|
42
|
+
if (input.code) {
|
|
43
|
+
lines.push(`Code: ${input.code}`, "");
|
|
44
|
+
}
|
|
45
|
+
if (input.facts?.length) {
|
|
46
|
+
for (const fact of input.facts)
|
|
47
|
+
lines.push(`${fact.label}: ${fact.value}`);
|
|
48
|
+
lines.push("");
|
|
49
|
+
}
|
|
50
|
+
if (input.cta) {
|
|
51
|
+
lines.push(`${input.cta.label}: ${input.cta.url}`, "");
|
|
52
|
+
}
|
|
53
|
+
if (input.footnote) {
|
|
54
|
+
lines.push(input.footnote);
|
|
55
|
+
}
|
|
56
|
+
while (lines.length && lines[lines.length - 1] === "")
|
|
57
|
+
lines.pop();
|
|
58
|
+
return lines.join(`
|
|
59
|
+
`);
|
|
60
|
+
}
|
|
61
|
+
function renderEmail(input) {
|
|
62
|
+
return { html: renderHtml(input), text: renderText(input) };
|
|
63
|
+
}
|
|
64
|
+
// src/env.ts
|
|
65
|
+
import { z } from "zod";
|
|
66
|
+
var networksSchema = z.string().transform((val) => {
|
|
67
|
+
const networks = val.split(",").map((n) => n.trim()).filter(Boolean);
|
|
68
|
+
const valid = ["mainnet", "testnet"];
|
|
69
|
+
for (const n of networks) {
|
|
70
|
+
if (!valid.includes(n)) {
|
|
71
|
+
throw new Error(`Invalid network: ${n}. Must be one of: ${valid.join(", ")}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return networks;
|
|
75
|
+
});
|
|
76
|
+
var envSchema = z.object({
|
|
77
|
+
DATABASE_URL: z.preprocess((val) => typeof val === "string" && val.length === 0 ? undefined : val, z.string().url().optional()),
|
|
78
|
+
SOURCE_DATABASE_URL: z.preprocess((val) => typeof val === "string" && val.length === 0 ? undefined : val, z.string().url().optional()),
|
|
79
|
+
TARGET_DATABASE_URL: z.preprocess((val) => typeof val === "string" && val.length === 0 ? undefined : val, z.string().url().optional()),
|
|
80
|
+
NETWORK: z.enum(["mainnet", "testnet"]).optional(),
|
|
81
|
+
NETWORKS: networksSchema.optional(),
|
|
82
|
+
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
|
|
83
|
+
NODE_ENV: z.enum(["development", "production", "test"]).default("development")
|
|
84
|
+
});
|
|
85
|
+
var cachedEnv = null;
|
|
86
|
+
function getEnv() {
|
|
87
|
+
if (cachedEnv) {
|
|
88
|
+
return cachedEnv;
|
|
89
|
+
}
|
|
90
|
+
const result = envSchema.safeParse(process.env);
|
|
91
|
+
if (!result.success) {
|
|
92
|
+
console.error("❌ Invalid environment configuration:");
|
|
93
|
+
console.error(z.treeifyError(result.error));
|
|
94
|
+
throw new Error("Invalid environment configuration");
|
|
95
|
+
}
|
|
96
|
+
let enabledNetworks;
|
|
97
|
+
if (result.data.NETWORKS && result.data.NETWORKS.length > 0) {
|
|
98
|
+
enabledNetworks = result.data.NETWORKS;
|
|
99
|
+
} else if (result.data.NETWORK) {
|
|
100
|
+
enabledNetworks = [result.data.NETWORK];
|
|
101
|
+
} else {
|
|
102
|
+
enabledNetworks = ["mainnet"];
|
|
103
|
+
}
|
|
104
|
+
cachedEnv = { ...result.data, enabledNetworks };
|
|
105
|
+
return cachedEnv;
|
|
106
|
+
}
|
|
107
|
+
function isProductionEnv() {
|
|
108
|
+
return process.env["NODE_ENV"] === "production";
|
|
109
|
+
}
|
|
110
|
+
function isPox4DecoderEnabled(env = process.env) {
|
|
111
|
+
return env.POX4_DECODER_ENABLED !== "false";
|
|
112
|
+
}
|
|
113
|
+
function isPox5DecoderEnabled(env = process.env) {
|
|
114
|
+
return env.POX5_DECODER_ENABLED !== "false";
|
|
115
|
+
}
|
|
116
|
+
function isSbtcDecoderEnabled(env = process.env) {
|
|
117
|
+
return env.SBTC_DECODER_ENABLED !== "false";
|
|
118
|
+
}
|
|
119
|
+
function isBnsDecoderEnabled(env = process.env) {
|
|
120
|
+
return env.BNS_DECODER_ENABLED === "true";
|
|
121
|
+
}
|
|
122
|
+
// src/logger.ts
|
|
123
|
+
var LOG_LEVELS = {
|
|
124
|
+
debug: 0,
|
|
125
|
+
info: 1,
|
|
126
|
+
warn: 2,
|
|
127
|
+
error: 3
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
class Logger {
|
|
131
|
+
_level;
|
|
132
|
+
_isProduction;
|
|
133
|
+
_initialized = false;
|
|
134
|
+
init() {
|
|
135
|
+
if (this._initialized)
|
|
136
|
+
return;
|
|
137
|
+
this._initialized = true;
|
|
138
|
+
try {
|
|
139
|
+
const env = getEnv();
|
|
140
|
+
this._level = env.LOG_LEVEL;
|
|
141
|
+
this._isProduction = env.NODE_ENV === "production";
|
|
142
|
+
} catch {
|
|
143
|
+
this._level = "info";
|
|
144
|
+
this._isProduction = false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
get level() {
|
|
148
|
+
this.init();
|
|
149
|
+
return this._level;
|
|
150
|
+
}
|
|
151
|
+
get isProduction() {
|
|
152
|
+
this.init();
|
|
153
|
+
return this._isProduction;
|
|
154
|
+
}
|
|
155
|
+
shouldLog(level) {
|
|
156
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
157
|
+
}
|
|
158
|
+
formatMessage(level, message, meta) {
|
|
159
|
+
const timestamp = new Date().toISOString();
|
|
160
|
+
if (this.isProduction) {
|
|
161
|
+
return JSON.stringify({
|
|
162
|
+
timestamp,
|
|
163
|
+
level,
|
|
164
|
+
message,
|
|
165
|
+
...meta
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const metaStr = meta ? ` ${JSON.stringify(meta)}` : "";
|
|
169
|
+
return `[${timestamp}] ${level.toUpperCase()}: ${message}${metaStr}`;
|
|
170
|
+
}
|
|
171
|
+
debug(message, meta) {
|
|
172
|
+
if (this.shouldLog("debug")) {
|
|
173
|
+
console.debug(this.formatMessage("debug", message, meta));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
info(message, meta) {
|
|
177
|
+
if (this.shouldLog("info")) {
|
|
178
|
+
console.info(this.formatMessage("info", message, meta));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
warn(message, meta) {
|
|
182
|
+
if (this.shouldLog("warn")) {
|
|
183
|
+
console.warn(this.formatMessage("warn", message, meta));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
error(message, meta) {
|
|
187
|
+
if (this.shouldLog("error")) {
|
|
188
|
+
console.error(this.formatMessage("error", message, meta));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
var logger = new Logger;
|
|
193
|
+
|
|
194
|
+
// src/email/send.ts
|
|
195
|
+
async function sendEmail(input) {
|
|
196
|
+
const apiKey = process.env.RESEND_API_KEY;
|
|
197
|
+
if (!apiKey) {
|
|
198
|
+
logger.warn("RESEND_API_KEY unset — skipping email", {
|
|
199
|
+
subject: input.subject
|
|
200
|
+
});
|
|
201
|
+
return { skipped: true };
|
|
202
|
+
}
|
|
203
|
+
const from = process.env.EMAIL_FROM ?? "secondlayer <noreply@secondlayer.tools>";
|
|
204
|
+
const response = await fetch("https://api.resend.com/emails", {
|
|
205
|
+
method: "POST",
|
|
206
|
+
headers: {
|
|
207
|
+
"Content-Type": "application/json",
|
|
208
|
+
Authorization: `Bearer ${apiKey}`
|
|
209
|
+
},
|
|
210
|
+
body: JSON.stringify({
|
|
211
|
+
from,
|
|
212
|
+
to: [input.to],
|
|
213
|
+
subject: input.subject,
|
|
214
|
+
html: input.html,
|
|
215
|
+
text: input.text
|
|
216
|
+
})
|
|
217
|
+
});
|
|
218
|
+
if (!response.ok) {
|
|
219
|
+
const body = await response.text().catch(() => "");
|
|
220
|
+
throw new Error(`Resend API error (${response.status}): ${body.slice(0, 200)}`);
|
|
221
|
+
}
|
|
222
|
+
return { skipped: false };
|
|
223
|
+
}
|
|
224
|
+
export {
|
|
225
|
+
renderEmail,
|
|
226
|
+
sendEmail
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
//# debugId=E2163B20AB81801464756E2164756E21
|
|
230
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/email/render.ts", "../src/env.ts", "../src/logger.ts", "../src/email/send.ts"],
|
|
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, \"&\")\n\t\t.replace(/</g, \"<\")\n\t\t.replace(/>/g, \">\")\n\t\t.replace(/\"/g, \""\")\n\t\t.replace(/'/g, \"'\");\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",
|
|
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
|
+
"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
|
+
"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}\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}),\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
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "E2163B20AB81801464756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -820,6 +820,7 @@ interface Database {
|
|
|
820
820
|
stage_failures: StageFailuresTable;
|
|
821
821
|
archive_fetches: ArchiveFetchesTable;
|
|
822
822
|
usage_ledger: UsageLedgerTable;
|
|
823
|
+
account_balance_alerts: AccountBalanceAlertsTable;
|
|
823
824
|
waitlists: WaitlistsTable;
|
|
824
825
|
waitlist_signups: WaitlistSignupsTable;
|
|
825
826
|
}
|
|
@@ -887,6 +888,10 @@ interface UsageLedgerTable {
|
|
|
887
888
|
account_id: string;
|
|
888
889
|
unit: string;
|
|
889
890
|
quantity: string | number | bigint;
|
|
891
|
+
/** Raw sampled quantity before any floor (e.g. `memory.gb_hour`'s actual
|
|
892
|
+
* RAM, before the 0.5 GB minimum). NULL for every unit that has no
|
|
893
|
+
* floor to observe past. */
|
|
894
|
+
observed_quantity: string | number | null;
|
|
890
895
|
usd_micros: string | number | bigint;
|
|
891
896
|
debited: Generated<boolean>;
|
|
892
897
|
source: string;
|
|
@@ -897,6 +902,19 @@ interface UsageLedgerTable {
|
|
|
897
902
|
type UsageLedgerRow = Selectable<UsageLedgerTable>;
|
|
898
903
|
type InsertUsageLedgerRow = Insertable<UsageLedgerTable>;
|
|
899
904
|
type UpdateUsageLedgerRow = Updateable<UsageLedgerTable>;
|
|
905
|
+
/** Preferences + debounce state for the balance-runway email alerts. One
|
|
906
|
+
* row per account; a missing row means both alerts are on (defaults). */
|
|
907
|
+
interface AccountBalanceAlertsTable {
|
|
908
|
+
account_id: string;
|
|
909
|
+
notify_7d: Generated<boolean>;
|
|
910
|
+
notify_2d: Generated<boolean>;
|
|
911
|
+
sent_7d_at: Date | null;
|
|
912
|
+
sent_2d_at: Date | null;
|
|
913
|
+
sent_stopped_at: Date | null;
|
|
914
|
+
}
|
|
915
|
+
type AccountBalanceAlerts = Selectable<AccountBalanceAlertsTable>;
|
|
916
|
+
type InsertAccountBalanceAlerts = Insertable<AccountBalanceAlertsTable>;
|
|
917
|
+
type UpdateAccountBalanceAlerts = Updateable<AccountBalanceAlertsTable>;
|
|
900
918
|
type Block = Selectable<BlocksTable>;
|
|
901
919
|
type InsertBlock = Insertable<BlocksTable>;
|
|
902
920
|
type UpdateBlock = Updateable<BlocksTable>;
|
|
@@ -2095,6 +2113,7 @@ declare const TABLE_TO_DB: {
|
|
|
2095
2113
|
account_credits: string
|
|
2096
2114
|
archive_fetches: string
|
|
2097
2115
|
usage_ledger: string
|
|
2116
|
+
account_balance_alerts: string
|
|
2098
2117
|
waitlists: string
|
|
2099
2118
|
waitlist_signups: string
|
|
2100
2119
|
service_heartbeats: string
|
|
@@ -3299,4 +3318,4 @@ declare function publicKeyPemFromPrivate(privateKeyPem: string): string;
|
|
|
3299
3318
|
declare function ed25519KeyId(publicKeyPem: string): string;
|
|
3300
3319
|
declare function signEd25519(payload: string, privateKey: KeyObject): string;
|
|
3301
3320
|
declare function verifyEd25519(payload: string, signatureBase64: string, publicKey: KeyObject): boolean;
|
|
3302
|
-
export { Account, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiKey, ApiKeysTable, ArchiveFetch, ArchiveFetchesTable, AuthenticationError, AuthorizationError, 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, 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, ForbiddenError, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountCredits, InsertAccountSpendCap, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, KeyRotatedError, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NotFoundError, NumericAsText, 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, 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, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StreamsCursor, StreamsDbEventType, StreamsEventType, Subgraph, SubgraphAgentSchema, SubgraphAggregateParams, SubgraphAggregateResponse, SubgraphDetail, SubgraphGap, SubgraphGapEntry, SubgraphGapRange, SubgraphGapsResponse, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphQueryParams, SubgraphSpecFormat, SubgraphSpecOptions, SubgraphSummary, SubgraphSyncInfo, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, TABLE_TO_DB, TenantSuspendedError, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, 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_FILTER_OPERATORS, WEBHOOK_FORMATS, WEBHOOK_RUNTIMES, WEBHOOK_STATUSES, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookDetail, WebhookFilter, WebhookFilterClause, WebhookFilterClauseSchema, WebhookFilterOperator, WebhookFilterOperatorSchema, WebhookFilterPrimitive, WebhookFilterPrimitiveSchema, WebhookFilterSchema, WebhookFormat, WebhookFormatSchema, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookRuntime, WebhookRuntimeSchema, WebhookSchemaColumn, WebhookSchemaTable, WebhookSchemaTables, WebhookStatus, WebhookStatusSchema, WebhookSummary, WebhooksTable, applicationDatabaseUrl, assertDbSplit, blockEndCursor, 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, getRawClientFor, getSourceDb, getTargetDb, isBnsDecoderEnabled, isEmptyRangeCursor, isPox4DecoderEnabled, isPox5DecoderEnabled, isSbtcDecoderEnabled, jsonb, logger, onChainPlane, onControlPlane, parseJsonb, resolveSourceUrl, resolveTargetUrl, setMigrationRole, sql, validateWebhookFilterForTable };
|
|
3321
|
+
export { Account, AccountBalanceAlerts, AccountBalanceAlertsTable, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiKey, ApiKeysTable, ArchiveFetch, ArchiveFetchesTable, AuthenticationError, AuthorizationError, 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, 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, ForbiddenError, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountBalanceAlerts, InsertAccountCredits, InsertAccountSpendCap, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, KeyRotatedError, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NotFoundError, NumericAsText, 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, 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, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StreamsCursor, StreamsDbEventType, StreamsEventType, Subgraph, SubgraphAgentSchema, SubgraphAggregateParams, SubgraphAggregateResponse, SubgraphDetail, SubgraphGap, SubgraphGapEntry, SubgraphGapRange, SubgraphGapsResponse, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphQueryParams, SubgraphSpecFormat, SubgraphSpecOptions, SubgraphSummary, SubgraphSyncInfo, 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_FILTER_OPERATORS, WEBHOOK_FORMATS, WEBHOOK_RUNTIMES, WEBHOOK_STATUSES, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookDetail, WebhookFilter, WebhookFilterClause, WebhookFilterClauseSchema, WebhookFilterOperator, WebhookFilterOperatorSchema, WebhookFilterPrimitive, WebhookFilterPrimitiveSchema, WebhookFilterSchema, WebhookFormat, WebhookFormatSchema, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookRuntime, WebhookRuntimeSchema, WebhookSchemaColumn, WebhookSchemaTable, WebhookSchemaTables, WebhookStatus, WebhookStatusSchema, WebhookSummary, WebhooksTable, applicationDatabaseUrl, assertDbSplit, blockEndCursor, 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, getRawClientFor, getSourceDb, getTargetDb, isBnsDecoderEnabled, isEmptyRangeCursor, isPox4DecoderEnabled, isPox5DecoderEnabled, isSbtcDecoderEnabled, jsonb, logger, onChainPlane, onControlPlane, parseJsonb, resolveSourceUrl, resolveTargetUrl, setMigrationRole, sql, validateWebhookFilterForTable };
|
package/dist/src/index.js
CHANGED
|
@@ -856,6 +856,7 @@ var TABLE_TO_DB = {
|
|
|
856
856
|
account_credits: "target",
|
|
857
857
|
archive_fetches: "target",
|
|
858
858
|
usage_ledger: "target",
|
|
859
|
+
account_balance_alerts: "target",
|
|
859
860
|
waitlists: "target",
|
|
860
861
|
waitlist_signups: "target",
|
|
861
862
|
service_heartbeats: "both"
|
|
@@ -2262,5 +2263,5 @@ export {
|
|
|
2262
2263
|
validateWebhookFilterForTable
|
|
2263
2264
|
};
|
|
2264
2265
|
|
|
2265
|
-
//# debugId=
|
|
2266
|
+
//# debugId=BEA1E4A2E36AC50B64756E2164756E21
|
|
2266
2267
|
//# sourceMappingURL=index.js.map
|