@singularity-layer/grid 0.5.0 → 0.6.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/dist/index.d.mts +39 -1
- package/dist/index.d.ts +39 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -90,6 +90,33 @@ interface ChatCompletionRequest {
|
|
|
90
90
|
* nodes at/under this and never bills above it. Omit for no cap. */
|
|
91
91
|
max_price?: number;
|
|
92
92
|
}
|
|
93
|
+
/** Request for {@link SGLClient.embed}. `input` is a string or an array of strings. */
|
|
94
|
+
interface EmbeddingRequest {
|
|
95
|
+
model: string;
|
|
96
|
+
input: string | string[];
|
|
97
|
+
/** Truncate Matryoshka models (e.g. nomic 768→256). Ignored by fixed-size models. */
|
|
98
|
+
dimensions?: number;
|
|
99
|
+
/** Asymmetric-retrieval hint for models that support it. */
|
|
100
|
+
input_type?: "query" | "document";
|
|
101
|
+
/** Route tier: 'standard' (any node) or 'confidential' (attested only). */
|
|
102
|
+
tier?: "standard" | "confidential";
|
|
103
|
+
}
|
|
104
|
+
/** One embedding vector plus its position in the input array. */
|
|
105
|
+
interface EmbeddingDatum {
|
|
106
|
+
object: "embedding";
|
|
107
|
+
index: number;
|
|
108
|
+
embedding: number[];
|
|
109
|
+
}
|
|
110
|
+
/** OpenAI-compatible response from `/v1/embeddings`. */
|
|
111
|
+
interface EmbeddingResponse {
|
|
112
|
+
object: "list";
|
|
113
|
+
data: EmbeddingDatum[];
|
|
114
|
+
model: string;
|
|
115
|
+
usage?: {
|
|
116
|
+
prompt_tokens: number;
|
|
117
|
+
total_tokens: number;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
93
120
|
/** A node serving a model, with its effective per-token price. From `providers()`. */
|
|
94
121
|
interface ProviderInfo {
|
|
95
122
|
node_id: string;
|
|
@@ -264,6 +291,17 @@ declare class GridClient {
|
|
|
264
291
|
* replies 402 (the SDK does not sign x402 payments — use the wallet/browser flow).
|
|
265
292
|
*/
|
|
266
293
|
chatCompletions(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
|
|
294
|
+
/**
|
|
295
|
+
* Create embeddings via the grid's OpenAI-compatible `/v1/embeddings` endpoint.
|
|
296
|
+
*
|
|
297
|
+
* `input` is a string or array of strings; `dimensions` truncates Matryoshka models
|
|
298
|
+
* (e.g. nomic 768→256); `input_type` ('query' | 'document') hints asymmetric
|
|
299
|
+
* retrieval models. Billed on input tokens only — there is no generation. Requires
|
|
300
|
+
* an `apiKey` (credits); the TS SDK does not sign x402 payments. Unlike chat, the
|
|
301
|
+
* input is not client-sealed — the orchestrator seals it to the node in-TEE. The
|
|
302
|
+
* returned `data` is ordered to match `input`.
|
|
303
|
+
*/
|
|
304
|
+
embed(request: EmbeddingRequest): Promise<EmbeddingResponse>;
|
|
267
305
|
/**
|
|
268
306
|
* Streaming end-to-end encrypted chat completion. Yields decoded text as it
|
|
269
307
|
* arrives; each chunk is decrypted and its ordering + termination verified (a
|
|
@@ -312,4 +350,4 @@ declare class SGLConnectionError extends SGLError {
|
|
|
312
350
|
constructor(message: string);
|
|
313
351
|
}
|
|
314
352
|
|
|
315
|
-
export { type Attestation, type AttestationProof, type CapacityResponse, type ChatChoice, type ChatCompletionRequest, type ChatCompletionResponse, type ChatMessage, DEFAULT_BASE_URL, type DeployProcessorOptions, GridClient, type GridClientOptions, type JobResponse, type JobResult, type JobSubmission, type ModelInfo, type ModelPricing, type PricingInfo, type ProcessorDeployResult, type ProcessorInfo, type ProcessorInvokeResult, type ProcessorListResponse, type ProcessorLogEntry, type ProcessorLogsResponse, type ReserveResponse, SGLAPIError, SGLAuthError, SGLConnectionError, SGLError, SGLNotFoundError, type TeeCapacity, type WalletAuth };
|
|
353
|
+
export { type Attestation, type AttestationProof, type CapacityResponse, type ChatChoice, type ChatCompletionRequest, type ChatCompletionResponse, type ChatMessage, DEFAULT_BASE_URL, type DeployProcessorOptions, type EmbeddingDatum, type EmbeddingRequest, type EmbeddingResponse, GridClient, type GridClientOptions, type JobResponse, type JobResult, type JobSubmission, type ModelInfo, type ModelPricing, type PricingInfo, type ProcessorDeployResult, type ProcessorInfo, type ProcessorInvokeResult, type ProcessorListResponse, type ProcessorLogEntry, type ProcessorLogsResponse, type ReserveResponse, SGLAPIError, SGLAuthError, SGLConnectionError, SGLError, SGLNotFoundError, type TeeCapacity, type WalletAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -90,6 +90,33 @@ interface ChatCompletionRequest {
|
|
|
90
90
|
* nodes at/under this and never bills above it. Omit for no cap. */
|
|
91
91
|
max_price?: number;
|
|
92
92
|
}
|
|
93
|
+
/** Request for {@link SGLClient.embed}. `input` is a string or an array of strings. */
|
|
94
|
+
interface EmbeddingRequest {
|
|
95
|
+
model: string;
|
|
96
|
+
input: string | string[];
|
|
97
|
+
/** Truncate Matryoshka models (e.g. nomic 768→256). Ignored by fixed-size models. */
|
|
98
|
+
dimensions?: number;
|
|
99
|
+
/** Asymmetric-retrieval hint for models that support it. */
|
|
100
|
+
input_type?: "query" | "document";
|
|
101
|
+
/** Route tier: 'standard' (any node) or 'confidential' (attested only). */
|
|
102
|
+
tier?: "standard" | "confidential";
|
|
103
|
+
}
|
|
104
|
+
/** One embedding vector plus its position in the input array. */
|
|
105
|
+
interface EmbeddingDatum {
|
|
106
|
+
object: "embedding";
|
|
107
|
+
index: number;
|
|
108
|
+
embedding: number[];
|
|
109
|
+
}
|
|
110
|
+
/** OpenAI-compatible response from `/v1/embeddings`. */
|
|
111
|
+
interface EmbeddingResponse {
|
|
112
|
+
object: "list";
|
|
113
|
+
data: EmbeddingDatum[];
|
|
114
|
+
model: string;
|
|
115
|
+
usage?: {
|
|
116
|
+
prompt_tokens: number;
|
|
117
|
+
total_tokens: number;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
93
120
|
/** A node serving a model, with its effective per-token price. From `providers()`. */
|
|
94
121
|
interface ProviderInfo {
|
|
95
122
|
node_id: string;
|
|
@@ -264,6 +291,17 @@ declare class GridClient {
|
|
|
264
291
|
* replies 402 (the SDK does not sign x402 payments — use the wallet/browser flow).
|
|
265
292
|
*/
|
|
266
293
|
chatCompletions(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
|
|
294
|
+
/**
|
|
295
|
+
* Create embeddings via the grid's OpenAI-compatible `/v1/embeddings` endpoint.
|
|
296
|
+
*
|
|
297
|
+
* `input` is a string or array of strings; `dimensions` truncates Matryoshka models
|
|
298
|
+
* (e.g. nomic 768→256); `input_type` ('query' | 'document') hints asymmetric
|
|
299
|
+
* retrieval models. Billed on input tokens only — there is no generation. Requires
|
|
300
|
+
* an `apiKey` (credits); the TS SDK does not sign x402 payments. Unlike chat, the
|
|
301
|
+
* input is not client-sealed — the orchestrator seals it to the node in-TEE. The
|
|
302
|
+
* returned `data` is ordered to match `input`.
|
|
303
|
+
*/
|
|
304
|
+
embed(request: EmbeddingRequest): Promise<EmbeddingResponse>;
|
|
267
305
|
/**
|
|
268
306
|
* Streaming end-to-end encrypted chat completion. Yields decoded text as it
|
|
269
307
|
* arrives; each chunk is decrypted and its ordering + termination verified (a
|
|
@@ -312,4 +350,4 @@ declare class SGLConnectionError extends SGLError {
|
|
|
312
350
|
constructor(message: string);
|
|
313
351
|
}
|
|
314
352
|
|
|
315
|
-
export { type Attestation, type AttestationProof, type CapacityResponse, type ChatChoice, type ChatCompletionRequest, type ChatCompletionResponse, type ChatMessage, DEFAULT_BASE_URL, type DeployProcessorOptions, GridClient, type GridClientOptions, type JobResponse, type JobResult, type JobSubmission, type ModelInfo, type ModelPricing, type PricingInfo, type ProcessorDeployResult, type ProcessorInfo, type ProcessorInvokeResult, type ProcessorListResponse, type ProcessorLogEntry, type ProcessorLogsResponse, type ReserveResponse, SGLAPIError, SGLAuthError, SGLConnectionError, SGLError, SGLNotFoundError, type TeeCapacity, type WalletAuth };
|
|
353
|
+
export { type Attestation, type AttestationProof, type CapacityResponse, type ChatChoice, type ChatCompletionRequest, type ChatCompletionResponse, type ChatMessage, DEFAULT_BASE_URL, type DeployProcessorOptions, type EmbeddingDatum, type EmbeddingRequest, type EmbeddingResponse, GridClient, type GridClientOptions, type JobResponse, type JobResult, type JobSubmission, type ModelInfo, type ModelPricing, type PricingInfo, type ProcessorDeployResult, type ProcessorInfo, type ProcessorInvokeResult, type ProcessorListResponse, type ProcessorLogEntry, type ProcessorLogsResponse, type ReserveResponse, SGLAPIError, SGLAuthError, SGLConnectionError, SGLError, SGLNotFoundError, type TeeCapacity, type WalletAuth };
|
package/dist/index.js
CHANGED
|
@@ -326,6 +326,30 @@ var GridClient = class {
|
|
|
326
326
|
}
|
|
327
327
|
};
|
|
328
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* Create embeddings via the grid's OpenAI-compatible `/v1/embeddings` endpoint.
|
|
331
|
+
*
|
|
332
|
+
* `input` is a string or array of strings; `dimensions` truncates Matryoshka models
|
|
333
|
+
* (e.g. nomic 768→256); `input_type` ('query' | 'document') hints asymmetric
|
|
334
|
+
* retrieval models. Billed on input tokens only — there is no generation. Requires
|
|
335
|
+
* an `apiKey` (credits); the TS SDK does not sign x402 payments. Unlike chat, the
|
|
336
|
+
* input is not client-sealed — the orchestrator seals it to the node in-TEE. The
|
|
337
|
+
* returned `data` is ordered to match `input`.
|
|
338
|
+
*/
|
|
339
|
+
async embed(request) {
|
|
340
|
+
const body = { model: request.model, input: request.input };
|
|
341
|
+
if (request.dimensions != null) body.dimensions = request.dimensions;
|
|
342
|
+
if (request.input_type != null) body.input_type = request.input_type;
|
|
343
|
+
if (request.tier != null) body.tier = request.tier;
|
|
344
|
+
try {
|
|
345
|
+
return await this.request("POST", "/v1/embeddings", body);
|
|
346
|
+
} catch (err) {
|
|
347
|
+
if (err instanceof SGLAPIError && err.statusCode === 402) {
|
|
348
|
+
throw new SGLAPIError(402, "Payment required \u2014 pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.");
|
|
349
|
+
}
|
|
350
|
+
throw err;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
329
353
|
/**
|
|
330
354
|
* Streaming end-to-end encrypted chat completion. Yields decoded text as it
|
|
331
355
|
* arrives; each chunk is decrypted and its ordering + termination verified (a
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/e2e.ts","../src/client.ts"],"sourcesContent":["export { GridClient, DEFAULT_BASE_URL } from \"./client.js\";\nexport {\n SGLError,\n SGLAPIError,\n SGLAuthError,\n SGLNotFoundError,\n SGLConnectionError,\n} from \"./errors.js\";\nexport type {\n Attestation,\n AttestationProof,\n CapacityResponse,\n ChatChoice,\n ChatCompletionRequest,\n ChatCompletionResponse,\n ChatMessage,\n ReserveResponse,\n DeployProcessorOptions,\n GridClientOptions,\n JobResponse,\n JobResult,\n JobSubmission,\n ModelInfo,\n ModelPricing,\n PricingInfo,\n ProcessorDeployResult,\n ProcessorInfo,\n ProcessorInvokeResult,\n ProcessorListResponse,\n ProcessorLogEntry,\n ProcessorLogsResponse,\n TeeCapacity,\n WalletAuth,\n} from \"./types.js\";\n","export class SGLError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SGLError\";\n }\n}\n\nexport class SGLAPIError extends SGLError {\n readonly statusCode: number;\n readonly body?: Record<string, unknown>;\n\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(`HTTP ${statusCode}: ${message}`);\n this.name = \"SGLAPIError\";\n this.statusCode = statusCode;\n this.body = body;\n }\n}\n\nexport class SGLAuthError extends SGLAPIError {\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(statusCode, message, body);\n this.name = \"SGLAuthError\";\n }\n}\n\nexport class SGLNotFoundError extends SGLAPIError {\n constructor(message: string, body?: Record<string, unknown>) {\n super(404, message, body);\n this.name = \"SGLNotFoundError\";\n }\n}\n\nexport class SGLConnectionError extends SGLError {\n constructor(message: string) {\n super(message);\n this.name = \"SGLConnectionError\";\n }\n}\n","/**\n * End-to-end encryption for the SGL grid (client side).\n *\n * Must match sgl-node/src/encryption.rs, the orchestrator, and the browser/Python\n * clients byte-for-byte: X25519 ECDH -> HKDF-SHA256 -> XChaCha20-Poly1305 (24-byte\n * nonce), AAD-bound. Sealed blob layout: nonce(24) || ciphertext, base58.\n *\n * The orchestrator only ever relays ciphertext — it never sees the prompt or reply.\n */\n\nimport { x25519 } from \"@noble/curves/ed25519\";\nimport { xchacha20poly1305 } from \"@noble/ciphers/chacha\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { hkdf } from \"@noble/hashes/hkdf\";\nimport bs58 from \"bs58\";\n\nexport const ALGO_V2 = \"x25519-xchacha20poly1305-hkdf-v2\";\nexport const ALGO_V2_STREAM = \"x25519-xchacha20poly1305-hkdf-v2-stream\";\n\nconst HKDF_SALT = new TextEncoder().encode(\"sgl-e2e-v2-salt\");\nconst HKDF_INFO_INPUT = new TextEncoder().encode(\"sgl-e2e-v2-input\");\nconst HKDF_INFO_OUTPUT = new TextEncoder().encode(\"sgl-e2e-v2-output\");\n\nfunction v2Key(shared: Uint8Array, info: Uint8Array): Uint8Array {\n return hkdf(sha256, shared, HKDF_SALT, info, 32);\n}\nfunction aadInput(nodeB58: string, ephB58: string, respB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/input|node=${nodeB58}|eph=${ephB58}|resp=${respB58}`);\n}\nfunction aadOutput(respB58: string, ephB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/output|resp=${respB58}|eph=${ephB58}`);\n}\nfunction aadStream(respB58: string, ephB58: string, nonceB58: string, seq: number, isFinal: boolean): Uint8Array {\n return new TextEncoder().encode(\n `sgl-aad/v2/stream|resp=${respB58}|eph=${ephB58}|nonce=${nonceB58}|seq=${seq}|final=${isFinal ? 1 : 0}`,\n );\n}\n\nfunction b58enc(u: Uint8Array): string {\n return bs58.encode(u);\n}\nfunction b58dec(s: string): Uint8Array {\n return bs58.decode(s);\n}\nfunction randomBytes(n: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(n));\n}\n\nexport interface ResponseKeypair {\n secret: Uint8Array;\n pubB58: string;\n}\n\n/** The caller's response keypair — the node seals its reply to this. */\nexport function newResponseKeypair(): ResponseKeypair {\n const secret = x25519.utils.randomPrivateKey();\n return { secret, pubB58: b58enc(x25519.getPublicKey(secret)) };\n}\n\n/** A per-request nonce bound into every stream chunk's AAD. */\nexport function randomNonceB58(): string {\n return b58enc(randomBytes(16));\n}\n\n/** Seal the prompt to the node's X25519 key. */\nexport function sealInputV2(\n nodePubB58: string,\n respPubB58: string,\n plaintext: Uint8Array,\n): { ciphertext: string; ephemeralPub: string } {\n const nodePub = b58dec(nodePubB58);\n const ephSecret = x25519.utils.randomPrivateKey();\n const ephPub = x25519.getPublicKey(ephSecret);\n const ephB58 = b58enc(ephPub);\n const shared = x25519.getSharedSecret(ephSecret, nodePub);\n const key = v2Key(shared, HKDF_INFO_INPUT);\n const aad = aadInput(nodePubB58, ephB58, respPubB58);\n const nonce = randomBytes(24);\n const ct = xchacha20poly1305(key, nonce, aad).encrypt(plaintext);\n const out = new Uint8Array(24 + ct.length);\n out.set(nonce, 0);\n out.set(ct, 24);\n return { ciphertext: b58enc(out), ephemeralPub: ephB58 };\n}\n\n/** Open the node's (non-stream) reply sealed to our response key. */\nexport function openOutputV2(\n respSecret: Uint8Array,\n respPubB58: string,\n nodeEphB58: string,\n ciphertextB58: string,\n): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeEphB58));\n const key = v2Key(shared, HKDF_INFO_OUTPUT);\n const aad = aadOutput(respPubB58, nodeEphB58);\n const blob = b58dec(ciphertextB58);\n return xchacha20poly1305(key, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n\n/** Derive the stream output key once from the node's stream ephemeral (chunk 0). */\nexport function streamOutKey(respSecret: Uint8Array, nodeStreamEphB58: string): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeStreamEphB58));\n return v2Key(shared, HKDF_INFO_OUTPUT);\n}\n\n/** Open one stream chunk with the precomputed key + nonce/seq/final-bound AAD. */\nexport function openStreamChunk(\n outKey: Uint8Array,\n respPubB58: string,\n streamEphB58: string,\n reqNonceB58: string,\n seq: number,\n isFinal: boolean,\n ctB58: string,\n): Uint8Array {\n const aad = aadStream(respPubB58, streamEphB58, reqNonceB58, seq, isFinal);\n const blob = b58dec(ctB58);\n return xchacha20poly1305(outKey, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n","import { SGLAPIError, SGLAuthError, SGLConnectionError, SGLNotFoundError } from \"./errors.js\";\nimport * as e2e from \"./e2e.js\";\nimport type {\n AttestationProof,\n CapacityResponse,\n ChatCompletionRequest,\n ChatCompletionResponse,\n DeployProcessorOptions,\n GridClientOptions,\n JobResponse,\n JobResult,\n ModelInfo,\n PricingInfo,\n ProcessorDeployResult,\n ProcessorInfo,\n ProcessorInvokeResult,\n ProcessorListResponse,\n ProcessorLogEntry,\n ProcessorLogsResponse,\n ProviderInfo,\n ProvidersResponse,\n ReserveResponse,\n WalletAuth,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://grid.x402compute.cc\";\n\nconst DEFAULT_TIMEOUT = 60_000;\n\nexport class GridClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly timeout: number;\n\n constructor(options: GridClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.headers = { Accept: \"application/json\", \"Content-Type\": \"application/json\" };\n if (options.apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${options.apiKey}`;\n // Grid credit billing reads X-API-Key; send both so reserve + chat resolve\n // the paying wallet (credits mode) rather than falling back to anonymous x402.\n this.headers[\"X-API-Key\"] = options.apiKey;\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n // -- Public endpoints (no auth) ------------------------------------------\n\n async capacity(): Promise<CapacityResponse> {\n return this.request<CapacityResponse>(\"GET\", \"/grid/capacity\");\n }\n\n async models(): Promise<ModelInfo[]> {\n const data = await this.request<{ models: ModelInfo[] }>(\"GET\", \"/grid/models\");\n return data.models ?? [];\n }\n\n async pricing(): Promise<PricingInfo[]> {\n const data = await this.request<{ pricing: PricingInfo[] }>(\"GET\", \"/grid/pricing\");\n return data.pricing ?? [];\n }\n\n /**\n * List the nodes serving a model with each node's effective per-token price\n * (operator's custom price if set, else the platform reference), cheapest\n * first. Pass a chosen `node_id` as `node` on `chatCompletions` to pin it,\n * or omit to let the grid route. Optional `cluster` filter (slug or id).\n */\n async providers(\n model: string,\n options?: { cluster?: string },\n ): Promise<ProviderInfo[]> {\n const params = new URLSearchParams({ model });\n if (options?.cluster) params.set(\"cluster\", options.cluster);\n const data = await this.request<ProvidersResponse>(\n \"GET\",\n `/v1/providers?${params.toString()}`,\n );\n return data.providers ?? [];\n }\n\n // -- Authenticated endpoints ---------------------------------------------\n\n async submitJob(\n model: string,\n input: Record<string, unknown>,\n options?: { submitterWallet?: string; submitterChain?: string },\n ): Promise<JobResponse> {\n const body: Record<string, unknown> = { model, input };\n if (options?.submitterWallet) body.submitter_wallet = options.submitterWallet;\n if (options?.submitterChain) body.submitter_chain = options.submitterChain;\n return this.request<JobResponse>(\"POST\", \"/grid/jobs\", body);\n }\n\n async getJob(jobId: string): Promise<JobResult> {\n return this.request<JobResult>(\"GET\", `/grid/jobs/${jobId}`);\n }\n\n async getAttestation(jobId: string): Promise<AttestationProof> {\n return this.request<AttestationProof>(\"GET\", `/grid/jobs/${jobId}/attestation`);\n }\n\n // -- OpenAI-compatible (end-to-end encrypted) ----------------------------\n\n /** Reserve a node + learn its X25519 key so we can seal the prompt to it.\n * Forwards an optional pinned `node` (see `providers()`), `cluster` filter,\n * and `pay_in_coin` so the orchestrator reserves + quotes accordingly. */\n private async reserve(req: {\n model: string;\n node?: string;\n cluster?: string;\n pay_in_coin?: boolean;\n max_price?: number;\n }): Promise<ReserveResponse> {\n const body: Record<string, unknown> = { model: req.model };\n if (req.node) body.node = req.node;\n if (req.cluster) body.cluster = req.cluster;\n if (req.pay_in_coin) body.pay_in_coin = req.pay_in_coin;\n if (req.max_price != null) body.max_price = req.max_price;\n const res = await this.request<ReserveResponse>(\"POST\", \"/v1/reserve\", body);\n if (!res.node_x25519_pubkey) {\n throw new SGLAPIError(503, \"Reserved node does not support E2E encryption\");\n }\n return res;\n }\n\n /**\n * End-to-end encrypted chat completion. The prompt is sealed in this client to\n * the serving node's key and only decrypts inside its TEE — the orchestrator\n * only relays ciphertext. Requires an `apiKey` (credits); without one the grid\n * replies 402 (the SDK does not sign x402 payments — use the wallet/browser flow).\n */\n async chatCompletions(\n request: ChatCompletionRequest,\n ): Promise<ChatCompletionResponse> {\n if (request.stream) {\n // Collapse the stream into a single response for the non-streaming API.\n let content = \"\";\n for await (const delta of this.chatCompletionStream(request)) content += delta;\n return {\n id: \"\", object: \"chat.completion\", created: 0, model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content }, finish_reason: \"stop\" }],\n };\n }\n\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n max_tokens: maxTokens, // cleartext, only used to quote the x402 price\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n let data: {\n id?: string; created?: number; sealed_result?: { ephemeral_public_key: string; ciphertext: string };\n usage?: ChatCompletionResponse[\"usage\"];\n };\n try {\n data = await this.request(\"POST\", \"/v1/chat/completions\", body);\n } catch (err) {\n if (err instanceof SGLAPIError && err.statusCode === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n throw err;\n }\n\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const parsed = JSON.parse(new TextDecoder().decode(plain)) as { content?: string; usage?: ChatCompletionResponse[\"usage\"] };\n\n return {\n id: data.id ?? \"\",\n object: \"chat.completion\",\n created: data.created ?? 0,\n model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content: parsed.content ?? \"\" }, finish_reason: \"stop\" }],\n usage: data.usage ?? parsed.usage,\n attestation: {\n nodeId: reservation.node_id,\n teeType: reservation.tee_type ?? null,\n verified: !!reservation.attestation_verified,\n },\n };\n }\n\n /**\n * Streaming end-to-end encrypted chat completion. Yields decoded text as it\n * arrives; each chunk is decrypted and its ordering + termination verified (a\n * truncated stream throws). Requires `apiKey` (credits). If the server isn't\n * streaming (toggle off), the whole reply is yielded as a single chunk.\n */\n async *chatCompletionStream(\n request: ChatCompletionRequest,\n ): AsyncGenerator<string, void, unknown> {\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const nonce = e2e.randomNonceB58();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n stream: true,\n nonce,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n stream: true,\n max_tokens: maxTokens,\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n const controller = new AbortController();\n const overall = setTimeout(() => controller.abort(), this.timeout);\n let resp: Response;\n try {\n resp = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(overall);\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (!resp.ok) {\n clearTimeout(overall);\n if (resp.status === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n let message = resp.statusText;\n try {\n const j = (await resp.json()) as { error?: unknown };\n if (typeof j.error === \"string\") message = j.error;\n else if (j.error && typeof j.error === \"object\" && \"message\" in j.error) message = String((j.error as { message: unknown }).message);\n } catch { /* ignore */ }\n throw new SGLAPIError(resp.status, message);\n }\n\n const ctype = resp.headers.get(\"content-type\") ?? \"\";\n if (!ctype.includes(\"text/event-stream\") || !resp.body) {\n clearTimeout(overall);\n const data = (await resp.json()) as { sealed_result?: { ephemeral_public_key: string; ciphertext: string } };\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const content = (JSON.parse(new TextDecoder().decode(plain)) as { content?: string }).content ?? \"\";\n if (content) yield content;\n return;\n }\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n const INACTIVITY_MS = 60_000;\n const readChunk = async (): Promise<ReadableStreamReadResult<Uint8Array>> => {\n let t: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n t = setTimeout(() => reject(new SGLConnectionError(\"stream timed out (no tokens)\")), INACTIVITY_MS);\n });\n try {\n return (await Promise.race([reader.read(), timeout])) as ReadableStreamReadResult<Uint8Array>;\n } finally {\n if (t) clearTimeout(t);\n }\n };\n\n let buf = \"\";\n let expectedSeq = 0;\n let outKey: Uint8Array | null = null;\n let streamEph: string | null = null;\n let sawFinal = false;\n try {\n for (;;) {\n if (sawFinal) break;\n const { value, done } = await readChunk();\n if (done) break;\n // Normalize CRLF so \\n\\n event framing works regardless of line endings.\n buf += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let idx: number;\n while ((idx = buf.indexOf(\"\\n\\n\")) !== -1) {\n const raw = buf.slice(0, idx);\n buf = buf.slice(idx + 2);\n if (raw.includes(\"event: error\")) throw new SGLAPIError(502, \"stream aborted by server\");\n const dataStr = raw.split(\"\\n\").filter((l) => l.startsWith(\"data:\")).map((l) => l.slice(5).trim()).join(\"\\n\");\n if (!dataStr || dataStr === \"[DONE]\") continue;\n // Fail closed: a malformed or non-chunk data event is a protocol error.\n let chunk: { seq?: number; final?: boolean; eph?: string; ct?: string };\n try {\n chunk = JSON.parse(dataStr);\n } catch {\n throw new SGLAPIError(502, \"malformed stream chunk\");\n }\n if (typeof chunk.seq !== \"number\" || !chunk.ct) {\n throw new SGLAPIError(502, \"invalid stream chunk (missing seq/ciphertext)\");\n }\n if (chunk.seq !== expectedSeq) throw new SGLAPIError(502, `stream out of order (expected ${expectedSeq}, got ${chunk.seq})`);\n if (chunk.seq === 0) {\n if (!chunk.eph) throw new SGLAPIError(502, \"stream chunk 0 missing ephemeral key\");\n streamEph = chunk.eph;\n outKey = e2e.streamOutKey(secret, streamEph);\n }\n const isFinal = chunk.final === true;\n const text = new TextDecoder().decode(\n e2e.openStreamChunk(outKey as Uint8Array, pubB58, streamEph as string, nonce, chunk.seq, isFinal, chunk.ct),\n );\n if (text) yield text;\n expectedSeq++;\n if (isFinal) { sawFinal = true; break; }\n }\n }\n } finally {\n clearTimeout(overall);\n try { await reader.cancel(); } catch { /* ignore */ }\n }\n if (!sawFinal) throw new SGLAPIError(502, \"stream ended before final chunk (truncated)\");\n }\n\n // -- Processor helpers ----------------------------------------------------\n\n private async requestWithWalletAuth<T>(\n method: string,\n path: string,\n wallet: WalletAuth,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = {\n ...this.headers,\n \"X-Auth-Address\": wallet.address,\n \"X-Auth-Chain\": wallet.chain ?? \"solana\",\n \"X-Auth-Signature\": wallet.signature,\n \"X-Auth-Timestamp\": wallet.timestamp,\n \"X-Auth-Nonce\": wallet.nonce,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n private async requestWithPayment<T>(\n method: string,\n path: string,\n body?: unknown,\n paymentHeader?: string,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = { ...this.headers };\n if (paymentHeader) {\n reqHeaders[\"X-Payment\"] = paymentHeader;\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (response.status === 402) {\n const requirements = (await response.json()) as Record<string, unknown>;\n throw new SGLAPIError(402, \"Payment required\", requirements);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n } catch {\n /* body not JSON */\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n return (await response.json()) as T;\n }\n\n // -- Processors -----------------------------------------------------------\n\n async deployProcessor(\n wallet: WalletAuth,\n options: DeployProcessorOptions,\n ): Promise<ProcessorDeployResult> {\n return this.requestWithWalletAuth<ProcessorDeployResult>(\n \"POST\",\n \"/grid/processors\",\n wallet,\n options,\n );\n }\n\n async invokeProcessor(\n processorName: string,\n input: Record<string, unknown>,\n options?: { paymentHeader?: string; paymentToken?: \"USDC\" | \"SGL\" },\n ): Promise<ProcessorInvokeResult> {\n const body: Record<string, unknown> = { input };\n if (options?.paymentToken) body.payment_token = options.paymentToken;\n return this.requestWithPayment<ProcessorInvokeResult>(\n \"POST\",\n `/grid/processors/${encodeURIComponent(processorName)}/invoke`,\n body,\n options?.paymentHeader,\n );\n }\n\n async listProcessors(options?: {\n owner?: string;\n page?: number;\n limit?: number;\n }): Promise<ProcessorListResponse> {\n const params = new URLSearchParams();\n if (options?.owner) params.set(\"owner\", options.owner);\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.request<ProcessorListResponse>(\n \"GET\",\n `/grid/processors${qs ? `?${qs}` : \"\"}`,\n );\n }\n\n async getProcessor(processorId: string): Promise<ProcessorInfo> {\n return this.request<ProcessorInfo>(\"GET\", `/grid/processors/${processorId}`);\n }\n\n async deleteProcessor(\n processorId: string,\n wallet: WalletAuth,\n ): Promise<{ deleted: boolean; id: string }> {\n return this.requestWithWalletAuth<{ deleted: boolean; id: string }>(\n \"DELETE\",\n `/grid/processors/${processorId}`,\n wallet,\n );\n }\n\n async getProcessorLogs(\n processorId: string,\n wallet: WalletAuth,\n options?: { page?: number; limit?: number },\n ): Promise<ProcessorLogsResponse> {\n const params = new URLSearchParams();\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.requestWithWalletAuth<ProcessorLogsResponse>(\n \"GET\",\n `/grid/processors/${processorId}/logs${qs ? `?${qs}` : \"\"}`,\n wallet,\n );\n }\n}\n"],"mappings":"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","names":["bs58"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/e2e.ts","../src/client.ts"],"sourcesContent":["export { GridClient, DEFAULT_BASE_URL } from \"./client.js\";\nexport {\n SGLError,\n SGLAPIError,\n SGLAuthError,\n SGLNotFoundError,\n SGLConnectionError,\n} from \"./errors.js\";\nexport type {\n Attestation,\n AttestationProof,\n CapacityResponse,\n ChatChoice,\n ChatCompletionRequest,\n ChatCompletionResponse,\n ChatMessage,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingDatum,\n ReserveResponse,\n DeployProcessorOptions,\n GridClientOptions,\n JobResponse,\n JobResult,\n JobSubmission,\n ModelInfo,\n ModelPricing,\n PricingInfo,\n ProcessorDeployResult,\n ProcessorInfo,\n ProcessorInvokeResult,\n ProcessorListResponse,\n ProcessorLogEntry,\n ProcessorLogsResponse,\n TeeCapacity,\n WalletAuth,\n} from \"./types.js\";\n","export class SGLError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SGLError\";\n }\n}\n\nexport class SGLAPIError extends SGLError {\n readonly statusCode: number;\n readonly body?: Record<string, unknown>;\n\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(`HTTP ${statusCode}: ${message}`);\n this.name = \"SGLAPIError\";\n this.statusCode = statusCode;\n this.body = body;\n }\n}\n\nexport class SGLAuthError extends SGLAPIError {\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(statusCode, message, body);\n this.name = \"SGLAuthError\";\n }\n}\n\nexport class SGLNotFoundError extends SGLAPIError {\n constructor(message: string, body?: Record<string, unknown>) {\n super(404, message, body);\n this.name = \"SGLNotFoundError\";\n }\n}\n\nexport class SGLConnectionError extends SGLError {\n constructor(message: string) {\n super(message);\n this.name = \"SGLConnectionError\";\n }\n}\n","/**\n * End-to-end encryption for the SGL grid (client side).\n *\n * Must match sgl-node/src/encryption.rs, the orchestrator, and the browser/Python\n * clients byte-for-byte: X25519 ECDH -> HKDF-SHA256 -> XChaCha20-Poly1305 (24-byte\n * nonce), AAD-bound. Sealed blob layout: nonce(24) || ciphertext, base58.\n *\n * The orchestrator only ever relays ciphertext — it never sees the prompt or reply.\n */\n\nimport { x25519 } from \"@noble/curves/ed25519\";\nimport { xchacha20poly1305 } from \"@noble/ciphers/chacha\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { hkdf } from \"@noble/hashes/hkdf\";\nimport bs58 from \"bs58\";\n\nexport const ALGO_V2 = \"x25519-xchacha20poly1305-hkdf-v2\";\nexport const ALGO_V2_STREAM = \"x25519-xchacha20poly1305-hkdf-v2-stream\";\n\nconst HKDF_SALT = new TextEncoder().encode(\"sgl-e2e-v2-salt\");\nconst HKDF_INFO_INPUT = new TextEncoder().encode(\"sgl-e2e-v2-input\");\nconst HKDF_INFO_OUTPUT = new TextEncoder().encode(\"sgl-e2e-v2-output\");\n\nfunction v2Key(shared: Uint8Array, info: Uint8Array): Uint8Array {\n return hkdf(sha256, shared, HKDF_SALT, info, 32);\n}\nfunction aadInput(nodeB58: string, ephB58: string, respB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/input|node=${nodeB58}|eph=${ephB58}|resp=${respB58}`);\n}\nfunction aadOutput(respB58: string, ephB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/output|resp=${respB58}|eph=${ephB58}`);\n}\nfunction aadStream(respB58: string, ephB58: string, nonceB58: string, seq: number, isFinal: boolean): Uint8Array {\n return new TextEncoder().encode(\n `sgl-aad/v2/stream|resp=${respB58}|eph=${ephB58}|nonce=${nonceB58}|seq=${seq}|final=${isFinal ? 1 : 0}`,\n );\n}\n\nfunction b58enc(u: Uint8Array): string {\n return bs58.encode(u);\n}\nfunction b58dec(s: string): Uint8Array {\n return bs58.decode(s);\n}\nfunction randomBytes(n: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(n));\n}\n\nexport interface ResponseKeypair {\n secret: Uint8Array;\n pubB58: string;\n}\n\n/** The caller's response keypair — the node seals its reply to this. */\nexport function newResponseKeypair(): ResponseKeypair {\n const secret = x25519.utils.randomPrivateKey();\n return { secret, pubB58: b58enc(x25519.getPublicKey(secret)) };\n}\n\n/** A per-request nonce bound into every stream chunk's AAD. */\nexport function randomNonceB58(): string {\n return b58enc(randomBytes(16));\n}\n\n/** Seal the prompt to the node's X25519 key. */\nexport function sealInputV2(\n nodePubB58: string,\n respPubB58: string,\n plaintext: Uint8Array,\n): { ciphertext: string; ephemeralPub: string } {\n const nodePub = b58dec(nodePubB58);\n const ephSecret = x25519.utils.randomPrivateKey();\n const ephPub = x25519.getPublicKey(ephSecret);\n const ephB58 = b58enc(ephPub);\n const shared = x25519.getSharedSecret(ephSecret, nodePub);\n const key = v2Key(shared, HKDF_INFO_INPUT);\n const aad = aadInput(nodePubB58, ephB58, respPubB58);\n const nonce = randomBytes(24);\n const ct = xchacha20poly1305(key, nonce, aad).encrypt(plaintext);\n const out = new Uint8Array(24 + ct.length);\n out.set(nonce, 0);\n out.set(ct, 24);\n return { ciphertext: b58enc(out), ephemeralPub: ephB58 };\n}\n\n/** Open the node's (non-stream) reply sealed to our response key. */\nexport function openOutputV2(\n respSecret: Uint8Array,\n respPubB58: string,\n nodeEphB58: string,\n ciphertextB58: string,\n): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeEphB58));\n const key = v2Key(shared, HKDF_INFO_OUTPUT);\n const aad = aadOutput(respPubB58, nodeEphB58);\n const blob = b58dec(ciphertextB58);\n return xchacha20poly1305(key, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n\n/** Derive the stream output key once from the node's stream ephemeral (chunk 0). */\nexport function streamOutKey(respSecret: Uint8Array, nodeStreamEphB58: string): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeStreamEphB58));\n return v2Key(shared, HKDF_INFO_OUTPUT);\n}\n\n/** Open one stream chunk with the precomputed key + nonce/seq/final-bound AAD. */\nexport function openStreamChunk(\n outKey: Uint8Array,\n respPubB58: string,\n streamEphB58: string,\n reqNonceB58: string,\n seq: number,\n isFinal: boolean,\n ctB58: string,\n): Uint8Array {\n const aad = aadStream(respPubB58, streamEphB58, reqNonceB58, seq, isFinal);\n const blob = b58dec(ctB58);\n return xchacha20poly1305(outKey, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n","import { SGLAPIError, SGLAuthError, SGLConnectionError, SGLNotFoundError } from \"./errors.js\";\nimport * as e2e from \"./e2e.js\";\nimport type {\n AttestationProof,\n CapacityResponse,\n ChatCompletionRequest,\n ChatCompletionResponse,\n EmbeddingRequest,\n EmbeddingResponse,\n DeployProcessorOptions,\n GridClientOptions,\n JobResponse,\n JobResult,\n ModelInfo,\n PricingInfo,\n ProcessorDeployResult,\n ProcessorInfo,\n ProcessorInvokeResult,\n ProcessorListResponse,\n ProcessorLogEntry,\n ProcessorLogsResponse,\n ProviderInfo,\n ProvidersResponse,\n ReserveResponse,\n WalletAuth,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://grid.x402compute.cc\";\n\nconst DEFAULT_TIMEOUT = 60_000;\n\nexport class GridClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly timeout: number;\n\n constructor(options: GridClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.headers = { Accept: \"application/json\", \"Content-Type\": \"application/json\" };\n if (options.apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${options.apiKey}`;\n // Grid credit billing reads X-API-Key; send both so reserve + chat resolve\n // the paying wallet (credits mode) rather than falling back to anonymous x402.\n this.headers[\"X-API-Key\"] = options.apiKey;\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n // -- Public endpoints (no auth) ------------------------------------------\n\n async capacity(): Promise<CapacityResponse> {\n return this.request<CapacityResponse>(\"GET\", \"/grid/capacity\");\n }\n\n async models(): Promise<ModelInfo[]> {\n const data = await this.request<{ models: ModelInfo[] }>(\"GET\", \"/grid/models\");\n return data.models ?? [];\n }\n\n async pricing(): Promise<PricingInfo[]> {\n const data = await this.request<{ pricing: PricingInfo[] }>(\"GET\", \"/grid/pricing\");\n return data.pricing ?? [];\n }\n\n /**\n * List the nodes serving a model with each node's effective per-token price\n * (operator's custom price if set, else the platform reference), cheapest\n * first. Pass a chosen `node_id` as `node` on `chatCompletions` to pin it,\n * or omit to let the grid route. Optional `cluster` filter (slug or id).\n */\n async providers(\n model: string,\n options?: { cluster?: string },\n ): Promise<ProviderInfo[]> {\n const params = new URLSearchParams({ model });\n if (options?.cluster) params.set(\"cluster\", options.cluster);\n const data = await this.request<ProvidersResponse>(\n \"GET\",\n `/v1/providers?${params.toString()}`,\n );\n return data.providers ?? [];\n }\n\n // -- Authenticated endpoints ---------------------------------------------\n\n async submitJob(\n model: string,\n input: Record<string, unknown>,\n options?: { submitterWallet?: string; submitterChain?: string },\n ): Promise<JobResponse> {\n const body: Record<string, unknown> = { model, input };\n if (options?.submitterWallet) body.submitter_wallet = options.submitterWallet;\n if (options?.submitterChain) body.submitter_chain = options.submitterChain;\n return this.request<JobResponse>(\"POST\", \"/grid/jobs\", body);\n }\n\n async getJob(jobId: string): Promise<JobResult> {\n return this.request<JobResult>(\"GET\", `/grid/jobs/${jobId}`);\n }\n\n async getAttestation(jobId: string): Promise<AttestationProof> {\n return this.request<AttestationProof>(\"GET\", `/grid/jobs/${jobId}/attestation`);\n }\n\n // -- OpenAI-compatible (end-to-end encrypted) ----------------------------\n\n /** Reserve a node + learn its X25519 key so we can seal the prompt to it.\n * Forwards an optional pinned `node` (see `providers()`), `cluster` filter,\n * and `pay_in_coin` so the orchestrator reserves + quotes accordingly. */\n private async reserve(req: {\n model: string;\n node?: string;\n cluster?: string;\n pay_in_coin?: boolean;\n max_price?: number;\n }): Promise<ReserveResponse> {\n const body: Record<string, unknown> = { model: req.model };\n if (req.node) body.node = req.node;\n if (req.cluster) body.cluster = req.cluster;\n if (req.pay_in_coin) body.pay_in_coin = req.pay_in_coin;\n if (req.max_price != null) body.max_price = req.max_price;\n const res = await this.request<ReserveResponse>(\"POST\", \"/v1/reserve\", body);\n if (!res.node_x25519_pubkey) {\n throw new SGLAPIError(503, \"Reserved node does not support E2E encryption\");\n }\n return res;\n }\n\n /**\n * End-to-end encrypted chat completion. The prompt is sealed in this client to\n * the serving node's key and only decrypts inside its TEE — the orchestrator\n * only relays ciphertext. Requires an `apiKey` (credits); without one the grid\n * replies 402 (the SDK does not sign x402 payments — use the wallet/browser flow).\n */\n async chatCompletions(\n request: ChatCompletionRequest,\n ): Promise<ChatCompletionResponse> {\n if (request.stream) {\n // Collapse the stream into a single response for the non-streaming API.\n let content = \"\";\n for await (const delta of this.chatCompletionStream(request)) content += delta;\n return {\n id: \"\", object: \"chat.completion\", created: 0, model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content }, finish_reason: \"stop\" }],\n };\n }\n\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n max_tokens: maxTokens, // cleartext, only used to quote the x402 price\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n let data: {\n id?: string; created?: number; sealed_result?: { ephemeral_public_key: string; ciphertext: string };\n usage?: ChatCompletionResponse[\"usage\"];\n };\n try {\n data = await this.request(\"POST\", \"/v1/chat/completions\", body);\n } catch (err) {\n if (err instanceof SGLAPIError && err.statusCode === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n throw err;\n }\n\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const parsed = JSON.parse(new TextDecoder().decode(plain)) as { content?: string; usage?: ChatCompletionResponse[\"usage\"] };\n\n return {\n id: data.id ?? \"\",\n object: \"chat.completion\",\n created: data.created ?? 0,\n model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content: parsed.content ?? \"\" }, finish_reason: \"stop\" }],\n usage: data.usage ?? parsed.usage,\n attestation: {\n nodeId: reservation.node_id,\n teeType: reservation.tee_type ?? null,\n verified: !!reservation.attestation_verified,\n },\n };\n }\n\n /**\n * Create embeddings via the grid's OpenAI-compatible `/v1/embeddings` endpoint.\n *\n * `input` is a string or array of strings; `dimensions` truncates Matryoshka models\n * (e.g. nomic 768→256); `input_type` ('query' | 'document') hints asymmetric\n * retrieval models. Billed on input tokens only — there is no generation. Requires\n * an `apiKey` (credits); the TS SDK does not sign x402 payments. Unlike chat, the\n * input is not client-sealed — the orchestrator seals it to the node in-TEE. The\n * returned `data` is ordered to match `input`.\n */\n async embed(request: EmbeddingRequest): Promise<EmbeddingResponse> {\n const body: Record<string, unknown> = { model: request.model, input: request.input };\n if (request.dimensions != null) body.dimensions = request.dimensions;\n if (request.input_type != null) body.input_type = request.input_type;\n if (request.tier != null) body.tier = request.tier;\n try {\n return (await this.request(\"POST\", \"/v1/embeddings\", body)) as EmbeddingResponse;\n } catch (err) {\n if (err instanceof SGLAPIError && err.statusCode === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n throw err;\n }\n }\n\n /**\n * Streaming end-to-end encrypted chat completion. Yields decoded text as it\n * arrives; each chunk is decrypted and its ordering + termination verified (a\n * truncated stream throws). Requires `apiKey` (credits). If the server isn't\n * streaming (toggle off), the whole reply is yielded as a single chunk.\n */\n async *chatCompletionStream(\n request: ChatCompletionRequest,\n ): AsyncGenerator<string, void, unknown> {\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const nonce = e2e.randomNonceB58();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n stream: true,\n nonce,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n stream: true,\n max_tokens: maxTokens,\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n const controller = new AbortController();\n const overall = setTimeout(() => controller.abort(), this.timeout);\n let resp: Response;\n try {\n resp = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(overall);\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (!resp.ok) {\n clearTimeout(overall);\n if (resp.status === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n let message = resp.statusText;\n try {\n const j = (await resp.json()) as { error?: unknown };\n if (typeof j.error === \"string\") message = j.error;\n else if (j.error && typeof j.error === \"object\" && \"message\" in j.error) message = String((j.error as { message: unknown }).message);\n } catch { /* ignore */ }\n throw new SGLAPIError(resp.status, message);\n }\n\n const ctype = resp.headers.get(\"content-type\") ?? \"\";\n if (!ctype.includes(\"text/event-stream\") || !resp.body) {\n clearTimeout(overall);\n const data = (await resp.json()) as { sealed_result?: { ephemeral_public_key: string; ciphertext: string } };\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const content = (JSON.parse(new TextDecoder().decode(plain)) as { content?: string }).content ?? \"\";\n if (content) yield content;\n return;\n }\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n const INACTIVITY_MS = 60_000;\n const readChunk = async (): Promise<ReadableStreamReadResult<Uint8Array>> => {\n let t: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n t = setTimeout(() => reject(new SGLConnectionError(\"stream timed out (no tokens)\")), INACTIVITY_MS);\n });\n try {\n return (await Promise.race([reader.read(), timeout])) as ReadableStreamReadResult<Uint8Array>;\n } finally {\n if (t) clearTimeout(t);\n }\n };\n\n let buf = \"\";\n let expectedSeq = 0;\n let outKey: Uint8Array | null = null;\n let streamEph: string | null = null;\n let sawFinal = false;\n try {\n for (;;) {\n if (sawFinal) break;\n const { value, done } = await readChunk();\n if (done) break;\n // Normalize CRLF so \\n\\n event framing works regardless of line endings.\n buf += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let idx: number;\n while ((idx = buf.indexOf(\"\\n\\n\")) !== -1) {\n const raw = buf.slice(0, idx);\n buf = buf.slice(idx + 2);\n if (raw.includes(\"event: error\")) throw new SGLAPIError(502, \"stream aborted by server\");\n const dataStr = raw.split(\"\\n\").filter((l) => l.startsWith(\"data:\")).map((l) => l.slice(5).trim()).join(\"\\n\");\n if (!dataStr || dataStr === \"[DONE]\") continue;\n // Fail closed: a malformed or non-chunk data event is a protocol error.\n let chunk: { seq?: number; final?: boolean; eph?: string; ct?: string };\n try {\n chunk = JSON.parse(dataStr);\n } catch {\n throw new SGLAPIError(502, \"malformed stream chunk\");\n }\n if (typeof chunk.seq !== \"number\" || !chunk.ct) {\n throw new SGLAPIError(502, \"invalid stream chunk (missing seq/ciphertext)\");\n }\n if (chunk.seq !== expectedSeq) throw new SGLAPIError(502, `stream out of order (expected ${expectedSeq}, got ${chunk.seq})`);\n if (chunk.seq === 0) {\n if (!chunk.eph) throw new SGLAPIError(502, \"stream chunk 0 missing ephemeral key\");\n streamEph = chunk.eph;\n outKey = e2e.streamOutKey(secret, streamEph);\n }\n const isFinal = chunk.final === true;\n const text = new TextDecoder().decode(\n e2e.openStreamChunk(outKey as Uint8Array, pubB58, streamEph as string, nonce, chunk.seq, isFinal, chunk.ct),\n );\n if (text) yield text;\n expectedSeq++;\n if (isFinal) { sawFinal = true; break; }\n }\n }\n } finally {\n clearTimeout(overall);\n try { await reader.cancel(); } catch { /* ignore */ }\n }\n if (!sawFinal) throw new SGLAPIError(502, \"stream ended before final chunk (truncated)\");\n }\n\n // -- Processor helpers ----------------------------------------------------\n\n private async requestWithWalletAuth<T>(\n method: string,\n path: string,\n wallet: WalletAuth,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = {\n ...this.headers,\n \"X-Auth-Address\": wallet.address,\n \"X-Auth-Chain\": wallet.chain ?? \"solana\",\n \"X-Auth-Signature\": wallet.signature,\n \"X-Auth-Timestamp\": wallet.timestamp,\n \"X-Auth-Nonce\": wallet.nonce,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n private async requestWithPayment<T>(\n method: string,\n path: string,\n body?: unknown,\n paymentHeader?: string,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = { ...this.headers };\n if (paymentHeader) {\n reqHeaders[\"X-Payment\"] = paymentHeader;\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (response.status === 402) {\n const requirements = (await response.json()) as Record<string, unknown>;\n throw new SGLAPIError(402, \"Payment required\", requirements);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n } catch {\n /* body not JSON */\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n return (await response.json()) as T;\n }\n\n // -- Processors -----------------------------------------------------------\n\n async deployProcessor(\n wallet: WalletAuth,\n options: DeployProcessorOptions,\n ): Promise<ProcessorDeployResult> {\n return this.requestWithWalletAuth<ProcessorDeployResult>(\n \"POST\",\n \"/grid/processors\",\n wallet,\n options,\n );\n }\n\n async invokeProcessor(\n processorName: string,\n input: Record<string, unknown>,\n options?: { paymentHeader?: string; paymentToken?: \"USDC\" | \"SGL\" },\n ): Promise<ProcessorInvokeResult> {\n const body: Record<string, unknown> = { input };\n if (options?.paymentToken) body.payment_token = options.paymentToken;\n return this.requestWithPayment<ProcessorInvokeResult>(\n \"POST\",\n `/grid/processors/${encodeURIComponent(processorName)}/invoke`,\n body,\n options?.paymentHeader,\n );\n }\n\n async listProcessors(options?: {\n owner?: string;\n page?: number;\n limit?: number;\n }): Promise<ProcessorListResponse> {\n const params = new URLSearchParams();\n if (options?.owner) params.set(\"owner\", options.owner);\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.request<ProcessorListResponse>(\n \"GET\",\n `/grid/processors${qs ? `?${qs}` : \"\"}`,\n );\n }\n\n async getProcessor(processorId: string): Promise<ProcessorInfo> {\n return this.request<ProcessorInfo>(\"GET\", `/grid/processors/${processorId}`);\n }\n\n async deleteProcessor(\n processorId: string,\n wallet: WalletAuth,\n ): Promise<{ deleted: boolean; id: string }> {\n return this.requestWithWalletAuth<{ deleted: boolean; id: string }>(\n \"DELETE\",\n `/grid/processors/${processorId}`,\n wallet,\n );\n }\n\n async getProcessorLogs(\n processorId: string,\n wallet: WalletAuth,\n options?: { page?: number; limit?: number },\n ): Promise<ProcessorLogsResponse> {\n const params = new URLSearchParams();\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.requestWithWalletAuth<ProcessorLogsResponse>(\n \"GET\",\n `/grid/processors/${processorId}/logs${qs ? `?${qs}` : \"\"}`,\n wallet,\n );\n }\n}\n"],"mappings":"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","names":["bs58"]}
|
package/dist/index.mjs
CHANGED
|
@@ -284,6 +284,30 @@ var GridClient = class {
|
|
|
284
284
|
}
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Create embeddings via the grid's OpenAI-compatible `/v1/embeddings` endpoint.
|
|
289
|
+
*
|
|
290
|
+
* `input` is a string or array of strings; `dimensions` truncates Matryoshka models
|
|
291
|
+
* (e.g. nomic 768→256); `input_type` ('query' | 'document') hints asymmetric
|
|
292
|
+
* retrieval models. Billed on input tokens only — there is no generation. Requires
|
|
293
|
+
* an `apiKey` (credits); the TS SDK does not sign x402 payments. Unlike chat, the
|
|
294
|
+
* input is not client-sealed — the orchestrator seals it to the node in-TEE. The
|
|
295
|
+
* returned `data` is ordered to match `input`.
|
|
296
|
+
*/
|
|
297
|
+
async embed(request) {
|
|
298
|
+
const body = { model: request.model, input: request.input };
|
|
299
|
+
if (request.dimensions != null) body.dimensions = request.dimensions;
|
|
300
|
+
if (request.input_type != null) body.input_type = request.input_type;
|
|
301
|
+
if (request.tier != null) body.tier = request.tier;
|
|
302
|
+
try {
|
|
303
|
+
return await this.request("POST", "/v1/embeddings", body);
|
|
304
|
+
} catch (err) {
|
|
305
|
+
if (err instanceof SGLAPIError && err.statusCode === 402) {
|
|
306
|
+
throw new SGLAPIError(402, "Payment required \u2014 pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.");
|
|
307
|
+
}
|
|
308
|
+
throw err;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
287
311
|
/**
|
|
288
312
|
* Streaming end-to-end encrypted chat completion. Yields decoded text as it
|
|
289
313
|
* arrives; each chunk is decrypted and its ordering + termination verified (a
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/e2e.ts","../src/client.ts"],"sourcesContent":["export class SGLError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SGLError\";\n }\n}\n\nexport class SGLAPIError extends SGLError {\n readonly statusCode: number;\n readonly body?: Record<string, unknown>;\n\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(`HTTP ${statusCode}: ${message}`);\n this.name = \"SGLAPIError\";\n this.statusCode = statusCode;\n this.body = body;\n }\n}\n\nexport class SGLAuthError extends SGLAPIError {\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(statusCode, message, body);\n this.name = \"SGLAuthError\";\n }\n}\n\nexport class SGLNotFoundError extends SGLAPIError {\n constructor(message: string, body?: Record<string, unknown>) {\n super(404, message, body);\n this.name = \"SGLNotFoundError\";\n }\n}\n\nexport class SGLConnectionError extends SGLError {\n constructor(message: string) {\n super(message);\n this.name = \"SGLConnectionError\";\n }\n}\n","/**\n * End-to-end encryption for the SGL grid (client side).\n *\n * Must match sgl-node/src/encryption.rs, the orchestrator, and the browser/Python\n * clients byte-for-byte: X25519 ECDH -> HKDF-SHA256 -> XChaCha20-Poly1305 (24-byte\n * nonce), AAD-bound. Sealed blob layout: nonce(24) || ciphertext, base58.\n *\n * The orchestrator only ever relays ciphertext — it never sees the prompt or reply.\n */\n\nimport { x25519 } from \"@noble/curves/ed25519\";\nimport { xchacha20poly1305 } from \"@noble/ciphers/chacha\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { hkdf } from \"@noble/hashes/hkdf\";\nimport bs58 from \"bs58\";\n\nexport const ALGO_V2 = \"x25519-xchacha20poly1305-hkdf-v2\";\nexport const ALGO_V2_STREAM = \"x25519-xchacha20poly1305-hkdf-v2-stream\";\n\nconst HKDF_SALT = new TextEncoder().encode(\"sgl-e2e-v2-salt\");\nconst HKDF_INFO_INPUT = new TextEncoder().encode(\"sgl-e2e-v2-input\");\nconst HKDF_INFO_OUTPUT = new TextEncoder().encode(\"sgl-e2e-v2-output\");\n\nfunction v2Key(shared: Uint8Array, info: Uint8Array): Uint8Array {\n return hkdf(sha256, shared, HKDF_SALT, info, 32);\n}\nfunction aadInput(nodeB58: string, ephB58: string, respB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/input|node=${nodeB58}|eph=${ephB58}|resp=${respB58}`);\n}\nfunction aadOutput(respB58: string, ephB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/output|resp=${respB58}|eph=${ephB58}`);\n}\nfunction aadStream(respB58: string, ephB58: string, nonceB58: string, seq: number, isFinal: boolean): Uint8Array {\n return new TextEncoder().encode(\n `sgl-aad/v2/stream|resp=${respB58}|eph=${ephB58}|nonce=${nonceB58}|seq=${seq}|final=${isFinal ? 1 : 0}`,\n );\n}\n\nfunction b58enc(u: Uint8Array): string {\n return bs58.encode(u);\n}\nfunction b58dec(s: string): Uint8Array {\n return bs58.decode(s);\n}\nfunction randomBytes(n: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(n));\n}\n\nexport interface ResponseKeypair {\n secret: Uint8Array;\n pubB58: string;\n}\n\n/** The caller's response keypair — the node seals its reply to this. */\nexport function newResponseKeypair(): ResponseKeypair {\n const secret = x25519.utils.randomPrivateKey();\n return { secret, pubB58: b58enc(x25519.getPublicKey(secret)) };\n}\n\n/** A per-request nonce bound into every stream chunk's AAD. */\nexport function randomNonceB58(): string {\n return b58enc(randomBytes(16));\n}\n\n/** Seal the prompt to the node's X25519 key. */\nexport function sealInputV2(\n nodePubB58: string,\n respPubB58: string,\n plaintext: Uint8Array,\n): { ciphertext: string; ephemeralPub: string } {\n const nodePub = b58dec(nodePubB58);\n const ephSecret = x25519.utils.randomPrivateKey();\n const ephPub = x25519.getPublicKey(ephSecret);\n const ephB58 = b58enc(ephPub);\n const shared = x25519.getSharedSecret(ephSecret, nodePub);\n const key = v2Key(shared, HKDF_INFO_INPUT);\n const aad = aadInput(nodePubB58, ephB58, respPubB58);\n const nonce = randomBytes(24);\n const ct = xchacha20poly1305(key, nonce, aad).encrypt(plaintext);\n const out = new Uint8Array(24 + ct.length);\n out.set(nonce, 0);\n out.set(ct, 24);\n return { ciphertext: b58enc(out), ephemeralPub: ephB58 };\n}\n\n/** Open the node's (non-stream) reply sealed to our response key. */\nexport function openOutputV2(\n respSecret: Uint8Array,\n respPubB58: string,\n nodeEphB58: string,\n ciphertextB58: string,\n): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeEphB58));\n const key = v2Key(shared, HKDF_INFO_OUTPUT);\n const aad = aadOutput(respPubB58, nodeEphB58);\n const blob = b58dec(ciphertextB58);\n return xchacha20poly1305(key, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n\n/** Derive the stream output key once from the node's stream ephemeral (chunk 0). */\nexport function streamOutKey(respSecret: Uint8Array, nodeStreamEphB58: string): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeStreamEphB58));\n return v2Key(shared, HKDF_INFO_OUTPUT);\n}\n\n/** Open one stream chunk with the precomputed key + nonce/seq/final-bound AAD. */\nexport function openStreamChunk(\n outKey: Uint8Array,\n respPubB58: string,\n streamEphB58: string,\n reqNonceB58: string,\n seq: number,\n isFinal: boolean,\n ctB58: string,\n): Uint8Array {\n const aad = aadStream(respPubB58, streamEphB58, reqNonceB58, seq, isFinal);\n const blob = b58dec(ctB58);\n return xchacha20poly1305(outKey, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n","import { SGLAPIError, SGLAuthError, SGLConnectionError, SGLNotFoundError } from \"./errors.js\";\nimport * as e2e from \"./e2e.js\";\nimport type {\n AttestationProof,\n CapacityResponse,\n ChatCompletionRequest,\n ChatCompletionResponse,\n DeployProcessorOptions,\n GridClientOptions,\n JobResponse,\n JobResult,\n ModelInfo,\n PricingInfo,\n ProcessorDeployResult,\n ProcessorInfo,\n ProcessorInvokeResult,\n ProcessorListResponse,\n ProcessorLogEntry,\n ProcessorLogsResponse,\n ProviderInfo,\n ProvidersResponse,\n ReserveResponse,\n WalletAuth,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://grid.x402compute.cc\";\n\nconst DEFAULT_TIMEOUT = 60_000;\n\nexport class GridClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly timeout: number;\n\n constructor(options: GridClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.headers = { Accept: \"application/json\", \"Content-Type\": \"application/json\" };\n if (options.apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${options.apiKey}`;\n // Grid credit billing reads X-API-Key; send both so reserve + chat resolve\n // the paying wallet (credits mode) rather than falling back to anonymous x402.\n this.headers[\"X-API-Key\"] = options.apiKey;\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n // -- Public endpoints (no auth) ------------------------------------------\n\n async capacity(): Promise<CapacityResponse> {\n return this.request<CapacityResponse>(\"GET\", \"/grid/capacity\");\n }\n\n async models(): Promise<ModelInfo[]> {\n const data = await this.request<{ models: ModelInfo[] }>(\"GET\", \"/grid/models\");\n return data.models ?? [];\n }\n\n async pricing(): Promise<PricingInfo[]> {\n const data = await this.request<{ pricing: PricingInfo[] }>(\"GET\", \"/grid/pricing\");\n return data.pricing ?? [];\n }\n\n /**\n * List the nodes serving a model with each node's effective per-token price\n * (operator's custom price if set, else the platform reference), cheapest\n * first. Pass a chosen `node_id` as `node` on `chatCompletions` to pin it,\n * or omit to let the grid route. Optional `cluster` filter (slug or id).\n */\n async providers(\n model: string,\n options?: { cluster?: string },\n ): Promise<ProviderInfo[]> {\n const params = new URLSearchParams({ model });\n if (options?.cluster) params.set(\"cluster\", options.cluster);\n const data = await this.request<ProvidersResponse>(\n \"GET\",\n `/v1/providers?${params.toString()}`,\n );\n return data.providers ?? [];\n }\n\n // -- Authenticated endpoints ---------------------------------------------\n\n async submitJob(\n model: string,\n input: Record<string, unknown>,\n options?: { submitterWallet?: string; submitterChain?: string },\n ): Promise<JobResponse> {\n const body: Record<string, unknown> = { model, input };\n if (options?.submitterWallet) body.submitter_wallet = options.submitterWallet;\n if (options?.submitterChain) body.submitter_chain = options.submitterChain;\n return this.request<JobResponse>(\"POST\", \"/grid/jobs\", body);\n }\n\n async getJob(jobId: string): Promise<JobResult> {\n return this.request<JobResult>(\"GET\", `/grid/jobs/${jobId}`);\n }\n\n async getAttestation(jobId: string): Promise<AttestationProof> {\n return this.request<AttestationProof>(\"GET\", `/grid/jobs/${jobId}/attestation`);\n }\n\n // -- OpenAI-compatible (end-to-end encrypted) ----------------------------\n\n /** Reserve a node + learn its X25519 key so we can seal the prompt to it.\n * Forwards an optional pinned `node` (see `providers()`), `cluster` filter,\n * and `pay_in_coin` so the orchestrator reserves + quotes accordingly. */\n private async reserve(req: {\n model: string;\n node?: string;\n cluster?: string;\n pay_in_coin?: boolean;\n max_price?: number;\n }): Promise<ReserveResponse> {\n const body: Record<string, unknown> = { model: req.model };\n if (req.node) body.node = req.node;\n if (req.cluster) body.cluster = req.cluster;\n if (req.pay_in_coin) body.pay_in_coin = req.pay_in_coin;\n if (req.max_price != null) body.max_price = req.max_price;\n const res = await this.request<ReserveResponse>(\"POST\", \"/v1/reserve\", body);\n if (!res.node_x25519_pubkey) {\n throw new SGLAPIError(503, \"Reserved node does not support E2E encryption\");\n }\n return res;\n }\n\n /**\n * End-to-end encrypted chat completion. The prompt is sealed in this client to\n * the serving node's key and only decrypts inside its TEE — the orchestrator\n * only relays ciphertext. Requires an `apiKey` (credits); without one the grid\n * replies 402 (the SDK does not sign x402 payments — use the wallet/browser flow).\n */\n async chatCompletions(\n request: ChatCompletionRequest,\n ): Promise<ChatCompletionResponse> {\n if (request.stream) {\n // Collapse the stream into a single response for the non-streaming API.\n let content = \"\";\n for await (const delta of this.chatCompletionStream(request)) content += delta;\n return {\n id: \"\", object: \"chat.completion\", created: 0, model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content }, finish_reason: \"stop\" }],\n };\n }\n\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n max_tokens: maxTokens, // cleartext, only used to quote the x402 price\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n let data: {\n id?: string; created?: number; sealed_result?: { ephemeral_public_key: string; ciphertext: string };\n usage?: ChatCompletionResponse[\"usage\"];\n };\n try {\n data = await this.request(\"POST\", \"/v1/chat/completions\", body);\n } catch (err) {\n if (err instanceof SGLAPIError && err.statusCode === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n throw err;\n }\n\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const parsed = JSON.parse(new TextDecoder().decode(plain)) as { content?: string; usage?: ChatCompletionResponse[\"usage\"] };\n\n return {\n id: data.id ?? \"\",\n object: \"chat.completion\",\n created: data.created ?? 0,\n model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content: parsed.content ?? \"\" }, finish_reason: \"stop\" }],\n usage: data.usage ?? parsed.usage,\n attestation: {\n nodeId: reservation.node_id,\n teeType: reservation.tee_type ?? null,\n verified: !!reservation.attestation_verified,\n },\n };\n }\n\n /**\n * Streaming end-to-end encrypted chat completion. Yields decoded text as it\n * arrives; each chunk is decrypted and its ordering + termination verified (a\n * truncated stream throws). Requires `apiKey` (credits). If the server isn't\n * streaming (toggle off), the whole reply is yielded as a single chunk.\n */\n async *chatCompletionStream(\n request: ChatCompletionRequest,\n ): AsyncGenerator<string, void, unknown> {\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const nonce = e2e.randomNonceB58();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n stream: true,\n nonce,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n stream: true,\n max_tokens: maxTokens,\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n const controller = new AbortController();\n const overall = setTimeout(() => controller.abort(), this.timeout);\n let resp: Response;\n try {\n resp = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(overall);\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (!resp.ok) {\n clearTimeout(overall);\n if (resp.status === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n let message = resp.statusText;\n try {\n const j = (await resp.json()) as { error?: unknown };\n if (typeof j.error === \"string\") message = j.error;\n else if (j.error && typeof j.error === \"object\" && \"message\" in j.error) message = String((j.error as { message: unknown }).message);\n } catch { /* ignore */ }\n throw new SGLAPIError(resp.status, message);\n }\n\n const ctype = resp.headers.get(\"content-type\") ?? \"\";\n if (!ctype.includes(\"text/event-stream\") || !resp.body) {\n clearTimeout(overall);\n const data = (await resp.json()) as { sealed_result?: { ephemeral_public_key: string; ciphertext: string } };\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const content = (JSON.parse(new TextDecoder().decode(plain)) as { content?: string }).content ?? \"\";\n if (content) yield content;\n return;\n }\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n const INACTIVITY_MS = 60_000;\n const readChunk = async (): Promise<ReadableStreamReadResult<Uint8Array>> => {\n let t: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n t = setTimeout(() => reject(new SGLConnectionError(\"stream timed out (no tokens)\")), INACTIVITY_MS);\n });\n try {\n return (await Promise.race([reader.read(), timeout])) as ReadableStreamReadResult<Uint8Array>;\n } finally {\n if (t) clearTimeout(t);\n }\n };\n\n let buf = \"\";\n let expectedSeq = 0;\n let outKey: Uint8Array | null = null;\n let streamEph: string | null = null;\n let sawFinal = false;\n try {\n for (;;) {\n if (sawFinal) break;\n const { value, done } = await readChunk();\n if (done) break;\n // Normalize CRLF so \\n\\n event framing works regardless of line endings.\n buf += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let idx: number;\n while ((idx = buf.indexOf(\"\\n\\n\")) !== -1) {\n const raw = buf.slice(0, idx);\n buf = buf.slice(idx + 2);\n if (raw.includes(\"event: error\")) throw new SGLAPIError(502, \"stream aborted by server\");\n const dataStr = raw.split(\"\\n\").filter((l) => l.startsWith(\"data:\")).map((l) => l.slice(5).trim()).join(\"\\n\");\n if (!dataStr || dataStr === \"[DONE]\") continue;\n // Fail closed: a malformed or non-chunk data event is a protocol error.\n let chunk: { seq?: number; final?: boolean; eph?: string; ct?: string };\n try {\n chunk = JSON.parse(dataStr);\n } catch {\n throw new SGLAPIError(502, \"malformed stream chunk\");\n }\n if (typeof chunk.seq !== \"number\" || !chunk.ct) {\n throw new SGLAPIError(502, \"invalid stream chunk (missing seq/ciphertext)\");\n }\n if (chunk.seq !== expectedSeq) throw new SGLAPIError(502, `stream out of order (expected ${expectedSeq}, got ${chunk.seq})`);\n if (chunk.seq === 0) {\n if (!chunk.eph) throw new SGLAPIError(502, \"stream chunk 0 missing ephemeral key\");\n streamEph = chunk.eph;\n outKey = e2e.streamOutKey(secret, streamEph);\n }\n const isFinal = chunk.final === true;\n const text = new TextDecoder().decode(\n e2e.openStreamChunk(outKey as Uint8Array, pubB58, streamEph as string, nonce, chunk.seq, isFinal, chunk.ct),\n );\n if (text) yield text;\n expectedSeq++;\n if (isFinal) { sawFinal = true; break; }\n }\n }\n } finally {\n clearTimeout(overall);\n try { await reader.cancel(); } catch { /* ignore */ }\n }\n if (!sawFinal) throw new SGLAPIError(502, \"stream ended before final chunk (truncated)\");\n }\n\n // -- Processor helpers ----------------------------------------------------\n\n private async requestWithWalletAuth<T>(\n method: string,\n path: string,\n wallet: WalletAuth,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = {\n ...this.headers,\n \"X-Auth-Address\": wallet.address,\n \"X-Auth-Chain\": wallet.chain ?? \"solana\",\n \"X-Auth-Signature\": wallet.signature,\n \"X-Auth-Timestamp\": wallet.timestamp,\n \"X-Auth-Nonce\": wallet.nonce,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n private async requestWithPayment<T>(\n method: string,\n path: string,\n body?: unknown,\n paymentHeader?: string,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = { ...this.headers };\n if (paymentHeader) {\n reqHeaders[\"X-Payment\"] = paymentHeader;\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (response.status === 402) {\n const requirements = (await response.json()) as Record<string, unknown>;\n throw new SGLAPIError(402, \"Payment required\", requirements);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n } catch {\n /* body not JSON */\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n return (await response.json()) as T;\n }\n\n // -- Processors -----------------------------------------------------------\n\n async deployProcessor(\n wallet: WalletAuth,\n options: DeployProcessorOptions,\n ): Promise<ProcessorDeployResult> {\n return this.requestWithWalletAuth<ProcessorDeployResult>(\n \"POST\",\n \"/grid/processors\",\n wallet,\n options,\n );\n }\n\n async invokeProcessor(\n processorName: string,\n input: Record<string, unknown>,\n options?: { paymentHeader?: string; paymentToken?: \"USDC\" | \"SGL\" },\n ): Promise<ProcessorInvokeResult> {\n const body: Record<string, unknown> = { input };\n if (options?.paymentToken) body.payment_token = options.paymentToken;\n return this.requestWithPayment<ProcessorInvokeResult>(\n \"POST\",\n `/grid/processors/${encodeURIComponent(processorName)}/invoke`,\n body,\n options?.paymentHeader,\n );\n }\n\n async listProcessors(options?: {\n owner?: string;\n page?: number;\n limit?: number;\n }): Promise<ProcessorListResponse> {\n const params = new URLSearchParams();\n if (options?.owner) params.set(\"owner\", options.owner);\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.request<ProcessorListResponse>(\n \"GET\",\n `/grid/processors${qs ? `?${qs}` : \"\"}`,\n );\n }\n\n async getProcessor(processorId: string): Promise<ProcessorInfo> {\n return this.request<ProcessorInfo>(\"GET\", `/grid/processors/${processorId}`);\n }\n\n async deleteProcessor(\n processorId: string,\n wallet: WalletAuth,\n ): Promise<{ deleted: boolean; id: string }> {\n return this.requestWithWalletAuth<{ deleted: boolean; id: string }>(\n \"DELETE\",\n `/grid/processors/${processorId}`,\n wallet,\n );\n }\n\n async getProcessorLogs(\n processorId: string,\n wallet: WalletAuth,\n options?: { page?: number; limit?: number },\n ): Promise<ProcessorLogsResponse> {\n const params = new URLSearchParams();\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.requestWithWalletAuth<ProcessorLogsResponse>(\n \"GET\",\n `/grid/processors/${processorId}/logs${qs ? `?${qs}` : \"\"}`,\n wallet,\n );\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/e2e.ts","../src/client.ts"],"sourcesContent":["export class SGLError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SGLError\";\n }\n}\n\nexport class SGLAPIError extends SGLError {\n readonly statusCode: number;\n readonly body?: Record<string, unknown>;\n\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(`HTTP ${statusCode}: ${message}`);\n this.name = \"SGLAPIError\";\n this.statusCode = statusCode;\n this.body = body;\n }\n}\n\nexport class SGLAuthError extends SGLAPIError {\n constructor(\n statusCode: number,\n message: string,\n body?: Record<string, unknown>,\n ) {\n super(statusCode, message, body);\n this.name = \"SGLAuthError\";\n }\n}\n\nexport class SGLNotFoundError extends SGLAPIError {\n constructor(message: string, body?: Record<string, unknown>) {\n super(404, message, body);\n this.name = \"SGLNotFoundError\";\n }\n}\n\nexport class SGLConnectionError extends SGLError {\n constructor(message: string) {\n super(message);\n this.name = \"SGLConnectionError\";\n }\n}\n","/**\n * End-to-end encryption for the SGL grid (client side).\n *\n * Must match sgl-node/src/encryption.rs, the orchestrator, and the browser/Python\n * clients byte-for-byte: X25519 ECDH -> HKDF-SHA256 -> XChaCha20-Poly1305 (24-byte\n * nonce), AAD-bound. Sealed blob layout: nonce(24) || ciphertext, base58.\n *\n * The orchestrator only ever relays ciphertext — it never sees the prompt or reply.\n */\n\nimport { x25519 } from \"@noble/curves/ed25519\";\nimport { xchacha20poly1305 } from \"@noble/ciphers/chacha\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { hkdf } from \"@noble/hashes/hkdf\";\nimport bs58 from \"bs58\";\n\nexport const ALGO_V2 = \"x25519-xchacha20poly1305-hkdf-v2\";\nexport const ALGO_V2_STREAM = \"x25519-xchacha20poly1305-hkdf-v2-stream\";\n\nconst HKDF_SALT = new TextEncoder().encode(\"sgl-e2e-v2-salt\");\nconst HKDF_INFO_INPUT = new TextEncoder().encode(\"sgl-e2e-v2-input\");\nconst HKDF_INFO_OUTPUT = new TextEncoder().encode(\"sgl-e2e-v2-output\");\n\nfunction v2Key(shared: Uint8Array, info: Uint8Array): Uint8Array {\n return hkdf(sha256, shared, HKDF_SALT, info, 32);\n}\nfunction aadInput(nodeB58: string, ephB58: string, respB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/input|node=${nodeB58}|eph=${ephB58}|resp=${respB58}`);\n}\nfunction aadOutput(respB58: string, ephB58: string): Uint8Array {\n return new TextEncoder().encode(`sgl-aad/v2/output|resp=${respB58}|eph=${ephB58}`);\n}\nfunction aadStream(respB58: string, ephB58: string, nonceB58: string, seq: number, isFinal: boolean): Uint8Array {\n return new TextEncoder().encode(\n `sgl-aad/v2/stream|resp=${respB58}|eph=${ephB58}|nonce=${nonceB58}|seq=${seq}|final=${isFinal ? 1 : 0}`,\n );\n}\n\nfunction b58enc(u: Uint8Array): string {\n return bs58.encode(u);\n}\nfunction b58dec(s: string): Uint8Array {\n return bs58.decode(s);\n}\nfunction randomBytes(n: number): Uint8Array {\n return crypto.getRandomValues(new Uint8Array(n));\n}\n\nexport interface ResponseKeypair {\n secret: Uint8Array;\n pubB58: string;\n}\n\n/** The caller's response keypair — the node seals its reply to this. */\nexport function newResponseKeypair(): ResponseKeypair {\n const secret = x25519.utils.randomPrivateKey();\n return { secret, pubB58: b58enc(x25519.getPublicKey(secret)) };\n}\n\n/** A per-request nonce bound into every stream chunk's AAD. */\nexport function randomNonceB58(): string {\n return b58enc(randomBytes(16));\n}\n\n/** Seal the prompt to the node's X25519 key. */\nexport function sealInputV2(\n nodePubB58: string,\n respPubB58: string,\n plaintext: Uint8Array,\n): { ciphertext: string; ephemeralPub: string } {\n const nodePub = b58dec(nodePubB58);\n const ephSecret = x25519.utils.randomPrivateKey();\n const ephPub = x25519.getPublicKey(ephSecret);\n const ephB58 = b58enc(ephPub);\n const shared = x25519.getSharedSecret(ephSecret, nodePub);\n const key = v2Key(shared, HKDF_INFO_INPUT);\n const aad = aadInput(nodePubB58, ephB58, respPubB58);\n const nonce = randomBytes(24);\n const ct = xchacha20poly1305(key, nonce, aad).encrypt(plaintext);\n const out = new Uint8Array(24 + ct.length);\n out.set(nonce, 0);\n out.set(ct, 24);\n return { ciphertext: b58enc(out), ephemeralPub: ephB58 };\n}\n\n/** Open the node's (non-stream) reply sealed to our response key. */\nexport function openOutputV2(\n respSecret: Uint8Array,\n respPubB58: string,\n nodeEphB58: string,\n ciphertextB58: string,\n): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeEphB58));\n const key = v2Key(shared, HKDF_INFO_OUTPUT);\n const aad = aadOutput(respPubB58, nodeEphB58);\n const blob = b58dec(ciphertextB58);\n return xchacha20poly1305(key, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n\n/** Derive the stream output key once from the node's stream ephemeral (chunk 0). */\nexport function streamOutKey(respSecret: Uint8Array, nodeStreamEphB58: string): Uint8Array {\n const shared = x25519.getSharedSecret(respSecret, b58dec(nodeStreamEphB58));\n return v2Key(shared, HKDF_INFO_OUTPUT);\n}\n\n/** Open one stream chunk with the precomputed key + nonce/seq/final-bound AAD. */\nexport function openStreamChunk(\n outKey: Uint8Array,\n respPubB58: string,\n streamEphB58: string,\n reqNonceB58: string,\n seq: number,\n isFinal: boolean,\n ctB58: string,\n): Uint8Array {\n const aad = aadStream(respPubB58, streamEphB58, reqNonceB58, seq, isFinal);\n const blob = b58dec(ctB58);\n return xchacha20poly1305(outKey, blob.slice(0, 24), aad).decrypt(blob.slice(24));\n}\n","import { SGLAPIError, SGLAuthError, SGLConnectionError, SGLNotFoundError } from \"./errors.js\";\nimport * as e2e from \"./e2e.js\";\nimport type {\n AttestationProof,\n CapacityResponse,\n ChatCompletionRequest,\n ChatCompletionResponse,\n EmbeddingRequest,\n EmbeddingResponse,\n DeployProcessorOptions,\n GridClientOptions,\n JobResponse,\n JobResult,\n ModelInfo,\n PricingInfo,\n ProcessorDeployResult,\n ProcessorInfo,\n ProcessorInvokeResult,\n ProcessorListResponse,\n ProcessorLogEntry,\n ProcessorLogsResponse,\n ProviderInfo,\n ProvidersResponse,\n ReserveResponse,\n WalletAuth,\n} from \"./types.js\";\n\nexport const DEFAULT_BASE_URL = \"https://grid.x402compute.cc\";\n\nconst DEFAULT_TIMEOUT = 60_000;\n\nexport class GridClient {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly timeout: number;\n\n constructor(options: GridClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.headers = { Accept: \"application/json\", \"Content-Type\": \"application/json\" };\n if (options.apiKey) {\n this.headers[\"Authorization\"] = `Bearer ${options.apiKey}`;\n // Grid credit billing reads X-API-Key; send both so reserve + chat resolve\n // the paying wallet (credits mode) rather than falling back to anonymous x402.\n this.headers[\"X-API-Key\"] = options.apiKey;\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n // -- Public endpoints (no auth) ------------------------------------------\n\n async capacity(): Promise<CapacityResponse> {\n return this.request<CapacityResponse>(\"GET\", \"/grid/capacity\");\n }\n\n async models(): Promise<ModelInfo[]> {\n const data = await this.request<{ models: ModelInfo[] }>(\"GET\", \"/grid/models\");\n return data.models ?? [];\n }\n\n async pricing(): Promise<PricingInfo[]> {\n const data = await this.request<{ pricing: PricingInfo[] }>(\"GET\", \"/grid/pricing\");\n return data.pricing ?? [];\n }\n\n /**\n * List the nodes serving a model with each node's effective per-token price\n * (operator's custom price if set, else the platform reference), cheapest\n * first. Pass a chosen `node_id` as `node` on `chatCompletions` to pin it,\n * or omit to let the grid route. Optional `cluster` filter (slug or id).\n */\n async providers(\n model: string,\n options?: { cluster?: string },\n ): Promise<ProviderInfo[]> {\n const params = new URLSearchParams({ model });\n if (options?.cluster) params.set(\"cluster\", options.cluster);\n const data = await this.request<ProvidersResponse>(\n \"GET\",\n `/v1/providers?${params.toString()}`,\n );\n return data.providers ?? [];\n }\n\n // -- Authenticated endpoints ---------------------------------------------\n\n async submitJob(\n model: string,\n input: Record<string, unknown>,\n options?: { submitterWallet?: string; submitterChain?: string },\n ): Promise<JobResponse> {\n const body: Record<string, unknown> = { model, input };\n if (options?.submitterWallet) body.submitter_wallet = options.submitterWallet;\n if (options?.submitterChain) body.submitter_chain = options.submitterChain;\n return this.request<JobResponse>(\"POST\", \"/grid/jobs\", body);\n }\n\n async getJob(jobId: string): Promise<JobResult> {\n return this.request<JobResult>(\"GET\", `/grid/jobs/${jobId}`);\n }\n\n async getAttestation(jobId: string): Promise<AttestationProof> {\n return this.request<AttestationProof>(\"GET\", `/grid/jobs/${jobId}/attestation`);\n }\n\n // -- OpenAI-compatible (end-to-end encrypted) ----------------------------\n\n /** Reserve a node + learn its X25519 key so we can seal the prompt to it.\n * Forwards an optional pinned `node` (see `providers()`), `cluster` filter,\n * and `pay_in_coin` so the orchestrator reserves + quotes accordingly. */\n private async reserve(req: {\n model: string;\n node?: string;\n cluster?: string;\n pay_in_coin?: boolean;\n max_price?: number;\n }): Promise<ReserveResponse> {\n const body: Record<string, unknown> = { model: req.model };\n if (req.node) body.node = req.node;\n if (req.cluster) body.cluster = req.cluster;\n if (req.pay_in_coin) body.pay_in_coin = req.pay_in_coin;\n if (req.max_price != null) body.max_price = req.max_price;\n const res = await this.request<ReserveResponse>(\"POST\", \"/v1/reserve\", body);\n if (!res.node_x25519_pubkey) {\n throw new SGLAPIError(503, \"Reserved node does not support E2E encryption\");\n }\n return res;\n }\n\n /**\n * End-to-end encrypted chat completion. The prompt is sealed in this client to\n * the serving node's key and only decrypts inside its TEE — the orchestrator\n * only relays ciphertext. Requires an `apiKey` (credits); without one the grid\n * replies 402 (the SDK does not sign x402 payments — use the wallet/browser flow).\n */\n async chatCompletions(\n request: ChatCompletionRequest,\n ): Promise<ChatCompletionResponse> {\n if (request.stream) {\n // Collapse the stream into a single response for the non-streaming API.\n let content = \"\";\n for await (const delta of this.chatCompletionStream(request)) content += delta;\n return {\n id: \"\", object: \"chat.completion\", created: 0, model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content }, finish_reason: \"stop\" }],\n };\n }\n\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n max_tokens: maxTokens, // cleartext, only used to quote the x402 price\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n let data: {\n id?: string; created?: number; sealed_result?: { ephemeral_public_key: string; ciphertext: string };\n usage?: ChatCompletionResponse[\"usage\"];\n };\n try {\n data = await this.request(\"POST\", \"/v1/chat/completions\", body);\n } catch (err) {\n if (err instanceof SGLAPIError && err.statusCode === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n throw err;\n }\n\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const parsed = JSON.parse(new TextDecoder().decode(plain)) as { content?: string; usage?: ChatCompletionResponse[\"usage\"] };\n\n return {\n id: data.id ?? \"\",\n object: \"chat.completion\",\n created: data.created ?? 0,\n model: request.model,\n choices: [{ index: 0, message: { role: \"assistant\", content: parsed.content ?? \"\" }, finish_reason: \"stop\" }],\n usage: data.usage ?? parsed.usage,\n attestation: {\n nodeId: reservation.node_id,\n teeType: reservation.tee_type ?? null,\n verified: !!reservation.attestation_verified,\n },\n };\n }\n\n /**\n * Create embeddings via the grid's OpenAI-compatible `/v1/embeddings` endpoint.\n *\n * `input` is a string or array of strings; `dimensions` truncates Matryoshka models\n * (e.g. nomic 768→256); `input_type` ('query' | 'document') hints asymmetric\n * retrieval models. Billed on input tokens only — there is no generation. Requires\n * an `apiKey` (credits); the TS SDK does not sign x402 payments. Unlike chat, the\n * input is not client-sealed — the orchestrator seals it to the node in-TEE. The\n * returned `data` is ordered to match `input`.\n */\n async embed(request: EmbeddingRequest): Promise<EmbeddingResponse> {\n const body: Record<string, unknown> = { model: request.model, input: request.input };\n if (request.dimensions != null) body.dimensions = request.dimensions;\n if (request.input_type != null) body.input_type = request.input_type;\n if (request.tier != null) body.tier = request.tier;\n try {\n return (await this.request(\"POST\", \"/v1/embeddings\", body)) as EmbeddingResponse;\n } catch (err) {\n if (err instanceof SGLAPIError && err.statusCode === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n throw err;\n }\n }\n\n /**\n * Streaming end-to-end encrypted chat completion. Yields decoded text as it\n * arrives; each chunk is decrypted and its ordering + termination verified (a\n * truncated stream throws). Requires `apiKey` (credits). If the server isn't\n * streaming (toggle off), the whole reply is yielded as a single chunk.\n */\n async *chatCompletionStream(\n request: ChatCompletionRequest,\n ): AsyncGenerator<string, void, unknown> {\n const reservation = await this.reserve(request);\n const { secret, pubB58 } = e2e.newResponseKeypair();\n const nonce = e2e.randomNonceB58();\n const maxTokens = request.max_tokens ?? 512;\n const sealed = e2e.sealInputV2(\n reservation.node_x25519_pubkey,\n pubB58,\n new TextEncoder().encode(JSON.stringify({\n messages: request.messages,\n temperature: request.temperature ?? 0.7,\n max_tokens: maxTokens,\n stream: true,\n nonce,\n })),\n );\n const body = {\n reservation_token: reservation.reservation_token,\n stream: true,\n max_tokens: maxTokens,\n enc: {\n ciphertext: sealed.ciphertext,\n client_ephemeral_pubkey: sealed.ephemeralPub,\n client_response_pubkey: pubB58,\n algorithm: e2e.ALGO_V2,\n },\n };\n\n const controller = new AbortController();\n const overall = setTimeout(() => controller.abort(), this.timeout);\n let resp: Response;\n try {\n resp = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers: this.headers,\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(overall);\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (!resp.ok) {\n clearTimeout(overall);\n if (resp.status === 402) {\n throw new SGLAPIError(402, \"Payment required — pass an apiKey (credits). The TS SDK does not sign x402 payments; use the wallet/browser flow for pay-per-call.\");\n }\n let message = resp.statusText;\n try {\n const j = (await resp.json()) as { error?: unknown };\n if (typeof j.error === \"string\") message = j.error;\n else if (j.error && typeof j.error === \"object\" && \"message\" in j.error) message = String((j.error as { message: unknown }).message);\n } catch { /* ignore */ }\n throw new SGLAPIError(resp.status, message);\n }\n\n const ctype = resp.headers.get(\"content-type\") ?? \"\";\n if (!ctype.includes(\"text/event-stream\") || !resp.body) {\n clearTimeout(overall);\n const data = (await resp.json()) as { sealed_result?: { ephemeral_public_key: string; ciphertext: string } };\n if (!data.sealed_result) throw new SGLAPIError(500, \"No sealed result returned\");\n const plain = e2e.openOutputV2(secret, pubB58, data.sealed_result.ephemeral_public_key, data.sealed_result.ciphertext);\n const content = (JSON.parse(new TextDecoder().decode(plain)) as { content?: string }).content ?? \"\";\n if (content) yield content;\n return;\n }\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n const INACTIVITY_MS = 60_000;\n const readChunk = async (): Promise<ReadableStreamReadResult<Uint8Array>> => {\n let t: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n t = setTimeout(() => reject(new SGLConnectionError(\"stream timed out (no tokens)\")), INACTIVITY_MS);\n });\n try {\n return (await Promise.race([reader.read(), timeout])) as ReadableStreamReadResult<Uint8Array>;\n } finally {\n if (t) clearTimeout(t);\n }\n };\n\n let buf = \"\";\n let expectedSeq = 0;\n let outKey: Uint8Array | null = null;\n let streamEph: string | null = null;\n let sawFinal = false;\n try {\n for (;;) {\n if (sawFinal) break;\n const { value, done } = await readChunk();\n if (done) break;\n // Normalize CRLF so \\n\\n event framing works regardless of line endings.\n buf += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\");\n let idx: number;\n while ((idx = buf.indexOf(\"\\n\\n\")) !== -1) {\n const raw = buf.slice(0, idx);\n buf = buf.slice(idx + 2);\n if (raw.includes(\"event: error\")) throw new SGLAPIError(502, \"stream aborted by server\");\n const dataStr = raw.split(\"\\n\").filter((l) => l.startsWith(\"data:\")).map((l) => l.slice(5).trim()).join(\"\\n\");\n if (!dataStr || dataStr === \"[DONE]\") continue;\n // Fail closed: a malformed or non-chunk data event is a protocol error.\n let chunk: { seq?: number; final?: boolean; eph?: string; ct?: string };\n try {\n chunk = JSON.parse(dataStr);\n } catch {\n throw new SGLAPIError(502, \"malformed stream chunk\");\n }\n if (typeof chunk.seq !== \"number\" || !chunk.ct) {\n throw new SGLAPIError(502, \"invalid stream chunk (missing seq/ciphertext)\");\n }\n if (chunk.seq !== expectedSeq) throw new SGLAPIError(502, `stream out of order (expected ${expectedSeq}, got ${chunk.seq})`);\n if (chunk.seq === 0) {\n if (!chunk.eph) throw new SGLAPIError(502, \"stream chunk 0 missing ephemeral key\");\n streamEph = chunk.eph;\n outKey = e2e.streamOutKey(secret, streamEph);\n }\n const isFinal = chunk.final === true;\n const text = new TextDecoder().decode(\n e2e.openStreamChunk(outKey as Uint8Array, pubB58, streamEph as string, nonce, chunk.seq, isFinal, chunk.ct),\n );\n if (text) yield text;\n expectedSeq++;\n if (isFinal) { sawFinal = true; break; }\n }\n }\n } finally {\n clearTimeout(overall);\n try { await reader.cancel(); } catch { /* ignore */ }\n }\n if (!sawFinal) throw new SGLAPIError(502, \"stream ended before final chunk (truncated)\");\n }\n\n // -- Processor helpers ----------------------------------------------------\n\n private async requestWithWalletAuth<T>(\n method: string,\n path: string,\n wallet: WalletAuth,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = {\n ...this.headers,\n \"X-Auth-Address\": wallet.address,\n \"X-Auth-Chain\": wallet.chain ?? \"solana\",\n \"X-Auth-Signature\": wallet.signature,\n \"X-Auth-Timestamp\": wallet.timestamp,\n \"X-Auth-Nonce\": wallet.nonce,\n };\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n else if (err && typeof err === \"object\" && \"message\" in err)\n message = String((err as { message: unknown }).message);\n } catch {\n /* body not JSON */\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new SGLAuthError(response.status, message, errorBody);\n }\n if (response.status === 404) {\n throw new SGLNotFoundError(message, errorBody);\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n if (response.status === 204) return {} as T;\n return (await response.json()) as T;\n }\n\n private async requestWithPayment<T>(\n method: string,\n path: string,\n body?: unknown,\n paymentHeader?: string,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n const reqHeaders: Record<string, string> = { ...this.headers };\n if (paymentHeader) {\n reqHeaders[\"X-Payment\"] = paymentHeader;\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: reqHeaders,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new SGLConnectionError(`Request to ${url} timed out`);\n }\n throw new SGLConnectionError(\n `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n\n if (response.status === 402) {\n const requirements = (await response.json()) as Record<string, unknown>;\n throw new SGLAPIError(402, \"Payment required\", requirements);\n }\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> | undefined;\n let message = response.statusText;\n try {\n errorBody = (await response.json()) as Record<string, unknown>;\n const err = errorBody?.error;\n if (typeof err === \"string\") message = err;\n } catch {\n /* body not JSON */\n }\n throw new SGLAPIError(response.status, message, errorBody);\n }\n\n return (await response.json()) as T;\n }\n\n // -- Processors -----------------------------------------------------------\n\n async deployProcessor(\n wallet: WalletAuth,\n options: DeployProcessorOptions,\n ): Promise<ProcessorDeployResult> {\n return this.requestWithWalletAuth<ProcessorDeployResult>(\n \"POST\",\n \"/grid/processors\",\n wallet,\n options,\n );\n }\n\n async invokeProcessor(\n processorName: string,\n input: Record<string, unknown>,\n options?: { paymentHeader?: string; paymentToken?: \"USDC\" | \"SGL\" },\n ): Promise<ProcessorInvokeResult> {\n const body: Record<string, unknown> = { input };\n if (options?.paymentToken) body.payment_token = options.paymentToken;\n return this.requestWithPayment<ProcessorInvokeResult>(\n \"POST\",\n `/grid/processors/${encodeURIComponent(processorName)}/invoke`,\n body,\n options?.paymentHeader,\n );\n }\n\n async listProcessors(options?: {\n owner?: string;\n page?: number;\n limit?: number;\n }): Promise<ProcessorListResponse> {\n const params = new URLSearchParams();\n if (options?.owner) params.set(\"owner\", options.owner);\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.request<ProcessorListResponse>(\n \"GET\",\n `/grid/processors${qs ? `?${qs}` : \"\"}`,\n );\n }\n\n async getProcessor(processorId: string): Promise<ProcessorInfo> {\n return this.request<ProcessorInfo>(\"GET\", `/grid/processors/${processorId}`);\n }\n\n async deleteProcessor(\n processorId: string,\n wallet: WalletAuth,\n ): Promise<{ deleted: boolean; id: string }> {\n return this.requestWithWalletAuth<{ deleted: boolean; id: string }>(\n \"DELETE\",\n `/grid/processors/${processorId}`,\n wallet,\n );\n }\n\n async getProcessorLogs(\n processorId: string,\n wallet: WalletAuth,\n options?: { page?: number; limit?: number },\n ): Promise<ProcessorLogsResponse> {\n const params = new URLSearchParams();\n if (options?.page != null) params.set(\"page\", String(options.page));\n if (options?.limit != null) params.set(\"limit\", String(options.limit));\n const qs = params.toString();\n return this.requestWithWalletAuth<ProcessorLogsResponse>(\n \"GET\",\n `/grid/processors/${processorId}/logs${qs ? `?${qs}` : \"\"}`,\n wallet,\n );\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED