@drm3/sdk 0.1.2

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 (228) hide show
  1. package/LICENSE +75 -0
  2. package/README.md +426 -0
  3. package/bin/drm3.js +255 -0
  4. package/dist/alerts-bell.d.ts +7 -0
  5. package/dist/alerts-bell.d.ts.map +1 -0
  6. package/dist/alerts-bell.js +118 -0
  7. package/dist/alerts-bell.js.map +1 -0
  8. package/dist/alerts-fetch.d.ts +41 -0
  9. package/dist/alerts-fetch.d.ts.map +1 -0
  10. package/dist/alerts-fetch.js +60 -0
  11. package/dist/alerts-fetch.js.map +1 -0
  12. package/dist/alerts-styles.d.ts +4 -0
  13. package/dist/alerts-styles.d.ts.map +1 -0
  14. package/dist/alerts-styles.js +49 -0
  15. package/dist/alerts-styles.js.map +1 -0
  16. package/dist/alerts.d.ts +3 -0
  17. package/dist/alerts.d.ts.map +1 -0
  18. package/dist/alerts.global.js +206 -0
  19. package/dist/alerts.global.text.js +2 -0
  20. package/dist/alerts.js +21 -0
  21. package/dist/alerts.js.map +1 -0
  22. package/dist/index.d.ts +64 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +117 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/keys-canonical.d.ts +7 -0
  27. package/dist/keys-canonical.d.ts.map +1 -0
  28. package/dist/keys-canonical.js +57 -0
  29. package/dist/keys-canonical.js.map +1 -0
  30. package/dist/keys-generate.d.ts +39 -0
  31. package/dist/keys-generate.d.ts.map +1 -0
  32. package/dist/keys-generate.js +39 -0
  33. package/dist/keys-generate.js.map +1 -0
  34. package/dist/keys-verify.d.ts +62 -0
  35. package/dist/keys-verify.d.ts.map +1 -0
  36. package/dist/keys-verify.js +68 -0
  37. package/dist/keys-verify.js.map +1 -0
  38. package/dist/keys.d.ts +4 -0
  39. package/dist/keys.d.ts.map +1 -0
  40. package/dist/keys.js +22 -0
  41. package/dist/keys.js.map +1 -0
  42. package/dist/meter/adapter.d.ts +35 -0
  43. package/dist/meter/adapter.d.ts.map +1 -0
  44. package/dist/meter/adapter.js +0 -0
  45. package/dist/meter/adapter.js.map +1 -0
  46. package/dist/meter/cascade.d.ts +56 -0
  47. package/dist/meter/cascade.d.ts.map +1 -0
  48. package/dist/meter/cascade.js +64 -0
  49. package/dist/meter/cascade.js.map +1 -0
  50. package/dist/meter/client.d.ts +78 -0
  51. package/dist/meter/client.d.ts.map +1 -0
  52. package/dist/meter/client.js +84 -0
  53. package/dist/meter/client.js.map +1 -0
  54. package/dist/meter/core.d.ts +37 -0
  55. package/dist/meter/core.d.ts.map +1 -0
  56. package/dist/meter/core.js +49 -0
  57. package/dist/meter/core.js.map +1 -0
  58. package/dist/meter/gate-client.d.ts +94 -0
  59. package/dist/meter/gate-client.d.ts.map +1 -0
  60. package/dist/meter/gate-client.js +77 -0
  61. package/dist/meter/gate-client.js.map +1 -0
  62. package/dist/meter/gate-decide.d.ts +61 -0
  63. package/dist/meter/gate-decide.d.ts.map +1 -0
  64. package/dist/meter/gate-decide.js +54 -0
  65. package/dist/meter/gate-decide.js.map +1 -0
  66. package/dist/meter/gate.d.ts +10 -0
  67. package/dist/meter/gate.d.ts.map +1 -0
  68. package/dist/meter/gate.js +10 -0
  69. package/dist/meter/gate.js.map +1 -0
  70. package/dist/meter/index.d.ts +28 -0
  71. package/dist/meter/index.d.ts.map +1 -0
  72. package/dist/meter/index.js +28 -0
  73. package/dist/meter/index.js.map +1 -0
  74. package/dist/meter/meters-buckets.d.ts +56 -0
  75. package/dist/meter/meters-buckets.d.ts.map +1 -0
  76. package/dist/meter/meters-buckets.js +111 -0
  77. package/dist/meter/meters-buckets.js.map +1 -0
  78. package/dist/meter/meters-charge.d.ts +13 -0
  79. package/dist/meter/meters-charge.d.ts.map +1 -0
  80. package/dist/meter/meters-charge.js +76 -0
  81. package/dist/meter/meters-charge.js.map +1 -0
  82. package/dist/meter/meters.d.ts +63 -0
  83. package/dist/meter/meters.d.ts.map +1 -0
  84. package/dist/meter/meters.js +44 -0
  85. package/dist/meter/meters.js.map +1 -0
  86. package/dist/meter/plans.d.ts +63 -0
  87. package/dist/meter/plans.d.ts.map +1 -0
  88. package/dist/meter/plans.js +114 -0
  89. package/dist/meter/plans.js.map +1 -0
  90. package/dist/meter/pricebook.d.ts +32 -0
  91. package/dist/meter/pricebook.d.ts.map +1 -0
  92. package/dist/meter/pricebook.js +38 -0
  93. package/dist/meter/pricebook.js.map +1 -0
  94. package/dist/meter/resolve.d.ts +103 -0
  95. package/dist/meter/resolve.d.ts.map +1 -0
  96. package/dist/meter/resolve.js +100 -0
  97. package/dist/meter/resolve.js.map +1 -0
  98. package/dist/meter/sink.d.ts +26 -0
  99. package/dist/meter/sink.d.ts.map +1 -0
  100. package/dist/meter/sink.js +9 -0
  101. package/dist/meter/sink.js.map +1 -0
  102. package/dist/meter/sql/d1.d.ts +32 -0
  103. package/dist/meter/sql/d1.d.ts.map +1 -0
  104. package/dist/meter/sql/d1.js +41 -0
  105. package/dist/meter/sql/d1.js.map +1 -0
  106. package/dist/meter/sql/driver.d.ts +34 -0
  107. package/dist/meter/sql/driver.d.ts.map +1 -0
  108. package/dist/meter/sql/driver.js +17 -0
  109. package/dist/meter/sql/driver.js.map +1 -0
  110. package/dist/meter/sql/postgres.d.ts +23 -0
  111. package/dist/meter/sql/postgres.d.ts.map +1 -0
  112. package/dist/meter/sql/postgres.js +36 -0
  113. package/dist/meter/sql/postgres.js.map +1 -0
  114. package/dist/meter/sql/schema.d.ts +13 -0
  115. package/dist/meter/sql/schema.d.ts.map +1 -0
  116. package/dist/meter/sql/schema.js +32 -0
  117. package/dist/meter/sql/schema.js.map +1 -0
  118. package/dist/meter/sql/sql-adapter.d.ts +36 -0
  119. package/dist/meter/sql/sql-adapter.d.ts.map +1 -0
  120. package/dist/meter/sql/sql-adapter.js +124 -0
  121. package/dist/meter/sql/sql-adapter.js.map +1 -0
  122. package/dist/meter/sql/statements.d.ts +30 -0
  123. package/dist/meter/sql/statements.d.ts.map +1 -0
  124. package/dist/meter/sql/statements.js +24 -0
  125. package/dist/meter/sql/statements.js.map +1 -0
  126. package/dist/meter/types.d.ts +48 -0
  127. package/dist/meter/types.d.ts.map +1 -0
  128. package/dist/meter/types.js +8 -0
  129. package/dist/meter/types.js.map +1 -0
  130. package/dist/meter/units.d.ts +33 -0
  131. package/dist/meter/units.d.ts.map +1 -0
  132. package/dist/meter/units.js +45 -0
  133. package/dist/meter/units.js.map +1 -0
  134. package/dist/meter/wallet-buckets.d.ts +63 -0
  135. package/dist/meter/wallet-buckets.d.ts.map +1 -0
  136. package/dist/meter/wallet-buckets.js +131 -0
  137. package/dist/meter/wallet-buckets.js.map +1 -0
  138. package/dist/meter/wallet-charge.d.ts +15 -0
  139. package/dist/meter/wallet-charge.d.ts.map +1 -0
  140. package/dist/meter/wallet-charge.js +64 -0
  141. package/dist/meter/wallet-charge.js.map +1 -0
  142. package/dist/meter/wallet.d.ts +68 -0
  143. package/dist/meter/wallet.d.ts.map +1 -0
  144. package/dist/meter/wallet.js +47 -0
  145. package/dist/meter/wallet.js.map +1 -0
  146. package/dist/receipts-api.d.ts +5 -0
  147. package/dist/receipts-api.d.ts.map +1 -0
  148. package/dist/receipts-api.js +117 -0
  149. package/dist/receipts-api.js.map +1 -0
  150. package/dist/receipts-chain.d.ts +3 -0
  151. package/dist/receipts-chain.d.ts.map +1 -0
  152. package/dist/receipts-chain.js +121 -0
  153. package/dist/receipts-chain.js.map +1 -0
  154. package/dist/receipts-modal.d.ts +14 -0
  155. package/dist/receipts-modal.d.ts.map +1 -0
  156. package/dist/receipts-modal.js +100 -0
  157. package/dist/receipts-modal.js.map +1 -0
  158. package/dist/receipts-registry.d.ts +4 -0
  159. package/dist/receipts-registry.d.ts.map +1 -0
  160. package/dist/receipts-registry.js +54 -0
  161. package/dist/receipts-registry.js.map +1 -0
  162. package/dist/receipts-render.d.ts +9 -0
  163. package/dist/receipts-render.d.ts.map +1 -0
  164. package/dist/receipts-render.js +83 -0
  165. package/dist/receipts-render.js.map +1 -0
  166. package/dist/receipts-types.d.ts +61 -0
  167. package/dist/receipts-types.d.ts.map +1 -0
  168. package/dist/receipts-types.js +12 -0
  169. package/dist/receipts-types.js.map +1 -0
  170. package/dist/receipts-ui.d.ts +10 -0
  171. package/dist/receipts-ui.d.ts.map +1 -0
  172. package/dist/receipts-ui.js +103 -0
  173. package/dist/receipts-ui.js.map +1 -0
  174. package/dist/receipts-verify.d.ts +8 -0
  175. package/dist/receipts-verify.d.ts.map +1 -0
  176. package/dist/receipts-verify.js +113 -0
  177. package/dist/receipts-verify.js.map +1 -0
  178. package/dist/receipts.d.ts +9 -0
  179. package/dist/receipts.d.ts.map +1 -0
  180. package/dist/receipts.global.js +587 -0
  181. package/dist/receipts.global.text.js +2 -0
  182. package/dist/receipts.js +28 -0
  183. package/dist/receipts.js.map +1 -0
  184. package/dist/sso/index.d.ts +4 -0
  185. package/dist/sso/index.d.ts.map +1 -0
  186. package/dist/sso/index.js +10 -0
  187. package/dist/sso/index.js.map +1 -0
  188. package/dist/sso/jwt.d.ts +29 -0
  189. package/dist/sso/jwt.d.ts.map +1 -0
  190. package/dist/sso/jwt.js +73 -0
  191. package/dist/sso/jwt.js.map +1 -0
  192. package/dist/sso/launch.d.ts +70 -0
  193. package/dist/sso/launch.d.ts.map +1 -0
  194. package/dist/sso/launch.js +75 -0
  195. package/dist/sso/launch.js.map +1 -0
  196. package/dist/sso/revocation.d.ts +23 -0
  197. package/dist/sso/revocation.d.ts.map +1 -0
  198. package/dist/sso/revocation.js +53 -0
  199. package/dist/sso/revocation.js.map +1 -0
  200. package/dist/switcher.d.ts +22 -0
  201. package/dist/switcher.d.ts.map +1 -0
  202. package/dist/switcher.js +174 -0
  203. package/dist/switcher.js.map +1 -0
  204. package/dist/x402/chain.d.ts +49 -0
  205. package/dist/x402/chain.d.ts.map +1 -0
  206. package/dist/x402/chain.js +33 -0
  207. package/dist/x402/chain.js.map +1 -0
  208. package/dist/x402/crypto.d.ts +25 -0
  209. package/dist/x402/crypto.d.ts.map +1 -0
  210. package/dist/x402/crypto.js +74 -0
  211. package/dist/x402/crypto.js.map +1 -0
  212. package/dist/x402/eip712.d.ts +20 -0
  213. package/dist/x402/eip712.d.ts.map +1 -0
  214. package/dist/x402/eip712.js +49 -0
  215. package/dist/x402/eip712.js.map +1 -0
  216. package/dist/x402/envelope.d.ts +45 -0
  217. package/dist/x402/envelope.d.ts.map +1 -0
  218. package/dist/x402/envelope.js +50 -0
  219. package/dist/x402/envelope.js.map +1 -0
  220. package/dist/x402/index.d.ts +41 -0
  221. package/dist/x402/index.d.ts.map +1 -0
  222. package/dist/x402/index.js +41 -0
  223. package/dist/x402/index.js.map +1 -0
  224. package/dist/x402/verify.d.ts +51 -0
  225. package/dist/x402/verify.d.ts.map +1 -0
  226. package/dist/x402/verify.js +110 -0
  227. package/dist/x402/verify.js.map +1 -0
  228. package/package.json +100 -0
@@ -0,0 +1,117 @@
1
+ // @drm3/sdk/receipts - the public drop-in API (open a modal, resolve by id, mount).
2
+ //
3
+ // openReceiptModal(chain, { registryUrl, resolverBase });
4
+ // openReceiptById("rcpt_…", { resolverBase: "https://your-app.example" });
5
+ // mountVerifyButton(el, chainOrReceiptOrId, cfg);
6
+ import { verifyChainInto } from "./receipts-chain.js";
7
+ import { appendDownload, buildModal, sealVerdict } from "./receipts-modal.js";
8
+ import { loadRegistry, resolveReceipt } from "./receipts-registry.js";
9
+ import { CHECK, injectStyles } from "./receipts-ui.js";
10
+ import { isEd25519Supported } from "./receipts-verify.js";
11
+ // The config of the most-recently-opened modal. Gated-leg "resolve this receipt"
12
+ // links call openReceiptById with no cfg, and fall back to this so they resolve
13
+ // against the same host/registry the current modal used. A module variable (always
14
+ // writable) - never a property on window.drm3Receipts, which may be a read-only
15
+ // esbuild namespace with getter-only exports.
16
+ let activeCfg = {};
17
+ // Verify + render a receipt chain you already hold. Opens the gorgeous modal, runs
18
+ // the live tri-state verification, and seals with the aggregate verdict.
19
+ export async function openReceiptModal(chain, cfg = activeCfg) {
20
+ if (typeof document === "undefined")
21
+ return;
22
+ registerGlobal(cfg);
23
+ const { final, addStep, settle, wait } = buildModal(cfg.title || "Provenance receipt", cfg.subtitle ||
24
+ "A signed, content-addressed receipt, verified <b>in your browser</b> against the public key registry. Each leg confirms only the one before it; anything it cannot open, it says so.");
25
+ if (!(await isEd25519Supported())) {
26
+ final.className = "drm3v-final bad";
27
+ final.innerHTML =
28
+ "This browser can't do Ed25519 in the page (try a recent Chrome, Safari, or Firefox). The receipts are still independently verifiable - see <b>status.drm3.network</b>.";
29
+ return;
30
+ }
31
+ if (!chain.length) {
32
+ final.className = "drm3v-final bad";
33
+ final.textContent = "No receipts attached.";
34
+ return;
35
+ }
36
+ const registry = await loadRegistry(cfg.registryUrl);
37
+ const counts = await verifyChainInto(chain, registry, addStep, settle, wait, cfg.contentRef);
38
+ await wait(200);
39
+ sealVerdict(final, counts);
40
+ if (chain.length === 1)
41
+ appendDownload(final, `receipt-${chain[0].id || "drm3"}.json`, chain[0].receipt_json || chain[0]);
42
+ }
43
+ // Resolve a receipt by its content-addressed id (DRM3 resolver convention) and
44
+ // render it. The resolved envelope's `receipt` is treated as the chain head.
45
+ export async function openReceiptById(id, cfg = activeCfg) {
46
+ if (typeof document === "undefined")
47
+ return;
48
+ registerGlobal(cfg);
49
+ const { final, addStep, settle, wait } = buildModal(cfg.title || "Provenance receipt", cfg.subtitle || "Resolved by its content-addressed id and verified <b>in your browser</b> against the public key registry.");
50
+ if (!(await isEd25519Supported())) {
51
+ final.className = "drm3v-final bad";
52
+ final.innerHTML = "This browser can't do Ed25519 in the page. The receipt is still independently verifiable - see <b>status.drm3.network</b>.";
53
+ return;
54
+ }
55
+ const resolved = await resolveReceipt(id, cfg);
56
+ if (!resolved?.receipt) {
57
+ final.className = "drm3v-final bad";
58
+ final.textContent = "This receipt isn't retrievable here (it may live on another host, or require access).";
59
+ return;
60
+ }
61
+ const rc = resolved.receipt;
62
+ const chain = [
63
+ {
64
+ id,
65
+ receipt_json: rc,
66
+ signature: rc.signature,
67
+ public_key: rc.public_key,
68
+ action: rc.action,
69
+ },
70
+ ];
71
+ const registry = await loadRegistry(cfg.registryUrl);
72
+ const counts = await verifyChainInto(chain, registry, addStep, settle, wait, cfg.contentRef);
73
+ await wait(200);
74
+ sealVerdict(final, counts);
75
+ appendDownload(final, `receipt-${id}.json`, rc);
76
+ }
77
+ // Mount a "Verify provenance" button into `target`. `source` is either a receipt
78
+ // chain (array), a single receipt, or a string receipt-id to resolve on click.
79
+ export function mountVerifyButton(target, source, cfg = {}) {
80
+ if (!target || typeof document === "undefined")
81
+ return;
82
+ injectStyles();
83
+ const btn = document.createElement("button");
84
+ btn.type = "button";
85
+ btn.className = "drm3v-trigger";
86
+ btn.innerHTML = `${CHECK}<span>Verify provenance in your browser</span>`;
87
+ btn.addEventListener("click", async () => {
88
+ const resolved = typeof source === "function" ? await source() : source;
89
+ if (typeof resolved === "string")
90
+ return void openReceiptById(resolved, cfg);
91
+ const chain = Array.isArray(resolved) ? resolved : [resolved];
92
+ return void openReceiptModal(chain, cfg);
93
+ });
94
+ target.appendChild(btn);
95
+ }
96
+ // Remember the active config (for gated-leg links) and ensure a stable global
97
+ // exists so inline "resolve this receipt" links (rendered as HTML strings) can
98
+ // reach the resolver cross-app. When the viewer is loaded as the prebuilt IIFE,
99
+ // window.drm3Receipts is already the esbuild namespace (read-only getters) and
100
+ // ALSO exposes these functions, so we leave it untouched - assigning onto it
101
+ // throws ("only a getter"). We only create the global when it's absent (the
102
+ // bundler-import path, where consumers import the functions directly).
103
+ function registerGlobal(cfg) {
104
+ activeCfg = cfg;
105
+ if (typeof window === "undefined")
106
+ return;
107
+ const w = window;
108
+ if (!w.drm3Receipts) {
109
+ try {
110
+ w.drm3Receipts = { openReceiptById, openReceiptModal, mountVerifyButton };
111
+ }
112
+ catch {
113
+ /* read-only global already present - it exposes the API itself */
114
+ }
115
+ }
116
+ }
117
+ //# sourceMappingURL=receipts-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-api.js","sourceRoot":"","sources":["../src/receipts-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type AddStep, type ContentRef, type Counts, type Receipt, type RegKey, type Settle, type Wait } from "./receipts-types.js";
2
+ export declare function verifyChainInto(chain: Receipt[], registry: Map<string, RegKey>, addStep: AddStep, settle: Settle, wait: Wait, contentRef?: ContentRef): Promise<Counts>;
3
+ //# sourceMappingURL=receipts-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-chain.d.ts","sourceRoot":"","sources":["../src/receipts-chain.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,MAAM,EAEX,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,MAAM,EAIX,KAAK,IAAI,EACV,MAAM,qBAAqB,CAAC;AA0B7B,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EAAE,EAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,EACV,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,MAAM,CAAC,CAmFjB"}
@@ -0,0 +1,121 @@
1
+ // @drm3/sdk/receipts - the shared tri-state chain verifier.
2
+ //
3
+ // Same verifier for a single receipt or a full fetch→analyze→compose DAG. Renders
4
+ // into caller-provided hooks and returns tri-state counts.
5
+ import { esc, legDetail, prettyAction, shortHex, shortKey } from "./receipts-render.js";
6
+ import { FAILED, UNVERIFIABLE_NO_ACCESS, VERIFIED, } from "./receipts-types.js";
7
+ import { verifyReceipt } from "./receipts-verify.js";
8
+ // Parent receipt ids this leg derives from: top-level parent_receipt_id plus
9
+ // receipt_json.parent_id / inputs[].ref.
10
+ function parentRefs(r, pj) {
11
+ const out = [];
12
+ const add = (v) => {
13
+ if (typeof v === "string" && v)
14
+ out.push(v);
15
+ };
16
+ add(r.parent_receipt_id);
17
+ add(pj?.parent_id);
18
+ for (const e of pj?.inputs || [])
19
+ if (e && typeof e === "object")
20
+ add(e.ref);
21
+ return out;
22
+ }
23
+ function safeParse(s) {
24
+ try {
25
+ return JSON.parse(s);
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ // ── shared chain verifier ────────────────────────────────────────────────────
32
+ // Verify a receipt chain into caller-provided render hooks, returning tri-state
33
+ // counts. Same verifier for a single receipt or a full fetch→analyze→compose DAG.
34
+ export async function verifyChainInto(chain, registry, addStep, settle, wait, contentRef) {
35
+ const counts = { verified: 0, gated: 0, failed: 0 };
36
+ // The chain we hold is the set of legs THIS caller can retrieve. Any leg
37
+ // referenced by a parent link that is NOT in this set is gated - we can see the
38
+ // leg derived from it, but the receipt itself isn't retrievable. A STATE, not a fault.
39
+ const present = new Set();
40
+ for (const r of chain) {
41
+ const pj = (typeof r.receipt_json === "string" ? safeParse(r.receipt_json) : r.receipt_json);
42
+ if (r.id)
43
+ present.add(r.id);
44
+ if (typeof pj?.id === "string")
45
+ present.add(pj.id);
46
+ }
47
+ const referencedGated = new Set();
48
+ for (const r of chain) {
49
+ const pj = (typeof r.receipt_json === "string" ? safeParse(r.receipt_json) : r.receipt_json);
50
+ for (const pid of parentRefs(r, pj))
51
+ if (!present.has(pid))
52
+ referencedGated.add(pid);
53
+ }
54
+ // oldest first for a natural chain animation
55
+ const ordered = [...chain].reverse();
56
+ for (const r of ordered) {
57
+ const payload = (typeof r.receipt_json === "string" ? JSON.parse(r.receipt_json) : r.receipt_json);
58
+ const action = (r.action || payload?.action || r.receipt_type || "receipt");
59
+ const pub = (r.public_key || payload?.public_key || "").toLowerCase();
60
+ const signer = r.signer_path || payload?.metadata?._meta?.signer || "";
61
+ const el = addStep(prettyAction(action), signer ? `signer ${signer} · ${shortKey(pub)}` : shortKey(pub), legDetail(payload, contentRef));
62
+ await wait(420);
63
+ let ok = false;
64
+ try {
65
+ ok = await verifyReceipt(r);
66
+ }
67
+ catch {
68
+ ok = false;
69
+ }
70
+ const rec = registry.get(pub);
71
+ const known = registry.size === 0 || !!rec;
72
+ // Grade against the key's lifecycle. A receipt signed by a since-rotated
73
+ // (superseded/retired) key is STILL verified if its timestamp falls inside
74
+ // that key's window - the no-backfill state. Compromised/revoked => fail.
75
+ const ts = payload?.timestamp || r.timestamp || "";
76
+ let verdict = ok && known ? VERIFIED : FAILED;
77
+ let note = "";
78
+ if (ok && rec) {
79
+ if (rec.status === "compromised" || rec.status === "revoked") {
80
+ verdict = FAILED;
81
+ note = ` · ⚠ key ${rec.status}`;
82
+ }
83
+ else if (rec.status === "superseded" || rec.status === "retired") {
84
+ const inWindow = (!rec.valid_from || !ts || ts >= rec.valid_from) && (!rec.valid_until || !ts || ts <= rec.valid_until);
85
+ if (inWindow) {
86
+ verdict = VERIFIED;
87
+ note = ` · key since rotated${rec.valid_until ? ` ${rec.valid_until.slice(0, 10)}` : ""} (verified)`;
88
+ }
89
+ else {
90
+ verdict = FAILED;
91
+ note = " · ⚠ signed outside the key's validity window";
92
+ }
93
+ }
94
+ }
95
+ else if (ok && !known) {
96
+ note = " · ⚠ key not found in registry";
97
+ }
98
+ settle(el, verdict);
99
+ if (verdict === VERIFIED)
100
+ counts.verified++;
101
+ else
102
+ counts.failed++;
103
+ if (note) {
104
+ const meta = el.querySelector(".drm3v-meta");
105
+ if (meta)
106
+ meta.textContent += note;
107
+ }
108
+ await wait(180);
109
+ }
110
+ // Surface each referenced-but-unretrievable parent as its own gated leg, with the
111
+ // LINK: a resolve attempt against /receipts/:id so you can see where it lives.
112
+ for (const pid of referencedGated) {
113
+ const el = addStep("Upstream step (not accessible)", `referenced ${shortHex(pid)} · receipt not retrievable to you`, `<div class="drm3v-detail"><div class="drm3v-clinks"><a class="drm3v-clink" href="#" onclick="event.preventDefault();event.stopPropagation();window.drm3Receipts&&window.drm3Receipts.openReceiptById('${esc(pid)}')">resolve this receipt</a></div></div>`);
114
+ await wait(280);
115
+ settle(el, UNVERIFIABLE_NO_ACCESS);
116
+ counts.gated++;
117
+ await wait(120);
118
+ }
119
+ return counts;
120
+ }
121
+ //# sourceMappingURL=receipts-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-chain.js","sourceRoot":"","sources":["../src/receipts-chain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type AddStep, type Counts, type Settle, type Wait } from "./receipts-types.js";
2
+ export declare function appendDownload(host: HTMLElement, filename: string, obj: unknown): void;
3
+ interface ModalParts {
4
+ ov: HTMLElement;
5
+ steps: HTMLElement;
6
+ final: HTMLElement;
7
+ addStep: AddStep;
8
+ settle: Settle;
9
+ wait: Wait;
10
+ }
11
+ export declare function buildModal(title: string, subtitle: string): ModalParts;
12
+ export declare function sealVerdict(final: HTMLElement, counts: Counts): void;
13
+ export {};
14
+ //# sourceMappingURL=receipts-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-modal.d.ts","sourceRoot":"","sources":["../src/receipts-modal.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAkD,KAAK,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAaxI,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAQtF;AAED,UAAU,UAAU;IAClB,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;CACZ;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAgDtE;AAID,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAgBpE"}
@@ -0,0 +1,100 @@
1
+ // @drm3/sdk/receipts - the modal scaffolding + step/seal DOM.
2
+ //
3
+ // Builds the overlay, wires close handlers, and exposes the addStep/settle/wait
4
+ // render hooks the chain verifier drives. Also the download button + final seal.
5
+ import { countsLine, esc } from "./receipts-render.js";
6
+ import { UNVERIFIABLE_NO_ACCESS, VERIFIED } from "./receipts-types.js";
7
+ import { CHECK, DOWNLOAD, LOCK, RECEIPT, injectStyles } from "./receipts-ui.js";
8
+ // ── modal scaffolding ─────────────────────────────────────────────────────────
9
+ function dlJSON(filename, obj) {
10
+ const blob = new Blob([JSON.stringify(obj, null, 2)], { type: "application/json" });
11
+ const url = URL.createObjectURL(blob);
12
+ const a = document.createElement("a");
13
+ a.href = url;
14
+ a.download = filename;
15
+ a.click();
16
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
17
+ }
18
+ export function appendDownload(host, filename, obj) {
19
+ if (!obj)
20
+ return;
21
+ const btn = document.createElement("button");
22
+ btn.type = "button";
23
+ btn.className = "drm3v-dlbtn";
24
+ btn.innerHTML = `${DOWNLOAD}<span>Download receipt JSON</span>`;
25
+ btn.addEventListener("click", () => dlJSON(filename, obj));
26
+ host.appendChild(btn);
27
+ }
28
+ export function buildModal(title, subtitle) {
29
+ injectStyles();
30
+ const ov = document.createElement("div");
31
+ ov.className = "drm3v-ov";
32
+ ov.innerHTML = `<div class="drm3v-modal" role="dialog" aria-label="${esc(title)}">
33
+ <div class="drm3v-h"><h3>${RECEIPT}${esc(title)}</h3><button class="drm3v-x" aria-label="Close">&times;</button></div>
34
+ <div class="drm3v-sub">${subtitle}</div>
35
+ <div class="drm3v-steps"></div>
36
+ <div class="drm3v-final"></div></div>`;
37
+ document.body.appendChild(ov);
38
+ const close = () => ov.remove();
39
+ ov.addEventListener("click", (e) => {
40
+ if (e.target === ov)
41
+ close();
42
+ });
43
+ ov.querySelector(".drm3v-x")?.addEventListener("click", close);
44
+ const onEsc = (e) => {
45
+ if (e.key === "Escape") {
46
+ close();
47
+ document.removeEventListener("keydown", onEsc);
48
+ }
49
+ };
50
+ document.addEventListener("keydown", onEsc);
51
+ const steps = ov.querySelector(".drm3v-steps");
52
+ const final = ov.querySelector(".drm3v-final");
53
+ const addStep = (act, meta, detail) => {
54
+ const el = document.createElement("div");
55
+ el.className = "drm3v-step";
56
+ el.innerHTML = `<div class="drm3v-dot spin"></div><div class="drm3v-body"><div class="drm3v-act">${esc(act)}</div><div class="drm3v-meta">${esc(meta)}</div>${detail || ""}</div>`;
57
+ steps.appendChild(el);
58
+ requestAnimationFrame(() => el.classList.add("on"));
59
+ return el;
60
+ };
61
+ const settle = (el, verdict) => {
62
+ const dot = el.querySelector(".drm3v-dot");
63
+ if (verdict === VERIFIED) {
64
+ dot.className = "drm3v-dot ok";
65
+ dot.innerHTML = CHECK;
66
+ }
67
+ else if (verdict === UNVERIFIABLE_NO_ACCESS) {
68
+ dot.className = "drm3v-dot warn";
69
+ dot.innerHTML = LOCK;
70
+ }
71
+ else {
72
+ dot.className = "drm3v-dot bad";
73
+ dot.innerHTML = "&times;";
74
+ }
75
+ };
76
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
77
+ return { ov, steps, final, addStep, settle, wait };
78
+ }
79
+ // Aggregate (mirrors drm3-verifier): any failed dominates; else any gated →
80
+ // verified in part; else fully verified. A gated leg is normal, not a warning.
81
+ export function sealVerdict(final, counts) {
82
+ if (counts.verified + counts.gated + counts.failed === 0) {
83
+ final.className = "drm3v-final bad";
84
+ final.textContent = "No receipts were found to verify.";
85
+ return;
86
+ }
87
+ if (counts.failed > 0) {
88
+ final.className = "drm3v-final bad";
89
+ final.innerHTML = `One or more signatures did not verify. That's exactly what provenance is for - it tells you when something doesn't add up.${countsLine(counts)}`;
90
+ }
91
+ else if (counts.gated > 0) {
92
+ final.className = "drm3v-final part";
93
+ final.innerHTML = `${LOCK} <b>Verified in part.</b> Every receipt you could retrieve carries a valid Ed25519 signature from a registered DRM3 signer, checked right here in your browser. ${counts.gated} upstream step${counts.gated === 1 ? "" : "s"} ${counts.gated === 1 ? "is" : "are"} referenced but not accessible to you - a normal access boundary, not a failure.${countsLine(counts)}`;
94
+ }
95
+ else {
96
+ final.className = "drm3v-final ok";
97
+ final.innerHTML = `${CHECK} <b>Verified.</b> Every receipt in this chain carries a valid Ed25519 signature from a registered DRM3 signer - checked right here in your browser.${countsLine(counts)}`;
98
+ }
99
+ }
100
+ //# sourceMappingURL=receipts-modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-modal.js","sourceRoot":"","sources":["../src/receipts-modal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { RegKey, ResolvedReceipt, ViewerConfig } from "./receipts-types.js";
2
+ export declare function loadRegistry(url?: string): Promise<Map<string, RegKey>>;
3
+ export declare function resolveReceipt(id: string, cfg?: ViewerConfig): Promise<ResolvedReceipt | null>;
4
+ //# sourceMappingURL=receipts-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-registry.d.ts","sourceRoot":"","sources":["../src/receipts-registry.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAa,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAO5F,wBAAsB,YAAY,CAAC,GAAG,GAAE,MAA6B,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwBnG;AAOD,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,YAAiB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAUxG"}
@@ -0,0 +1,54 @@
1
+ // @drm3/sdk/receipts - the public-key registry loader + resolve-by-id fetch.
2
+ //
3
+ // No trust in the host: the registry is fetched once per URL and cached, and used
4
+ // only to grade a signer against the key it CLAIMED across that key's lifecycle.
5
+ // The default registry mirrors STATUS_HUB in ./index.
6
+ const DEFAULT_REGISTRY_URL = "https://status.drm3.network/.well-known/drm3-keys.json";
7
+ // ── key registry (per-URL cached) ────────────────────────────────────────────
8
+ const registryCache = new Map();
9
+ export async function loadRegistry(url = DEFAULT_REGISTRY_URL) {
10
+ const cached = registryCache.get(url);
11
+ if (cached)
12
+ return cached;
13
+ const map = new Map();
14
+ try {
15
+ const reg = (await (await fetch(url)).json());
16
+ for (const svc of reg.services || []) {
17
+ for (const k of svc.current || [])
18
+ if (k.key)
19
+ map.set(k.key.toLowerCase(), { status: k.status || "current", valid_from: k.valid_from, valid_until: k.valid_until });
20
+ // history keys signed real receipts; a superseded/retired key still verifies
21
+ // within its window. Don't overwrite a current entry if the same key appears in both.
22
+ for (const k of svc.history || [])
23
+ if (k.key && !map.has(k.key.toLowerCase()))
24
+ map.set(k.key.toLowerCase(), { status: k.status || "superseded", valid_from: k.valid_from, valid_until: k.valid_until });
25
+ }
26
+ for (const k of reg.keys || [])
27
+ if (k.key && !map.has(k.key.toLowerCase()))
28
+ map.set(k.key.toLowerCase(), { status: "current" }); // v1 compat
29
+ }
30
+ catch {
31
+ /* registry unreachable → signature still proves authorship; we just can't confirm publication */
32
+ }
33
+ registryCache.set(url, map);
34
+ return map;
35
+ }
36
+ // Resolve a receipt by its content-addressed id through the DRM3 resolver
37
+ // convention (GET {resolverBase}/receipts/:id, drm3-provenance/spec/
38
+ // RESOLVER-CONVENTION). The attestation is public and keyed purely by id. Returns
39
+ // the resolver envelope, or null when the host has no such receipt / it isn't
40
+ // retrievable. A full cross-host walk resolves signer → registry → resolverBase first.
41
+ export async function resolveReceipt(id, cfg = {}) {
42
+ try {
43
+ const base = cfg.resolverBase || "";
44
+ const r = await fetch(`${base}/receipts/${encodeURIComponent(id)}`, cfg.headers ? { headers: cfg.headers } : undefined);
45
+ if (!r.ok)
46
+ return null;
47
+ const j = (await r.json());
48
+ return j?.ok && j.receipt ? j : null;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ //# sourceMappingURL=receipts-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-registry.js","sourceRoot":"","sources":["../src/receipts-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ContentRef, Counts } from "./receipts-types.js";
2
+ export declare const esc: (s: string) => string;
3
+ export declare function shortHex(h: string): string;
4
+ export declare function shortKey(k: string): string;
5
+ export declare function prettyAction(a: string): string;
6
+ export declare function monoColor(s: string): string;
7
+ export declare function countsLine(c: Counts): string;
8
+ export declare function legDetail(payload: Record<string, unknown>, contentRef?: ContentRef): string;
9
+ //# sourceMappingURL=receipts-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-render.d.ts","sourceRoot":"","sources":["../src/receipts-render.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG9D,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,KAAG,MAAuH,CAAC;AACxJ,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1C;AACD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1C;AAGD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAS9C;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3C;AACD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAWD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAyB3F"}
@@ -0,0 +1,83 @@
1
+ // @drm3/sdk/receipts - display helpers + the per-leg detail panel renderer.
2
+ //
3
+ // Pure string builders (no DOM). Everything they render comes straight out of the
4
+ // signed receipt.
5
+ // ── display helpers ───────────────────────────────────────────────────────────
6
+ export const esc = (s) => String(s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
7
+ export function shortHex(h) {
8
+ const x = String(h || "").replace(/^(ed25519|sha256|sha1):/, "");
9
+ return x ? `${x.slice(0, 10)}…${x.slice(-6)}` : "-";
10
+ }
11
+ export function shortKey(k) {
12
+ const h = String(k || "").replace(/^ed25519:/, "");
13
+ return h ? `ed25519:${h.slice(0, 8)}…${h.slice(-6)}` : "-";
14
+ }
15
+ // Humanize an action id. Apps with domain-specific actions can pass their own
16
+ // label by pre-formatting; this is the neutral default.
17
+ export function prettyAction(a) {
18
+ if (/fetch/i.test(a))
19
+ return "Fetched & extracted";
20
+ if (/analy/i.test(a))
21
+ return "AI analysis";
22
+ if (/scrape|extract/i.test(a))
23
+ return "Content extracted";
24
+ if (/digest|compose/i.test(a))
25
+ return "Composed";
26
+ if (/infer/i.test(a))
27
+ return "Inference";
28
+ return String(a || "receipt")
29
+ .replace(/[._-]/g, " ")
30
+ .replace(/\b\w/g, (c) => c.toUpperCase());
31
+ }
32
+ // Deterministic monogram tint for a name (no network favicon calls).
33
+ export function monoColor(s) {
34
+ let h = 0;
35
+ for (let i = 0; i < s.length; i++)
36
+ h = (h * 31 + s.charCodeAt(i)) % 360;
37
+ return `hsl(${h} 52% 64%)`;
38
+ }
39
+ export function countsLine(c) {
40
+ return `<span class="drm3v-counts">${c.verified} verified · ${c.gated} not accessible · ${c.failed} failed</span>`;
41
+ }
42
+ function fieldRow(label, value, mono = false) {
43
+ return `<div class="drm3v-kv"><span>${esc(label)}</span>${mono ? `<code>${esc(value)}</code>` : `<b>${esc(value)}</b>`}</div>`;
44
+ }
45
+ // The SUBSTANCE behind a leg's green check: WHAT produced it (model · provider, or
46
+ // the extractor), the exact input→output hashes the signature covers, when it was
47
+ // signed, the signer's own plain-English attestation of what the hash is over, and
48
+ // links to the content so you can SEE and re-check it. Everything comes straight
49
+ // out of the signed receipt.
50
+ export function legDetail(payload, contentRef) {
51
+ const meta = (payload?.metadata?._meta || {});
52
+ const rows = [];
53
+ const model = String(meta.model || "");
54
+ const provider = String(meta.provider || "");
55
+ if (model)
56
+ rows.push(fieldRow("model", provider ? `${model} · ${provider}` : model));
57
+ else if (meta.extractor)
58
+ rows.push(fieldRow("extractor", String(meta.extractor)));
59
+ const ih = String(payload.input_hash || "");
60
+ const oh = String(payload.output_hash || "");
61
+ if (ih)
62
+ rows.push(fieldRow("input", shortHex(ih), true));
63
+ if (oh)
64
+ rows.push(fieldRow("output", shortHex(oh), true));
65
+ if (payload.timestamp) {
66
+ const d = new Date(String(payload.timestamp));
67
+ if (!Number.isNaN(d.getTime()))
68
+ rows.push(fieldRow("signed", d.toUTCString()));
69
+ }
70
+ const att = String(meta.attestation || "");
71
+ const attHtml = att ? `<div class="drm3v-att">${esc(att)}</div>` : "";
72
+ const links = [];
73
+ // New tab - the panel is a modal; same-tab nav would load the content BEHIND it.
74
+ if (contentRef?.ourUrl)
75
+ links.push(`<a class="drm3v-clink" href="${esc(contentRef.ourUrl)}" target="_blank" rel="noopener">read the copy ↗</a>`);
76
+ if (contentRef?.origUrl)
77
+ links.push(`<a class="drm3v-clink" href="${esc(contentRef.origUrl)}" target="_blank" rel="noopener noreferrer">original source ↗</a>`);
78
+ const linksHtml = links.length ? `<div class="drm3v-clinks">${links.join("")}</div>` : "";
79
+ if (!rows.length && !attHtml && !linksHtml)
80
+ return "";
81
+ return `<div class="drm3v-detail">${rows.join("")}${attHtml}${linksHtml}</div>`;
82
+ }
83
+ //# sourceMappingURL=receipts-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts-render.js","sourceRoot":"","sources":["../src/receipts-render.ts"],"names":[],"mappings":"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"}