@naulon/shared 0.0.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.
- package/dist/attribution.d.ts +92 -0
- package/dist/attribution.d.ts.map +1 -0
- package/dist/attribution.js +145 -0
- package/dist/attribution.js.map +1 -0
- package/dist/botAuthSign.d.ts +74 -0
- package/dist/botAuthSign.d.ts.map +1 -0
- package/dist/botAuthSign.js +90 -0
- package/dist/botAuthSign.js.map +1 -0
- package/dist/config.d.ts +131 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +400 -0
- package/dist/config.js.map +1 -0
- package/dist/credits.d.ts +7 -0
- package/dist/credits.d.ts.map +1 -0
- package/dist/credits.js +7 -0
- package/dist/credits.js.map +1 -0
- package/dist/eip3009.d.ts +69 -0
- package/dist/eip3009.d.ts.map +1 -0
- package/dist/eip3009.js +34 -0
- package/dist/eip3009.js.map +1 -0
- package/dist/eventsink.d.ts +19 -0
- package/dist/eventsink.d.ts.map +1 -0
- package/dist/eventsink.js +110 -0
- package/dist/eventsink.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/license.d.ts +178 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +252 -0
- package/dist/license.js.map +1 -0
- package/dist/networks.d.ts +63 -0
- package/dist/networks.d.ts.map +1 -0
- package/dist/networks.js +84 -0
- package/dist/networks.js.map +1 -0
- package/dist/observationsink.d.ts +22 -0
- package/dist/observationsink.d.ts.map +1 -0
- package/dist/observationsink.js +83 -0
- package/dist/observationsink.js.map +1 -0
- package/dist/publisher.d.ts +209 -0
- package/dist/publisher.d.ts.map +1 -0
- package/dist/publisher.js +2 -0
- package/dist/publisher.js.map +1 -0
- package/dist/settlementEmit.d.ts +31 -0
- package/dist/settlementEmit.d.ts.map +1 -0
- package/dist/settlementEmit.js +65 -0
- package/dist/settlementEmit.js.map +1 -0
- package/dist/supabase.d.ts +8 -0
- package/dist/supabase.d.ts.map +1 -0
- package/dist/supabase.js +47 -0
- package/dist/supabase.js.map +1 -0
- package/dist/types.d.ts +154 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env loading + validation. Fail loud at boot if a required var is missing,
|
|
3
|
+
* rather than mid-payment. Secrets never get a default.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { config as loadDotenv } from "dotenv";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
// Find the repo root by walking UP from the cwd until we hit the workspace root
|
|
10
|
+
// (marked by package-lock.json). We anchor on cwd, not import.meta.url, because
|
|
11
|
+
// this package is symlinked into node_modules/@naulon/shared — under
|
|
12
|
+
// `npm run -w` the module URL can resolve to the symlink path, sending an
|
|
13
|
+
// import.meta.url-relative lookup into node_modules/ instead of the repo. Every
|
|
14
|
+
// entrypoint (make, npm -w, tests) runs with cwd inside the repo, so walking up
|
|
15
|
+
// from cwd is reliable and symlink-immune. Falls back to cwd if no marker found.
|
|
16
|
+
function findRepoRoot() {
|
|
17
|
+
let dir = process.cwd();
|
|
18
|
+
for (let i = 0; i < 12; i++) {
|
|
19
|
+
if (existsSync(join(dir, "package-lock.json")))
|
|
20
|
+
return dir;
|
|
21
|
+
const parent = dirname(dir);
|
|
22
|
+
if (parent === dir)
|
|
23
|
+
break;
|
|
24
|
+
dir = parent;
|
|
25
|
+
}
|
|
26
|
+
return process.cwd();
|
|
27
|
+
}
|
|
28
|
+
const REPO_ROOT = findRepoRoot();
|
|
29
|
+
// Anchor .env to the repo root, not cwd — npm workspaces run each package script
|
|
30
|
+
// with cwd set to the package dir, so a cwd-relative lookup would miss the root
|
|
31
|
+
// .env and silently fall back to defaults (mock mode, ephemeral keys).
|
|
32
|
+
// Tests are hermetic — they must not pick up a developer's local .env (which may
|
|
33
|
+
// set PAYMENT_MODE=gateway, real creds, etc.). Everything else loads the root .env.
|
|
34
|
+
if (process.env.NODE_ENV !== "test") {
|
|
35
|
+
loadDotenv({ path: join(REPO_ROOT, ".env") });
|
|
36
|
+
}
|
|
37
|
+
// Anchor the ledger to the repo root, not the current working directory — npm
|
|
38
|
+
// workspaces change cwd per package, so a cwd-relative default would split the
|
|
39
|
+
// ledger across folders. Uses REPO_ROOT (cwd-walked) for the same symlink-immune
|
|
40
|
+
// reason as the .env load above.
|
|
41
|
+
const DEFAULT_EVENTS_PATH = join(REPO_ROOT, "data/events.jsonl");
|
|
42
|
+
const DEFAULT_OBSERVATIONS_PATH = join(REPO_ROOT, "data/observations.jsonl");
|
|
43
|
+
const DEFAULT_PAYOUTS_PATH = join(REPO_ROOT, "data/payouts.jsonl");
|
|
44
|
+
const DEFAULT_LICENSE_STORE = join(REPO_ROOT, "data/wayfarer-licenses.json");
|
|
45
|
+
const DEFAULT_CREDITS_FIXTURES = join(REPO_ROOT, "examples/meridian/credits.json");
|
|
46
|
+
const DEFAULT_SETTLEMENT_OUTBOX = join(REPO_ROOT, "data/settlement-outbox.jsonl");
|
|
47
|
+
// Exported so config validation (e.g. the licensing superRefine) is unit-testable
|
|
48
|
+
// without mutating process.env / the getConfig() singleton.
|
|
49
|
+
export const configSchema = z.object({
|
|
50
|
+
// Payment rail. "mock" settles offline (no creds); "gateway" uses the real
|
|
51
|
+
// Circle Gateway batching SDK (needs a funded BUYER_PRIVATE_KEY).
|
|
52
|
+
PAYMENT_MODE: z.enum(["mock", "gateway"]).default("mock"),
|
|
53
|
+
// Settlement network — which Circle Gateway chain the gate tolls on. Selects the
|
|
54
|
+
// whole rail (x402 quote, settlement body, discovery manifest, buyer client, and
|
|
55
|
+
// the testnet-vs-mainnet facilitator) from one switch. Default arcTestnet so a
|
|
56
|
+
// misconfigured deploy settles on testnet, never silently on mainnet. See
|
|
57
|
+
// shared/networks.ts for the per-network constants.
|
|
58
|
+
SETTLEMENT_NETWORK: z.enum(["arcTestnet", "baseSepolia", "base"]).default("arcTestnet"),
|
|
59
|
+
// Circle Gateway. GATEWAY_API_URL overrides the facilitator endpoint; the
|
|
60
|
+
// testnet facilitator needs no key.
|
|
61
|
+
CIRCLE_API_KEY: z.string().optional(),
|
|
62
|
+
GATEWAY_API_URL: z.string().url().optional(),
|
|
63
|
+
// Relayer key for the Arc self-relay (memo) settlement path. Required ONLY when
|
|
64
|
+
// PAYMENT_MODE=gateway AND the active network ships the Memo predeploy (Arc) —
|
|
65
|
+
// on Base/Base Sepolia the rail is Circle Gateway and this is unused. The relayer
|
|
66
|
+
// is an EOA (the Memo precompile is EOA-only) that signs the OUTER tx and pays gas
|
|
67
|
+
// (native USDC on Arc, an operating cost); it NEVER touches the transferred funds
|
|
68
|
+
// (buyer→author by the buyer's EIP-3009 authorization). Custody-free holds. A
|
|
69
|
+
// settle-time guard (not boot) errors clearly if it's missing on a memo network.
|
|
70
|
+
RELAYER_PRIVATE_KEY: z.string().optional(),
|
|
71
|
+
// Override the Arc USDC EIP-712 domain `name` if it is ever not the standard
|
|
72
|
+
// "USD Coin" (PREFLIGHT: confirm against the on-chain name() before real settle).
|
|
73
|
+
USDC_EIP712_NAME: z.string().optional(),
|
|
74
|
+
// Validity window (seconds) we advertise in the x402 quote (validBefore = now +
|
|
75
|
+
// this). Circle's Gateway facilitator rejects `verify` unless the REMAINING
|
|
76
|
+
// validity at verify time is >= 7 days (604800s). The SDK client clamps short
|
|
77
|
+
// windows up, but a non-SDK buyer that trusts our advertised value verbatim
|
|
78
|
+
// fails `authorization_validity_too_short` if it is below the floor. Default 8
|
|
79
|
+
// days = ~1 day of margin over the floor for signing->verify latency + clock
|
|
80
|
+
// skew. Keep it >= 604900 (floor + the SDK's 100s buffer) — enforced below so a
|
|
81
|
+
// future edit can't silently re-arm the 4d footgun this fix removed.
|
|
82
|
+
X402_MAX_TIMEOUT_SECONDS: z.coerce
|
|
83
|
+
.number()
|
|
84
|
+
.int()
|
|
85
|
+
.positive()
|
|
86
|
+
.default(691_200)
|
|
87
|
+
.refine((v) => v >= 604_900, {
|
|
88
|
+
message: "must be >= 604900 (Circle Gateway's 7-day validity floor 604800 + the SDK's 100s buffer); below it a non-SDK buyer that signs our advertised window verbatim fails authorization_validity_too_short",
|
|
89
|
+
}),
|
|
90
|
+
// Tollgate
|
|
91
|
+
TOLLGATE_PORT: z.coerce.number().int().positive().default(8402),
|
|
92
|
+
// The site the gate sits in front of. Any publisher; not tied to one product.
|
|
93
|
+
ORIGIN_URL: z.string().url().default("http://localhost:3000"),
|
|
94
|
+
DEFAULT_PRICE_USDC: z.coerce.number().positive().default(0.001),
|
|
95
|
+
// Citation tolls cost this multiple of a single read (a citation has downstream
|
|
96
|
+
// reach — it grounds an answer many will see). Both resolve to the same author
|
|
97
|
+
// payees; only the price differs. 1 = price a citation the same as a read.
|
|
98
|
+
CITATION_MULTIPLIER: z.coerce.number().positive().default(5),
|
|
99
|
+
// Which path prefixes count as gateable articles (comma-separated).
|
|
100
|
+
ARTICLE_PATH_PREFIXES: z.string().default("essays,articles,posts"),
|
|
101
|
+
// ── Hardening ──
|
|
102
|
+
// HMAC secret that signs 402 payment nonces. If unset, the gate mints an
|
|
103
|
+
// ephemeral one at boot (fine for a single instance; set it for multi-instance
|
|
104
|
+
// or to keep outstanding nonces valid across restarts).
|
|
105
|
+
TOLLGATE_SECRET: z.string().optional(),
|
|
106
|
+
// How long an issued 402 nonce stays valid (seconds). Also the replay window.
|
|
107
|
+
NONCE_TTL_SECONDS: z.coerce.number().int().positive().default(300),
|
|
108
|
+
// Per-client request ceiling. 0 disables rate limiting. Sustained rate is
|
|
109
|
+
// RATE_LIMIT_RPM/min; short bursts up to RATE_LIMIT_BURST are absorbed.
|
|
110
|
+
RATE_LIMIT_RPM: z.coerce.number().int().nonnegative().default(120),
|
|
111
|
+
RATE_LIMIT_BURST: z.coerce.number().int().positive().default(40),
|
|
112
|
+
// Trust X-Forwarded-For for the client IP. Only enable behind a proxy you
|
|
113
|
+
// control — otherwise clients spoof their rate-limit identity. Default: off.
|
|
114
|
+
TRUST_PROXY: z
|
|
115
|
+
.enum(["true", "false"])
|
|
116
|
+
.default("false")
|
|
117
|
+
.transform((v) => v === "true"),
|
|
118
|
+
// Web Bot Auth: allow http:// + loopback key directories so a LOCAL signer
|
|
119
|
+
// fixture can serve its directory from a loopback port. Test walks only —
|
|
120
|
+
// never enable in production (the directory URL is attacker-supplied).
|
|
121
|
+
BOT_AUTH_ALLOW_HTTP: z
|
|
122
|
+
.enum(["true", "false"])
|
|
123
|
+
.default("false")
|
|
124
|
+
.transform((v) => v === "true"),
|
|
125
|
+
// Web Bot Auth SIGNING identity (slice 3 — the toll's own species marker).
|
|
126
|
+
// A base64url 32-byte Ed25519 seed (generate: scripts/wba-keygen.mjs). When
|
|
127
|
+
// set, the gate serves + self-signs the key directory at
|
|
128
|
+
// /.well-known/http-message-signatures-directory, and the wayfarer signs its
|
|
129
|
+
// outbound requests. Unset ⇒ both surfaces are dark (byte-identical traffic).
|
|
130
|
+
BOT_AUTH_SIGNING_KEY: z.string().optional(),
|
|
131
|
+
// The directory host the wayfarer advertises in Signature-Agent — it must
|
|
132
|
+
// actually serve OUR directory (e.g. "naulon.app"). An http://127.0.0.1:port
|
|
133
|
+
// form is a local-walk fixture (needs the verifying gate's BOT_AUTH_ALLOW_HTTP).
|
|
134
|
+
BOT_AUTH_SIGNATURE_AGENT: z.string().optional(),
|
|
135
|
+
// Credits resolution — how the gate maps an article to its author(s).
|
|
136
|
+
// If CREDITS_API_URL is set, the gate fetches `${url}/credits/:slug`.
|
|
137
|
+
// Otherwise it reads a local JSON fixture (CREDITS_FIXTURES).
|
|
138
|
+
CREDITS_API_URL: z.string().url().optional(),
|
|
139
|
+
CREDITS_API_TOKEN: z.string().optional(),
|
|
140
|
+
CREDITS_FIXTURES: z.string().default(DEFAULT_CREDITS_FIXTURES),
|
|
141
|
+
// Shared HMAC secret for the naulon → publisher settlement emit (POST
|
|
142
|
+
// ${ORIGIN_URL}/api/credits/settlement). Must match the publisher's value. When
|
|
143
|
+
// unset the emit is dark — the gate still tolls and serves; it just doesn't
|
|
144
|
+
// report earnings (keeps the no-creds mock loop working, per hard rule).
|
|
145
|
+
CREDITS_SETTLEMENT_SECRET: z.string().optional(),
|
|
146
|
+
// Crash-safe at-least-once delivery for the settlement emit. The hot path
|
|
147
|
+
// tries once; a background drain re-sends anything not yet acked. The outbox
|
|
148
|
+
// is an append-only log of acked event ids — durable across restarts, and
|
|
149
|
+
// only an optimization (a lost outbox just re-POSTs, which IA dedupes).
|
|
150
|
+
SETTLEMENT_OUTBOX_PATH: z.string().default(DEFAULT_SETTLEMENT_OUTBOX),
|
|
151
|
+
// Bounded retry budget per event inside the drain (the hot path is always 1).
|
|
152
|
+
SETTLEMENT_MAX_ATTEMPTS: z.coerce.number().int().positive().default(5),
|
|
153
|
+
// Per-attempt POST timeout (ms) — a hung IA must never stall the gate.
|
|
154
|
+
SETTLEMENT_TIMEOUT_MS: z.coerce.number().int().positive().default(4000),
|
|
155
|
+
// How often the background drain sweeps for unacked events. 0 disables it
|
|
156
|
+
// (e.g. serverless, where a cron drives the drain instead of a live loop).
|
|
157
|
+
SETTLEMENT_DRAIN_INTERVAL_MS: z.coerce.number().int().nonnegative().default(60_000),
|
|
158
|
+
// Wayfarer
|
|
159
|
+
BUYER_ADDRESS: z.string().optional(),
|
|
160
|
+
BUYER_PRIVATE_KEY: z.string().optional(),
|
|
161
|
+
WAYFARER_BUDGET_USDC: z.coerce.number().positive().default(0.1),
|
|
162
|
+
// BUY-1.4 pay-path hardening. The buyer prices then pays in two separate requests,
|
|
163
|
+
// so the toll can move between them. The MCP re-quotes at pay time and aborts if the
|
|
164
|
+
// live total tops the quoted total by more than this tolerance (basis points). 0 =
|
|
165
|
+
// strict: abort on ANY increase over the quoted total (the budget-safe default; a
|
|
166
|
+
// price DROP is always fine). Raise it only to absorb known small price drift.
|
|
167
|
+
WAYFARER_TOLL_TOLERANCE_BPS: z.coerce.number().int().nonnegative().default(0),
|
|
168
|
+
// Floor (seconds) on the buyer's EIP-3009 validity window, stamped at pay time. If a
|
|
169
|
+
// gate advertises a too-short maxTimeoutSeconds, the signed authorization could expire
|
|
170
|
+
// before the relayer submits it (`authorization_validity_too_short`). The window only
|
|
171
|
+
// widens to this floor, never shrinks. See memory `x402-validity-window-floor`.
|
|
172
|
+
WAYFARER_MIN_VALIDITY_SECONDS: z.coerce.number().int().positive().default(60),
|
|
173
|
+
// BUY-3 policy engine (server-config, never LLM-controlled). All optional — unset
|
|
174
|
+
// ⇒ DEFAULT_POLICY. The MCP folds these into the DecisionPolicy it hands run().
|
|
175
|
+
// *_DOMAINS: comma-separated publisher hosts. ALLOW is an allowlist (deny-by-
|
|
176
|
+
// default for anything not listed); DENY always wins. CAP: max pays per host.
|
|
177
|
+
// APPROVAL_USDC: a toll at/above this becomes an "approve" (human gate), not a
|
|
178
|
+
// pay. KILL_SWITCH: halt all new spend (free re-reads of held licenses still ok).
|
|
179
|
+
// Parse to a non-empty host list, or `undefined` when blank/malformed (e.g. ","):
|
|
180
|
+
// a garbled value must read as "unset" (no restriction), never as an empty
|
|
181
|
+
// allowlist that would silently skip every essay.
|
|
182
|
+
WAYFARER_ALLOW_DOMAINS: z
|
|
183
|
+
.string()
|
|
184
|
+
.optional()
|
|
185
|
+
.transform((v) => {
|
|
186
|
+
const hosts = v ? v.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
187
|
+
return hosts.length ? hosts : undefined;
|
|
188
|
+
}),
|
|
189
|
+
WAYFARER_DENY_DOMAINS: z
|
|
190
|
+
.string()
|
|
191
|
+
.optional()
|
|
192
|
+
.transform((v) => {
|
|
193
|
+
const hosts = v ? v.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
194
|
+
return hosts.length ? hosts : undefined;
|
|
195
|
+
}),
|
|
196
|
+
WAYFARER_PER_DOMAIN_CAP: z.coerce.number().int().positive().optional(),
|
|
197
|
+
WAYFARER_APPROVAL_USDC: z.coerce.number().positive().optional(),
|
|
198
|
+
WAYFARER_KILL_SWITCH: z
|
|
199
|
+
.string()
|
|
200
|
+
.default("false")
|
|
201
|
+
.transform((v) => v === "true" || v === "1"),
|
|
202
|
+
OPENAI_API_KEY: z.string().optional(),
|
|
203
|
+
// USDC the agent deposits into the Gateway Wallet at the start of a run.
|
|
204
|
+
DEPOSIT_AMOUNT_USDC: z.string().default("1"),
|
|
205
|
+
// The tollgate the agent pays. Defaults to the local tollgate.
|
|
206
|
+
TOLLGATE_URL: z.string().url().optional(),
|
|
207
|
+
// Where the agent discovers candidate essays (a catalog of {slug,title,summary}).
|
|
208
|
+
CATALOG_URL: z.string().url().optional(),
|
|
209
|
+
// RSS/sitemap discovery. If set, the agent discovers from the publisher's live
|
|
210
|
+
// feed instead of a CATALOG_URL. Precedence: RSS_URL > PUBLISHER_URL > CATALOG_URL
|
|
211
|
+
// > bundled demo. rssSource reads ${PUBLISHER_URL}/rss.xml unless RSS_URL overrides.
|
|
212
|
+
PUBLISHER_URL: z.string().url().optional(),
|
|
213
|
+
RSS_URL: z.string().url().optional(),
|
|
214
|
+
// Optional — fills slug coverage RSS truncates (latest-N). Unused until sitemap
|
|
215
|
+
// parsing lands; reserved here so the seam is config-complete.
|
|
216
|
+
SITEMAP_URL: z.string().url().optional(),
|
|
217
|
+
// Where the agent caches Citation Licenses it has been issued, so a live one
|
|
218
|
+
// lets it re-read an essay free instead of paying again (across runs).
|
|
219
|
+
WAYFARER_LICENSE_PATH: z.string().default(DEFAULT_LICENSE_STORE),
|
|
220
|
+
// Dashboard
|
|
221
|
+
DASHBOARD_PORT: z.coerce.number().int().positive().default(8403),
|
|
222
|
+
// Interface the dashboard binds. Defaults to localhost: the earnings view has
|
|
223
|
+
// no built-in auth and exposes author wallets + USD, so it must not face the
|
|
224
|
+
// public internet directly. Set "0.0.0.0" only behind your own auth (reverse
|
|
225
|
+
// proxy, access gateway). See README "Dashboard exposure".
|
|
226
|
+
DASHBOARD_BIND: z.string().default("127.0.0.1"),
|
|
227
|
+
// ── Storage backend ──
|
|
228
|
+
// Where attributed events live. "jsonl" = an append-only local file (default,
|
|
229
|
+
// no creds — great for dev/demo and a single-box deploy). "supabase" = a
|
|
230
|
+
// Postgres table over Supabase's REST API, for serverless / multi-instance
|
|
231
|
+
// hosts (e.g. Vercel) that have no shared disk. Same `EventSink` seam either way.
|
|
232
|
+
EVENTS_BACKEND: z.enum(["jsonl", "supabase"]).default("jsonl"),
|
|
233
|
+
// Where spent 402 nonces are remembered (replay protection). "memory" =
|
|
234
|
+
// in-process (default; correct for a single instance). "supabase" = a shared
|
|
235
|
+
// table, so replay protection holds across many serverless instances.
|
|
236
|
+
NONCE_BACKEND: z.enum(["memory", "supabase"]).default("memory"),
|
|
237
|
+
// Where buyer-authorized EXTRA settlement legs await their deferred on-chain settle
|
|
238
|
+
// (the operator/co-author legs beyond the synchronous author leg). "memory" =
|
|
239
|
+
// in-process (default; correct for a single instance / mock dev). "supabase" = a
|
|
240
|
+
// shared table the deferred-settle drain reads, so pending authorizations survive a
|
|
241
|
+
// restart and settle exactly-once across instances. Same PendingLegSink seam either way.
|
|
242
|
+
PENDING_LEGS_BACKEND: z.enum(["memory", "supabase"]).default("memory"),
|
|
243
|
+
// Supabase project — only needed when a *_BACKEND above is "supabase". The
|
|
244
|
+
// service-role key is a secret; keep it in .env, never in the repo.
|
|
245
|
+
SUPABASE_URL: z.string().url().optional(),
|
|
246
|
+
SUPABASE_SERVICE_KEY: z.string().optional(),
|
|
247
|
+
SUPABASE_EVENTS_TABLE: z.string().default("naulon_events"),
|
|
248
|
+
SUPABASE_NONCES_TABLE: z.string().default("naulon_nonces"),
|
|
249
|
+
SUPABASE_PENDING_LEGS_TABLE: z.string().default("naulon_pending_legs"),
|
|
250
|
+
SUPABASE_REVOCATIONS_TABLE: z.string().default("naulon_revocations"),
|
|
251
|
+
// Where gated-request OBSERVATIONS go (the audit/observability plane — who was
|
|
252
|
+
// served free / denied / paid). "off" (default) records nothing, so the open
|
|
253
|
+
// core keeps its zero-overhead, nothing-stored posture; "jsonl" = a local file
|
|
254
|
+
// (dev); "supabase" = a shared table a multi-tenant embedder reads for its audit
|
|
255
|
+
// UI. Separate from EVENTS_BACKEND on purpose: observations are higher-volume,
|
|
256
|
+
// lower-value, and TTL'd, so a deploy may want them in a different place (or off).
|
|
257
|
+
OBSERVATIONS_BACKEND: z.enum(["off", "jsonl", "supabase"]).default("off"),
|
|
258
|
+
SUPABASE_OBSERVATIONS_TABLE: z.string().default("naulon_observations"),
|
|
259
|
+
// ── Citation License Tokens (CLT) ──
|
|
260
|
+
// Signed receipts handed to a paying agent (see docs/citation-license.md).
|
|
261
|
+
// On by default — they're additive (an extra response header) and the offline
|
|
262
|
+
// path mints with an ephemeral key. A STABLE key is required (below) for real
|
|
263
|
+
// payments or a supabase/multi-instance deploy.
|
|
264
|
+
LICENSES_ENABLED: z
|
|
265
|
+
.enum(["true", "false"])
|
|
266
|
+
.default("true")
|
|
267
|
+
.transform((v) => v === "true"),
|
|
268
|
+
// Ed25519 private key (PKCS8 PEM or base64 DER) that signs licenses. SECRET.
|
|
269
|
+
// Leave unset only for single-instance mock/dev (ephemeral key + boot warning).
|
|
270
|
+
LICENSE_SIGNING_KEY: z.string().optional(),
|
|
271
|
+
// Re-read window for a license, seconds. A CLT is an unrevocable bearer
|
|
272
|
+
// credential on the offline tier, so the TTL is the kill switch — kept short.
|
|
273
|
+
LICENSE_TTL_SECONDS: z.coerce.number().int().positive().default(600),
|
|
274
|
+
// Issuer/audience string; defaults to `naulon:<gate host>` derived at runtime.
|
|
275
|
+
LICENSE_ISSUER: z.string().optional(),
|
|
276
|
+
// Embed the full payees graph (transparent, default) or just a hash + primary.
|
|
277
|
+
LICENSE_PAYEES_MODE: z.enum(["full", "hashed"]).default("full"),
|
|
278
|
+
// Consult the jti revocation seam on the online verify tier (P2). Off = the
|
|
279
|
+
// offline JWKS tier only (exp-bounded). Needs shared state when on.
|
|
280
|
+
LICENSE_ONLINE_CHECK: z
|
|
281
|
+
.enum(["true", "false"])
|
|
282
|
+
.default("false")
|
|
283
|
+
.transform((v) => v === "true"),
|
|
284
|
+
// Holder-of-key (P5): mint licenses bound to the payer wallet (RFC 7800 cnf),
|
|
285
|
+
// and require a proof-of-possession (an EIP-191 wallet signature) on re-read.
|
|
286
|
+
// Off by default — v1 licenses are short-TTL bearer tokens; turn this on to
|
|
287
|
+
// close leak-replay (a captured token is then useless without the wallet key).
|
|
288
|
+
// Needs a signing-capable buyer wallet (BUYER_PRIVATE_KEY, or the dev key on
|
|
289
|
+
// the mock path) — the demo loop is unaffected while this is off.
|
|
290
|
+
LICENSE_POP: z
|
|
291
|
+
.enum(["true", "false"])
|
|
292
|
+
.default("false")
|
|
293
|
+
.transform((v) => v === "true"),
|
|
294
|
+
// Freshness window (seconds) for a proof-of-possession: the gate accepts a
|
|
295
|
+
// proof whose timestamp is within ±this of its clock, and remembers the proof
|
|
296
|
+
// nonce for this long to stop replay. Shorter = tighter replay window; longer
|
|
297
|
+
// = more clock-skew tolerance across instances.
|
|
298
|
+
LICENSE_POP_WINDOW_SECONDS: z.coerce.number().int().positive().default(120),
|
|
299
|
+
// Shared event ledger (jsonl backend). Tollgate appends here; dashboard +
|
|
300
|
+
// attribution read it.
|
|
301
|
+
EVENTS_PATH: z.string().default(DEFAULT_EVENTS_PATH),
|
|
302
|
+
// Observation ledger (jsonl backend). Tollgate appends; the audit plane reads.
|
|
303
|
+
OBSERVATIONS_PATH: z.string().default(DEFAULT_OBSERVATIONS_PATH),
|
|
304
|
+
// Attribution & settlement.
|
|
305
|
+
PAYOUTS_PATH: z.string().default(DEFAULT_PAYOUTS_PATH),
|
|
306
|
+
// Don't settle a wallet until its accrued tolls reach this — amortizes the
|
|
307
|
+
// per-transfer overhead across many sub-cent reads. Below it, carry forward.
|
|
308
|
+
MIN_PAYOUT_USDC: z.coerce.number().positive().default(0.005),
|
|
309
|
+
// How the single on-chain recipient is chosen when two co-authors tie for the
|
|
310
|
+
// top share. "wallet" (default) breaks ties by address, so who gets the on-chain
|
|
311
|
+
// leg is a pure function of who's credited — a reordered credits graph can't move
|
|
312
|
+
// it. "input" keeps the credits-graph order. The full split is recorded either way.
|
|
313
|
+
PRIMARY_PAYEE_TIEBREAK: z.enum(["wallet", "input"]).default("wallet"),
|
|
314
|
+
// Pay co-authors directly on-chain (split-at-source) for multi-author articles
|
|
315
|
+
// instead of routing the whole toll to the primary author. OFF by default → the
|
|
316
|
+
// stock single-recipient toll (the rest of the split is recorded for the publisher
|
|
317
|
+
// to reconcile off-protocol). ON → the primary's content-gating leg drops to its
|
|
318
|
+
// own share and each other co-author gets a direct deferred buyer→author leg
|
|
319
|
+
// (custody-free). Sets `PublisherConfig.coauthorSplit` for the single-tenant gate;
|
|
320
|
+
// a multi-tenant resolver decides this per publisher instead.
|
|
321
|
+
COAUTHOR_ONCHAIN_SPLIT: z
|
|
322
|
+
.enum(["true", "false"])
|
|
323
|
+
.default("false")
|
|
324
|
+
.transform((v) => v === "true"),
|
|
325
|
+
}).superRefine((cfg, ctx) => {
|
|
326
|
+
// A "supabase" backend is useless without the project creds — fail loud at
|
|
327
|
+
// boot, not mid-payment, naming exactly what's missing.
|
|
328
|
+
const usesSupabase = cfg.EVENTS_BACKEND === "supabase" ||
|
|
329
|
+
cfg.NONCE_BACKEND === "supabase" ||
|
|
330
|
+
cfg.PENDING_LEGS_BACKEND === "supabase" ||
|
|
331
|
+
cfg.OBSERVATIONS_BACKEND === "supabase";
|
|
332
|
+
if (usesSupabase) {
|
|
333
|
+
for (const key of ["SUPABASE_URL", "SUPABASE_SERVICE_KEY"]) {
|
|
334
|
+
if (!cfg[key]) {
|
|
335
|
+
ctx.addIssue({
|
|
336
|
+
code: "custom",
|
|
337
|
+
path: [key],
|
|
338
|
+
message: `required when EVENTS_BACKEND, NONCE_BACKEND or OBSERVATIONS_BACKEND is "supabase"`,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
// A CLT is a reusable, externally-verified token, so an ephemeral signing key
|
|
344
|
+
// is only safe on a single-instance mock box. Require a stable key once real
|
|
345
|
+
// money moves or any shared (supabase) backend / multi-instance is in play —
|
|
346
|
+
// otherwise JWKS and the paid re-read go non-deterministic across instances.
|
|
347
|
+
const needsStableKey = cfg.LICENSES_ENABLED && (cfg.PAYMENT_MODE !== "mock" || usesSupabase);
|
|
348
|
+
if (needsStableKey && !cfg.LICENSE_SIGNING_KEY) {
|
|
349
|
+
ctx.addIssue({
|
|
350
|
+
code: "custom",
|
|
351
|
+
path: ["LICENSE_SIGNING_KEY"],
|
|
352
|
+
message: "required (stable Ed25519 key) when licensing is on with real payments or a supabase backend — " +
|
|
353
|
+
"ephemeral keys break verification across instances. See docs/citation-license.md.",
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
if (cfg.LICENSE_TTL_SECONDS > 3600) {
|
|
357
|
+
ctx.addIssue({
|
|
358
|
+
code: "custom",
|
|
359
|
+
path: ["LICENSE_TTL_SECONDS"],
|
|
360
|
+
message: "must be <= 3600: a CLT is an unrevocable bearer credential on the offline tier, so a short TTL is the kill switch.",
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (cfg.LICENSE_POP_WINDOW_SECONDS > 600) {
|
|
364
|
+
ctx.addIssue({
|
|
365
|
+
code: "custom",
|
|
366
|
+
path: ["LICENSE_POP_WINDOW_SECONDS"],
|
|
367
|
+
message: "must be <= 600: the proof-of-possession window is a replay window — keep it tight (it only needs to cover clock skew + one round trip).",
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
let cached;
|
|
372
|
+
export function getConfig() {
|
|
373
|
+
if (cached)
|
|
374
|
+
return cached;
|
|
375
|
+
const parsed = configSchema.safeParse(process.env);
|
|
376
|
+
if (!parsed.success) {
|
|
377
|
+
const issues = parsed.error.issues
|
|
378
|
+
.map((i) => ` ${i.path.join(".")}: ${i.message}`)
|
|
379
|
+
.join("\n");
|
|
380
|
+
throw new Error(`Invalid environment:\n${issues}\nSee .env.example.`);
|
|
381
|
+
}
|
|
382
|
+
cached = parsed.data;
|
|
383
|
+
return cached;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Drop the memoized config so the next `getConfig()` re-reads `process.env`.
|
|
387
|
+
* A test seam for the env-dependent branches the singleton otherwise freezes
|
|
388
|
+
* (e.g. the Circle-key settlement guard) — not for production hot-reload.
|
|
389
|
+
*/
|
|
390
|
+
export function resetConfig() {
|
|
391
|
+
cached = undefined;
|
|
392
|
+
}
|
|
393
|
+
/** Assert a set of keys are present (call at a component's boot once it knows what it needs). */
|
|
394
|
+
export function requireKeys(cfg, keys) {
|
|
395
|
+
const missing = keys.filter((k) => cfg[k] === undefined || cfg[k] === "");
|
|
396
|
+
if (missing.length) {
|
|
397
|
+
throw new Error(`Missing required env: ${missing.join(", ")}. See .env.example.`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credits-graph validation now lives in @naulon/sdk — the one place the
|
|
3
|
+
* money-routing trust boundary's schema is defined. Re-exported here so existing
|
|
4
|
+
* `@naulon/shared` importers (and `shared/index.ts`'s barrel) are unchanged.
|
|
5
|
+
*/
|
|
6
|
+
export { creditsSchema, parseCredits, buildCredits } from "@naulon/sdk";
|
|
7
|
+
//# sourceMappingURL=credits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../src/credits.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/credits.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credits-graph validation now lives in @naulon/sdk — the one place the
|
|
3
|
+
* money-routing trust boundary's schema is defined. Re-exported here so existing
|
|
4
|
+
* `@naulon/shared` importers (and `shared/index.ts`'s barrel) are unchanged.
|
|
5
|
+
*/
|
|
6
|
+
export { creditsSchema, parseCredits, buildCredits } from "@naulon/sdk";
|
|
7
|
+
//# sourceMappingURL=credits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.js","sourceRoot":"","sources":["../src/credits.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-3009 (`transferWithAuthorization`) protocol descriptor — the SDK-free, pure-data
|
|
3
|
+
* definition of a USDC EIP-3009 authorization and the EIP-712 domain it is signed
|
|
4
|
+
* against. Both sides of the memo self-relay rail consume this single source of truth:
|
|
5
|
+
* the BUYER signs against it (wayfarer), the GATE verifies against it (tollgate). The
|
|
6
|
+
* viem signing/recovery act stays in each consumer — each already depends on viem; this
|
|
7
|
+
* file must not, so `shared` stays dependency-light (it is imported by the cloud control
|
|
8
|
+
* plane too).
|
|
9
|
+
*
|
|
10
|
+
* This is the sibling of `networks.ts` `gatewayExtra` (the GatewayWallet EIP-712 domain):
|
|
11
|
+
* same pattern — the protocol descriptor lives in `shared`, the crypto lives in the
|
|
12
|
+
* consumer. Keep them adjacent.
|
|
13
|
+
*/
|
|
14
|
+
import type { SettlementNetwork } from "./networks.ts";
|
|
15
|
+
/** The buyer's EIP-3009 authorization — the exact `{from,to,value,validAfter,
|
|
16
|
+
* validBefore,nonce}` message they sign, identical in shape to the Gateway payload's
|
|
17
|
+
* `authorization` (only the EIP-712 DOMAIN they sign it against differs: the USDC
|
|
18
|
+
* token here vs the GatewayWallet contract in batched mode). */
|
|
19
|
+
export interface MemoAuthorization {
|
|
20
|
+
from: `0x${string}`;
|
|
21
|
+
to: `0x${string}`;
|
|
22
|
+
value: string;
|
|
23
|
+
validAfter: string;
|
|
24
|
+
validBefore: string;
|
|
25
|
+
nonce: `0x${string}`;
|
|
26
|
+
}
|
|
27
|
+
/** EIP-712 typed-data type for the EIP-3009 transfer authorization (what the buyer
|
|
28
|
+
* signs against the USDC domain, and what the gate recovers the signer from). */
|
|
29
|
+
export declare const TRANSFER_WITH_AUTHORIZATION_TYPES: {
|
|
30
|
+
readonly TransferWithAuthorization: readonly [{
|
|
31
|
+
readonly name: "from";
|
|
32
|
+
readonly type: "address";
|
|
33
|
+
}, {
|
|
34
|
+
readonly name: "to";
|
|
35
|
+
readonly type: "address";
|
|
36
|
+
}, {
|
|
37
|
+
readonly name: "value";
|
|
38
|
+
readonly type: "uint256";
|
|
39
|
+
}, {
|
|
40
|
+
readonly name: "validAfter";
|
|
41
|
+
readonly type: "uint256";
|
|
42
|
+
}, {
|
|
43
|
+
readonly name: "validBefore";
|
|
44
|
+
readonly type: "uint256";
|
|
45
|
+
}, {
|
|
46
|
+
readonly name: "nonce";
|
|
47
|
+
readonly type: "bytes32";
|
|
48
|
+
}];
|
|
49
|
+
};
|
|
50
|
+
/** The USDC EIP-712 domain name/version — LAST-RESORT fallback only. The real values
|
|
51
|
+
* live per-network on `SettlementNetwork.usdcName`/`usdcVersion` (verified on-chain,
|
|
52
|
+
* e.g. Arc testnet = "USDC"/"2", NOT this mainnet FiatToken default), and the
|
|
53
|
+
* `USDC_EIP712_NAME` env var overrides everything. PREFLIGHT before the first real
|
|
54
|
+
* settle on a new network: confirm `name()` on its USDC contract matches the domain —
|
|
55
|
+
* a mismatch makes both the off-chain pre-verify AND the on-chain
|
|
56
|
+
* `transferWithAuthorization` reject a valid signature, with a confusing "signer != from".
|
|
57
|
+
* (`make arc-preflight` does this check.) */
|
|
58
|
+
export declare const USDC_EIP712_NAME = "USD Coin";
|
|
59
|
+
export declare const USDC_EIP712_VERSION = "2";
|
|
60
|
+
/** Resolve the USDC EIP-712 domain: env override → per-network verified value → the
|
|
61
|
+
* mainnet-FiatToken fallback. Never trusts the fallback for a network that declares
|
|
62
|
+
* its own (Arc), so the default path signs correctly with no env required. */
|
|
63
|
+
export declare function usdcDomain(net: SettlementNetwork, nameOverride?: string): {
|
|
64
|
+
readonly name: string;
|
|
65
|
+
readonly version: string;
|
|
66
|
+
readonly chainId: number;
|
|
67
|
+
readonly verifyingContract: `0x${string}`;
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=eip3009.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eip3009.d.ts","sourceRoot":"","sources":["../src/eip3009.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;;iEAGiE;AACjE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;CACtB;AAED;kFACkF;AAClF,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;CASpC,CAAC;AAEX;;;;;;;8CAO8C;AAC9C,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAC3C,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;+EAE+E;AAC/E,wBAAgB,UAAU,CAAC,GAAG,EAAE,iBAAiB,EAAE,YAAY,CAAC,EAAE,MAAM;;;;;EAOvE"}
|
package/dist/eip3009.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** EIP-712 typed-data type for the EIP-3009 transfer authorization (what the buyer
|
|
2
|
+
* signs against the USDC domain, and what the gate recovers the signer from). */
|
|
3
|
+
export const TRANSFER_WITH_AUTHORIZATION_TYPES = {
|
|
4
|
+
TransferWithAuthorization: [
|
|
5
|
+
{ name: "from", type: "address" },
|
|
6
|
+
{ name: "to", type: "address" },
|
|
7
|
+
{ name: "value", type: "uint256" },
|
|
8
|
+
{ name: "validAfter", type: "uint256" },
|
|
9
|
+
{ name: "validBefore", type: "uint256" },
|
|
10
|
+
{ name: "nonce", type: "bytes32" },
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
/** The USDC EIP-712 domain name/version — LAST-RESORT fallback only. The real values
|
|
14
|
+
* live per-network on `SettlementNetwork.usdcName`/`usdcVersion` (verified on-chain,
|
|
15
|
+
* e.g. Arc testnet = "USDC"/"2", NOT this mainnet FiatToken default), and the
|
|
16
|
+
* `USDC_EIP712_NAME` env var overrides everything. PREFLIGHT before the first real
|
|
17
|
+
* settle on a new network: confirm `name()` on its USDC contract matches the domain —
|
|
18
|
+
* a mismatch makes both the off-chain pre-verify AND the on-chain
|
|
19
|
+
* `transferWithAuthorization` reject a valid signature, with a confusing "signer != from".
|
|
20
|
+
* (`make arc-preflight` does this check.) */
|
|
21
|
+
export const USDC_EIP712_NAME = "USD Coin";
|
|
22
|
+
export const USDC_EIP712_VERSION = "2";
|
|
23
|
+
/** Resolve the USDC EIP-712 domain: env override → per-network verified value → the
|
|
24
|
+
* mainnet-FiatToken fallback. Never trusts the fallback for a network that declares
|
|
25
|
+
* its own (Arc), so the default path signs correctly with no env required. */
|
|
26
|
+
export function usdcDomain(net, nameOverride) {
|
|
27
|
+
return {
|
|
28
|
+
name: nameOverride ?? net.usdcName ?? USDC_EIP712_NAME,
|
|
29
|
+
version: net.usdcVersion ?? USDC_EIP712_VERSION,
|
|
30
|
+
chainId: net.chainId,
|
|
31
|
+
verifyingContract: net.usdc,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=eip3009.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eip3009.js","sourceRoot":"","sources":["../src/eip3009.ts"],"names":[],"mappings":"AA4BA;kFACkF;AAClF,MAAM,CAAC,MAAM,iCAAiC,GAAG;IAC/C,yBAAyB,EAAE;QACzB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE;QACjC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE;QAC/B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;QAClC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE;QACvC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE;QACxC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;KACnC;CACO,CAAC;AAEX;;;;;;;8CAO8C;AAC9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC;;+EAE+E;AAC/E,MAAM,UAAU,UAAU,CAAC,GAAsB,EAAE,YAAqB;IACtE,OAAO;QACL,IAAI,EAAE,YAAY,IAAI,GAAG,CAAC,QAAQ,IAAI,gBAAgB;QACtD,OAAO,EAAE,GAAG,CAAC,WAAW,IAAI,mBAAmB;QAC/C,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,iBAAiB,EAAE,GAAG,CAAC,IAAI;KACnB,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AttributedEvent, EventSink } from "./types.ts";
|
|
2
|
+
export declare function jsonlSink(path?: string): EventSink;
|
|
3
|
+
/**
|
|
4
|
+
* Supabase-backed sink. Each event is stored as one row: its `id` (primary key,
|
|
5
|
+
* so a retried write is idempotent), its `at` timestamp (indexed, for ordering),
|
|
6
|
+
* and the whole `AttributedEvent` as a jsonb `data` column — so `readAll` hands
|
|
7
|
+
* back the exact shape the writer stored, with no field-by-field mapping to drift.
|
|
8
|
+
* This is the backend to use on serverless/multi-instance hosts with no shared disk.
|
|
9
|
+
*/
|
|
10
|
+
export declare function supabaseSink(): EventSink;
|
|
11
|
+
/**
|
|
12
|
+
* Pick the EventSink the config asks for. JSONL file by default (offline, no
|
|
13
|
+
* creds); Supabase when EVENTS_BACKEND=supabase. Callers use this instead of
|
|
14
|
+
* naming a sink directly, so switching backends is one env var.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getSink(): EventSink;
|
|
17
|
+
/** In-memory sink, handy for tests. */
|
|
18
|
+
export declare function memorySink(seed?: AttributedEvent[]): EventSink;
|
|
19
|
+
//# sourceMappingURL=eventsink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventsink.d.ts","sourceRoot":"","sources":["../src/eventsink.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAqClD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,SAAS,CA4BxC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,SAAS,CAEnC;AAED,uCAAuC;AACvC,wBAAgB,UAAU,CAAC,IAAI,GAAE,eAAe,EAAO,GAAG,SAAS,CAalE"}
|