@routstr/sdk 0.3.11 → 0.3.13

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 (47) hide show
  1. package/dist/browser.d.mts +2 -1
  2. package/dist/browser.d.ts +2 -1
  3. package/dist/browser.js +360 -28
  4. package/dist/browser.js.map +1 -1
  5. package/dist/browser.mjs +355 -29
  6. package/dist/browser.mjs.map +1 -1
  7. package/dist/bun.d.mts +2 -1
  8. package/dist/bun.d.ts +2 -1
  9. package/dist/bun.js +367 -31
  10. package/dist/bun.js.map +1 -1
  11. package/dist/bun.mjs +362 -32
  12. package/dist/bun.mjs.map +1 -1
  13. package/dist/client/index.d.mts +85 -1
  14. package/dist/client/index.d.ts +85 -1
  15. package/dist/client/index.js +358 -27
  16. package/dist/client/index.js.map +1 -1
  17. package/dist/client/index.mjs +353 -28
  18. package/dist/client/index.mjs.map +1 -1
  19. package/dist/index.d.mts +2 -1
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.js +360 -28
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +355 -29
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/node.d.mts +2 -1
  26. package/dist/node.d.ts +2 -1
  27. package/dist/node.js +367 -31
  28. package/dist/node.js.map +1 -1
  29. package/dist/node.mjs +362 -32
  30. package/dist/node.mjs.map +1 -1
  31. package/dist/storage/bun.js +6 -1
  32. package/dist/storage/bun.js.map +1 -1
  33. package/dist/storage/bun.mjs +6 -1
  34. package/dist/storage/bun.mjs.map +1 -1
  35. package/dist/storage/index.js +2 -1
  36. package/dist/storage/index.js.map +1 -1
  37. package/dist/storage/index.mjs +2 -1
  38. package/dist/storage/index.mjs.map +1 -1
  39. package/dist/storage/node.js +6 -1
  40. package/dist/storage/node.js.map +1 -1
  41. package/dist/storage/node.mjs +6 -1
  42. package/dist/storage/node.mjs.map +1 -1
  43. package/dist/wallet/index.js +36 -8
  44. package/dist/wallet/index.js.map +1 -1
  45. package/dist/wallet/index.mjs +36 -8
  46. package/dist/wallet/index.mjs.map +1 -1
  47. package/package.json +9 -3
@@ -3,6 +3,7 @@ import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as St
3
3
  import { S as SdkStore, c as UsageTrackingDriver } from '../store-CuXwe5Rg.mjs';
4
4
  import { CashuSpender, BalanceManager } from '../wallet/index.mjs';
5
5
  import { Transform } from 'stream';
6
+ import { SecureClient, VerificationDocument } from 'tinfoil';
6
7
  import 'zustand/vanilla';
7
8
  import '../interfaces-Cv1k2EUK.mjs';
8
9
 
@@ -264,6 +265,9 @@ declare class RoutstrClient {
264
265
  * Make the API request with failover support
265
266
  */
266
267
  private _makeRequest;
268
+ /**
269
+ * Store request details to a file in the reqs/ folder before fetch.
270
+ */
267
271
  /**
268
272
  * Handle error responses with failover
269
273
  */
@@ -272,6 +276,11 @@ declare class RoutstrClient {
272
276
  * Handle post-response balance update for all modes
273
277
  */
274
278
  private _handlePostResponseBalanceUpdate;
279
+ /**
280
+ * Extract sats cost from EHBP/Tinfoil response headers as a last-resort
281
+ * fallback when neither balance delta nor SSE/body usage provides a cost.
282
+ */
283
+ private _headerSatsCost;
275
284
  private _trackResponseUsage;
276
285
  /**
277
286
  * Check wallet balance and throw if insufficient
@@ -289,6 +298,13 @@ declare class RoutstrClient {
289
298
  * Attach auth headers using the active client mode
290
299
  */
291
300
  private _withAuthHeader;
301
+ /**
302
+ * Attach auth headers and preserve the plaintext model hint required by the
303
+ * Routstr proxy for Tinfoil/EHBP requests. EHBP encrypts the JSON body, so
304
+ * retries/failover must not rebuild headers from baseHeaders alone or the
305
+ * proxy cannot route/price the encrypted request.
306
+ */
307
+ private _withAuthAndTinfoilHeaders;
292
308
  }
293
309
 
294
310
  /**
@@ -372,6 +388,15 @@ interface UsageTrackingData {
372
388
  declare function extractUsageFromResponseBody(body: unknown, fallbackSatsCost?: number): UsageTrackingData | null;
373
389
  declare function extractResponseId(body: unknown): string | undefined;
374
390
  declare function extractUsageFromSSEJson(parsed: any, fallbackSatsCost?: number): UsageTrackingData | null;
391
+ /**
392
+ * Extract cost/usage from EHBP/Tinfoil response headers.
393
+ *
394
+ * For EHBP requests the proxy cannot inject cost into the JSON/SSE body
395
+ * (the body is opaque encrypted). Instead it returns cost as response
396
+ * headers. This parses those headers into the same UsageTrackingData
397
+ * shape used for SSE/body extraction, so callers can merge or fall back.
398
+ */
399
+ declare function extractUsageFromResponseHeaders(headers: Headers | Record<string, string>): UsageTrackingData | null;
375
400
  declare function toUsageStats(usage: UsageTrackingData | null | undefined): UsageStats | undefined;
376
401
 
377
402
  /**
@@ -413,6 +438,65 @@ declare function inspectSSEWebStream(stream: ReadableStream<Uint8Array>, onUsage
413
438
  */
414
439
  declare function createSSEParserTransform(onUsage: (usage: UsageTrackingData) => void, onResponseId?: (responseId: string) => void): Transform;
415
440
 
441
+ /**
442
+ * TinfoilSecure - EHBP transport encryption + enclave attestation for Tinfoil models.
443
+ *
444
+ * Any model whose id starts with `tinfoil-` is routed through Tinfoil EHBP.
445
+ * SecureClient performs attestation (`ready()`) and verifies the enclave code
446
+ * fingerprint. The SDK then uses EHBP request encryption so only the attested
447
+ * enclave can decrypt request bodies.
448
+ *
449
+ * Unlike Venice E2EE, there is no per-field message encryption and no custom SSE
450
+ * decrypt transform. Successful enclave responses are decrypted before normal
451
+ * SDK response handling sees them. Plaintext proxy-side errors (for example
452
+ * auth/balance failures before the request reaches the enclave) are preserved
453
+ * with their real status/body.
454
+ */
455
+
456
+ interface TinfoilClientContext {
457
+ client: SecureClient;
458
+ verification: VerificationDocument;
459
+ }
460
+ interface TinfoilClientOptions {
461
+ /** Routstr/provider base URL that will receive the EHBP-wrapped request. */
462
+ baseUrl: string;
463
+ /** Optional explicit attestation bundle origin. Defaults to Tinfoil's ATC. */
464
+ attestationBundleURL?: string;
465
+ /** Optional explicit enclave URL for custom Tinfoil deployments. */
466
+ enclaveURL?: string;
467
+ /** Optional source repo for code verification when enclaveURL is explicit. */
468
+ configRepo?: string;
469
+ }
470
+ /** Check if a model ID should use Tinfoil EHBP transport. */
471
+ declare function isTinfoilModel(modelId: string): boolean;
472
+ /**
473
+ * Return the model id sent inside the EHBP-encrypted request body.
474
+ *
475
+ * Strips the `tinfoil-` prefix so the attested enclave receives the bare
476
+ * model id it expects (e.g. "kimi-k2-6"), not the caller-facing routstr id.
477
+ */
478
+ declare function getTinfoilUpstreamModelId(modelId: string): string;
479
+ /**
480
+ * Attest and return a cached Tinfoil SecureClient for a provider base URL.
481
+ */
482
+ declare function prepareTinfoilClient(options: TinfoilClientOptions): Promise<TinfoilClientContext>;
483
+ /**
484
+ * Fetch through Tinfoil EHBP while preserving plaintext proxy error responses.
485
+ *
486
+ * Tinfoil's stock SecureClient.fetch throws ProtocolError when a response to an
487
+ * encrypted request lacks Ehbp-Response-Nonce. That is correct for successful
488
+ * enclave responses, but Routstr proxy-side auth/balance errors are plaintext
489
+ * and need to flow through the SDK's normal error handling with their real
490
+ * status/body. This wrapper performs the same request-body encryption and
491
+ * response decryption, but returns non-EHBP responses unchanged.
492
+ *
493
+ * It also keeps SecureClient's key-rotation behavior: an EHBP key-config
494
+ * mismatch response triggers one fresh attestation and one retry.
495
+ */
496
+ declare function fetchTinfoilPreservingPlaintextErrors(options: TinfoilClientOptions, input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
497
+ /** Clear cached Tinfoil clients, mainly useful for tests or forced re-attest. */
498
+ declare function clearTinfoilClientCache(): void;
499
+
416
500
  /**
417
501
  * Options for fetching AI response
418
502
  */
@@ -451,4 +535,4 @@ interface FetchAIResponseDeps {
451
535
  */
452
536
  declare function fetchAIResponse(options: FetchOptions, callbacks: StreamingCallbacks, deps: FetchAIResponseDeps): Promise<void>;
453
537
 
454
- export { type AlertLevel, type DebugLevel, type FetchAIResponseDeps, type ModelProviderPrice, ProviderManager, type RequestResponseLogRequestInput, type RequestResponseLogSink, type RouteRequestParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, type UsageTrackingData, createSSEParserTransform, extractResponseId, extractUsageFromResponseBody, extractUsageFromSSEJson, fetchAIResponse, inspectSSEWebStream, toUsageStats };
538
+ export { type AlertLevel, type DebugLevel, type FetchAIResponseDeps, type ModelProviderPrice, ProviderManager, type RequestResponseLogRequestInput, type RequestResponseLogSink, type RouteRequestParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, type TinfoilClientContext, type TinfoilClientOptions, type UsageTrackingData, clearTinfoilClientCache, createSSEParserTransform, extractResponseId, extractUsageFromResponseBody, extractUsageFromResponseHeaders, extractUsageFromSSEJson, fetchAIResponse, fetchTinfoilPreservingPlaintextErrors, getTinfoilUpstreamModelId, inspectSSEWebStream, isTinfoilModel, prepareTinfoilClient, toUsageStats };
@@ -3,6 +3,7 @@ import { P as ProviderRegistry, W as WalletAdapter, S as StorageAdapter, a as St
3
3
  import { S as SdkStore, c as UsageTrackingDriver } from '../store-CAQLSbEj.js';
4
4
  import { CashuSpender, BalanceManager } from '../wallet/index.js';
5
5
  import { Transform } from 'stream';
6
+ import { SecureClient, VerificationDocument } from 'tinfoil';
6
7
  import 'zustand/vanilla';
7
8
  import '../interfaces-iL7CWeG5.js';
8
9
 
@@ -264,6 +265,9 @@ declare class RoutstrClient {
264
265
  * Make the API request with failover support
265
266
  */
266
267
  private _makeRequest;
268
+ /**
269
+ * Store request details to a file in the reqs/ folder before fetch.
270
+ */
267
271
  /**
268
272
  * Handle error responses with failover
269
273
  */
@@ -272,6 +276,11 @@ declare class RoutstrClient {
272
276
  * Handle post-response balance update for all modes
273
277
  */
274
278
  private _handlePostResponseBalanceUpdate;
279
+ /**
280
+ * Extract sats cost from EHBP/Tinfoil response headers as a last-resort
281
+ * fallback when neither balance delta nor SSE/body usage provides a cost.
282
+ */
283
+ private _headerSatsCost;
275
284
  private _trackResponseUsage;
276
285
  /**
277
286
  * Check wallet balance and throw if insufficient
@@ -289,6 +298,13 @@ declare class RoutstrClient {
289
298
  * Attach auth headers using the active client mode
290
299
  */
291
300
  private _withAuthHeader;
301
+ /**
302
+ * Attach auth headers and preserve the plaintext model hint required by the
303
+ * Routstr proxy for Tinfoil/EHBP requests. EHBP encrypts the JSON body, so
304
+ * retries/failover must not rebuild headers from baseHeaders alone or the
305
+ * proxy cannot route/price the encrypted request.
306
+ */
307
+ private _withAuthAndTinfoilHeaders;
292
308
  }
293
309
 
294
310
  /**
@@ -372,6 +388,15 @@ interface UsageTrackingData {
372
388
  declare function extractUsageFromResponseBody(body: unknown, fallbackSatsCost?: number): UsageTrackingData | null;
373
389
  declare function extractResponseId(body: unknown): string | undefined;
374
390
  declare function extractUsageFromSSEJson(parsed: any, fallbackSatsCost?: number): UsageTrackingData | null;
391
+ /**
392
+ * Extract cost/usage from EHBP/Tinfoil response headers.
393
+ *
394
+ * For EHBP requests the proxy cannot inject cost into the JSON/SSE body
395
+ * (the body is opaque encrypted). Instead it returns cost as response
396
+ * headers. This parses those headers into the same UsageTrackingData
397
+ * shape used for SSE/body extraction, so callers can merge or fall back.
398
+ */
399
+ declare function extractUsageFromResponseHeaders(headers: Headers | Record<string, string>): UsageTrackingData | null;
375
400
  declare function toUsageStats(usage: UsageTrackingData | null | undefined): UsageStats | undefined;
376
401
 
377
402
  /**
@@ -413,6 +438,65 @@ declare function inspectSSEWebStream(stream: ReadableStream<Uint8Array>, onUsage
413
438
  */
414
439
  declare function createSSEParserTransform(onUsage: (usage: UsageTrackingData) => void, onResponseId?: (responseId: string) => void): Transform;
415
440
 
441
+ /**
442
+ * TinfoilSecure - EHBP transport encryption + enclave attestation for Tinfoil models.
443
+ *
444
+ * Any model whose id starts with `tinfoil-` is routed through Tinfoil EHBP.
445
+ * SecureClient performs attestation (`ready()`) and verifies the enclave code
446
+ * fingerprint. The SDK then uses EHBP request encryption so only the attested
447
+ * enclave can decrypt request bodies.
448
+ *
449
+ * Unlike Venice E2EE, there is no per-field message encryption and no custom SSE
450
+ * decrypt transform. Successful enclave responses are decrypted before normal
451
+ * SDK response handling sees them. Plaintext proxy-side errors (for example
452
+ * auth/balance failures before the request reaches the enclave) are preserved
453
+ * with their real status/body.
454
+ */
455
+
456
+ interface TinfoilClientContext {
457
+ client: SecureClient;
458
+ verification: VerificationDocument;
459
+ }
460
+ interface TinfoilClientOptions {
461
+ /** Routstr/provider base URL that will receive the EHBP-wrapped request. */
462
+ baseUrl: string;
463
+ /** Optional explicit attestation bundle origin. Defaults to Tinfoil's ATC. */
464
+ attestationBundleURL?: string;
465
+ /** Optional explicit enclave URL for custom Tinfoil deployments. */
466
+ enclaveURL?: string;
467
+ /** Optional source repo for code verification when enclaveURL is explicit. */
468
+ configRepo?: string;
469
+ }
470
+ /** Check if a model ID should use Tinfoil EHBP transport. */
471
+ declare function isTinfoilModel(modelId: string): boolean;
472
+ /**
473
+ * Return the model id sent inside the EHBP-encrypted request body.
474
+ *
475
+ * Strips the `tinfoil-` prefix so the attested enclave receives the bare
476
+ * model id it expects (e.g. "kimi-k2-6"), not the caller-facing routstr id.
477
+ */
478
+ declare function getTinfoilUpstreamModelId(modelId: string): string;
479
+ /**
480
+ * Attest and return a cached Tinfoil SecureClient for a provider base URL.
481
+ */
482
+ declare function prepareTinfoilClient(options: TinfoilClientOptions): Promise<TinfoilClientContext>;
483
+ /**
484
+ * Fetch through Tinfoil EHBP while preserving plaintext proxy error responses.
485
+ *
486
+ * Tinfoil's stock SecureClient.fetch throws ProtocolError when a response to an
487
+ * encrypted request lacks Ehbp-Response-Nonce. That is correct for successful
488
+ * enclave responses, but Routstr proxy-side auth/balance errors are plaintext
489
+ * and need to flow through the SDK's normal error handling with their real
490
+ * status/body. This wrapper performs the same request-body encryption and
491
+ * response decryption, but returns non-EHBP responses unchanged.
492
+ *
493
+ * It also keeps SecureClient's key-rotation behavior: an EHBP key-config
494
+ * mismatch response triggers one fresh attestation and one retry.
495
+ */
496
+ declare function fetchTinfoilPreservingPlaintextErrors(options: TinfoilClientOptions, input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
497
+ /** Clear cached Tinfoil clients, mainly useful for tests or forced re-attest. */
498
+ declare function clearTinfoilClientCache(): void;
499
+
416
500
  /**
417
501
  * Options for fetching AI response
418
502
  */
@@ -451,4 +535,4 @@ interface FetchAIResponseDeps {
451
535
  */
452
536
  declare function fetchAIResponse(options: FetchOptions, callbacks: StreamingCallbacks, deps: FetchAIResponseDeps): Promise<void>;
453
537
 
454
- export { type AlertLevel, type DebugLevel, type FetchAIResponseDeps, type ModelProviderPrice, ProviderManager, type RequestResponseLogRequestInput, type RequestResponseLogSink, type RouteRequestParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, type UsageTrackingData, createSSEParserTransform, extractResponseId, extractUsageFromResponseBody, extractUsageFromSSEJson, fetchAIResponse, inspectSSEWebStream, toUsageStats };
538
+ export { type AlertLevel, type DebugLevel, type FetchAIResponseDeps, type ModelProviderPrice, ProviderManager, type RequestResponseLogRequestInput, type RequestResponseLogSink, type RouteRequestParams, RoutstrClient, type RoutstrClientConfig, type RoutstrClientMode, type StreamCallbacks, StreamProcessor, type TinfoilClientContext, type TinfoilClientOptions, type UsageTrackingData, clearTinfoilClientCache, createSSEParserTransform, extractResponseId, extractUsageFromResponseBody, extractUsageFromResponseHeaders, extractUsageFromSSEJson, fetchAIResponse, fetchTinfoilPreservingPlaintextErrors, getTinfoilUpstreamModelId, inspectSSEWebStream, isTinfoilModel, prepareTinfoilClient, toUsageStats };