@singularity-layer/grid 0.7.0 → 0.9.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.mjs CHANGED
@@ -449,161 +449,406 @@ var GridClient = class {
449
449
  }
450
450
  if (!sawFinal) throw new SGLAPIError(502, "stream ended before final chunk (truncated)");
451
451
  }
452
- // -- Processor helpers ----------------------------------------------------
453
- async requestWithWalletAuth(method, path, wallet, body) {
454
- const url = `${this.baseUrl}${path}`;
455
- const controller = new AbortController();
456
- const timer = setTimeout(() => controller.abort(), this.timeout);
457
- const reqHeaders = {
458
- ...this.headers,
459
- "X-Auth-Address": wallet.address,
460
- "X-Auth-Chain": wallet.chain ?? "solana",
461
- "X-Auth-Signature": wallet.signature,
462
- "X-Auth-Timestamp": wallet.timestamp,
463
- "X-Auth-Nonce": wallet.nonce
464
- };
465
- let response;
466
- try {
467
- response = await fetch(url, {
468
- method,
469
- headers: reqHeaders,
470
- body: body ? JSON.stringify(body) : void 0,
471
- signal: controller.signal
472
- });
473
- } catch (err) {
474
- if (err instanceof Error && err.name === "AbortError") {
475
- throw new SGLConnectionError(`Request to ${url} timed out`);
476
- }
477
- throw new SGLConnectionError(
478
- `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`
479
- );
480
- } finally {
481
- clearTimeout(timer);
452
+ };
453
+
454
+ // src/vault.ts
455
+ import { gcm } from "@noble/ciphers/aes";
456
+ import { scrypt } from "@noble/hashes/scrypt";
457
+ var VAULT_URL = "https://compute.x402layer.cc";
458
+ var SCRYPT_PARAMS = { N: 1 << 17, r: 8, p: 1 };
459
+ var SCRYPT_MIN_N = 1 << 15;
460
+ var te = new TextEncoder();
461
+ var td = new TextDecoder();
462
+ function aadBytes(aad) {
463
+ const { agentId, backupId, formatVersion, userId } = aad;
464
+ return te.encode(JSON.stringify({ agentId, backupId, formatVersion, userId }));
465
+ }
466
+ function b64(x) {
467
+ let s = "";
468
+ for (const b of x) s += String.fromCharCode(b);
469
+ return btoa(s);
470
+ }
471
+ function unb64(s) {
472
+ const bin = atob(s);
473
+ const out = new Uint8Array(bin.length);
474
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
475
+ return out;
476
+ }
477
+ function rand(n) {
478
+ const out = new Uint8Array(n);
479
+ crypto.getRandomValues(out);
480
+ return out;
481
+ }
482
+ function encryptEnvelope(plaintext, passphrase, aad) {
483
+ const salt = rand(16);
484
+ const kek = scrypt(te.encode(passphrase), salt, { ...SCRYPT_PARAMS, dkLen: 32 });
485
+ const dek = rand(32);
486
+ const aadBuf = aadBytes(aad);
487
+ const dekNonce = rand(12);
488
+ const wrapped = gcm(kek, dekNonce, aadBuf).encrypt(dek);
489
+ const blobNonce = rand(12);
490
+ const body = gcm(dek, blobNonce, aadBuf).encrypt(plaintext);
491
+ const header = te.encode(JSON.stringify({
492
+ formatVersion: 1,
493
+ kdf: "scrypt",
494
+ kdfParams: { ...SCRYPT_PARAMS, salt: b64(salt) },
495
+ cipher: "aes-256-gcm",
496
+ wrappedDek: { nonce: b64(dekNonce), ciphertext: b64(wrapped) },
497
+ blobNonce: b64(blobNonce),
498
+ aad
499
+ }));
500
+ const out = new Uint8Array(4 + header.length + body.length);
501
+ new DataView(out.buffer).setUint32(0, header.length, false);
502
+ out.set(header, 4);
503
+ out.set(body, 4 + header.length);
504
+ return out;
505
+ }
506
+ function decryptEnvelope(blob, passphrase, aad) {
507
+ if (blob.length < 4) throw new SGLAPIError(0, "malformed blob: too short");
508
+ const headerLen = new DataView(blob.buffer, blob.byteOffset).getUint32(0, false);
509
+ if (4 + headerLen > blob.length) throw new SGLAPIError(0, "malformed blob: header length out of bounds");
510
+ let header;
511
+ try {
512
+ header = JSON.parse(td.decode(blob.subarray(4, 4 + headerLen)));
513
+ } catch {
514
+ throw new SGLAPIError(0, "malformed blob: invalid header JSON");
515
+ }
516
+ if (header.kdf !== "scrypt") {
517
+ throw new SGLAPIError(0, `this backup uses ${String(header.kdf)} key derivation \u2014 restore it with the agentvault CLI`);
518
+ }
519
+ const p = header.kdfParams ?? {};
520
+ if (!Number.isInteger(p.N) || p.N < SCRYPT_MIN_N || p.N > SCRYPT_PARAMS.N || (p.N & p.N - 1) !== 0 || !Number.isInteger(p.r) || p.r < 8 || p.r > 16 || !Number.isInteger(p.p) || p.p < 1 || p.p > 4 || typeof p.salt !== "string" || !header.wrappedDek?.nonce || !header.wrappedDek?.ciphertext || !header.blobNonce) {
521
+ throw new SGLAPIError(0, "malformed blob: unsupported header parameters");
522
+ }
523
+ const salt = unb64(p.salt);
524
+ if (salt.length < 16) throw new SGLAPIError(0, "malformed blob: salt too short");
525
+ const kek = scrypt(te.encode(passphrase), salt, { N: p.N, r: p.r, p: p.p, dkLen: 32 });
526
+ const aadBuf = aadBytes(aad);
527
+ try {
528
+ const dek = gcm(kek, unb64(header.wrappedDek.nonce), aadBuf).decrypt(unb64(header.wrappedDek.ciphertext));
529
+ return gcm(dek, unb64(header.blobNonce), aadBuf).decrypt(blob.subarray(4 + headerLen));
530
+ } catch {
531
+ throw new SGLAPIError(0, "incorrect passphrase or corrupted backup");
532
+ }
533
+ }
534
+ function parseAadFromKey(r2Key) {
535
+ const parts = r2Key.split("/");
536
+ if (parts.length !== 5 || parts[0] !== "backups" || parts[4] !== "blob.enc" || !parts[1] || !parts[2] || !parts[3]) {
537
+ throw new SGLAPIError(0, `malformed r2 key: ${r2Key}`);
538
+ }
539
+ return { userId: parts[1], agentId: parts[2], backupId: parts[3], formatVersion: 1 };
540
+ }
541
+ var VaultClient = class _VaultClient {
542
+ constructor(options) {
543
+ const base = (options.baseUrl ?? VAULT_URL).replace(/\/+$/, "");
544
+ const u = new URL(base);
545
+ const local = ["localhost", "127.0.0.1", "[::1]"].includes(u.hostname);
546
+ if (u.protocol !== "https:" && !local) {
547
+ throw new SGLAPIError(0, "baseUrl must be https (the API key travels in a header)");
482
548
  }
483
- if (!response.ok) {
484
- let errorBody;
485
- let message = response.statusText;
486
- try {
487
- errorBody = await response.json();
488
- const err = errorBody?.error;
489
- if (typeof err === "string") message = err;
490
- else if (err && typeof err === "object" && "message" in err)
491
- message = String(err.message);
492
- } catch {
493
- }
494
- if (response.status === 401 || response.status === 403) {
495
- throw new SGLAuthError(response.status, message, errorBody);
496
- }
497
- if (response.status === 404) {
498
- throw new SGLNotFoundError(message, errorBody);
549
+ if (u.username || u.password || u.search || u.hash) {
550
+ throw new SGLAPIError(0, "baseUrl must be a bare origin");
551
+ }
552
+ this.base = base;
553
+ this.apiKey = options.apiKey;
554
+ this.fetchImpl = options.fetchImpl ?? fetch;
555
+ }
556
+ static id(v) {
557
+ if (!/^[0-9a-fA-F-]{36}$/.test(v)) throw new SGLAPIError(0, `not a snapshot id: ${v}`);
558
+ return v.toLowerCase();
559
+ }
560
+ async call(method, path, body) {
561
+ const res = await this.fetchImpl(`${this.base}${path}`, {
562
+ method,
563
+ headers: {
564
+ "x-api-key": this.apiKey,
565
+ ...body !== void 0 ? { "content-type": "application/json" } : {}
566
+ },
567
+ body: body !== void 0 ? JSON.stringify(body) : void 0
568
+ });
569
+ const data = await res.json().catch(() => ({}));
570
+ if (!res.ok) throw new SGLAPIError(res.status, String(data.error ?? `request failed: ${res.status}`));
571
+ return data;
572
+ }
573
+ async agents() {
574
+ return (await this.call("GET", "/backups/agents")).agents;
575
+ }
576
+ async createAgent(name, framework) {
577
+ return (await this.call("POST", "/backups/agents", { name, framework })).agent;
578
+ }
579
+ async snapshots(agentId) {
580
+ const q = agentId ? `?agentId=${encodeURIComponent(agentId)}` : "";
581
+ return (await this.call("GET", `/backups${q}`)).backups;
582
+ }
583
+ async usage() {
584
+ return this.call("GET", "/backups/usage");
585
+ }
586
+ /** Activate Vault Pro ($3/mo from credits). */
587
+ async subscribePro() {
588
+ return this.call("POST", "/backups/subscribe");
589
+ }
590
+ async deleteSnapshot(id) {
591
+ await this.call("DELETE", `/backups/${_VaultClient.id(id)}`);
592
+ }
593
+ /**
594
+ * Encrypt + upload arbitrary payload bytes (e.g. a tarball you packed) as a
595
+ * snapshot of `agentId`. Returns the snapshot id.
596
+ */
597
+ async backupBytes(agentId, payload, passphrase) {
598
+ const res = await this.call(
599
+ "POST",
600
+ "/backups",
601
+ { agentId, sizeBytes: payload.length }
602
+ );
603
+ const blob = encryptEnvelope(payload, passphrase, parseAadFromKey(res.r2Key));
604
+ const up = await this.fetchImpl(res.uploadUrl, {
605
+ method: "PUT",
606
+ body: blob,
607
+ headers: { "content-type": "application/octet-stream" }
608
+ });
609
+ if (!up.ok) throw new SGLAPIError(up.status, `upload failed: ${up.status}`);
610
+ const digest = await crypto.subtle.digest("SHA-256", blob);
611
+ const sha2562 = [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
612
+ await this.call("POST", `/backups/${res.backupId}/complete`, { sha256: sha2562 });
613
+ return res.backupId;
614
+ }
615
+ /** Download + decrypt a snapshot's payload bytes. */
616
+ async restoreBytes(snapshotId, passphrase) {
617
+ const info = await this.call("GET", `/backups/${_VaultClient.id(snapshotId)}/restore`);
618
+ const dl = await this.fetchImpl(info.downloadUrl);
619
+ if (!dl.ok) throw new SGLAPIError(dl.status, `download failed: ${dl.status}`);
620
+ const blob = new Uint8Array(await dl.arrayBuffer());
621
+ return decryptEnvelope(blob, passphrase, parseAadFromKey(info.r2Key));
622
+ }
623
+ };
624
+
625
+ // src/processors.ts
626
+ var PROCESSORS_BASE_URL = "https://processors.x402compute.cc";
627
+ var DEFAULT_TIMEOUT2 = 6e4;
628
+ function isLoopback(hostname) {
629
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1";
630
+ }
631
+ function parseBaseUrl(raw) {
632
+ let u;
633
+ try {
634
+ u = new URL(raw);
635
+ } catch {
636
+ throw new Error(`ProcessorsClient baseUrl is not a valid URL: ${raw}`);
637
+ }
638
+ if (u.protocol !== "https:" && !(u.protocol === "http:" && isLoopback(u.hostname))) {
639
+ throw new Error(
640
+ `ProcessorsClient baseUrl must be https (or http on localhost); got ${u.protocol}//${u.hostname}. The API key is a long-lived full-control credential and must not be sent in the clear.`
641
+ );
642
+ }
643
+ return u;
644
+ }
645
+ function keyAllowedOnHost(u) {
646
+ return u.origin === new URL(PROCESSORS_BASE_URL).origin || isLoopback(u.hostname);
647
+ }
648
+ var ProcessorsClient = class {
649
+ constructor(options = {}) {
650
+ const parsed = parseBaseUrl(options.baseUrl ?? PROCESSORS_BASE_URL);
651
+ this.baseUrl = (options.baseUrl ?? PROCESSORS_BASE_URL).replace(/\/+$/, "");
652
+ this.timeout = options.timeoutMs ?? DEFAULT_TIMEOUT2;
653
+ this.headers = { Accept: "application/json", "Content-Type": "application/json" };
654
+ if (options.apiKey) {
655
+ if (!keyAllowedOnHost(parsed) && !options.allowKeyOnCustomHost) {
656
+ throw new Error(
657
+ `ProcessorsClient refuses to send an API key to ${parsed.origin}. It is neither ${new URL(PROCESSORS_BASE_URL).origin} nor loopback. If you really do run your own processors host, pass allowKeyOnCustomHost: true.`
658
+ );
499
659
  }
500
- throw new SGLAPIError(response.status, message, errorBody);
660
+ this.headers["X-API-Key"] = options.apiKey;
501
661
  }
502
- if (response.status === 204) return {};
503
- return await response.json();
504
662
  }
505
- async requestWithPayment(method, path, body, paymentHeader) {
663
+ async request(method, path, body, extraHeaders, sendApiKey = true) {
506
664
  const url = `${this.baseUrl}${path}`;
507
665
  const controller = new AbortController();
508
666
  const timer = setTimeout(() => controller.abort(), this.timeout);
509
- const reqHeaders = { ...this.headers };
510
- if (paymentHeader) {
511
- reqHeaders["X-Payment"] = paymentHeader;
512
- }
513
667
  let response;
514
668
  try {
669
+ const base = { ...this.headers };
670
+ if (!sendApiKey) delete base["X-API-Key"];
515
671
  response = await fetch(url, {
516
672
  method,
517
- headers: reqHeaders,
518
- body: body ? JSON.stringify(body) : void 0,
673
+ headers: { ...base, ...extraHeaders },
674
+ body: body === void 0 ? void 0 : JSON.stringify(body),
519
675
  signal: controller.signal
520
676
  });
521
677
  } catch (err) {
522
- if (err instanceof Error && err.name === "AbortError") {
523
- throw new SGLConnectionError(`Request to ${url} timed out`);
524
- }
525
678
  throw new SGLConnectionError(
526
- `Could not connect to ${this.baseUrl}: ${err instanceof Error ? err.message : String(err)}`
679
+ `Could not reach ${url}: ${err instanceof Error ? err.message : String(err)}`
527
680
  );
528
681
  } finally {
529
682
  clearTimeout(timer);
530
683
  }
531
- if (response.status === 402) {
532
- const requirements = await response.json();
533
- throw new SGLAPIError(402, "Payment required", requirements);
684
+ if (response.status === 204) return {};
685
+ const text = await response.text();
686
+ let parsed;
687
+ try {
688
+ parsed = text ? JSON.parse(text) : void 0;
689
+ } catch {
690
+ parsed = text;
534
691
  }
535
692
  if (!response.ok) {
536
- let errorBody;
537
- let message = response.statusText;
538
- try {
539
- errorBody = await response.json();
540
- const err = errorBody?.error;
541
- if (typeof err === "string") message = err;
542
- } catch {
693
+ const body2 = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
694
+ const detail = typeof body2?.detail === "string" && body2.detail || typeof body2?.error === "string" && body2.error || "";
695
+ if (response.status === 401 || response.status === 403) {
696
+ throw new SGLAuthError(response.status, detail || "unauthorized", body2);
543
697
  }
544
- throw new SGLAPIError(response.status, message, errorBody);
698
+ if (response.status === 404) {
699
+ throw new SGLNotFoundError(detail || "not found", body2);
700
+ }
701
+ throw new SGLAPIError(response.status, detail || `HTTP ${response.status}`, body2);
545
702
  }
546
- return await response.json();
703
+ return parsed;
547
704
  }
548
- // -- Processors -----------------------------------------------------------
549
- async deployProcessor(wallet, options) {
550
- return this.requestWithWalletAuth(
551
- "POST",
552
- "/grid/processors",
553
- wallet,
554
- options
555
- );
705
+ // ── Discovery ────────────────────────────────────────────────────────────
706
+ /**
707
+ * The public catalogue.
708
+ *
709
+ * Sends NO credential, even when the client holds one. `GET /processors` is owner-scoped when a
710
+ * key is presented and public otherwise, so passing the key here would silently return your own
711
+ * processors instead of the catalogue — the opposite of what the name promises. Use `list()`
712
+ * when you want yours.
713
+ */
714
+ async catalogue() {
715
+ return this.request("GET", "/processors", void 0, void 0, false);
556
716
  }
557
- async invokeProcessor(processorName, input, options) {
558
- const body = { input };
559
- if (options?.paymentToken) body.payment_token = options.paymentToken;
560
- return this.requestWithPayment(
561
- "POST",
562
- `/grid/processors/${encodeURIComponent(processorName)}/invoke`,
563
- body,
564
- options?.paymentHeader
565
- );
717
+ /** Processors owned by this key's wallet. Needs `processors:read`. */
718
+ async list() {
719
+ return this.request("GET", "/processors");
566
720
  }
567
- async listProcessors(options) {
568
- const params = new URLSearchParams();
569
- if (options?.owner) params.set("owner", options.owner);
570
- if (options?.page != null) params.set("page", String(options.page));
571
- if (options?.limit != null) params.set("limit", String(options.limit));
572
- const qs = params.toString();
721
+ /** Owner projection when the key owns it, public projection otherwise. */
722
+ async get(slug) {
723
+ return this.request("GET", `/processors/${encodeURIComponent(slug)}`);
724
+ }
725
+ // ── Lifecycle (needs processors:write) ───────────────────────────────────
726
+ /**
727
+ * Deploy. The wallet behind the key becomes `owner_wallet`, which is also the x402 `payTo` and
728
+ * the runtime-billing account — so the key must be minted on a SOLANA wallet or this returns
729
+ * `400 solana_wallet_required`.
730
+ *
731
+ * The `invoke_token` in the response is shown once and never again.
732
+ */
733
+ async deploy(input) {
734
+ return this.request("POST", "/processors", input);
735
+ }
736
+ /** Push new code, a new manifest, or both. Omitting `manifest` keeps the stored one. */
737
+ async update(slug, input) {
738
+ return this.request("PATCH", `/processors/${encodeURIComponent(slug)}`, input);
739
+ }
740
+ /**
741
+ * Delete. **Irreversible, and the slug is burned forever** — it can never be reused, by you or
742
+ * anyone. In-flight runs finish first; the code is wiped when they drain.
743
+ */
744
+ async delete(slug) {
745
+ return this.request("DELETE", `/processors/${encodeURIComponent(slug)}`);
746
+ }
747
+ /** Stop or restart traffic WITHOUT losing the slug. This is the switch, not `delete`. */
748
+ async setPaused(slug, paused) {
749
+ return this.request("PUT", `/processors/${encodeURIComponent(slug)}/pause`, { paused });
750
+ }
751
+ /**
752
+ * List or unlist publicly. Instant, no review step.
753
+ *
754
+ * Unlisting is NOT stopping: an unlisted processor keeps answering anyone holding the URL or an
755
+ * invoke token, earning nothing while still drawing compute from your balance. Use `setPaused`.
756
+ */
757
+ async setListing(slug, listed) {
758
+ return this.request("PUT", `/processors/${encodeURIComponent(slug)}/listing`, { listed });
759
+ }
760
+ /** Set secret VALUES. Each name must already be declared in `manifest.secrets`. */
761
+ async setSecrets(slug, values) {
762
+ return this.request("PUT", `/processors/${encodeURIComponent(slug)}/secrets`, { values });
763
+ }
764
+ /** Mint a new invoke token. The old one stops working immediately. */
765
+ async rotateToken(slug) {
766
+ return this.request("POST", `/processors/${encodeURIComponent(slug)}/rotate-token`);
767
+ }
768
+ // ── Observability ────────────────────────────────────────────────────────
769
+ async runs(slug) {
770
+ return this.request("GET", `/processors/${encodeURIComponent(slug)}/runs`);
771
+ }
772
+ async run_(slug, runId) {
573
773
  return this.request(
574
774
  "GET",
575
- `/grid/processors${qs ? `?${qs}` : ""}`
775
+ `/processors/${encodeURIComponent(slug)}/runs/${encodeURIComponent(runId)}`
576
776
  );
577
777
  }
578
- async getProcessor(processorId) {
579
- return this.request("GET", `/grid/processors/${processorId}`);
778
+ /** Sales (paid straight to your wallet, with the on-chain tx per row) and runtime spend. */
779
+ async earnings(slug) {
780
+ return this.request("GET", `/processors/${encodeURIComponent(slug)}/earnings`);
580
781
  }
581
- async deleteProcessor(processorId, wallet) {
582
- return this.requestWithWalletAuth(
583
- "DELETE",
584
- `/grid/processors/${processorId}`,
585
- wallet
586
- );
782
+ /** The processor's own key/value state. Read-only from out here, by design. */
783
+ async kv(slug) {
784
+ return this.request("GET", `/processors/${encodeURIComponent(slug)}/kv`);
587
785
  }
588
- async getProcessorLogs(processorId, wallet, options) {
589
- const params = new URLSearchParams();
590
- if (options?.page != null) params.set("page", String(options.page));
591
- if (options?.limit != null) params.set("limit", String(options.limit));
592
- const qs = params.toString();
593
- return this.requestWithWalletAuth(
594
- "GET",
595
- `/grid/processors/${processorId}/logs${qs ? `?${qs}` : ""}`,
596
- wallet
786
+ // ── Webhooks ─────────────────────────────────────────────────────────────
787
+ async getWebhook(slug) {
788
+ return this.request("GET", `/processors/${encodeURIComponent(slug)}/webhook`);
789
+ }
790
+ /**
791
+ * Register or replace. We immediately POST a signed verification to the URL: it must answer 2xx
792
+ * or the webhook stays registered-but-inactive and delivers nothing. The signing secret comes
793
+ * back EXACTLY ONCE.
794
+ */
795
+ async setWebhook(slug, url) {
796
+ return this.request("PUT", `/processors/${encodeURIComponent(slug)}/webhook`, { url });
797
+ }
798
+ async deleteWebhook(slug) {
799
+ return this.request("DELETE", `/processors/${encodeURIComponent(slug)}/webhook`);
800
+ }
801
+ async testWebhook(slug) {
802
+ return this.request("POST", `/processors/${encodeURIComponent(slug)}/webhook/test`);
803
+ }
804
+ // ── Invoking ─────────────────────────────────────────────────────────────
805
+ /**
806
+ * Run YOUR OWN processor with the invoke token from `deploy()`.
807
+ *
808
+ * Not the API key: the run route deliberately does not read a key as an ownership claim, because
809
+ * it is the only route with both a money path and an anonymous buyer lane. You pay for the
810
+ * compute; nobody pays at call time.
811
+ */
812
+ async run(slug, input, invokeToken) {
813
+ return this.request(
814
+ "POST",
815
+ `/processors/${encodeURIComponent(slug)}/run`,
816
+ { input },
817
+ { Authorization: `Bearer ${invokeToken}` },
818
+ false
597
819
  );
598
820
  }
821
+ /**
822
+ * Run someone else's processor as a buyer, with an x402 payment header.
823
+ *
824
+ * Call once WITHOUT `paymentHeader` to get the 402 and its `accepts` array — one entry per chain
825
+ * that publisher takes. Match on `network`, pay that entry, and retry with the header.
826
+ *
827
+ * Re-sending the SAME header returns the run that payment already bought and does NOT charge
828
+ * again. That is the recovery path for every failure mode, because **there are no refunds**: the
829
+ * money went straight to the publisher and the platform never held it.
830
+ */
831
+ async runWithPayment(slug, input, paymentHeader, acceptNetworks) {
832
+ const extra = {};
833
+ if (paymentHeader) extra["X-Payment"] = paymentHeader;
834
+ if (acceptNetworks?.length) extra["X-Accept-Networks"] = acceptNetworks.join(",");
835
+ return this.request("POST", `/processors/${encodeURIComponent(slug)}/run`, { input }, extra, false);
836
+ }
599
837
  };
600
838
  export {
601
839
  DEFAULT_BASE_URL,
602
840
  GridClient,
841
+ PROCESSORS_BASE_URL,
842
+ ProcessorsClient,
603
843
  SGLAPIError,
604
844
  SGLAuthError,
605
845
  SGLConnectionError,
606
846
  SGLError,
607
- SGLNotFoundError
847
+ SGLNotFoundError,
848
+ VAULT_URL,
849
+ VaultClient,
850
+ decryptEnvelope,
851
+ encryptEnvelope,
852
+ parseAadFromKey
608
853
  };
609
854
  //# sourceMappingURL=index.mjs.map