@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.
Files changed (57) hide show
  1. package/dist/attribution.d.ts +92 -0
  2. package/dist/attribution.d.ts.map +1 -0
  3. package/dist/attribution.js +145 -0
  4. package/dist/attribution.js.map +1 -0
  5. package/dist/botAuthSign.d.ts +74 -0
  6. package/dist/botAuthSign.d.ts.map +1 -0
  7. package/dist/botAuthSign.js +90 -0
  8. package/dist/botAuthSign.js.map +1 -0
  9. package/dist/config.d.ts +131 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +400 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/credits.d.ts +7 -0
  14. package/dist/credits.d.ts.map +1 -0
  15. package/dist/credits.js +7 -0
  16. package/dist/credits.js.map +1 -0
  17. package/dist/eip3009.d.ts +69 -0
  18. package/dist/eip3009.d.ts.map +1 -0
  19. package/dist/eip3009.js +34 -0
  20. package/dist/eip3009.js.map +1 -0
  21. package/dist/eventsink.d.ts +19 -0
  22. package/dist/eventsink.d.ts.map +1 -0
  23. package/dist/eventsink.js +110 -0
  24. package/dist/eventsink.js.map +1 -0
  25. package/dist/index.d.ts +14 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +14 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/license.d.ts +178 -0
  30. package/dist/license.d.ts.map +1 -0
  31. package/dist/license.js +252 -0
  32. package/dist/license.js.map +1 -0
  33. package/dist/networks.d.ts +63 -0
  34. package/dist/networks.d.ts.map +1 -0
  35. package/dist/networks.js +84 -0
  36. package/dist/networks.js.map +1 -0
  37. package/dist/observationsink.d.ts +22 -0
  38. package/dist/observationsink.d.ts.map +1 -0
  39. package/dist/observationsink.js +83 -0
  40. package/dist/observationsink.js.map +1 -0
  41. package/dist/publisher.d.ts +209 -0
  42. package/dist/publisher.d.ts.map +1 -0
  43. package/dist/publisher.js +2 -0
  44. package/dist/publisher.js.map +1 -0
  45. package/dist/settlementEmit.d.ts +31 -0
  46. package/dist/settlementEmit.d.ts.map +1 -0
  47. package/dist/settlementEmit.js +65 -0
  48. package/dist/settlementEmit.js.map +1 -0
  49. package/dist/supabase.d.ts +8 -0
  50. package/dist/supabase.d.ts.map +1 -0
  51. package/dist/supabase.js +47 -0
  52. package/dist/supabase.js.map +1 -0
  53. package/dist/types.d.ts +154 -0
  54. package/dist/types.d.ts.map +1 -0
  55. package/dist/types.js +22 -0
  56. package/dist/types.js.map +1 -0
  57. package/package.json +44 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * A tiny Supabase client — just `fetch` against PostgREST, no SDK.
3
+ *
4
+ * We deliberately avoid `@supabase/supabase-js`: the only Supabase features the
5
+ * toll needs are "insert a row" and "select rows", both of which PostgREST
6
+ * exposes directly at `${SUPABASE_URL}/rest/v1/<table>`. Skipping the SDK keeps
7
+ * the dependency tree flat, leaves the offline (jsonl/memory) path with nothing
8
+ * extra to install, and runs unchanged on any runtime (Node or edge).
9
+ *
10
+ * Auth uses the service-role key in both `apikey` and `Authorization` — this
11
+ * runs server-side only (tollgate/dashboard/attribution), never in a browser.
12
+ */
13
+ import { getConfig } from "./config.js";
14
+ function creds() {
15
+ const cfg = getConfig();
16
+ if (!cfg.SUPABASE_URL || !cfg.SUPABASE_SERVICE_KEY) {
17
+ throw new Error("Supabase backend selected but SUPABASE_URL / SUPABASE_SERVICE_KEY are unset. See .env.example.");
18
+ }
19
+ return { url: cfg.SUPABASE_URL.replace(/\/$/, ""), key: cfg.SUPABASE_SERVICE_KEY };
20
+ }
21
+ /**
22
+ * Call the Supabase REST (PostgREST) API and return the parsed JSON body.
23
+ * Throws on any non-2xx so callers fail loud rather than silently losing a
24
+ * write. `path` is everything after the project URL, e.g.
25
+ * `/rest/v1/naulon_events?select=data&order=at.asc`.
26
+ */
27
+ export async function supabaseRest(path, init = {}) {
28
+ const { url, key } = creds();
29
+ const res = await fetch(`${url}${path}`, {
30
+ ...init,
31
+ headers: {
32
+ apikey: key,
33
+ authorization: `Bearer ${key}`,
34
+ "content-type": "application/json",
35
+ ...init.headers,
36
+ },
37
+ });
38
+ if (!res.ok) {
39
+ const body = await res.text().catch(() => "");
40
+ throw new Error(`Supabase ${init.method ?? "GET"} ${path} failed: ${res.status} ${body}`);
41
+ }
42
+ if (res.status === 204)
43
+ return [];
44
+ const text = await res.text();
45
+ return text ? JSON.parse(text) : [];
46
+ }
47
+ //# sourceMappingURL=supabase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../src/supabase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,SAAS,KAAK;IACZ,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CACb,gGAAgG,CACjG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,oBAAoB,EAAE,CAAC;AACrF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,OAAoB,EAAE;IACrE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE;QACvC,GAAG,IAAI;QACP,OAAO,EAAE;YACP,MAAM,EAAE,GAAG;YACX,aAAa,EAAE,UAAU,GAAG,EAAE;YAC9B,cAAc,EAAE,kBAAkB;YAClC,GAAI,IAAI,CAAC,OAA8C;SACxD;KACF,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,IAAI,YAAY,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Core domain types shared across the four naulon components.
3
+ *
4
+ * The thesis in one type: an attributed read/citation event resolves to one or
5
+ * more author wallets, each owed a fraction of the toll. Attribution metadata
6
+ * *is* the payout rule.
7
+ */
8
+ import { walletAddress } from "@naulon/sdk";
9
+ import type { WalletAddress, ArticleCredits, Contributor, CreditsResolver } from "@naulon/sdk";
10
+ export { walletAddress };
11
+ export type { WalletAddress, ArticleCredits, Contributor, CreditsResolver };
12
+ /** USDC amount in whole-token units (e.g. 0.001 = one tenth of a cent). */
13
+ export type Usdc = number & {
14
+ readonly __brand: "Usdc";
15
+ };
16
+ /** Gateway nanopayment floor. Amounts below this can't settle. */
17
+ export declare const USDC_FLOOR: Usdc;
18
+ export declare function usdc(value: number): Usdc;
19
+ /** A reason a request must pay — what kind of machine consumption happened. */
20
+ export type TollKind = "read" | "citation";
21
+ /**
22
+ * An author and the share of a toll they are owed.
23
+ * `share` is a fraction in [0, 1]; shares across a split sum to 1.
24
+ */
25
+ export interface AuthorShare {
26
+ authorId: string;
27
+ wallet: WalletAddress;
28
+ share: number;
29
+ }
30
+ /** A 402 payment requirement the tollgate hands an agent. */
31
+ export interface PaymentRequirement {
32
+ slug: string;
33
+ kind: TollKind;
34
+ price: Usdc;
35
+ /** Where settlement lands — resolved author wallets + shares. */
36
+ payees: AuthorShare[];
37
+ /** Arc network coordinates the agent needs to construct payment. */
38
+ network: {
39
+ chainId: number;
40
+ usdc: WalletAddress;
41
+ gateway: string;
42
+ };
43
+ /** Opaque nonce the agent echoes back in its signed payment. */
44
+ nonce: string;
45
+ }
46
+ /**
47
+ * Where attributed events are written and read. JSONL today; swap for
48
+ * Supabase/Postgres by implementing this interface — callers (tollgate,
49
+ * attribution, dashboard) don't change. Mirrors the CreditsResolver seam.
50
+ */
51
+ export interface EventSink {
52
+ record(event: AttributedEvent): Promise<void>;
53
+ /**
54
+ * Read events from the ledger. The optional `publisherId` filters to one
55
+ * publisher's events — an embedding seam a downstream resolver-based deploy can
56
+ * use to drain a single publisher in isolation. Omitted (the single-tenant
57
+ * default, and every OSS caller — dashboard, attribution) returns every event.
58
+ */
59
+ readAll(publisherId?: string): Promise<AttributedEvent[]>;
60
+ /**
61
+ * Fetch a single event by id (= a license `jti`). Backs `GET /licenses/:jti`
62
+ * without scanning the whole ledger — Supabase does a primary-key lookup;
63
+ * jsonl short-circuits on the first match. Returns undefined if not found.
64
+ */
65
+ get(id: string): Promise<AttributedEvent | undefined>;
66
+ }
67
+ /** A settled, attributed event — the row the dashboard reads. */
68
+ export interface AttributedEvent {
69
+ id: string;
70
+ /**
71
+ * The publisher this event is attributed to — `PublisherConfig.id` (the default
72
+ * resolver's is `"default"`). Optional: an embedding seam a downstream
73
+ * resolver-based deploy uses to attribute earnings; the single-tenant core
74
+ * neither filters nor drains on it, and every existing ledger row stays valid.
75
+ */
76
+ publisherId?: string;
77
+ slug: string;
78
+ kind: TollKind;
79
+ amount: Usdc;
80
+ payees: AuthorShare[];
81
+ payerAddress: WalletAddress;
82
+ /** Gateway settlement / batch reference. */
83
+ settlementRef: string;
84
+ /** epoch ms — passed in by the caller (no ambient clock in shared code). */
85
+ at: number;
86
+ }
87
+ /**
88
+ * What happened to a gated request, for the observability/audit plane. Unlike
89
+ * `AttributedEvent` (which exists ONLY when money moved), an observation is
90
+ * emitted for every gated-route decision — including the ones that earn nothing:
91
+ * a crawler served free, an agent that got a 402 and walked away. That negative
92
+ * space ("who is reading/scraping me without paying") is the audit product; the
93
+ * settlement ledger structurally can't see it.
94
+ */
95
+ export type ObservationVerdict =
96
+ /** Read free — a human, or a crawler the publisher allow-listed (e.g. search). */
97
+ "served-free"
98
+ /** An agent re-read on a valid, unexpired license (already paid earlier). */
99
+ | "agent-reread"
100
+ /** An agent got a 402 and presented no payment — the "scrape attempt, blocked". */
101
+ | "denied"
102
+ /** An agent the publisher explicitly blocked — refused 403, payment or not. */
103
+ | "blocked"
104
+ /** An agent presented payment that failed verify/settle — never served. */
105
+ | "payment-failed"
106
+ /** An agent paid; content served + license minted. Mirrors an `AttributedEvent`. */
107
+ | "paid";
108
+ /**
109
+ * One gated-request observation. Telemetry only — it never gates a request or
110
+ * moves money; emitting it must never change a serving decision. Higher volume
111
+ * and lower value than `AttributedEvent`, so a sink is expected to TTL/sample it.
112
+ */
113
+ export interface ObservationEvent {
114
+ /** uuid. */
115
+ id: string;
116
+ /** The publisher this request resolved to (`PublisherConfig.id`); optional like `AttributedEvent`. */
117
+ publisherId?: string;
118
+ /** The Host header the request came in on. */
119
+ host: string;
120
+ /** The article slug the gate priced (empty string for a non-article gated path). */
121
+ slug: string;
122
+ /** read | citation when the request reached the machine path; absent for a plain human read. */
123
+ kind?: TollKind;
124
+ verdict: ObservationVerdict;
125
+ /** The classifier's call — what the gate thought the caller was. */
126
+ classifiedAs: "human" | "agent";
127
+ /** Why the classifier ruled that way (e.g. which UA pattern matched). */
128
+ classifyReason?: string;
129
+ /** Raw User-Agent — the MVP identity basis (spoofable; Web Bot Auth supersedes it). */
130
+ agentUa?: string;
131
+ /** True when the caller's Web Bot Auth signature (RFC 9421/Ed25519) verified. */
132
+ verified?: boolean;
133
+ /** The verified operator's directory host (e.g. "chatgpt.com"), when verified. */
134
+ verifiedAgent?: string;
135
+ /**
136
+ * True when a signature was PRESENTED and failed verification — a masquerade
137
+ * attempt (or a badly broken signer), distinct from plain unsigned traffic.
138
+ */
139
+ sigInvalid?: boolean;
140
+ /** The quoted price (paid → settled; denied/payment-failed → what they'd have paid = "earnings missed"). */
141
+ price?: Usdc;
142
+ /** epoch ms — passed in by the caller (no ambient clock in shared code). */
143
+ at: number;
144
+ }
145
+ /**
146
+ * Where gated-request observations are written. A deliberate sibling of
147
+ * `EventSink` — same backend story (jsonl / supabase), same one-way seam — but
148
+ * write-only from the gate's side; the downstream audit BFF owns reads. Defaults
149
+ * to a no-op so the open core records nothing unless a deploy opts in.
150
+ */
151
+ export interface ObservationSink {
152
+ record(observation: ObservationEvent): Promise<void>;
153
+ }
154
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Core domain types shared across the four naulon components.
3
+ *
4
+ * The thesis in one type: an attributed read/citation event resolves to one or
5
+ * more author wallets, each owed a fraction of the toll. Attribution metadata
6
+ * *is* the payout rule.
7
+ */
8
+ // The wallet + credits contract primitives now live in @naulon/sdk (the
9
+ // publisher SDK — one source of truth for the money-routing wire contract).
10
+ // Imported for use in the gate-internal types below AND re-exported so every
11
+ // existing `from "@naulon/shared"` import keeps resolving unchanged.
12
+ import { walletAddress } from "@naulon/sdk";
13
+ export { walletAddress };
14
+ /** Gateway nanopayment floor. Amounts below this can't settle. */
15
+ export const USDC_FLOOR = 0.000001;
16
+ export function usdc(value) {
17
+ if (!Number.isFinite(value) || value < 0) {
18
+ throw new Error(`invalid USDC amount: ${value}`);
19
+ }
20
+ return value;
21
+ }
22
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,wEAAwE;AACxE,4EAA4E;AAC5E,6EAA6E;AAC7E,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,CAAC;AAMzB,kEAAkE;AAClE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAgB,CAAC;AAE3C,MAAM,UAAU,IAAI,CAAC,KAAa;IAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAa,CAAC;AACvB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@naulon/shared",
3
+ "version": "0.0.1",
4
+ "license": "MIT",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/naulonapp/naulon.git",
8
+ "directory": "packages/shared"
9
+ },
10
+ "type": "module",
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ },
18
+ "./config": {
19
+ "types": "./dist/config.d.ts",
20
+ "import": "./dist/config.js"
21
+ },
22
+ "./types": {
23
+ "types": "./dist/types.d.ts",
24
+ "import": "./dist/types.js"
25
+ },
26
+ "./attribution": {
27
+ "types": "./dist/attribution.d.ts",
28
+ "import": "./dist/attribution.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.json",
36
+ "prepublishOnly": "npm run build",
37
+ "test": "node --import tsx --test \"src/**/*.test.ts\""
38
+ },
39
+ "dependencies": {
40
+ "@naulon/sdk": "^0.1.0",
41
+ "dotenv": "^17.4.2",
42
+ "zod": "^4.4.3"
43
+ }
44
+ }