@fungi.computer/veil 0.2.1 → 0.4.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.
- package/README.md +69 -0
- package/dist/connections/contract.d.ts +141 -0
- package/dist/connections/contract.js +55 -0
- package/dist/connections/core.d.ts +48 -0
- package/dist/connections/core.js +372 -0
- package/dist/connections/egress.d.ts +8 -0
- package/dist/connections/egress.js +77 -0
- package/dist/connections/index.d.ts +3 -0
- package/dist/connections/index.js +3 -0
- package/dist/connections/sealed.d.ts +21 -0
- package/dist/connections/sealed.js +54 -0
- package/dist/credential-store.d.ts +64 -0
- package/dist/credential-store.js +151 -0
- package/dist/index.d.ts +1 -1
- package/dist/model-credentials.d.ts +8 -7
- package/dist/model-credentials.js +15 -12
- package/dist/model-keys.d.ts +24 -0
- package/dist/openapi-secrets.d.ts +1 -1
- package/dist/openapi-secrets.js +19 -58
- package/dist/provider-egress.d.ts +16 -5
- package/dist/provider-egress.js +194 -4
- package/package.json +12 -1
package/dist/provider-egress.js
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { VeilError } from "./index.js";
|
|
2
3
|
const CAMEL_BASE = "https://stream.camelai.com/v1";
|
|
3
4
|
const PARALLEL_BASE = "https://api.parallel.ai";
|
|
4
5
|
const GATEWAY_ORIGIN = "https://gateway.ai.cloudflare.com";
|
|
5
6
|
const CLOUDFLARE_API_ORIGIN = "https://api.cloudflare.com";
|
|
7
|
+
const HELIUS_BASE = "https://mainnet.helius-rpc.com/";
|
|
8
|
+
const OFAC_SDN = "https://sanctionslistservice.ofac.treas.gov/api/PublicationPreview/exports/SDN.XML";
|
|
9
|
+
const OFAC_DOWNLOAD_ORIGIN = "https://wc2h-sls-prod-public-published.s3.us-gov-west-1.amazonaws.com";
|
|
10
|
+
// Single read-only JSON-RPC calls used by the finalized holdings/lock reader.
|
|
11
|
+
// Zod owns JSON envelope decoding; the holdings owner owns params and results.
|
|
12
|
+
const snapshotCall = z
|
|
13
|
+
.object({
|
|
14
|
+
jsonrpc: z.literal("2.0"),
|
|
15
|
+
id: z.union([z.string(), z.number()]),
|
|
16
|
+
method: z.enum([
|
|
17
|
+
"getAccountInfo",
|
|
18
|
+
"getMultipleAccounts",
|
|
19
|
+
"getProgramAccounts",
|
|
20
|
+
"getTokenSupply",
|
|
21
|
+
"getSlot",
|
|
22
|
+
]),
|
|
23
|
+
params: z.array(z.unknown()).optional(),
|
|
24
|
+
})
|
|
25
|
+
.strict();
|
|
26
|
+
function snapshotRoute(route) {
|
|
27
|
+
return (route === "solana-rpc" ||
|
|
28
|
+
route === "solana-rpc-fallback" ||
|
|
29
|
+
route === "sanctions-screen");
|
|
30
|
+
}
|
|
6
31
|
const present = (value) => {
|
|
7
32
|
const trimmed = value?.trim();
|
|
8
33
|
return trimmed === undefined || trimmed === "" ? undefined : trimmed;
|
|
@@ -18,6 +43,34 @@ function gatewayScope(env) {
|
|
|
18
43
|
/** The destination and credential for a route; `undefined` if either is missing. */
|
|
19
44
|
function target(env, route) {
|
|
20
45
|
switch (route) {
|
|
46
|
+
case "solana-rpc":
|
|
47
|
+
case "solana-rpc-fallback": {
|
|
48
|
+
const primary = route === "solana-rpc";
|
|
49
|
+
const raw = present(primary ? env.SOLANA_RPC_URL : env.SOLANA_RPC_FALLBACK_URL);
|
|
50
|
+
const credential = present(primary ? env.SOLANA_RPC_API_KEY : env.SOLANA_RPC_FALLBACK_API_KEY);
|
|
51
|
+
if (raw === undefined || credential === undefined)
|
|
52
|
+
return undefined;
|
|
53
|
+
if (!URL.canParse(raw))
|
|
54
|
+
return undefined;
|
|
55
|
+
const base = new URL(raw);
|
|
56
|
+
if (base.protocol !== "https:" ||
|
|
57
|
+
base.username ||
|
|
58
|
+
base.password ||
|
|
59
|
+
base.port ||
|
|
60
|
+
base.pathname !== "/" ||
|
|
61
|
+
base.search ||
|
|
62
|
+
base.hash)
|
|
63
|
+
return undefined;
|
|
64
|
+
if (primary
|
|
65
|
+
? base.href !== HELIUS_BASE
|
|
66
|
+
: !/^[a-z0-9-]+\.solana-mainnet\.quiknode\.pro$/u.test(base.hostname))
|
|
67
|
+
return undefined;
|
|
68
|
+
return { base, credential };
|
|
69
|
+
}
|
|
70
|
+
case "sanctions-screen":
|
|
71
|
+
return present(env.SANCTIONS_SDN_URL) === OFAC_SDN
|
|
72
|
+
? { base: new URL(OFAC_SDN) }
|
|
73
|
+
: undefined;
|
|
21
74
|
case "camel": {
|
|
22
75
|
const credential = present(env.CAMEL_API_KEY);
|
|
23
76
|
return credential === undefined
|
|
@@ -67,6 +120,8 @@ function within(url, base) {
|
|
|
67
120
|
}
|
|
68
121
|
/** Replace whatever credential the caller sent with this route's own. */
|
|
69
122
|
function authorize(route, headers, credential) {
|
|
123
|
+
if (credential === undefined)
|
|
124
|
+
throw new VeilError("unavailable");
|
|
70
125
|
for (const name of [
|
|
71
126
|
"authorization",
|
|
72
127
|
"x-api-key",
|
|
@@ -75,6 +130,11 @@ function authorize(route, headers, credential) {
|
|
|
75
130
|
])
|
|
76
131
|
headers.delete(name);
|
|
77
132
|
switch (route) {
|
|
133
|
+
case "solana-rpc":
|
|
134
|
+
case "solana-rpc-fallback":
|
|
135
|
+
case "sanctions-screen":
|
|
136
|
+
// These doors construct their own headers and URL below.
|
|
137
|
+
return;
|
|
78
138
|
case "camel":
|
|
79
139
|
case "ai-gateway-logs":
|
|
80
140
|
headers.set("authorization", `Bearer ${credential}`);
|
|
@@ -87,6 +147,130 @@ function authorize(route, headers, credential) {
|
|
|
87
147
|
return;
|
|
88
148
|
}
|
|
89
149
|
}
|
|
150
|
+
/** A bounded body, before JSON decoding or returning a provider response. */
|
|
151
|
+
async function boundedText(message, limit) {
|
|
152
|
+
const reader = message.body?.getReader();
|
|
153
|
+
if (reader === undefined)
|
|
154
|
+
return "";
|
|
155
|
+
const chunks = [];
|
|
156
|
+
let size = 0;
|
|
157
|
+
try {
|
|
158
|
+
for (;;) {
|
|
159
|
+
const part = await reader.read();
|
|
160
|
+
if (part.done)
|
|
161
|
+
break;
|
|
162
|
+
const chunk = part.value;
|
|
163
|
+
if (!(chunk instanceof Uint8Array))
|
|
164
|
+
throw new VeilError("unavailable");
|
|
165
|
+
size += chunk.byteLength;
|
|
166
|
+
if (size > limit)
|
|
167
|
+
throw new VeilError("unavailable");
|
|
168
|
+
chunks.push(chunk);
|
|
169
|
+
}
|
|
170
|
+
return await new Blob(chunks).text();
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
try {
|
|
174
|
+
await reader.cancel();
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
reader.releaseLock();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Fixed, non-streaming snapshot doors never return upstream headers or URLs. */
|
|
182
|
+
async function fetchSnapshot(route, resolved, request, transport) {
|
|
183
|
+
try {
|
|
184
|
+
const url = new URL(request.url);
|
|
185
|
+
if (url.href !== resolved.base.href)
|
|
186
|
+
throw new VeilError("denied");
|
|
187
|
+
const screening = route === "sanctions-screen";
|
|
188
|
+
if (request.method !== (screening ? "GET" : "POST"))
|
|
189
|
+
throw new VeilError("denied");
|
|
190
|
+
let body;
|
|
191
|
+
if (!screening) {
|
|
192
|
+
body = await boundedText(request, 64 * 1024);
|
|
193
|
+
let envelope;
|
|
194
|
+
try {
|
|
195
|
+
envelope = JSON.parse(body);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
throw new VeilError("denied");
|
|
199
|
+
}
|
|
200
|
+
if (!snapshotCall.safeParse(envelope).success)
|
|
201
|
+
throw new VeilError("denied");
|
|
202
|
+
}
|
|
203
|
+
const destination = new URL(resolved.base);
|
|
204
|
+
const key = resolved.credential;
|
|
205
|
+
if (!screening) {
|
|
206
|
+
if (key === undefined)
|
|
207
|
+
throw new VeilError("unavailable");
|
|
208
|
+
if (route === "solana-rpc")
|
|
209
|
+
destination.searchParams.set("api-key", key);
|
|
210
|
+
else
|
|
211
|
+
destination.pathname = `/${encodeURIComponent(key)}/`;
|
|
212
|
+
}
|
|
213
|
+
const init = {
|
|
214
|
+
method: request.method,
|
|
215
|
+
headers: screening
|
|
216
|
+
? { accept: "application/xml" }
|
|
217
|
+
: {
|
|
218
|
+
accept: "application/json",
|
|
219
|
+
"content-type": "application/json",
|
|
220
|
+
},
|
|
221
|
+
signal: request.signal,
|
|
222
|
+
redirect: "manual",
|
|
223
|
+
};
|
|
224
|
+
if (body !== undefined)
|
|
225
|
+
init.body = body;
|
|
226
|
+
let response = await transport(new Request(destination, init));
|
|
227
|
+
// OFAC publishes a signed S3 download URL. Only this anonymous GET door
|
|
228
|
+
// may follow that one observed 302; the next response must succeed.
|
|
229
|
+
if (screening && response.status === 302) {
|
|
230
|
+
const location = response.headers.get("location");
|
|
231
|
+
await response.body?.cancel();
|
|
232
|
+
if (location === null ||
|
|
233
|
+
location.length > 8192 ||
|
|
234
|
+
!URL.canParse(location))
|
|
235
|
+
throw new VeilError("unavailable");
|
|
236
|
+
const download = new URL(location);
|
|
237
|
+
if (download.origin !== OFAC_DOWNLOAD_ORIGIN ||
|
|
238
|
+
download.username !== "" ||
|
|
239
|
+
download.password !== "" ||
|
|
240
|
+
!download.pathname.startsWith("/Published/") ||
|
|
241
|
+
!download.pathname.endsWith("/SDN.XML") ||
|
|
242
|
+
download.hash !== "")
|
|
243
|
+
throw new VeilError("unavailable");
|
|
244
|
+
request.signal.throwIfAborted();
|
|
245
|
+
response = await transport(new Request(download, {
|
|
246
|
+
method: "GET",
|
|
247
|
+
headers: { accept: "application/xml" },
|
|
248
|
+
signal: request.signal,
|
|
249
|
+
redirect: "manual",
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
if (!response.ok) {
|
|
253
|
+
await response.body?.cancel();
|
|
254
|
+
throw new VeilError("unavailable");
|
|
255
|
+
}
|
|
256
|
+
const text = await boundedText(response, 64 * 1024 * 1024);
|
|
257
|
+
if (key !== undefined &&
|
|
258
|
+
[key, encodeURIComponent(key), JSON.stringify(key).slice(1, -1)].some((echo) => text.includes(echo)))
|
|
259
|
+
throw new VeilError("unavailable");
|
|
260
|
+
return new Response(text, {
|
|
261
|
+
status: response.status,
|
|
262
|
+
headers: {
|
|
263
|
+
"content-type": screening ? "application/xml" : "application/json",
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
// Even aborted transports can include a credential-bearing URL in errors.
|
|
269
|
+
if (error instanceof VeilError)
|
|
270
|
+
throw error;
|
|
271
|
+
throw new VeilError("unavailable");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
90
274
|
/**
|
|
91
275
|
* The provider-key door. `fetch` is the transport the authorized request is
|
|
92
276
|
* finally sent on (a test double, or the Hub's telemetry-wrapped fetch).
|
|
@@ -94,9 +278,13 @@ function authorize(route, headers, credential) {
|
|
|
94
278
|
export function createProviderEgress(env, options = {}) {
|
|
95
279
|
const transport = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
96
280
|
return {
|
|
97
|
-
/** Whether
|
|
281
|
+
/** Whether required custody/configuration is present; reveals no value. */
|
|
98
282
|
credentialed(route) {
|
|
99
283
|
switch (route) {
|
|
284
|
+
case "solana-rpc":
|
|
285
|
+
case "solana-rpc-fallback":
|
|
286
|
+
case "sanctions-screen":
|
|
287
|
+
return target(env, route) !== undefined;
|
|
100
288
|
case "camel":
|
|
101
289
|
return present(env.CAMEL_API_KEY) !== undefined;
|
|
102
290
|
case "parallel":
|
|
@@ -116,9 +304,9 @@ export function createProviderEgress(env, options = {}) {
|
|
|
116
304
|
/**
|
|
117
305
|
* Send a credential-free request to a route. Refuses (`denied`) any
|
|
118
306
|
* destination outside the route and (`unavailable`) a route with no
|
|
119
|
-
* credential.
|
|
120
|
-
*
|
|
121
|
-
*
|
|
307
|
+
* credential. Credentialed routes never follow redirects (workerd has no
|
|
308
|
+
* `error` mode; `manual` hands the 3xx back instead). Only the anonymous
|
|
309
|
+
* sanctions GET may follow one pinned OFAC government-S3 302.
|
|
122
310
|
*/
|
|
123
311
|
async fetch(route, input, init) {
|
|
124
312
|
const resolved = target(env, route);
|
|
@@ -134,6 +322,8 @@ export function createProviderEgress(env, options = {}) {
|
|
|
134
322
|
}
|
|
135
323
|
if (!within(new URL(request.url), resolved.base))
|
|
136
324
|
throw new VeilError("denied");
|
|
325
|
+
if (snapshotRoute(route))
|
|
326
|
+
return fetchSnapshot(route, resolved, request, transport);
|
|
137
327
|
const headers = new Headers(request.headers);
|
|
138
328
|
authorize(route, headers, resolved.credential);
|
|
139
329
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fungi.computer/veil",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"author": "Levi <levi@technomancy.dev>",
|
|
5
5
|
"description": "Team-authorized credential custody and provider access",
|
|
6
6
|
"type": "module",
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"types": "./dist/model-credentials.d.ts",
|
|
24
24
|
"import": "./dist/model-credentials.js"
|
|
25
25
|
},
|
|
26
|
+
"./credential-store": {
|
|
27
|
+
"types": "./dist/credential-store.d.ts",
|
|
28
|
+
"import": "./dist/credential-store.js"
|
|
29
|
+
},
|
|
26
30
|
"./model-keys": {
|
|
27
31
|
"types": "./dist/model-keys.d.ts",
|
|
28
32
|
"import": "./dist/model-keys.js"
|
|
@@ -78,6 +82,10 @@
|
|
|
78
82
|
"./owned-infrastructure": {
|
|
79
83
|
"types": "./dist/owned-infrastructure.d.ts",
|
|
80
84
|
"import": "./dist/owned-infrastructure.js"
|
|
85
|
+
},
|
|
86
|
+
"./connections": {
|
|
87
|
+
"types": "./dist/connections/index.d.ts",
|
|
88
|
+
"import": "./dist/connections/index.js"
|
|
81
89
|
}
|
|
82
90
|
},
|
|
83
91
|
"files": [
|
|
@@ -87,6 +95,8 @@
|
|
|
87
95
|
],
|
|
88
96
|
"dependencies": {
|
|
89
97
|
"@fungi.computer/cairn": "0.1.0",
|
|
98
|
+
"@fungi.computer/forage": "0.3.1",
|
|
99
|
+
"@modelcontextprotocol/client": "2.0.0",
|
|
90
100
|
"@nangohq/node": "0.71.6",
|
|
91
101
|
"effect": "4.0.2",
|
|
92
102
|
"http-parser-js": "0.5.10",
|
|
@@ -94,6 +104,7 @@
|
|
|
94
104
|
"zod": "4.4.3"
|
|
95
105
|
},
|
|
96
106
|
"devDependencies": {
|
|
107
|
+
"@fungi.computer/watchdog": "0.1.0",
|
|
97
108
|
"@types/node": "24.13.3",
|
|
98
109
|
"typescript": "5.9.3",
|
|
99
110
|
"vitest": "4.1.11"
|