@zeke-02/tinfoil 0.0.11 → 0.11.7

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 (105) hide show
  1. package/dist/ai-sdk-provider.browser.d.ts +12 -0
  2. package/dist/ai-sdk-provider.browser.d.ts.map +1 -0
  3. package/dist/{esm/ai-sdk-provider.mjs → ai-sdk-provider.browser.js} +9 -5
  4. package/dist/ai-sdk-provider.browser.js.map +1 -0
  5. package/dist/ai-sdk-provider.d.ts +6 -1
  6. package/dist/ai-sdk-provider.d.ts.map +1 -0
  7. package/dist/ai-sdk-provider.js +12 -11
  8. package/dist/ai-sdk-provider.js.map +1 -0
  9. package/dist/config.d.ts +2 -1
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +3 -5
  12. package/dist/config.js.map +1 -0
  13. package/dist/encrypted-body-fetch.d.ts +8 -2
  14. package/dist/encrypted-body-fetch.d.ts.map +1 -0
  15. package/dist/encrypted-body-fetch.js +27 -26
  16. package/dist/encrypted-body-fetch.js.map +1 -0
  17. package/dist/env.d.ts +1 -0
  18. package/dist/env.d.ts.map +1 -0
  19. package/dist/env.js +2 -4
  20. package/dist/env.js.map +1 -0
  21. package/dist/index.browser.d.ts +8 -7
  22. package/dist/index.browser.d.ts.map +1 -0
  23. package/dist/index.browser.js +8 -28
  24. package/dist/index.browser.js.map +1 -0
  25. package/dist/index.d.ts +9 -8
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +10 -47
  28. package/dist/index.js.map +1 -0
  29. package/dist/pinned-tls-fetch.d.ts +1 -0
  30. package/dist/pinned-tls-fetch.d.ts.map +1 -0
  31. package/dist/pinned-tls-fetch.js +13 -17
  32. package/dist/pinned-tls-fetch.js.map +1 -0
  33. package/dist/router.d.ts +1 -0
  34. package/dist/router.d.ts.map +1 -0
  35. package/dist/router.js +6 -7
  36. package/dist/router.js.map +1 -0
  37. package/dist/{esm/secure-client.d.ts → secure-client.browser.d.ts} +2 -1
  38. package/dist/secure-client.browser.d.ts.map +1 -0
  39. package/dist/{esm/secure-client.mjs → secure-client.browser.js} +46 -56
  40. package/dist/secure-client.browser.js.map +1 -0
  41. package/dist/secure-client.d.ts +2 -1
  42. package/dist/secure-client.d.ts.map +1 -0
  43. package/dist/secure-client.js +51 -65
  44. package/dist/secure-client.js.map +1 -0
  45. package/dist/secure-fetch.browser.d.ts +1 -0
  46. package/dist/secure-fetch.browser.d.ts.map +1 -0
  47. package/dist/secure-fetch.browser.js +4 -6
  48. package/dist/secure-fetch.browser.js.map +1 -0
  49. package/dist/secure-fetch.d.ts +1 -0
  50. package/dist/secure-fetch.d.ts.map +1 -0
  51. package/dist/secure-fetch.js +16 -8
  52. package/dist/secure-fetch.js.map +1 -0
  53. package/dist/{tinfoilai.d.ts → tinfoil-ai.browser.d.ts} +5 -2
  54. package/dist/tinfoil-ai.browser.d.ts.map +1 -0
  55. package/dist/{tinfoilai.js → tinfoil-ai.browser.js} +50 -39
  56. package/dist/tinfoil-ai.browser.js.map +1 -0
  57. package/dist/{esm/tinfoilai.d.ts → tinfoil-ai.d.ts} +5 -2
  58. package/dist/tinfoil-ai.d.ts.map +1 -0
  59. package/dist/{esm/tinfoilai.mjs → tinfoil-ai.js} +29 -11
  60. package/dist/tinfoil-ai.js.map +1 -0
  61. package/dist/unverified-client.d.ts +1 -2
  62. package/dist/unverified-client.d.ts.map +1 -0
  63. package/dist/unverified-client.js +10 -13
  64. package/dist/unverified-client.js.map +1 -0
  65. package/dist/verifier.d.ts +2 -141
  66. package/dist/verifier.d.ts.map +1 -0
  67. package/dist/verifier.js +2 -570
  68. package/dist/verifier.js.map +1 -0
  69. package/package.json +48 -41
  70. package/LICENSE +0 -661
  71. package/README.md +0 -183
  72. package/dist/__tests__/test-utils.d.ts +0 -1
  73. package/dist/__tests__/test-utils.js +0 -44
  74. package/dist/esm/__tests__/test-utils.d.ts +0 -1
  75. package/dist/esm/__tests__/test-utils.mjs +0 -38
  76. package/dist/esm/ai-sdk-provider.d.ts +0 -7
  77. package/dist/esm/config.d.ts +0 -13
  78. package/dist/esm/config.mjs +0 -13
  79. package/dist/esm/encrypted-body-fetch.d.ts +0 -13
  80. package/dist/esm/encrypted-body-fetch.mjs +0 -105
  81. package/dist/esm/env.d.ts +0 -5
  82. package/dist/esm/env.mjs +0 -17
  83. package/dist/esm/fetch-adapter.d.ts +0 -21
  84. package/dist/esm/fetch-adapter.mjs +0 -23
  85. package/dist/esm/index.browser.d.ts +0 -7
  86. package/dist/esm/index.browser.mjs +0 -8
  87. package/dist/esm/index.d.ts +0 -9
  88. package/dist/esm/index.mjs +0 -13
  89. package/dist/esm/pinned-tls-fetch.d.ts +0 -1
  90. package/dist/esm/pinned-tls-fetch.mjs +0 -110
  91. package/dist/esm/router.d.ts +0 -11
  92. package/dist/esm/router.mjs +0 -33
  93. package/dist/esm/secure-fetch.browser.d.ts +0 -1
  94. package/dist/esm/secure-fetch.browser.mjs +0 -10
  95. package/dist/esm/secure-fetch.d.ts +0 -1
  96. package/dist/esm/secure-fetch.mjs +0 -12
  97. package/dist/esm/unverified-client.d.ts +0 -18
  98. package/dist/esm/unverified-client.mjs +0 -61
  99. package/dist/esm/verifier.d.ts +0 -141
  100. package/dist/esm/verifier.mjs +0 -532
  101. package/dist/esm/wasm-exec.js +0 -668
  102. package/dist/esm/wasm-exec.mjs +0 -668
  103. package/dist/fetch-adapter.d.ts +0 -21
  104. package/dist/fetch-adapter.js +0 -27
  105. package/dist/wasm-exec.js +0 -668
package/README.md DELETED
@@ -1,183 +0,0 @@
1
- # Tinfoil Node Client
2
-
3
- [![Build Status](https://github.com/tinfoilsh/tinfoil-node/actions/workflows/test.yml/badge.svg)](https://github.com/tinfoilsh/tinfoil-node/actions)
4
- [![NPM version](https://img.shields.io/npm/v/tinfoil.svg)](https://npmjs.org/package/tinfoil)
5
- [![Documentation](https://img.shields.io/badge/docs-tinfoil.sh-blue)](https://docs.tinfoil.sh/sdk/node-sdk)
6
-
7
- This client library provides secure and convenient access to the Tinfoil Private Inference endpoints from TypeScript or JavaScript.
8
-
9
- It is a wrapper around the OpenAI client that verifies enclave attestation and routes traffic to the Tinfoil Private Inference endpoints through an [EHBP](https://github.com/tinfoilsh/encrypted-http-body-protocol)-secured transport. EHBP encrypts all payloads directly to an attested enclave using [HPKE (RFC 9180)](https://www.rfc-editor.org/rfc/rfc9180.html).
10
-
11
- ## Installation
12
-
13
- ```bash
14
- npm install tinfoil
15
- ```
16
-
17
- ## Requirements
18
-
19
- Node 20+.
20
-
21
- ## Quick Start
22
-
23
- ```typescript
24
- import { TinfoilAI } from "tinfoil";
25
-
26
- const client = new TinfoilAI({
27
- apiKey: "<YOUR_API_KEY>", // or use TINFOIL_API_KEY env var
28
- });
29
-
30
- // Uses identical method calls as the OpenAI client
31
- const completion = await client.chat.completions.create({
32
- messages: [{ role: "user", content: "Hello!" }],
33
- model: "llama3-3-70b",
34
- });
35
- ```
36
-
37
- ## Browser Support
38
-
39
- The SDK supports browser environments. This allows you to use the secure enclave-backed OpenAI API directly from web applications.
40
-
41
- ### ⚠️ Security Warning
42
-
43
- Using API keys directly in the browser exposes them to anyone who can view your page source.
44
- For production applications, always use a backend server to handle API keys.
45
-
46
- ### Browser Usage
47
-
48
- ```javascript
49
- import { TinfoilAI } from 'tinfoil';
50
-
51
- const client = new TinfoilAI({
52
- apiKey: 'your-api-key',
53
- dangerouslyAllowBrowser: true // Required for browser usage
54
- });
55
-
56
- // Optional: pre-initialize; you can also call APIs directly
57
- await client.ready();
58
-
59
- const completion = await client.chat.completions.create({
60
- model: 'llama3-3-70b',
61
- messages: [{ role: 'user', content: 'Hello!' }]
62
- });
63
- ```
64
-
65
- ### Browser Requirements
66
-
67
- - Modern browsers with ES2020 support
68
- - WebAssembly support for enclave verification
69
-
70
-
71
- ## Verification helpers
72
-
73
- This package exposes verification helpers that load the Go-based WebAssembly verifier and provide end-to-end attestation with structured, stepwise results you can use in applications (e.g., to show progress, log transitions, or gate features).
74
-
75
- The verification functionality is contained in `verifier.ts`.
76
-
77
-
78
- ### Core Verifier API
79
-
80
- ```typescript
81
- import { Verifier } from "tinfoil";
82
-
83
- const verifier = new Verifier({ serverURL: "https://enclave.host.com" });
84
-
85
- // Perform full end-to-end verification
86
- const attestation = await verifier.verify();
87
- // Returns: AttestationResponse with measurement and cryptographic keys
88
- // This performs all verification steps atomically:
89
- // 1. Fetches the latest release digest from GitHub
90
- // 2. Verifies code provenance using Sigstore
91
- // 3. Performs runtime attestation against the enclave
92
- // 4. Verifies hardware measurements (for TDX platforms)
93
- // 5. Compares code and runtime measurements
94
-
95
- // Access detailed verification results
96
- const doc = verifier.getVerificationDocument();
97
- // Returns: VerificationDocument with step-by-step status including
98
- // measurements, fingerprints, and cryptographic keys
99
- ```
100
-
101
- ### Verification Document
102
-
103
- The `Verifier` provides access to a comprehensive verification document that tracks all verification steps, including failures:
104
-
105
- ```typescript
106
- import { Verifier } from "tinfoil";
107
-
108
- const verifier = new Verifier({ serverURL: "https://enclave.host.com" });
109
-
110
- try {
111
- const attestation = await verifier.verify();
112
- const doc = verifier.getVerificationDocument();
113
- console.log('Security verified:', doc.securityVerified);
114
- console.log('TLS fingerprint:', attestation.tlsPublicKeyFingerprint);
115
- console.log('HPKE public key:', attestation.hpkePublicKey);
116
- } catch (error) {
117
- // Even on error, you can access the verification document
118
- const doc = verifier.getVerificationDocument();
119
-
120
- // The document contains detailed step information:
121
- // - fetchDigest: GitHub release digest retrieval
122
- // - verifyCode: Code measurement verification
123
- // - verifyEnclave: Runtime attestation verification
124
- // - compareMeasurements: Code vs runtime measurement comparison
125
- // - otherError: Catch-all for unexpected errors (optional)
126
-
127
- // Check individual steps
128
- if (doc.steps.verifyEnclave.status === 'failed') {
129
- console.log('Enclave verification failed:', doc.steps.verifyEnclave.error);
130
- }
131
-
132
- // Error messages are prefixed with the failing step:
133
- // - "fetchDigest:" - Failed to fetch GitHub release digest
134
- // - "verifyCode:" - Failed to verify code provenance
135
- // - "verifyEnclave:" - Failed runtime attestation
136
- // - "verifyHardware:" - Failed TDX hardware verification
137
- // - "validateTLS:" - TLS public key validation failed
138
- // - "measurements:" - Measurement comparison failed
139
- }
140
- ```
141
-
142
- ## Testing
143
-
144
- The project includes both unit tests and integration tests:
145
-
146
- ### Running Unit Tests
147
-
148
- ```bash
149
- npm test
150
- ```
151
-
152
- ### Running Integration Tests
153
-
154
- ```bash
155
- RUN_TINFOIL_INTEGRATION=true npm test
156
- ```
157
-
158
- This runs the full test suite including integration tests that:
159
- - Make actual network requests to Tinfoil services
160
- - Perform real enclave attestation verification
161
- - Test end-to-end functionality with live services
162
-
163
- Integration tests are skipped by default to keep the test suite fast and avoid network dependencies during development.
164
-
165
- ## Running examples
166
-
167
- See [examples/README.md](https://github.com/tinfoilsh/tinfoil-node/blob/main/examples/README.md).
168
-
169
- ## API Documentation
170
-
171
- For complete documentation on using the Tinfoil Node SDK, including advanced examples and API reference, visit the [official documentation](https://docs.tinfoil.sh/sdk/node-sdk).
172
-
173
- This library mirrors the official OpenAI Node.js client for common endpoints (e.g., chat, images, embeddings) and types, and is designed to feel familiar. Some less commonly used surfaces may not be fully covered. See the [OpenAI client](https://github.com/openai/openai-node) for complete API usage and documentation.
174
-
175
- ## Reporting Vulnerabilities
176
-
177
- Please report security vulnerabilities by either:
178
-
179
- - Emailing [security@tinfoil.sh](mailto:security@tinfoil.sh)
180
-
181
- - Opening an issue on GitHub on this repository
182
-
183
- We aim to respond to security reports within 24 hours and will keep you updated on our progress.
@@ -1 +0,0 @@
1
- export declare function withMockedModules(mocks: Record<string, unknown>, modulesToReload: string[], run: () => Promise<void>): Promise<void>;
@@ -1,44 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.withMockedModules = withMockedModules;
7
- const module_1 = __importDefault(require("module"));
8
- const testRequire = module_1.default.createRequire(__filename);
9
- async function withMockedModules(mocks, modulesToReload, run) {
10
- const moduleAny = module_1.default;
11
- const originalLoad = moduleAny._load;
12
- moduleAny._load = function (request, parent, isMain) {
13
- if (Object.prototype.hasOwnProperty.call(mocks, request)) {
14
- return mocks[request];
15
- }
16
- // eslint-disable-next-line prefer-rest-params
17
- return originalLoad.apply(this, arguments);
18
- };
19
- const restoredCache = [];
20
- for (const specifier of modulesToReload) {
21
- try {
22
- const resolved = testRequire.resolve(specifier);
23
- restoredCache.push({ path: resolved, cached: require.cache[resolved] });
24
- delete require.cache[resolved];
25
- }
26
- catch {
27
- // Module not yet cached; nothing to remove.
28
- }
29
- }
30
- try {
31
- await run();
32
- }
33
- finally {
34
- moduleAny._load = originalLoad;
35
- for (const entry of restoredCache) {
36
- if (entry.cached) {
37
- require.cache[entry.path] = entry.cached;
38
- }
39
- else {
40
- delete require.cache[entry.path];
41
- }
42
- }
43
- }
44
- }
@@ -1 +0,0 @@
1
- export declare function withMockedModules(mocks: Record<string, unknown>, modulesToReload: string[], run: () => Promise<void>): Promise<void>;
@@ -1,38 +0,0 @@
1
- import Module from "module";
2
- const testRequire = Module.createRequire(__filename);
3
- export async function withMockedModules(mocks, modulesToReload, run) {
4
- const moduleAny = Module;
5
- const originalLoad = moduleAny._load;
6
- moduleAny._load = function (request, parent, isMain) {
7
- if (Object.prototype.hasOwnProperty.call(mocks, request)) {
8
- return mocks[request];
9
- }
10
- // eslint-disable-next-line prefer-rest-params
11
- return originalLoad.apply(this, arguments);
12
- };
13
- const restoredCache = [];
14
- for (const specifier of modulesToReload) {
15
- try {
16
- const resolved = testRequire.resolve(specifier);
17
- restoredCache.push({ path: resolved, cached: require.cache[resolved] });
18
- delete require.cache[resolved];
19
- }
20
- catch {
21
- // Module not yet cached; nothing to remove.
22
- }
23
- }
24
- try {
25
- await run();
26
- }
27
- finally {
28
- moduleAny._load = originalLoad;
29
- for (const entry of restoredCache) {
30
- if (entry.cached) {
31
- require.cache[entry.path] = entry.cached;
32
- }
33
- else {
34
- delete require.cache[entry.path];
35
- }
36
- }
37
- }
38
- }
@@ -1,7 +0,0 @@
1
- interface CreateTinfoilAIOptions {
2
- baseURL?: string;
3
- enclaveURL?: string;
4
- configRepo?: string;
5
- }
6
- export declare function createTinfoilAI(apiKey: string, options?: CreateTinfoilAIOptions, headers?: Record<string, string>): Promise<import("@ai-sdk/openai-compatible").OpenAICompatibleProvider<string, string, string, string>>;
7
- export {};
@@ -1,13 +0,0 @@
1
- /**
2
- * Configuration constants for the Tinfoil Node SDK
3
- */
4
- export declare const TINFOIL_CONFIG: {
5
- /**
6
- * The GitHub repository for code attestation verification
7
- */
8
- readonly INFERENCE_PROXY_REPO: "tinfoilsh/confidential-model-router";
9
- /**
10
- * The ATC (Attestation and Trust Center) API URL for fetching available routers
11
- */
12
- readonly ATC_API_URL: "https://atc.tinfoil.sh/routers";
13
- };
@@ -1,13 +0,0 @@
1
- /**
2
- * Configuration constants for the Tinfoil Node SDK
3
- */
4
- export const TINFOIL_CONFIG = {
5
- /**
6
- * The GitHub repository for code attestation verification
7
- */
8
- INFERENCE_PROXY_REPO: "tinfoilsh/confidential-model-router",
9
- /**
10
- * The ATC (Attestation and Trust Center) API URL for fetching available routers
11
- */
12
- ATC_API_URL: "https://atc.tinfoil.sh/routers",
13
- };
@@ -1,13 +0,0 @@
1
- import type { Transport as EhbpTransport } from "@zeke-02/ehbp";
2
- export declare function getHPKEKey(enclaveURL: string): Promise<CryptoKey>;
3
- export declare function normalizeEncryptedBodyRequestArgs(input: RequestInfo | URL, init?: RequestInit): {
4
- url: string;
5
- init?: RequestInit;
6
- };
7
- export declare function encryptedBodyRequest(input: RequestInfo | URL, hpkePublicKey?: string, init?: RequestInit, enclaveURL?: string, transportInstance?: EhbpTransport): Promise<Response>;
8
- type FetchWithResponse = typeof fetch & {
9
- Response: typeof Response;
10
- };
11
- export declare function createEncryptedBodyFetch(baseURL: string, hpkePublicKey?: string, enclaveURL?: string): FetchWithResponse;
12
- export declare function getTransportForOrigin(origin: string, keyOrigin: string): Promise<EhbpTransport>;
13
- export {};
@@ -1,105 +0,0 @@
1
- import { Identity, Transport, PROTOCOL } from "@zeke-02/ehbp";
2
- import { getFetch } from "./fetch-adapter.mjs";
3
- // Public API
4
- export async function getHPKEKey(enclaveURL) {
5
- const url = new URL(enclaveURL);
6
- const keysURL = new URL(PROTOCOL.KEYS_PATH, enclaveURL);
7
- if (keysURL.protocol !== "https:") {
8
- throw new Error(`HTTPS is required for remote key retrieval. Invalid protocol: ${keysURL.protocol}`);
9
- }
10
- const fetchFn = getFetch();
11
- const response = await fetchFn(keysURL.toString());
12
- if (!response.ok) {
13
- throw new Error(`Failed to get server public key: ${response.status}`);
14
- }
15
- const contentType = response.headers.get("content-type");
16
- if (contentType !== PROTOCOL.KEYS_MEDIA_TYPE) {
17
- throw new Error(`Invalid content type: ${contentType}`);
18
- }
19
- const keysData = new Uint8Array(await response.arrayBuffer());
20
- const serverIdentity = await Identity.unmarshalPublicConfig(keysData);
21
- return serverIdentity.getPublicKey();
22
- }
23
- export function normalizeEncryptedBodyRequestArgs(input, init) {
24
- if (typeof input === "string") {
25
- return { url: input, init };
26
- }
27
- if (input instanceof URL) {
28
- return { url: input.toString(), init };
29
- }
30
- const request = input;
31
- const cloned = request.clone();
32
- const derivedInit = {
33
- method: cloned.method,
34
- headers: new Headers(cloned.headers),
35
- body: cloned.body ?? undefined,
36
- signal: cloned.signal,
37
- };
38
- return {
39
- url: cloned.url,
40
- init: { ...derivedInit, ...init },
41
- };
42
- }
43
- export async function encryptedBodyRequest(input, hpkePublicKey, init, enclaveURL, transportInstance) {
44
- const { url: requestUrl, init: requestInit } = normalizeEncryptedBodyRequestArgs(input, init);
45
- let actualTransport;
46
- if (transportInstance) {
47
- // Use provided transport instance
48
- actualTransport = transportInstance;
49
- }
50
- else {
51
- // Create a new transport for this request
52
- const u = new URL(requestUrl);
53
- const { origin } = u;
54
- const keyOrigin = enclaveURL ? new URL(enclaveURL).origin : origin;
55
- actualTransport = await getTransportForOrigin(origin, keyOrigin);
56
- }
57
- if (hpkePublicKey) {
58
- const transportKeyHash = await actualTransport.getServerPublicKeyHex();
59
- if (transportKeyHash !== hpkePublicKey) {
60
- throw new Error(`HPKE public key mismatch. Expected: ${hpkePublicKey}, Got: ${transportKeyHash}`);
61
- }
62
- }
63
- return actualTransport.request(requestUrl, requestInit);
64
- }
65
- export function createEncryptedBodyFetch(baseURL, hpkePublicKey, enclaveURL) {
66
- // Create a dedicated transport instance for this fetch function
67
- let transportPromise = null;
68
- const getOrCreateTransport = async () => {
69
- if (!transportPromise) {
70
- const baseUrl = new URL(baseURL);
71
- const keyOrigin = enclaveURL
72
- ? new URL(enclaveURL).origin
73
- : baseUrl.origin;
74
- transportPromise = getTransportForOrigin(baseUrl.origin, keyOrigin);
75
- }
76
- return transportPromise;
77
- };
78
- const secureFetch = (async (input, init) => {
79
- const normalized = normalizeEncryptedBodyRequestArgs(input, init);
80
- const targetUrl = new URL(normalized.url, baseURL);
81
- // Get the dedicated transport instance for this fetch function
82
- const transportInstance = await getOrCreateTransport();
83
- return encryptedBodyRequest(targetUrl.toString(), hpkePublicKey, normalized.init, enclaveURL, transportInstance);
84
- });
85
- // Expose Response constructor for OpenAI SDK's FormData support detection
86
- // This prevents the SDK from making a test request to 'data:,' which would fail through EHBP
87
- secureFetch.Response = Response;
88
- return secureFetch;
89
- }
90
- export async function getTransportForOrigin(origin, keyOrigin) {
91
- if (typeof globalThis !== "undefined") {
92
- const isSecure = globalThis.isSecureContext !== false;
93
- const hasSubtle = !!(globalThis.crypto && globalThis.crypto.subtle);
94
- if (!isSecure || !hasSubtle) {
95
- const reason = !isSecure
96
- ? "insecure context (use HTTPS or localhost)"
97
- : "missing WebCrypto SubtleCrypto";
98
- throw new Error(`EHBP requires a secure browser context: ${reason}`);
99
- }
100
- }
101
- const clientIdentity = await Identity.generate();
102
- const serverPublicKey = await getHPKEKey(keyOrigin);
103
- const requestHost = new URL(origin).host;
104
- return new Transport(clientIdentity, requestHost, serverPublicKey);
105
- }
package/dist/esm/env.d.ts DELETED
@@ -1,5 +0,0 @@
1
- /**
2
- * Detects if the code is running in a real browser environment.
3
- * Returns false for Node.js environments, even with WASM loaded.
4
- */
5
- export declare function isRealBrowser(): boolean;
package/dist/esm/env.mjs DELETED
@@ -1,17 +0,0 @@
1
- /**
2
- * Detects if the code is running in a real browser environment.
3
- * Returns false for Node.js environments, even with WASM loaded.
4
- */
5
- export function isRealBrowser() {
6
- if (typeof process !== "undefined" &&
7
- process.versions &&
8
- process.versions.node) {
9
- return false;
10
- }
11
- if (typeof window !== "undefined" && typeof window.document !== "undefined") {
12
- if (typeof navigator !== "undefined" && navigator.userAgent) {
13
- return true;
14
- }
15
- }
16
- return false;
17
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Fetch adapter for Tauri v2
3
- *
4
- * This module provides a centralized fetch implementation for Tauri v2.
5
- * For testing purposes, the fetch function can be overridden by setting
6
- * the global __TINFOIL_TEST_FETCH__ property.
7
- */
8
- import { fetch as tauriFetch } from "@tauri-apps/plugin-http";
9
- declare global {
10
- var __TINFOIL_TEST_FETCH__: typeof fetch | undefined;
11
- }
12
- /**
13
- * Get the fetch implementation to use.
14
- * In tests, this can be overridden by setting globalThis.__TINFOIL_TEST_FETCH__
15
- */
16
- export declare function getFetch(): typeof tauriFetch;
17
- /**
18
- * The fetch function to use throughout the application.
19
- * Uses Tauri's fetch by default, but can be mocked for testing.
20
- */
21
- export declare const fetch: typeof tauriFetch;
@@ -1,23 +0,0 @@
1
- /**
2
- * Fetch adapter for Tauri v2
3
- *
4
- * This module provides a centralized fetch implementation for Tauri v2.
5
- * For testing purposes, the fetch function can be overridden by setting
6
- * the global __TINFOIL_TEST_FETCH__ property.
7
- */
8
- import { fetch as tauriFetch } from "@tauri-apps/plugin-http";
9
- /**
10
- * Get the fetch implementation to use.
11
- * In tests, this can be overridden by setting globalThis.__TINFOIL_TEST_FETCH__
12
- */
13
- export function getFetch() {
14
- if (typeof globalThis.__TINFOIL_TEST_FETCH__ === "function") {
15
- return globalThis.__TINFOIL_TEST_FETCH__;
16
- }
17
- return tauriFetch;
18
- }
19
- /**
20
- * The fetch function to use throughout the application.
21
- * Uses Tauri's fetch by default, but can be mocked for testing.
22
- */
23
- export const fetch = getFetch();
@@ -1,7 +0,0 @@
1
- export { TinfoilAI } from "./tinfoilai";
2
- export { TinfoilAI as default } from "./tinfoilai";
3
- export * from "./verifier";
4
- export * from "./ai-sdk-provider";
5
- export * from "./config";
6
- export { SecureClient } from "./secure-client";
7
- export { UnverifiedClient } from "./unverified-client";
@@ -1,8 +0,0 @@
1
- // Browser-safe entry point: avoids Node built-ins
2
- export { TinfoilAI } from "./tinfoilai.mjs";
3
- export { TinfoilAI as default } from "./tinfoilai.mjs";
4
- export * from "./verifier.mjs";
5
- export * from "./ai-sdk-provider.mjs";
6
- export * from "./config.mjs";
7
- export { SecureClient } from "./secure-client.mjs";
8
- export { UnverifiedClient } from "./unverified-client.mjs";
@@ -1,9 +0,0 @@
1
- export { TinfoilAI } from "./tinfoilai";
2
- export { TinfoilAI as default } from "./tinfoilai";
3
- export * from "./verifier";
4
- export * from "./ai-sdk-provider";
5
- export * from "./config";
6
- export { SecureClient } from "./secure-client";
7
- export { UnverifiedClient } from "./unverified-client";
8
- export { fetchRouter } from "./router";
9
- export { type Uploadable, toFile, APIPromise, PagePromise, OpenAIError, APIError, APIConnectionError, APIConnectionTimeoutError, APIUserAbortError, NotFoundError, ConflictError, RateLimitError, BadRequestError, AuthenticationError, InternalServerError, PermissionDeniedError, UnprocessableEntityError, } from "openai";
@@ -1,13 +0,0 @@
1
- // Re-export the TinfoilAI class
2
- export { TinfoilAI } from "./tinfoilai.mjs";
3
- export { TinfoilAI as default } from "./tinfoilai.mjs";
4
- // Export verifier
5
- export * from "./verifier.mjs";
6
- export * from "./ai-sdk-provider.mjs";
7
- export * from "./config.mjs";
8
- export { SecureClient } from "./secure-client.mjs";
9
- export { UnverifiedClient } from "./unverified-client.mjs";
10
- export { fetchRouter } from "./router.mjs";
11
- // Re-export OpenAI utility types and classes that users might need
12
- // Using public exports from the main OpenAI package instead of deep imports
13
- export { toFile, APIPromise, PagePromise, OpenAIError, APIError, APIConnectionError, APIConnectionTimeoutError, APIUserAbortError, NotFoundError, ConflictError, RateLimitError, BadRequestError, AuthenticationError, InternalServerError, PermissionDeniedError, UnprocessableEntityError, } from "openai";
@@ -1 +0,0 @@
1
- export declare function createPinnedTlsFetch(baseURL: string, expectedFingerprintHex: string): typeof fetch;
@@ -1,110 +0,0 @@
1
- import https from "https";
2
- import { checkServerIdentity as tlsCheckServerIdentity } from "tls";
3
- import { X509Certificate, createHash } from "crypto";
4
- import { Readable } from "stream";
5
- export function createPinnedTlsFetch(baseURL, expectedFingerprintHex) {
6
- return (async (input, init) => {
7
- // Normalize URL with base URL support
8
- const makeURL = (value) => {
9
- if (typeof value === "string")
10
- return new URL(value, baseURL);
11
- if (value instanceof URL)
12
- return value;
13
- return new URL(value.url, baseURL);
14
- };
15
- const url = makeURL(input);
16
- if (url.protocol !== "https:") {
17
- throw new Error(`HTTP connections are not allowed. Use HTTPS. URL: ${url.toString()}`);
18
- }
19
- // Gather method and headers
20
- const method = (init?.method || input.method || "GET").toUpperCase();
21
- const headers = new Headers(init?.headers || input?.headers || {});
22
- const headerObj = {};
23
- headers.forEach((v, k) => {
24
- headerObj[k] = v;
25
- });
26
- // Resolve body
27
- let body = init?.body;
28
- if (!body && input instanceof Request) {
29
- // If the original was a Request with a body, read it
30
- try {
31
- const buf = await input.arrayBuffer();
32
- if (buf && buf.byteLength)
33
- body = Buffer.from(buf);
34
- }
35
- catch { }
36
- }
37
- // Convert web streams to Node streams if needed
38
- if (body && typeof body.getReader === "function") {
39
- body = Readable.fromWeb(body);
40
- }
41
- if (body instanceof ArrayBuffer) {
42
- body = Buffer.from(body);
43
- }
44
- if (ArrayBuffer.isView(body)) {
45
- body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
46
- }
47
- const requestOptions = {
48
- protocol: url.protocol,
49
- hostname: url.hostname,
50
- port: url.port ? Number(url.port) : 443,
51
- path: `${url.pathname}${url.search}`,
52
- method,
53
- headers: headerObj,
54
- checkServerIdentity: (host, cert) => {
55
- const raw = cert.raw;
56
- if (!raw) {
57
- return new Error("Certificate raw bytes are unavailable for pinning");
58
- }
59
- const x509 = new X509Certificate(raw);
60
- const publicKeyDer = x509.publicKey.export({ type: "spki", format: "der" });
61
- const fp = createHash("sha256").update(publicKeyDer).digest("hex");
62
- if (fp !== expectedFingerprintHex) {
63
- return new Error(`Certificate public key fingerprint mismatch. Expected: ${expectedFingerprintHex}, Got: ${fp}`);
64
- }
65
- return tlsCheckServerIdentity(host, cert);
66
- },
67
- };
68
- const { signal } = init || {};
69
- const res = await new Promise((resolve, reject) => {
70
- const req = https.request(requestOptions, resolve);
71
- req.on("error", reject);
72
- if (signal) {
73
- if (signal.aborted) {
74
- req.destroy(new Error("Request aborted"));
75
- return;
76
- }
77
- signal.addEventListener("abort", () => req.destroy(new Error("Request aborted")));
78
- }
79
- if (body === undefined || body === null) {
80
- req.end();
81
- }
82
- else if (typeof body === "string" || Buffer.isBuffer(body) || ArrayBuffer.isView(body)) {
83
- req.end(body);
84
- }
85
- else if (typeof body.pipe === "function") {
86
- body.pipe(req);
87
- }
88
- else {
89
- // Fallback: try to serialize objects
90
- req.end(String(body));
91
- }
92
- });
93
- const responseHeaders = new Headers();
94
- for (const [k, v] of Object.entries(res.headers)) {
95
- if (Array.isArray(v)) {
96
- v.forEach(item => responseHeaders.append(k, item));
97
- }
98
- else if (v != null) {
99
- responseHeaders.set(k, String(v));
100
- }
101
- }
102
- // Convert Node stream to Web ReadableStream
103
- const webStream = Readable.toWeb(res);
104
- return new Response(webStream, {
105
- status: res.statusCode || 0,
106
- statusText: res.statusMessage || "",
107
- headers: responseHeaders,
108
- });
109
- });
110
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Router utilities for fetching available Tinfoil routers
3
- */
4
- /**
5
- * Fetches the list of available routers from the ATC API
6
- * and returns a randomly selected address.
7
- *
8
- * @returns Promise<string> A randomly selected router address
9
- * @throws Error if no routers are found or if the request fails
10
- */
11
- export declare function fetchRouter(): Promise<string>;