@provian/mcp 0.0.0-stage → 1.2.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 (101) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +266 -2
  4. package/bin/provian-mcp.mjs +18 -0
  5. package/dist/agent-wallet-registration.d.ts +34 -0
  6. package/dist/agent-wallet-registration.d.ts.map +1 -0
  7. package/dist/agent-wallet-registration.js +440 -0
  8. package/dist/agent-wallet-registration.js.map +1 -0
  9. package/dist/core/challenge.d.ts +187 -0
  10. package/dist/core/challenge.d.ts.map +1 -0
  11. package/dist/core/challenge.js +536 -0
  12. package/dist/core/challenge.js.map +1 -0
  13. package/dist/core/crypto.d.ts +44 -0
  14. package/dist/core/crypto.d.ts.map +1 -0
  15. package/dist/core/crypto.js +124 -0
  16. package/dist/core/crypto.js.map +1 -0
  17. package/dist/core/disclosure-request.d.ts +169 -0
  18. package/dist/core/disclosure-request.d.ts.map +1 -0
  19. package/dist/core/disclosure-request.js +400 -0
  20. package/dist/core/disclosure-request.js.map +1 -0
  21. package/dist/core/genesis-offer.d.ts +25 -0
  22. package/dist/core/genesis-offer.d.ts.map +1 -0
  23. package/dist/core/genesis-offer.js +34 -0
  24. package/dist/core/genesis-offer.js.map +1 -0
  25. package/dist/core/harness-tool-vocabulary.d.ts +55 -0
  26. package/dist/core/harness-tool-vocabulary.d.ts.map +1 -0
  27. package/dist/core/harness-tool-vocabulary.js +116 -0
  28. package/dist/core/harness-tool-vocabulary.js.map +1 -0
  29. package/dist/core/keccak256.d.ts +15 -0
  30. package/dist/core/keccak256.d.ts.map +1 -0
  31. package/dist/core/keccak256.js +111 -0
  32. package/dist/core/keccak256.js.map +1 -0
  33. package/dist/core/key-custody.d.ts +33 -0
  34. package/dist/core/key-custody.d.ts.map +1 -0
  35. package/dist/core/key-custody.js +59 -0
  36. package/dist/core/key-custody.js.map +1 -0
  37. package/dist/core/meter-hash.d.ts +2 -0
  38. package/dist/core/meter-hash.d.ts.map +1 -0
  39. package/dist/core/meter-hash.js +8 -0
  40. package/dist/core/meter-hash.js.map +1 -0
  41. package/dist/core/meter-wire.d.ts +193 -0
  42. package/dist/core/meter-wire.d.ts.map +1 -0
  43. package/dist/core/meter-wire.js +418 -0
  44. package/dist/core/meter-wire.js.map +1 -0
  45. package/dist/core/output-signature.d.ts +162 -0
  46. package/dist/core/output-signature.d.ts.map +1 -0
  47. package/dist/core/output-signature.js +367 -0
  48. package/dist/core/output-signature.js.map +1 -0
  49. package/dist/core/presentation.d.ts +141 -0
  50. package/dist/core/presentation.d.ts.map +1 -0
  51. package/dist/core/presentation.js +160 -0
  52. package/dist/core/presentation.js.map +1 -0
  53. package/dist/core/recovery-seal.d.ts +36 -0
  54. package/dist/core/recovery-seal.d.ts.map +1 -0
  55. package/dist/core/recovery-seal.js +122 -0
  56. package/dist/core/recovery-seal.js.map +1 -0
  57. package/dist/core/server.d.ts +38 -0
  58. package/dist/core/server.d.ts.map +1 -0
  59. package/dist/core/server.js +106 -0
  60. package/dist/core/server.js.map +1 -0
  61. package/dist/core/thread-reader.d.ts +8 -0
  62. package/dist/core/thread-reader.d.ts.map +1 -0
  63. package/dist/core/thread-reader.js +47 -0
  64. package/dist/core/thread-reader.js.map +1 -0
  65. package/dist/core/tool-set.d.ts +28 -0
  66. package/dist/core/tool-set.d.ts.map +1 -0
  67. package/dist/core/tool-set.js +71 -0
  68. package/dist/core/tool-set.js.map +1 -0
  69. package/dist/core/tools.d.ts +151 -0
  70. package/dist/core/tools.d.ts.map +1 -0
  71. package/dist/core/tools.js +3623 -0
  72. package/dist/core/tools.js.map +1 -0
  73. package/dist/core/types.d.ts +189 -0
  74. package/dist/core/types.d.ts.map +1 -0
  75. package/dist/core/types.js +17 -0
  76. package/dist/core/types.js.map +1 -0
  77. package/dist/credentials.d.ts +46 -0
  78. package/dist/credentials.d.ts.map +1 -0
  79. package/dist/credentials.js +213 -0
  80. package/dist/credentials.js.map +1 -0
  81. package/dist/device-credentials.d.ts +57 -0
  82. package/dist/device-credentials.d.ts.map +1 -0
  83. package/dist/device-credentials.js +403 -0
  84. package/dist/device-credentials.js.map +1 -0
  85. package/dist/eip191.d.ts +18 -0
  86. package/dist/eip191.d.ts.map +1 -0
  87. package/dist/eip191.js +41 -0
  88. package/dist/eip191.js.map +1 -0
  89. package/dist/index.d.ts +21 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +48 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/runtime-env.d.ts +131 -0
  94. package/dist/runtime-env.d.ts.map +1 -0
  95. package/dist/runtime-env.js +328 -0
  96. package/dist/runtime-env.js.map +1 -0
  97. package/dist/stdio.d.ts +6 -0
  98. package/dist/stdio.d.ts.map +1 -0
  99. package/dist/stdio.js +136 -0
  100. package/dist/stdio.js.map +1 -0
  101. package/package.json +60 -4
@@ -0,0 +1,536 @@
1
+ "use strict";
2
+ /**
3
+ * SIGNED CHALLENGES (`provian-challenge-v1`,) — the requester's half of burn-to-present, for
4
+ * the MCP tool core.
5
+ *
6
+ * SHARED CORE — canonical in `provian-mcp/src/core/`, mirrored byte-identically into
7
+ * `provian-backend/src/mcp/core/`. Edit only the canonical copy and run `scripts/sync-mcp-core.sh`.
8
+ *
9
+ * A byte-for-byte port of the relay's `core/presentation/challenge.ts` (signing string, predicate
10
+ * digest, parse, structural rules, Ed25519 verdict). The MCP core cannot import the relay or the
11
+ * SDK, so it carries its own audited copy, pinned by the fixed vectors in
12
+ * `challenge.test.ts` the same vectors every other package pins.
13
+ *
14
+ * A requester hands a presenter `{ v, audience, challenge, predicates?, issuedAt, expiresAt,
15
+ * presenter?, requester, sig }`. With `requester`/`sig` it is SIGNED (Ed25519): a domain requester
16
+ * with its own key published at `https://<domain>/.well-known/provian-requester.json`, a wallet
17
+ * requester by the RELAY with the Provian presentation key (`/v1/present/jwks`) after it
18
+ * authenticated that wallet. `audience === requester.id`, so the presentation's `aud` IS the
19
+ * verified requester. An unsigned legacy `{ audience, challenge, predicates? }` stays valid and is
20
+ * shown UNVERIFIED; a signed challenge failing any check is INVALID and refused (Unknown = Block).
21
+ *
22
+ * The one outbound fetch here (a domain requester's key document) is SSRF-guarded to the same bar
23
+ * as the relay (Security Invariant #6): hostname regex (no IP literals, no localhost), resolve and
24
+ * refuse ANY private address, pin the socket to the validated address (no DNS-rebinding TOCTOU),
25
+ * https only, no redirects, ≤ 64 KiB, ≤ 5 s. Node built-ins only, so the relay mirror compiles with
26
+ * nothing new.
27
+ */
28
+ var __importDefault = (this && this.__importDefault) || function (mod) {
29
+ return (mod && mod.__esModule) ? mod : { "default": mod };
30
+ };
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.requesterString = exports.REQUESTER_KEYS_CACHE_MS = exports.REQUESTER_KEYS_TIMEOUT_MS = exports.REQUESTER_KEYS_MAX_BYTES = exports.CHALLENGE_DEFAULT_TTL_SECONDS = exports.CHALLENGE_MAX_TTL_SECONDS = exports.CHALLENGE_MIN_TTL_SECONDS = exports.REQUESTER_WELL_KNOWN_PATH = exports.CHALLENGE_ENVELOPE_VERSION = exports.CHALLENGE_SIGNING_TAG = void 0;
33
+ exports.isSignedChallenge = isSignedChallenge;
34
+ exports.parseChallengeEnvelope = parseChallengeEnvelope;
35
+ exports.challengePredicatesDigest = challengePredicatesDigest;
36
+ exports.challengeSigningString = challengeSigningString;
37
+ exports.checkSignedStructure = checkSignedStructure;
38
+ exports.verifyChallengeEnvelope = verifyChallengeEnvelope;
39
+ exports.parseRequesterKeyDocument = parseRequesterKeyDocument;
40
+ exports.describeVerdict = describeVerdict;
41
+ exports.issueUnsignedChallenge = issueUnsignedChallenge;
42
+ exports.isPrivateIp = isPrivateIp;
43
+ exports.isAllowedRequesterDomain = isAllowedRequesterDomain;
44
+ exports.clearRequesterKeyCache = clearRequesterKeyCache;
45
+ exports.fetchRequesterKeysGuarded = fetchRequesterKeysGuarded;
46
+ const crypto_1 = require("crypto");
47
+ const promises_1 = __importDefault(require("dns/promises"));
48
+ const net_1 = __importDefault(require("net"));
49
+ const https_1 = require("https");
50
+ const presentation_1 = require("./presentation");
51
+ Object.defineProperty(exports, "requesterString", { enumerable: true, get: function () { return presentation_1.requesterString; } });
52
+ const disclosure_request_1 = require("./disclosure-request");
53
+ exports.CHALLENGE_SIGNING_TAG = 'provian-challenge-v1';
54
+ exports.CHALLENGE_ENVELOPE_VERSION = 1;
55
+ /** The requester key document path under the requester's domain. */
56
+ exports.REQUESTER_WELL_KNOWN_PATH = '/.well-known/provian-requester.json';
57
+ /** Signed-challenge lifetime bounds (seconds): 60 s .. 7 days. */
58
+ exports.CHALLENGE_MIN_TTL_SECONDS = 60;
59
+ exports.CHALLENGE_MAX_TTL_SECONDS = 7 * 24 * 3600;
60
+ /** Local gates default to 15 minutes. */
61
+ exports.CHALLENGE_DEFAULT_TTL_SECONDS = 900;
62
+ exports.REQUESTER_KEYS_MAX_BYTES = 64 * 1024;
63
+ exports.REQUESTER_KEYS_TIMEOUT_MS = 5000;
64
+ exports.REQUESTER_KEYS_CACHE_MS = 5 * 60 * 1000;
65
+ const DOMAIN_RE = /^(?=.{4,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/;
66
+ const ADDRESS_RE = /^0x[0-9a-f]{40}$/;
67
+ const KID_RE = /^[A-Za-z0-9._-]{1,128}$/;
68
+ /** A Provian wallet id (agent wallet id / human wallet doc id): no separator characters. */
69
+ const WALLET_ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
70
+ const BASE64URL_RE = /^[A-Za-z0-9_-]+$/;
71
+ function isRecord(v) {
72
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
73
+ }
74
+ /** True when the envelope carries a requester signature (identity claim). */
75
+ function isSignedChallenge(env) {
76
+ return env.requester !== undefined || env.sig !== undefined;
77
+ }
78
+ /**
79
+ * Parse an untrusted challenge envelope (object or JSON string). Structural only — no signature
80
+ * check. Returns null when it is not a well-formed challenge (legacy or signed).
81
+ */
82
+ function parseChallengeEnvelope(raw) {
83
+ let obj = raw;
84
+ if (typeof raw === 'string') {
85
+ try {
86
+ obj = JSON.parse(raw);
87
+ }
88
+ catch {
89
+ return null;
90
+ }
91
+ }
92
+ if (!isRecord(obj))
93
+ return null;
94
+ const audience = typeof obj.audience === 'string' ? obj.audience.trim() : '';
95
+ const challenge = typeof obj.challenge === 'string' ? obj.challenge.trim() : '';
96
+ if (audience.length === 0 || audience.length > presentation_1.PRESENTATION_AUDIENCE_MAX_LEN)
97
+ return null;
98
+ if (challenge.length < presentation_1.PRESENTATION_CHALLENGE_MIN_LEN || challenge.length > presentation_1.PRESENTATION_CHALLENGE_MAX_LEN)
99
+ return null;
100
+ const predicates = (0, presentation_1.normalizePredicateRequests)(obj.predicates);
101
+ if (predicates === null)
102
+ return null;
103
+ const disclosures = (0, disclosure_request_1.normalizeDisclosureRequests)(obj.disclosures);
104
+ if (disclosures === null)
105
+ return null;
106
+ const env = { audience, challenge };
107
+ if (predicates.length > 0)
108
+ env.predicates = predicates;
109
+ if (disclosures.length > 0)
110
+ env.disclosures = disclosures;
111
+ if (obj.v !== undefined)
112
+ env.v = obj.v;
113
+ if (obj.issuedAt !== undefined)
114
+ env.issuedAt = obj.issuedAt;
115
+ if (obj.expiresAt !== undefined)
116
+ env.expiresAt = obj.expiresAt;
117
+ if (obj.presenter !== undefined)
118
+ env.presenter = obj.presenter;
119
+ if (obj.requester !== undefined)
120
+ env.requester = obj.requester;
121
+ if (obj.sig !== undefined)
122
+ env.sig = obj.sig;
123
+ return env;
124
+ }
125
+ /** sha256 hex of the canonical (sorted, normalized) predicate list — the signing-string commitment. */
126
+ function challengePredicatesDigest(predicates) {
127
+ const canonical = (0, presentation_1.canonicalReputationDirective)({ redact: [], predicates: predicates ?? [] }).predicates;
128
+ return (0, crypto_1.createHash)('sha256').update(JSON.stringify(canonical), 'utf8').digest('hex');
129
+ }
130
+ /** The exact bytes a requester signs. Fixed line order, `\n`-joined, no trailing newline. */
131
+ function challengeSigningString(env) {
132
+ const lines = [
133
+ exports.CHALLENGE_SIGNING_TAG,
134
+ `aud=${env.audience}`,
135
+ `chal=${env.challenge}`,
136
+ `iat=${env.issuedAt}`,
137
+ `exp=${env.expiresAt}`,
138
+ `req=${(0, presentation_1.requesterString)(env.requester)}`,
139
+ `kid=${env.requester.kid}`,
140
+ `presenter=${(env.presenter ?? '').toLowerCase()}`,
141
+ `predicates=${challengePredicatesDigest(env.predicates)}`,
142
+ ];
143
+ if (env.disclosures !== undefined && env.disclosures.length > 0)
144
+ lines.push(`disclosures=${(0, disclosure_request_1.challengeDisclosuresDigest)(env.disclosures)}`);
145
+ return lines.join('\n');
146
+ }
147
+ /** Structural rules for a SIGNED envelope (A.2), excluding the signature itself. */
148
+ function checkSignedStructure(env) {
149
+ if (env.v !== exports.CHALLENGE_ENVELOPE_VERSION)
150
+ return 'unsupported_version';
151
+ const r = env.requester;
152
+ if (!isRecord(r) || (r.type !== 'domain' && r.type !== 'wallet') || typeof r.id !== 'string')
153
+ return 'bad_requester';
154
+ if (typeof r.kid !== 'string' || !KID_RE.test(r.kid))
155
+ return 'bad_requester';
156
+ if (r.type === 'domain') {
157
+ if (!DOMAIN_RE.test(r.id))
158
+ return 'bad_requester';
159
+ if (r.address !== undefined)
160
+ return 'bad_requester';
161
+ }
162
+ else {
163
+ if (!WALLET_ID_RE.test(r.id))
164
+ return 'bad_requester';
165
+ if (typeof r.address !== 'string' || !ADDRESS_RE.test(r.address))
166
+ return 'bad_requester';
167
+ }
168
+ if (env.audience !== r.id)
169
+ return 'audience_not_requester';
170
+ if (!Number.isInteger(env.issuedAt) || !Number.isInteger(env.expiresAt))
171
+ return 'bad_window';
172
+ const ttl = env.expiresAt - env.issuedAt;
173
+ if (ttl < exports.CHALLENGE_MIN_TTL_SECONDS || ttl > exports.CHALLENGE_MAX_TTL_SECONDS)
174
+ return 'bad_window';
175
+ if (env.presenter !== undefined && (typeof env.presenter !== 'string' || !ADDRESS_RE.test(env.presenter)))
176
+ return 'bad_presenter';
177
+ if (typeof env.sig !== 'string' || env.sig.length === 0)
178
+ return 'bad_signature';
179
+ return null;
180
+ }
181
+ function verifyEd25519(message, sigB64url, key) {
182
+ if (!BASE64URL_RE.test(sigB64url))
183
+ return false;
184
+ if (key.kty !== 'OKP' || key.crv !== 'Ed25519' || typeof key.x !== 'string')
185
+ return false;
186
+ const sig = Buffer.from(sigB64url, 'base64url');
187
+ if (sig.length !== 64)
188
+ return false;
189
+ try {
190
+ const pub = (0, crypto_1.createPublicKey)({ key: { kty: 'OKP', crv: 'Ed25519', x: key.x }, format: 'jwk' });
191
+ return (0, crypto_1.verify)(null, Buffer.from(message, 'utf8'), pub, sig);
192
+ }
193
+ catch {
194
+ return false;
195
+ }
196
+ }
197
+ /**
198
+ * Verify a challenge envelope the way a presenter surface must BEFORE burning (A.3). Unsigned →
199
+ * `unverified`; signed and every check passes → `verified` (or `expired` / `not_addressed` when
200
+ * the signature holds but the deadline passed / the challenge names another presenter); any
201
+ * failure → `invalid`. A domain requester needs `fetchRequesterKeys`; a wallet requester needs
202
+ * `provianKeys` (the Provian presentation JWKS, or a lazy loader for it).
203
+ */
204
+ async function verifyChallengeEnvelope(env, opts = {}) {
205
+ if (!isSignedChallenge(env))
206
+ return { status: 'unverified', envelope: env };
207
+ const structural = checkSignedStructure(env);
208
+ if (structural)
209
+ return { status: 'invalid', reason: structural, envelope: env };
210
+ const requester = env.requester;
211
+ const message = challengeSigningString({
212
+ audience: env.audience,
213
+ challenge: env.challenge,
214
+ issuedAt: env.issuedAt,
215
+ expiresAt: env.expiresAt,
216
+ requester,
217
+ presenter: env.presenter,
218
+ predicates: env.predicates,
219
+ disclosures: env.disclosures,
220
+ });
221
+ let keys;
222
+ if (requester.type === 'wallet') {
223
+ if (!opts.provianKeys)
224
+ return { status: 'invalid', reason: 'requester_key_unreachable', envelope: env };
225
+ const source = opts.provianKeys;
226
+ try {
227
+ keys = typeof source === 'function' ? await source() : source;
228
+ }
229
+ catch {
230
+ return { status: 'invalid', reason: 'requester_key_unreachable', envelope: env };
231
+ }
232
+ }
233
+ else {
234
+ if (!opts.fetchRequesterKeys)
235
+ return { status: 'invalid', reason: 'requester_key_unreachable', envelope: env };
236
+ try {
237
+ keys = await opts.fetchRequesterKeys(requester.id);
238
+ }
239
+ catch {
240
+ return { status: 'invalid', reason: 'requester_key_unreachable', envelope: env };
241
+ }
242
+ }
243
+ const key = keys.find((k) => isRecord(k) && k.kid === requester.kid);
244
+ if (!key)
245
+ return { status: 'invalid', reason: 'key_not_found', envelope: env };
246
+ if (!verifyEd25519(message, env.sig, key))
247
+ return { status: 'invalid', reason: 'bad_signature', envelope: env };
248
+ const identity = requester.type === 'wallet'
249
+ ? { type: 'wallet', id: requester.id, address: requester.address }
250
+ : { type: 'domain', id: requester.id };
251
+ const now = opts.nowSeconds ?? Math.floor(Date.now() / 1000);
252
+ if (now > env.expiresAt + presentation_1.PRESENTATION_CLOCK_SKEW_SECONDS)
253
+ return { status: 'expired', requester: identity, envelope: env };
254
+ if (env.presenter !== undefined && opts.presenterAddress !== undefined
255
+ && env.presenter !== opts.presenterAddress.toLowerCase()) {
256
+ return { status: 'not_addressed', requester: identity, envelope: env };
257
+ }
258
+ return { status: 'verified', requester: identity, envelope: env };
259
+ }
260
+ /** Parse a well-known requester key document body (or a JWKS). Throws on a malformed document. */
261
+ function parseRequesterKeyDocument(body) {
262
+ if (!isRecord(body) || !Array.isArray(body.keys))
263
+ throw new Error('requester key document missing keys');
264
+ const keys = [];
265
+ for (const k of body.keys.slice(0, 16)) {
266
+ if (isRecord(k) && k.kty === 'OKP' && k.crv === 'Ed25519' && typeof k.x === 'string' && typeof k.kid === 'string') {
267
+ keys.push({ kty: 'OKP', crv: 'Ed25519', x: k.x, kid: k.kid });
268
+ }
269
+ }
270
+ return keys;
271
+ }
272
+ function identityLabel(r) {
273
+ return r.type === 'wallet' ? `${r.id} (${r.address ?? ''})` : r.id;
274
+ }
275
+ function describeVerdict(v) {
276
+ switch (v.status) {
277
+ case 'verified':
278
+ return { status: 'verified', identity: v.requester, display: `Requester: ${identityLabel(v.requester)} — verified` };
279
+ case 'unverified':
280
+ return { status: 'unverified', identity: null, display: `Requester: ${v.envelope.audience} — unverified (unsigned challenge)` };
281
+ case 'expired':
282
+ return { status: 'expired', identity: v.requester, display: `Requester: ${identityLabel(v.requester)} — challenge EXPIRED; do not burn or present` };
283
+ case 'not_addressed':
284
+ return { status: 'not_addressed', identity: v.requester, display: `Requester: ${identityLabel(v.requester)} — challenge is addressed to a DIFFERENT presenter; do not burn or present` };
285
+ default:
286
+ return { status: 'invalid', identity: null, reason: v.reason, display: `Signed challenge is INVALID (${v.reason}) — refuse; do not burn or present` };
287
+ }
288
+ }
289
+ /** A fresh unsigned (legacy) challenge in the wire shape. Presenters see it as UNVERIFIED. */
290
+ function issueUnsignedChallenge(input) {
291
+ const issuedAt = input.nowSeconds ?? Math.floor(Date.now() / 1000);
292
+ const ttl = input.ttlSeconds ?? exports.CHALLENGE_DEFAULT_TTL_SECONDS;
293
+ const env = { audience: input.audience, challenge: (0, crypto_1.randomBytes)(32).toString('hex') };
294
+ if (input.predicates && input.predicates.length > 0)
295
+ env.predicates = [...input.predicates];
296
+ if (input.disclosures && input.disclosures.length > 0)
297
+ env.disclosures = [...input.disclosures];
298
+ env.issuedAt = issuedAt;
299
+ env.expiresAt = issuedAt + ttl;
300
+ if (input.presenter !== undefined)
301
+ env.presenter = input.presenter.toLowerCase();
302
+ return env;
303
+ }
304
+ // ---------------------------------------------------------------------------
305
+ // Domain requester key discovery — SSRF-guarded (Security Invariant #6).
306
+ // ---------------------------------------------------------------------------
307
+ function parseIpv4(ip) {
308
+ const parts = ip.split('.');
309
+ if (parts.length !== 4)
310
+ return null;
311
+ const out = [];
312
+ for (const p of parts) {
313
+ if (!/^\d{1,3}$/.test(p))
314
+ return null;
315
+ const n = Number(p);
316
+ if (n > 255)
317
+ return null;
318
+ out.push(n);
319
+ }
320
+ return out;
321
+ }
322
+ /** Eight 16-bit segments, or null when the text (brackets / zone id tolerated) is not one IPv6 address. */
323
+ function expandIpv6(raw) {
324
+ let text = raw.trim().replace(/^\[|\]$/g, '');
325
+ const zone = text.indexOf('%');
326
+ if (zone !== -1)
327
+ text = text.slice(0, zone);
328
+ if (text.length === 0 || !/^[0-9a-fA-F:.]+$/.test(text))
329
+ return null;
330
+ if (text.includes('.')) {
331
+ const lastColon = text.lastIndexOf(':');
332
+ if (lastColon === -1)
333
+ return null;
334
+ const v4 = parseIpv4(text.slice(lastColon + 1));
335
+ if (v4 === null)
336
+ return null;
337
+ text = `${text.slice(0, lastColon + 1)}${((v4[0] << 8) | v4[1]).toString(16)}:${((v4[2] << 8) | v4[3]).toString(16)}`;
338
+ }
339
+ const halves = text.split('::');
340
+ if (halves.length > 2)
341
+ return null;
342
+ const left = halves[0] ? halves[0].split(':') : [];
343
+ const right = halves.length === 2 && halves[1] ? halves[1].split(':') : [];
344
+ let segments;
345
+ if (halves.length === 2) {
346
+ const missing = 8 - left.length - right.length;
347
+ if (missing < 1)
348
+ return null;
349
+ segments = [...left, ...new Array(missing).fill('0'), ...right];
350
+ }
351
+ else {
352
+ segments = left;
353
+ }
354
+ if (segments.length !== 8)
355
+ return null;
356
+ const out = [];
357
+ for (const segment of segments) {
358
+ if (!/^[0-9a-fA-F]{1,4}$/.test(segment))
359
+ return null;
360
+ out.push(parseInt(segment, 16));
361
+ }
362
+ return out;
363
+ }
364
+ /**
365
+ * Private / internal / non-routable address predicate. Anything it cannot parse as a public IPv4 /
366
+ * IPv6 address is treated as private (fail-closed). A superset of the relay's `isPrivateIp`
367
+ * (adds CGNAT, multicast/reserved, IPv6 multicast, NAT64 / 6to4 which can embed a private v4).
368
+ */
369
+ function isPrivateIp(ip) {
370
+ if (ip.includes(':')) {
371
+ // Judged on the PARSED segments, never the text: an uncompressed `0:0:0:0:0:0:0:1` or a
372
+ // bracketed literal spells the same loopback (2026-10-17 bug check).
373
+ const s = expandIpv6(ip);
374
+ if (s === null)
375
+ return true;
376
+ const zeroThrough = (n) => s.slice(0, n).every((x) => x === 0);
377
+ if (zeroThrough(8))
378
+ return true; // ::
379
+ if (zeroThrough(7) && s[7] === 1)
380
+ return true; // ::1
381
+ const embedded = `${s[6] >> 8}.${s[6] & 0xff}.${s[7] >> 8}.${s[7] & 0xff}`;
382
+ // Every IPv4-embedding form under ::/80 — mapped `::ffff:a.b.c.d`, translated `::ffff:0:a.b.c.d`
383
+ // (SIIT), compatible `::a.b.c.d` — is refused whatever it embeds: a public host is reached by its
384
+ // plain IPv4, and a translation path is a way to reach a private one .
385
+ if (zeroThrough(4) && (s[4] === 0 || s[4] === 0xffff) && (s[5] === 0 || s[5] === 0xffff))
386
+ return true;
387
+ if (s[0] === 0x0064 && s[1] === 0xff9b)
388
+ return isPrivateIp(embedded); // NAT64 — judged by the embedded v4
389
+ if (s[0] === 0x2002)
390
+ return isPrivateIp(`${s[1] >> 8}.${s[1] & 0xff}.${s[2] >> 8}.${s[2] & 0xff}`); // 6to4
391
+ if ((s[0] & 0xffc0) === 0xfe80)
392
+ return true; // link-local fe80::/10
393
+ if ((s[0] & 0xffc0) === 0xfec0)
394
+ return true; // site-local (deprecated)
395
+ if ((s[0] & 0xfe00) === 0xfc00)
396
+ return true; // unique local fc00::/7
397
+ if ((s[0] & 0xff00) === 0xff00)
398
+ return true; // multicast
399
+ if (s[0] === 0x2001 && s[1] === 0x0db8)
400
+ return true; // documentation — never routable
401
+ return false;
402
+ }
403
+ const p = parseIpv4(ip);
404
+ if (!p)
405
+ return true;
406
+ if (p[0] === 0 || p[0] === 10 || p[0] === 127)
407
+ return true;
408
+ if (p[0] === 100 && p[1] >= 64 && p[1] <= 127)
409
+ return true; // CGNAT 100.64/10
410
+ if (p[0] === 169 && p[1] === 254)
411
+ return true; // link-local incl. cloud metadata
412
+ if (p[0] === 172 && p[1] >= 16 && p[1] <= 31)
413
+ return true;
414
+ if (p[0] === 192 && p[1] === 168)
415
+ return true;
416
+ if (p[0] === 192 && p[1] === 0 && (p[2] === 0 || p[2] === 2))
417
+ return true;
418
+ if (p[0] === 198 && (p[1] === 18 || p[1] === 19))
419
+ return true; // benchmarking
420
+ if (p[0] >= 224)
421
+ return true; // multicast + reserved + broadcast
422
+ return false;
423
+ }
424
+ /** A requester domain the guard will fetch from: the spec's hostname regex, never localhost. */
425
+ function isAllowedRequesterDomain(domain) {
426
+ if (!DOMAIN_RE.test(domain))
427
+ return false;
428
+ if (domain === 'localhost' || domain.endsWith('.localhost'))
429
+ return false;
430
+ return net_1.default.isIP(domain) === 0;
431
+ }
432
+ async function defaultResolve(hostname) {
433
+ const [v4, v6] = await Promise.all([
434
+ promises_1.default.resolve4(hostname).catch(() => []),
435
+ promises_1.default.resolve6(hostname).catch(() => []),
436
+ ]);
437
+ return [...v4, ...v6];
438
+ }
439
+ function pinnedGet(url, pinnedIp) {
440
+ const family = net_1.default.isIP(pinnedIp) === 6 ? 6 : 4;
441
+ // Node 20+ calls an Agent's lookup with `{ all: true }` (autoSelectFamily) and expects an ARRAY;
442
+ // the single-address answer fails the connection ("Invalid IP address: undefined"). Answer both.
443
+ const lookupImpl = (_h, options, cb) => {
444
+ const all = typeof options === 'object' && options !== null && options.all === true;
445
+ if (all)
446
+ cb(null, [{ address: pinnedIp, family }]);
447
+ else
448
+ cb(null, pinnedIp, family);
449
+ };
450
+ const agent = new https_1.Agent({ lookup: lookupImpl });
451
+ return new Promise((resolve) => {
452
+ let settled = false;
453
+ const done = (v) => { if (!settled) {
454
+ settled = true;
455
+ resolve(v);
456
+ } };
457
+ const outbound = (0, https_1.request)(url, { method: 'GET', agent, timeout: exports.REQUESTER_KEYS_TIMEOUT_MS, headers: { accept: 'application/json' } }, (response) => {
458
+ const status = response.statusCode ?? 0;
459
+ if (status < 200 || status >= 300) {
460
+ response.resume();
461
+ done(null);
462
+ return;
463
+ } // no redirects
464
+ const chunks = [];
465
+ let total = 0;
466
+ response.on('data', (chunk) => {
467
+ total += chunk.length;
468
+ if (total > exports.REQUESTER_KEYS_MAX_BYTES) {
469
+ outbound.destroy(new Error('too_large'));
470
+ done(null);
471
+ return;
472
+ }
473
+ chunks.push(chunk);
474
+ });
475
+ response.on('end', () => done(Buffer.concat(chunks)));
476
+ response.on('error', () => done(null));
477
+ });
478
+ const hardStop = setTimeout(() => { outbound.destroy(new Error('timeout')); done(null); }, exports.REQUESTER_KEYS_TIMEOUT_MS);
479
+ outbound.on('timeout', () => outbound.destroy(new Error('timeout')));
480
+ outbound.on('error', () => done(null));
481
+ outbound.on('close', () => clearTimeout(hardStop));
482
+ outbound.end();
483
+ }).finally(() => agent.destroy());
484
+ }
485
+ function withTimeout(p, ms, what) {
486
+ let timer;
487
+ return Promise.race([
488
+ p,
489
+ new Promise((_resolve, reject) => { timer = setTimeout(() => reject(new Error(`${what} timed out`)), ms); }),
490
+ ]).finally(() => { if (timer)
491
+ clearTimeout(timer); });
492
+ }
493
+ const keyCache = new Map();
494
+ /** Clear the per-domain key cache (tests / key rotation). */
495
+ function clearRequesterKeyCache() {
496
+ keyCache.clear();
497
+ }
498
+ /**
499
+ * Fetch a domain requester's Ed25519 keys, SSRF-guarded. Throws on any failure (the caller maps a
500
+ * throw to `requester_key_unreachable`, never to a verified identity). Cached 5 minutes per domain
501
+ * so one requester cannot turn a presenter surface into a request amplifier.
502
+ */
503
+ async function fetchRequesterKeysGuarded(domain, deps = {}) {
504
+ if (!isAllowedRequesterDomain(domain))
505
+ throw new Error('requester domain is not a public DNS hostname');
506
+ const now = deps.nowMs ? deps.nowMs() : Date.now();
507
+ const hit = keyCache.get(domain);
508
+ if (hit && now - hit.atMs < exports.REQUESTER_KEYS_CACHE_MS)
509
+ return hit.keys;
510
+ const addresses = await withTimeout((deps.resolveHostname ?? defaultResolve)(domain), exports.REQUESTER_KEYS_TIMEOUT_MS, 'requester domain resolution');
511
+ if (addresses.length === 0)
512
+ throw new Error('requester domain does not resolve');
513
+ for (const addr of addresses) {
514
+ if (net_1.default.isIP(addr) === 0 || isPrivateIp(addr))
515
+ throw new Error('requester domain resolves to a private address');
516
+ }
517
+ const url = `https://${domain}${exports.REQUESTER_WELL_KNOWN_PATH}`;
518
+ const body = await withTimeout((deps.get ?? pinnedGet)(url, addresses[0]), exports.REQUESTER_KEYS_TIMEOUT_MS + 500, 'requester key fetch');
519
+ if (!body)
520
+ throw new Error('requester key document unreachable');
521
+ if (body.length > exports.REQUESTER_KEYS_MAX_BYTES)
522
+ throw new Error('requester key document too large');
523
+ let parsed;
524
+ try {
525
+ parsed = JSON.parse(body.toString('utf8'));
526
+ }
527
+ catch {
528
+ throw new Error('requester key document is not JSON');
529
+ }
530
+ const keys = parseRequesterKeyDocument(parsed);
531
+ if (keys.length === 0)
532
+ throw new Error('requester key document has no Ed25519 keys');
533
+ keyCache.set(domain, { keys, atMs: now });
534
+ return keys;
535
+ }
536
+ //# sourceMappingURL=challenge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge.js","sourceRoot":"","sources":["../../src/core/challenge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Agent-key crypto for the MCP tool core.
3
+ *
4
+ * SHARED CORE — canonical in `provian-mcp/src/core/`, mirrored into
5
+ * `provian-backend/src/mcp/core/`. Edit only the canonical copy.
6
+ *
7
+ * Line-for-line ports of the SDK's key handling so the relay accepts
8
+ * signatures from either package interchangeably:
9
+ * - generateAgentKeyPair / signPoPChallenge ← provian-agent-sdk/src/wallet.ts
10
+ * (Node crypto secp256k1 keygen; PoP challenge signed with
11
+ * createSign('SHA256') → DER hex, exactly what
12
+ * POST /v1/agent/wallet/create verifies)
13
+ *
14
+ * Deliberately Node-crypto-only (zero npm deps beyond the vendored keccak):
15
+ * the mirror compiles inside the relay with no new dependencies. EIP-191
16
+ * signing (external-address one-shot linking, local mode only) is NOT here —
17
+ * it is injected by the local stdio server via ToolContext.signEip191; the
18
+ * remote endpoint refuses private-key material by design.
19
+ */
20
+ export interface AgentKeyPair {
21
+ /** 32-byte private key, hex, no 0x prefix. */
22
+ privateKey: string;
23
+ /** 64-byte uncompressed public key (no 04 prefix), hex. */
24
+ publicKey: string;
25
+ /** EIP-55 checksummed EVM address. */
26
+ address: string;
27
+ }
28
+ /**
29
+ * Generate a new secp256k1 key pair using Node.js crypto and derive the
30
+ * EVM address (keccak256 of the raw public key, last 20 bytes).
31
+ */
32
+ export declare function generateAgentKeyPair(): AgentKeyPair;
33
+ /**
34
+ * Sign a wallet-create proof-of-possession challenge with the agent's
35
+ * private key. Plain ECDSA-SHA256 over the challenge string, DER-encoded
36
+ * hex — byte-identical to the SDK's `signMessage` and exactly what the
37
+ * relay's challenge verifier expects.
38
+ */
39
+ export declare function signPoPChallenge(privateKeyHex: string, challenge: string): string;
40
+ /** Derive the EIP-55 checksummed EVM address for a hex private key. */
41
+ export declare function deriveAddressFromPrivateKey(privateKeyHex: string): string;
42
+ /** Derive the 64-byte uncompressed public key (without the 04 prefix). */
43
+ export declare function derivePublicKeyFromPrivateKey(privateKeyHex: string): string;
44
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/core/crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,YAAY,CAmBnD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAWjF;AAED,uEAAuE;AACvE,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAOzE;AAED,0EAA0E;AAC1E,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAmB3E"}