@oxy.so/protocol 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +16 -0
  3. package/dist/cjs/.tsbuildinfo +1 -0
  4. package/dist/cjs/chain/continuity.js +54 -0
  5. package/dist/cjs/chain/engine.js +34 -0
  6. package/dist/cjs/chain/recordStore.js +25 -0
  7. package/dist/cjs/chain/types.js +22 -0
  8. package/dist/cjs/chain/verify.js +82 -0
  9. package/dist/cjs/envelope/canonicalJson.js +107 -0
  10. package/dist/cjs/envelope/recordId.js +60 -0
  11. package/dist/cjs/envelope/sign.js +75 -0
  12. package/dist/cjs/envelope/signingInput.js +32 -0
  13. package/dist/cjs/identity/resolver.js +50 -0
  14. package/dist/cjs/index.js +71 -0
  15. package/dist/cjs/node/constants.js +85 -0
  16. package/dist/cjs/node/didWebResolver.js +126 -0
  17. package/dist/cjs/node/httpFetch.js +61 -0
  18. package/dist/cjs/node/index.js +71 -0
  19. package/dist/cjs/node/nodeApp.js +344 -0
  20. package/dist/cjs/node/nodeClient.js +204 -0
  21. package/dist/cjs/node/rateLimit.js +187 -0
  22. package/dist/cjs/node/verifyRecord.js +51 -0
  23. package/dist/cjs/platform/crypto.js +186 -0
  24. package/dist/cjs/platform/crypto.native.js +204 -0
  25. package/dist/cjs/platform/expoTypes.js +24 -0
  26. package/dist/cjs/platform/platform.js +33 -0
  27. package/dist/cjs/secp256k1.js +148 -0
  28. package/dist/cjs/transparency/checkpoint.js +79 -0
  29. package/dist/cjs/transparency/tree.js +197 -0
  30. package/dist/esm/.tsbuildinfo +1 -0
  31. package/dist/esm/chain/continuity.js +51 -0
  32. package/dist/esm/chain/engine.js +31 -0
  33. package/dist/esm/chain/recordStore.js +24 -0
  34. package/dist/esm/chain/types.js +19 -0
  35. package/dist/esm/chain/verify.js +78 -0
  36. package/dist/esm/envelope/canonicalJson.js +104 -0
  37. package/dist/esm/envelope/recordId.js +56 -0
  38. package/dist/esm/envelope/sign.js +69 -0
  39. package/dist/esm/envelope/signingInput.js +29 -0
  40. package/dist/esm/identity/resolver.js +47 -0
  41. package/dist/esm/index.js +36 -0
  42. package/dist/esm/node/constants.js +82 -0
  43. package/dist/esm/node/didWebResolver.js +122 -0
  44. package/dist/esm/node/httpFetch.js +55 -0
  45. package/dist/esm/node/index.js +28 -0
  46. package/dist/esm/node/nodeApp.js +336 -0
  47. package/dist/esm/node/nodeClient.js +198 -0
  48. package/dist/esm/node/rateLimit.js +182 -0
  49. package/dist/esm/node/verifyRecord.js +48 -0
  50. package/dist/esm/platform/crypto.js +145 -0
  51. package/dist/esm/platform/crypto.native.js +196 -0
  52. package/dist/esm/platform/expoTypes.js +23 -0
  53. package/dist/esm/platform/platform.js +29 -0
  54. package/dist/esm/secp256k1.js +137 -0
  55. package/dist/esm/transparency/checkpoint.js +73 -0
  56. package/dist/esm/transparency/tree.js +189 -0
  57. package/dist/types/.tsbuildinfo +1 -0
  58. package/dist/types/chain/continuity.d.ts +28 -0
  59. package/dist/types/chain/engine.d.ts +27 -0
  60. package/dist/types/chain/recordStore.d.ts +85 -0
  61. package/dist/types/chain/types.d.ts +79 -0
  62. package/dist/types/chain/verify.d.ts +45 -0
  63. package/dist/types/envelope/canonicalJson.d.ts +44 -0
  64. package/dist/types/envelope/recordId.d.ts +30 -0
  65. package/dist/types/envelope/sign.d.ts +47 -0
  66. package/dist/types/envelope/signingInput.d.ts +33 -0
  67. package/dist/types/identity/resolver.d.ts +67 -0
  68. package/dist/types/index.d.ts +32 -0
  69. package/dist/types/node/constants.d.ts +80 -0
  70. package/dist/types/node/didWebResolver.d.ts +47 -0
  71. package/dist/types/node/httpFetch.d.ts +60 -0
  72. package/dist/types/node/index.d.ts +28 -0
  73. package/dist/types/node/nodeApp.d.ts +120 -0
  74. package/dist/types/node/nodeClient.d.ts +135 -0
  75. package/dist/types/node/rateLimit.d.ts +95 -0
  76. package/dist/types/node/verifyRecord.d.ts +41 -0
  77. package/dist/types/platform/crypto.d.ts +93 -0
  78. package/dist/types/platform/crypto.native.d.ts +77 -0
  79. package/dist/types/platform/expoTypes.d.ts +99 -0
  80. package/dist/types/platform/platform.d.ts +25 -0
  81. package/dist/types/secp256k1.d.ts +45 -0
  82. package/dist/types/transparency/checkpoint.d.ts +71 -0
  83. package/dist/types/transparency/tree.d.ts +135 -0
  84. package/package.json +157 -0
  85. package/src/__tests__/canonicalJson.test.ts +116 -0
  86. package/src/__tests__/chain.test.ts +279 -0
  87. package/src/__tests__/didWebResolver.test.ts +132 -0
  88. package/src/__tests__/envelope.test.ts +267 -0
  89. package/src/__tests__/nodeApp.test.ts +410 -0
  90. package/src/__tests__/nodeClient.test.ts +177 -0
  91. package/src/__tests__/nodeHarness.ts +151 -0
  92. package/src/__tests__/optionalNativePeers.test.ts +233 -0
  93. package/src/__tests__/rateLimit.test.ts +268 -0
  94. package/src/__tests__/runnerGuard.test.ts +85 -0
  95. package/src/__tests__/secp256k1.test.ts +118 -0
  96. package/src/__tests__/transparency.test.ts +353 -0
  97. package/src/chain/continuity.ts +59 -0
  98. package/src/chain/engine.ts +43 -0
  99. package/src/chain/recordStore.ts +98 -0
  100. package/src/chain/types.ts +85 -0
  101. package/src/chain/verify.ts +102 -0
  102. package/src/envelope/canonicalJson.ts +120 -0
  103. package/src/envelope/recordId.ts +63 -0
  104. package/src/envelope/sign.ts +86 -0
  105. package/src/envelope/signingInput.ts +48 -0
  106. package/src/identity/resolver.ts +90 -0
  107. package/src/index.ts +101 -0
  108. package/src/node/constants.ts +105 -0
  109. package/src/node/didWebResolver.ts +162 -0
  110. package/src/node/httpFetch.ts +88 -0
  111. package/src/node/index.ts +87 -0
  112. package/src/node/nodeApp.ts +471 -0
  113. package/src/node/nodeClient.ts +322 -0
  114. package/src/node/rateLimit.ts +233 -0
  115. package/src/node/verifyRecord.ts +60 -0
  116. package/src/platform/crypto.native.ts +251 -0
  117. package/src/platform/crypto.ts +172 -0
  118. package/src/platform/expoTypes.ts +99 -0
  119. package/src/platform/platform.ts +31 -0
  120. package/src/secp256k1.ts +207 -0
  121. package/src/transparency/checkpoint.ts +109 -0
  122. package/src/transparency/tree.ts +258 -0
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * Node-protocol shape constants — the wire-level contract of an Oxy-protocol
4
+ * data node, shared by the generic node app factory ({@link ./nodeApp}), the
5
+ * HTTP {@link ./nodeClient.NodeClient}, and any app's node deployment
6
+ * (`@oxy.so/node`, a future `mention-node`).
7
+ *
8
+ * These were previously hardcoded inside `@oxy.so/node`; they live here so the
9
+ * SAME values drive a server and a client without either side re-declaring (and
10
+ * drifting) the contract. Deployment-specific knobs (owner key, port, data dir)
11
+ * are still resolved per-deployment from the environment — only the protocol's
12
+ * own shape constants live here.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DEFAULT_DID_DOC_MAX_BYTES = exports.DEFAULT_WRITE_RESPONSE_MAX_BYTES = exports.DEFAULT_LOG_MAX_BYTES = exports.DEFAULT_HEAD_MAX_BYTES = exports.DEFAULT_CLIENT_MAX_REDIRECTS = exports.DEFAULT_CLIENT_TIMEOUT_MS = exports.NODE_BLOBS_PATH = exports.NODE_SYNC_PUSH_PATH = exports.NODE_RECORDS_PATH = exports.NODE_LOG_PATH = exports.NODE_HEAD_PATH = exports.SHA256_HEX = exports.OWNER_ACTION_BLOB_PIN = exports.NODE_MODES = exports.OWNER_AUTH_MAX_AGE_MS = exports.OWNER_AUTH_HEADERS = exports.JSON_BODY_LIMIT = exports.MAX_SYNC_BATCH = exports.DEFAULT_MAX_BLOB_BYTES = exports.MAX_LOG_LIMIT = exports.DEFAULT_LOG_LIMIT = exports.DEFAULT_PORT = exports.DEFAULT_APP_NAMESPACE = exports.DEFAULT_SERVICE_TYPE = exports.DEFAULT_WELL_KNOWN_PATH = exports.PROTOCOL_VERSION = void 0;
16
+ /**
17
+ * The node-protocol version advertised at the well-known manifest. Bumped only
18
+ * on a breaking change to the wire shape of the log / head / record APIs. This
19
+ * is the DEFAULT `protocolId` a deployment advertises (overridable per app).
20
+ */
21
+ exports.PROTOCOL_VERSION = 'oxy-node/1';
22
+ /** Default well-known manifest path (the existing `@oxy.so/node` value). */
23
+ exports.DEFAULT_WELL_KNOWN_PATH = '/.well-known/oxy-node.json';
24
+ /** Default DID-document service-type label advertised by a node deployment. */
25
+ exports.DEFAULT_SERVICE_TYPE = 'OxyPersonalDataNode';
26
+ /**
27
+ * Default application namespace a node deployment serves. The records a node
28
+ * stores all live under this namespace (e.g. `app.oxy.*`); a `collections`
29
+ * allowlist (when set) MUST be within it.
30
+ */
31
+ exports.DEFAULT_APP_NAMESPACE = 'app.oxy';
32
+ /** Default HTTP port when the port env var is unset (always overridable). */
33
+ exports.DEFAULT_PORT = 4000;
34
+ /** Default and maximum number of log entries returned by `GET /oxy/log`. */
35
+ exports.DEFAULT_LOG_LIMIT = 100;
36
+ exports.MAX_LOG_LIMIT = 500;
37
+ /** Default upper bound on a single pinned blob's size when unset (25 MiB). */
38
+ exports.DEFAULT_MAX_BLOB_BYTES = 25 * 1024 * 1024;
39
+ /** Maximum number of envelopes accepted in one `POST /sync/push` batch. */
40
+ exports.MAX_SYNC_BATCH = 200;
41
+ /** Body-size ceiling for JSON request bodies (`/records`, `/sync/push`). */
42
+ exports.JSON_BODY_LIMIT = '5mb';
43
+ /** HTTP headers carrying an owner-signed action authorization (blob pins). */
44
+ exports.OWNER_AUTH_HEADERS = {
45
+ publicKey: 'x-oxy-node-public-key',
46
+ signature: 'x-oxy-node-signature',
47
+ timestamp: 'x-oxy-node-timestamp',
48
+ };
49
+ /**
50
+ * Freshness window for an owner-signed action (e.g. a blob pin). A signed
51
+ * authorization header older/newer than this (accounting for clock skew) is
52
+ * rejected, bounding replay of a captured pin authorization.
53
+ */
54
+ exports.OWNER_AUTH_MAX_AGE_MS = 5 * 60 * 1000; // 5 minutes
55
+ /** Operating modes a node can advertise. */
56
+ exports.NODE_MODES = ['self-hosted', 'managed'];
57
+ /** The node operation an owner can authorize with a signed header. */
58
+ exports.OWNER_ACTION_BLOB_PIN = 'blob-pin';
59
+ /** A 32-byte (64 hex char) lowercase SHA-256 digest, used as the blob address. */
60
+ exports.SHA256_HEX = /^[0-9a-f]{64}$/;
61
+ /* -------------------------------------------------------------------------- */
62
+ /* HTTP NodeClient — the node-facing routes a client drives */
63
+ /* -------------------------------------------------------------------------- */
64
+ /** Chain head endpoint (`GET`). */
65
+ exports.NODE_HEAD_PATH = '/oxy/head';
66
+ /** Ordered log endpoint (`GET ?since=&limit=`). */
67
+ exports.NODE_LOG_PATH = '/oxy/log';
68
+ /** Single-record write endpoint (`POST`, owner-signed envelope). */
69
+ exports.NODE_RECORDS_PATH = '/records';
70
+ /** Batch push endpoint (`POST`, owner-signed envelopes). */
71
+ exports.NODE_SYNC_PUSH_PATH = '/sync/push';
72
+ /** Content-addressed blob endpoint prefix (`GET|PUT /blobs/:hash`). */
73
+ exports.NODE_BLOBS_PATH = '/blobs';
74
+ /** Default time-to-first-byte deadline for a NodeClient request (ms). */
75
+ exports.DEFAULT_CLIENT_TIMEOUT_MS = 8000;
76
+ /** Default redirect budget for a NodeClient request (each re-validated upstream). */
77
+ exports.DEFAULT_CLIENT_MAX_REDIRECTS = 1;
78
+ /** Default bounded read for a `/oxy/head` response (tiny JSON). */
79
+ exports.DEFAULT_HEAD_MAX_BYTES = 64 * 1024;
80
+ /** Default bounded read for a `/oxy/log` page response. */
81
+ exports.DEFAULT_LOG_MAX_BYTES = 2 * 1024 * 1024;
82
+ /** Default bounded read for a small JSON write response (`/records`, blob pin). */
83
+ exports.DEFAULT_WRITE_RESPONSE_MAX_BYTES = 64 * 1024;
84
+ /** Default bounded read for a fetched `<did>.json` document. */
85
+ exports.DEFAULT_DID_DOC_MAX_BYTES = 256 * 1024;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * `createDidWebResolver` — a {@link VerificationMethodResolver} for arbitrary
4
+ * `did:web` subjects, backing the chain engine on multi-subject relay/ingest
5
+ * paths (where the signer is NOT a local account but any DID that publishes a
6
+ * DID document).
7
+ *
8
+ * It resolves a `did:web:<host>[:<path>]` subject to its `did.json`, fetched via
9
+ * an INJECTED {@link NodeFetch} — Oxy passes an adapter over `@oxy.so/core/server`
10
+ * `safeFetch` (so the SSRF/transport policy stays in core); a test passes a
11
+ * stub. The subject's current verification keys are read from the DID document's
12
+ * `verificationMethod[].publicKeyHex` (the active assertion methods), and the
13
+ * engine's `isAuthorizedKey` then applies the uniform self-issued rule.
14
+ *
15
+ * `did:web` → URL mapping (W3C did:web):
16
+ * - `did:web:example.com` → `https://example.com/.well-known/did.json`
17
+ * - `did:web:example.com:u:123` → `https://example.com/u/123/did.json`
18
+ * - a `%3A` in the host segment is decoded to `:` (an explicit port).
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.didWebToUrl = didWebToUrl;
22
+ exports.createDidWebResolver = createDidWebResolver;
23
+ const contracts_1 = require("@oxy.so/contracts");
24
+ const httpFetch_1 = require("./httpFetch");
25
+ const constants_1 = require("./constants");
26
+ /**
27
+ * Map a `did:web` DID to its `did.json` URL, or `null` when `did` is not a
28
+ * well-formed `did:web` identifier.
29
+ */
30
+ function didWebToUrl(did) {
31
+ const prefix = 'did:web:';
32
+ if (!did.startsWith(prefix)) {
33
+ return null;
34
+ }
35
+ const msi = did.slice(prefix.length);
36
+ if (msi.length === 0) {
37
+ return null;
38
+ }
39
+ const [domainPart, ...pathParts] = msi.split(':');
40
+ const host = domainPart.replace(/%3A/gi, ':');
41
+ if (host.length === 0 || host.includes('/')) {
42
+ return null;
43
+ }
44
+ const base = `https://${host}`;
45
+ if (pathParts.length === 0) {
46
+ return `${base}/.well-known/did.json`;
47
+ }
48
+ if (pathParts.some((part) => part.length === 0)) {
49
+ return null;
50
+ }
51
+ return `${base}/${pathParts.join('/')}/did.json`;
52
+ }
53
+ /** True for a secp256k1 verification method (carries `publicKeyHex`). */
54
+ function isSecp256k1Vm(vm) {
55
+ return vm.type === 'EcdsaSecp256k1VerificationKey2019';
56
+ }
57
+ /**
58
+ * Collect the subject's current verification keys from its DID document: the
59
+ * `publicKeyHex` of every secp256k1 verification method referenced by
60
+ * `assertionMethod` (the keys that may sign assertions/records), deduped. Falls
61
+ * back to ALL secp256k1 `verificationMethod[]` keys when `assertionMethod`
62
+ * references nothing local. Non-secp256k1 methods (e.g. the atproto `Multikey`,
63
+ * which carries the SAME key in multibase form, not hex) are skipped — record
64
+ * signatures verify against the hex key.
65
+ */
66
+ function collectCurrentPublicKeys(doc) {
67
+ const byId = new Map(doc.verificationMethod
68
+ .filter(isSecp256k1Vm)
69
+ .map((vm) => [vm.id, vm.publicKeyHex]));
70
+ const keys = [];
71
+ for (const id of doc.assertionMethod) {
72
+ const key = byId.get(id);
73
+ if (key && !keys.includes(key)) {
74
+ keys.push(key);
75
+ }
76
+ }
77
+ if (keys.length === 0) {
78
+ for (const key of byId.values()) {
79
+ if (!keys.includes(key)) {
80
+ keys.push(key);
81
+ }
82
+ }
83
+ }
84
+ return keys;
85
+ }
86
+ /**
87
+ * Build a {@link VerificationMethodResolver} that resolves `did:web` subjects via
88
+ * the injected `fetch`. Returns `null` for any subject that is not a `did:web`
89
+ * DID, whose `did.json` cannot be fetched, or whose document fails schema
90
+ * validation — the engine then treats the signer as unauthorized.
91
+ */
92
+ function createDidWebResolver(fetch, options = {}) {
93
+ const headersTimeoutMs = options.headersTimeoutMs ?? constants_1.DEFAULT_CLIENT_TIMEOUT_MS;
94
+ const maxRedirects = options.maxRedirects ?? constants_1.DEFAULT_CLIENT_MAX_REDIRECTS;
95
+ const maxBytes = options.maxBytes ?? constants_1.DEFAULT_DID_DOC_MAX_BYTES;
96
+ return {
97
+ async resolve(subjectDid) {
98
+ const url = didWebToUrl(subjectDid);
99
+ if (!url) {
100
+ return null;
101
+ }
102
+ try {
103
+ const res = await fetch(url, { method: 'GET', headersTimeoutMs, maxRedirects });
104
+ if (res.status < 200 || res.status >= 300) {
105
+ res.destroy();
106
+ return null;
107
+ }
108
+ const body = await (0, httpFetch_1.readBoundedJson)(res, maxBytes);
109
+ const parsed = contracts_1.didDocumentSchema.safeParse(body);
110
+ if (!parsed.success) {
111
+ return null;
112
+ }
113
+ // The DID document `id` MUST match the subject we asked for — a document
114
+ // served at the subject's URL but claiming another id is not authoritative.
115
+ if (parsed.data.id !== subjectDid) {
116
+ return null;
117
+ }
118
+ return { currentPublicKeys: collectCurrentPublicKeys(parsed.data) };
119
+ }
120
+ catch (err) {
121
+ options.onError?.(err, subjectDid);
122
+ return null;
123
+ }
124
+ },
125
+ };
126
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * The injected HTTP transport the node {@link ./nodeClient.NodeClient} and the
4
+ * {@link ./didWebResolver} drive — plus the bounded-read helpers that make a
5
+ * response stream safe to consume.
6
+ *
7
+ * The protocol package is app-agnostic and MUST NOT depend on `@oxy.so/core`
8
+ * (core depends on protocol). So instead of importing `@oxy.so/core/server`'s
9
+ * `safeFetch` directly, the node client/resolver accept a {@link NodeFetch} —
10
+ * Oxy supplies an adapter over `safeFetch` (HTTPS-only, DNS-pinned, private-IP
11
+ * denylist, bounded redirects); a test supplies an in-process stub. Either way
12
+ * the SSRF/transport policy stays in the injected implementation, and the
13
+ * bounded body read (the cap that stops a malicious node streaming forever)
14
+ * stays here, close to the parsing.
15
+ *
16
+ * A Node `IncomingMessage` (what `safeFetch` returns) satisfies
17
+ * {@link NodeFetchResponse.body} directly — it is an `AsyncIterable<Buffer>`,
18
+ * and `Buffer` is a `Uint8Array`.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.ResponseTooLargeError = void 0;
22
+ exports.readBoundedBytes = readBoundedBytes;
23
+ exports.readBoundedJson = readBoundedJson;
24
+ /** Thrown when a response body exceeds the caller's byte ceiling. */
25
+ class ResponseTooLargeError extends Error {
26
+ constructor(maxBytes) {
27
+ super(`response exceeded ${maxBytes} bytes`);
28
+ this.maxBytes = maxBytes;
29
+ this.name = 'ResponseTooLargeError';
30
+ }
31
+ }
32
+ exports.ResponseTooLargeError = ResponseTooLargeError;
33
+ /**
34
+ * Read a response body into a single buffer, aborting (and destroying the
35
+ * stream) the moment it exceeds `maxBytes`. The bound is the defence against a
36
+ * node that streams an unbounded body.
37
+ */
38
+ async function readBoundedBytes(res, maxBytes) {
39
+ const chunks = [];
40
+ let total = 0;
41
+ try {
42
+ for await (const chunk of res.body) {
43
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
44
+ total += buf.length;
45
+ if (total > maxBytes) {
46
+ throw new ResponseTooLargeError(maxBytes);
47
+ }
48
+ chunks.push(buf);
49
+ }
50
+ }
51
+ catch (err) {
52
+ res.destroy();
53
+ throw err;
54
+ }
55
+ return Buffer.concat(chunks);
56
+ }
57
+ /** Read a bounded response body and parse it as JSON. */
58
+ async function readBoundedJson(res, maxBytes) {
59
+ const bytes = await readBoundedBytes(res, maxBytes);
60
+ return JSON.parse(bytes.toString('utf8'));
61
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * `@oxy.so/protocol/node` — the runnable node substrate.
4
+ *
5
+ * The Node-only half of the protocol: the Express app factory that backs any
6
+ * Oxy-protocol data node ({@link createNodeApp}), the HTTP {@link NodeClient}
7
+ * that drives a node's routes, the `did:web` verification-method resolver, the
8
+ * record verifier, and the node-protocol shape constants. A SEPARATE subpath
9
+ * from the package root so this Express/Node-only code never enters React
10
+ * Native / web bundles that import `@oxy.so/protocol`.
11
+ *
12
+ * Reused by `@oxy.so/node` (the runnable node), a future `mention-node` (an
13
+ * env-only deployment of the same base), and oxy-api's node sync (which drives
14
+ * a node via `NodeClient`).
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.DEFAULT_DID_DOC_MAX_BYTES = exports.DEFAULT_WRITE_RESPONSE_MAX_BYTES = exports.DEFAULT_LOG_MAX_BYTES = exports.DEFAULT_HEAD_MAX_BYTES = exports.DEFAULT_CLIENT_MAX_REDIRECTS = exports.DEFAULT_CLIENT_TIMEOUT_MS = exports.NODE_BLOBS_PATH = exports.NODE_SYNC_PUSH_PATH = exports.NODE_RECORDS_PATH = exports.NODE_LOG_PATH = exports.NODE_HEAD_PATH = exports.SHA256_HEX = exports.OWNER_ACTION_BLOB_PIN = exports.NODE_MODES = exports.OWNER_AUTH_MAX_AGE_MS = exports.OWNER_AUTH_HEADERS = exports.JSON_BODY_LIMIT = exports.MAX_SYNC_BATCH = exports.DEFAULT_MAX_BLOB_BYTES = exports.MAX_LOG_LIMIT = exports.DEFAULT_LOG_LIMIT = exports.DEFAULT_PORT = exports.DEFAULT_APP_NAMESPACE = exports.DEFAULT_SERVICE_TYPE = exports.DEFAULT_WELL_KNOWN_PATH = exports.PROTOCOL_VERSION = exports.didWebToUrl = exports.createDidWebResolver = exports.ResponseTooLargeError = exports.readBoundedJson = exports.readBoundedBytes = exports.trimTrailingSlashes = exports.NodeClientError = exports.NodeClient = exports.verifyNodeRecordEnvelope = exports.DEFAULT_MAX_RATE_LIMIT_ENTRIES = exports.DEFAULT_WRITE_RATE_LIMIT = exports.createRateLimiter = exports.BlobHashMismatchError = exports.createNodeApp = void 0;
18
+ // ── Express app factory ───────────────────────────────────────────────────────
19
+ var nodeApp_1 = require("./nodeApp");
20
+ Object.defineProperty(exports, "createNodeApp", { enumerable: true, get: function () { return nodeApp_1.createNodeApp; } });
21
+ Object.defineProperty(exports, "BlobHashMismatchError", { enumerable: true, get: function () { return nodeApp_1.BlobHashMismatchError; } });
22
+ // ── Per-IP write rate limiter ──────────────────────────────────────────────────
23
+ var rateLimit_1 = require("./rateLimit");
24
+ Object.defineProperty(exports, "createRateLimiter", { enumerable: true, get: function () { return rateLimit_1.createRateLimiter; } });
25
+ Object.defineProperty(exports, "DEFAULT_WRITE_RATE_LIMIT", { enumerable: true, get: function () { return rateLimit_1.DEFAULT_WRITE_RATE_LIMIT; } });
26
+ Object.defineProperty(exports, "DEFAULT_MAX_RATE_LIMIT_ENTRIES", { enumerable: true, get: function () { return rateLimit_1.DEFAULT_MAX_RATE_LIMIT_ENTRIES; } });
27
+ // ── Record verification (signature + v2 + content address) ─────────────────────
28
+ var verifyRecord_1 = require("./verifyRecord");
29
+ Object.defineProperty(exports, "verifyNodeRecordEnvelope", { enumerable: true, get: function () { return verifyRecord_1.verifyNodeRecordEnvelope; } });
30
+ // ── HTTP client ────────────────────────────────────────────────────────────────
31
+ var nodeClient_1 = require("./nodeClient");
32
+ Object.defineProperty(exports, "NodeClient", { enumerable: true, get: function () { return nodeClient_1.NodeClient; } });
33
+ Object.defineProperty(exports, "NodeClientError", { enumerable: true, get: function () { return nodeClient_1.NodeClientError; } });
34
+ Object.defineProperty(exports, "trimTrailingSlashes", { enumerable: true, get: function () { return nodeClient_1.trimTrailingSlashes; } });
35
+ // ── Injected transport contract + bounded readers ──────────────────────────────
36
+ var httpFetch_1 = require("./httpFetch");
37
+ Object.defineProperty(exports, "readBoundedBytes", { enumerable: true, get: function () { return httpFetch_1.readBoundedBytes; } });
38
+ Object.defineProperty(exports, "readBoundedJson", { enumerable: true, get: function () { return httpFetch_1.readBoundedJson; } });
39
+ Object.defineProperty(exports, "ResponseTooLargeError", { enumerable: true, get: function () { return httpFetch_1.ResponseTooLargeError; } });
40
+ // ── did:web verification-method resolver ───────────────────────────────────────
41
+ var didWebResolver_1 = require("./didWebResolver");
42
+ Object.defineProperty(exports, "createDidWebResolver", { enumerable: true, get: function () { return didWebResolver_1.createDidWebResolver; } });
43
+ Object.defineProperty(exports, "didWebToUrl", { enumerable: true, get: function () { return didWebResolver_1.didWebToUrl; } });
44
+ // ── Node-protocol shape constants ──────────────────────────────────────────────
45
+ var constants_1 = require("./constants");
46
+ Object.defineProperty(exports, "PROTOCOL_VERSION", { enumerable: true, get: function () { return constants_1.PROTOCOL_VERSION; } });
47
+ Object.defineProperty(exports, "DEFAULT_WELL_KNOWN_PATH", { enumerable: true, get: function () { return constants_1.DEFAULT_WELL_KNOWN_PATH; } });
48
+ Object.defineProperty(exports, "DEFAULT_SERVICE_TYPE", { enumerable: true, get: function () { return constants_1.DEFAULT_SERVICE_TYPE; } });
49
+ Object.defineProperty(exports, "DEFAULT_APP_NAMESPACE", { enumerable: true, get: function () { return constants_1.DEFAULT_APP_NAMESPACE; } });
50
+ Object.defineProperty(exports, "DEFAULT_PORT", { enumerable: true, get: function () { return constants_1.DEFAULT_PORT; } });
51
+ Object.defineProperty(exports, "DEFAULT_LOG_LIMIT", { enumerable: true, get: function () { return constants_1.DEFAULT_LOG_LIMIT; } });
52
+ Object.defineProperty(exports, "MAX_LOG_LIMIT", { enumerable: true, get: function () { return constants_1.MAX_LOG_LIMIT; } });
53
+ Object.defineProperty(exports, "DEFAULT_MAX_BLOB_BYTES", { enumerable: true, get: function () { return constants_1.DEFAULT_MAX_BLOB_BYTES; } });
54
+ Object.defineProperty(exports, "MAX_SYNC_BATCH", { enumerable: true, get: function () { return constants_1.MAX_SYNC_BATCH; } });
55
+ Object.defineProperty(exports, "JSON_BODY_LIMIT", { enumerable: true, get: function () { return constants_1.JSON_BODY_LIMIT; } });
56
+ Object.defineProperty(exports, "OWNER_AUTH_HEADERS", { enumerable: true, get: function () { return constants_1.OWNER_AUTH_HEADERS; } });
57
+ Object.defineProperty(exports, "OWNER_AUTH_MAX_AGE_MS", { enumerable: true, get: function () { return constants_1.OWNER_AUTH_MAX_AGE_MS; } });
58
+ Object.defineProperty(exports, "NODE_MODES", { enumerable: true, get: function () { return constants_1.NODE_MODES; } });
59
+ Object.defineProperty(exports, "OWNER_ACTION_BLOB_PIN", { enumerable: true, get: function () { return constants_1.OWNER_ACTION_BLOB_PIN; } });
60
+ Object.defineProperty(exports, "SHA256_HEX", { enumerable: true, get: function () { return constants_1.SHA256_HEX; } });
61
+ Object.defineProperty(exports, "NODE_HEAD_PATH", { enumerable: true, get: function () { return constants_1.NODE_HEAD_PATH; } });
62
+ Object.defineProperty(exports, "NODE_LOG_PATH", { enumerable: true, get: function () { return constants_1.NODE_LOG_PATH; } });
63
+ Object.defineProperty(exports, "NODE_RECORDS_PATH", { enumerable: true, get: function () { return constants_1.NODE_RECORDS_PATH; } });
64
+ Object.defineProperty(exports, "NODE_SYNC_PUSH_PATH", { enumerable: true, get: function () { return constants_1.NODE_SYNC_PUSH_PATH; } });
65
+ Object.defineProperty(exports, "NODE_BLOBS_PATH", { enumerable: true, get: function () { return constants_1.NODE_BLOBS_PATH; } });
66
+ Object.defineProperty(exports, "DEFAULT_CLIENT_TIMEOUT_MS", { enumerable: true, get: function () { return constants_1.DEFAULT_CLIENT_TIMEOUT_MS; } });
67
+ Object.defineProperty(exports, "DEFAULT_CLIENT_MAX_REDIRECTS", { enumerable: true, get: function () { return constants_1.DEFAULT_CLIENT_MAX_REDIRECTS; } });
68
+ Object.defineProperty(exports, "DEFAULT_HEAD_MAX_BYTES", { enumerable: true, get: function () { return constants_1.DEFAULT_HEAD_MAX_BYTES; } });
69
+ Object.defineProperty(exports, "DEFAULT_LOG_MAX_BYTES", { enumerable: true, get: function () { return constants_1.DEFAULT_LOG_MAX_BYTES; } });
70
+ Object.defineProperty(exports, "DEFAULT_WRITE_RESPONSE_MAX_BYTES", { enumerable: true, get: function () { return constants_1.DEFAULT_WRITE_RESPONSE_MAX_BYTES; } });
71
+ Object.defineProperty(exports, "DEFAULT_DID_DOC_MAX_BYTES", { enumerable: true, get: function () { return constants_1.DEFAULT_DID_DOC_MAX_BYTES; } });