zk-credits 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ are founder-provisioned test credits, and the circuit is not independently
7
7
  audited.
8
8
 
9
9
  ```bash
10
- npm install --global zk-credits@0.2.3
10
+ npm install --global zk-credits@0.2.5
11
11
  ```
12
12
 
13
13
  ## Pinned pilot versions
@@ -17,11 +17,11 @@ not mix versions between the sidecar, the adapter package, and the gateway:
17
17
 
18
18
  | Package | Version |
19
19
  | --- | --- |
20
- | `zk-credits` (this sidecar) | `0.2.3` |
20
+ | `zk-credits` (this sidecar) | `0.2.5` |
21
21
  | `@zk-credits/x402-zk-prepaid` (adapter) | `0.1.0` |
22
22
  | `@zk-credits/shared` | `0.1.0` |
23
23
 
24
- The pinned Base Sepolia trial version is `0.2.3`. It uses the non-streaming
24
+ The pinned Base Sepolia trial version is `0.2.5`. It uses the non-streaming
25
25
  `POST /v1/chat/completions` path below, includes the loopback Responses bridge
26
26
  for Codex, and acquires the pinned private proving bundle through the local
27
27
  GitHub CLI session. It also synchronizes V2 Base events and checks the gateway
@@ -79,9 +79,11 @@ still receives the class. A rejected request consumes no credit.
79
79
  owner-only permissions. Missing GitHub access or any mismatch stops setup.
80
80
  It syncs public Base events from the pinned V2 bond and deployment block,
81
81
  validates that the resulting witness resolves the activated credential,
82
- and asks the gateway whether the resulting root is known. The witness and
83
- event cache remain local. The package does not accept a supplied witness
84
- file for this V2 deployment.
82
+ and asks the gateway's public `POST /v1/root-known` endpoint whether the
83
+ resulting root is known. This check sends no admin token and returns only
84
+ `{ "known": boolean }`; the protected admin endpoints remain unavailable
85
+ to setup. The witness and event cache remain local. The package does not
86
+ accept a supplied witness file for this V2 deployment.
85
87
 
86
88
  The package ships `circuits/manifest.json`, which fixes the immutable
87
89
  release identity, the SHA-256 of the archive and each proving artifact, and
@@ -104,7 +106,8 @@ still receives the class. A rejected request consumes no credit.
104
106
  zk-credits setup codex
105
107
  ```
106
108
 
107
- Then run `zk-credits codex` to open Codex with the local sidecar.
109
+ No gateway admin token is required. Then run `zk-credits codex` to open
110
+ Codex with the local sidecar.
108
111
 
109
112
  The sidecar binds `127.0.0.1:3210` only. It does not modify `~/.cline` or
110
113
  `~/.codex`.
package/dist/cli.js CHANGED
@@ -24,6 +24,7 @@ import { createSidecarServer } from './sidecar.js';
24
24
  import { runBaseRegisteredTrialExchange } from './base-registered-trial.js';
25
25
  import { loadCircuitManifest } from './artifact-bundle.js';
26
26
  import { BASE_SEPOLIA_NETWORK } from '@zk-credits/x402-zk-prepaid';
27
+ import { requireGatewayKnownRoot as checkGatewayKnownRoot } from './gateway-root-check.js';
27
28
  const DEFAULT_GATEWAY_URL = 'https://zk-credits-gateway.onrender.com';
28
29
  const DEFAULT_PORT = 3210;
29
30
  function stateDirectory() {
@@ -260,36 +261,7 @@ async function readGatewayJson(url, headers) {
260
261
  }
261
262
  }
262
263
  async function requireGatewayKnownRoot(root) {
263
- const origin = gatewayOrigin();
264
- const token = process.env.BILLING_INTERNAL_TOKEN?.trim() || await readHiddenValue('Gateway admin token: ');
265
- if (!token)
266
- throw new Error('Base Sepolia V2 setup requires gateway admin access to check the activated credential root');
267
- let response;
268
- try {
269
- response = await fetch(new URL('/v1/admin/root-known', origin), {
270
- method: 'POST',
271
- headers: {
272
- accept: 'application/json',
273
- authorization: `Bearer ${token}`,
274
- 'content-type': 'application/json',
275
- },
276
- body: JSON.stringify({ root }),
277
- signal: AbortSignal.timeout(10_000),
278
- });
279
- }
280
- catch {
281
- throw new Error('The gateway could not confirm that the activated credential root is known');
282
- }
283
- let body;
284
- try {
285
- body = await response.json();
286
- }
287
- catch {
288
- body = undefined;
289
- }
290
- if (response.status !== 200 || !isRecord(body) || body.known !== true) {
291
- throw new Error('The activated credential root is not in the gateway known-root set; stop setup and reconcile the V2 activation');
292
- }
264
+ await checkGatewayKnownRoot(root, gatewayOrigin());
293
265
  }
294
266
  async function gatewayReadiness(origin) {
295
267
  const response = await readGatewayJson(new URL('/ready', origin), { accept: 'application/json' });
@@ -23,6 +23,7 @@ export function renderCodexProfile(options) {
23
23
  const model = options.model?.trim() || DEFAULT_CODEX_MODEL;
24
24
  return [
25
25
  `model = ${tomlString(model)}`,
26
+ 'model_reasoning_effort = "none"',
26
27
  'model_provider = "zk_credits"',
27
28
  '',
28
29
  '[model_providers.zk_credits]',
@@ -0,0 +1,2 @@
1
+ /** Public setup check. It sends the public root only and never needs an admin credential. */
2
+ export declare function requireGatewayKnownRoot(root: string, origin: URL, fetcher?: typeof fetch): Promise<void>;
@@ -0,0 +1,28 @@
1
+ function isRecord(value) {
2
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
3
+ }
4
+ /** Public setup check. It sends the public root only and never needs an admin credential. */
5
+ export async function requireGatewayKnownRoot(root, origin, fetcher = fetch) {
6
+ let response;
7
+ try {
8
+ response = await fetcher(new URL('/v1/root-known', origin), {
9
+ method: 'POST',
10
+ headers: { accept: 'application/json', 'content-type': 'application/json' },
11
+ body: JSON.stringify({ root }),
12
+ signal: AbortSignal.timeout(10_000),
13
+ });
14
+ }
15
+ catch {
16
+ throw new Error('The gateway could not confirm that the activated credential root is known');
17
+ }
18
+ let body;
19
+ try {
20
+ body = await response.json();
21
+ }
22
+ catch {
23
+ body = undefined;
24
+ }
25
+ if (response.status !== 200 || !isRecord(body) || body.known !== true) {
26
+ throw new Error('The activated credential root is not in the gateway known-root set; stop setup and reconcile the V2 activation');
27
+ }
28
+ }
@@ -91,6 +91,21 @@ function responseTools(value) {
91
91
  tools.push({ type: 'function', function: definition });
92
92
  continue;
93
93
  }
94
+ // Codex sends its local freeform apply_patch tool with every Responses
95
+ // request. Chat Completions cannot execute that tool, so validate this
96
+ // known declaration and omit it from the provider request.
97
+ if (tool.type === 'custom') {
98
+ if (!hasOnlyKeys(tool, ['type', 'name', 'description', 'format'])
99
+ || tool.name !== 'apply_patch'
100
+ || (tool.description !== undefined && typeof tool.description !== 'string')
101
+ || !isRecord(tool.format)
102
+ || !hasOnlyKeys(tool.format, ['type', 'syntax', 'definition'])
103
+ || tool.format.type !== 'grammar'
104
+ || tool.format.syntax !== 'lark'
105
+ || typeof tool.format.definition !== 'string')
106
+ return undefined;
107
+ continue;
108
+ }
94
109
  // Codex includes these tool declarations in each Responses request. The
95
110
  // fixed service class has no web-search executor and accepts only direct
96
111
  // function tools, so validate their known shape and drop them.
@@ -151,8 +166,9 @@ export function translateResponsesRequest(body) {
151
166
  return { ok: false, error: 'unsupported_include' };
152
167
  }
153
168
  if (body.reasoning !== undefined
154
- && (!isRecord(body.reasoning) || !hasOnlyKeys(body.reasoning, ['summary'])
155
- || (body.reasoning.summary !== undefined && !['auto', 'concise', 'detailed'].includes(String(body.reasoning.summary))))) {
169
+ && (!isRecord(body.reasoning) || !hasOnlyKeys(body.reasoning, ['effort', 'summary'])
170
+ || (body.reasoning.effort !== undefined && body.reasoning.effort !== 'none')
171
+ || (body.reasoning.summary !== undefined && !['none', 'auto', 'concise', 'detailed'].includes(String(body.reasoning.summary))))) {
156
172
  return { ok: false, error: 'unsupported_reasoning_controls' };
157
173
  }
158
174
  if (body.parallel_tool_calls !== undefined && typeof body.parallel_tool_calls !== 'boolean') {
@@ -80687,6 +80687,7 @@ function renderCodexProfile(options) {
80687
80687
  const model = options.model?.trim() || DEFAULT_CODEX_MODEL;
80688
80688
  return [
80689
80689
  `model = ${tomlString(model)}`,
80690
+ 'model_reasoning_effort = "none"',
80690
80691
  'model_provider = "zk_credits"',
80691
80692
  "",
80692
80693
  "[model_providers.zk_credits]",
@@ -82873,6 +82874,11 @@ function responseTools(value) {
82873
82874
  tools.push({ type: "function", function: definition });
82874
82875
  continue;
82875
82876
  }
82877
+ if (tool.type === "custom") {
82878
+ if (!hasOnlyKeys(tool, ["type", "name", "description", "format"]) || tool.name !== "apply_patch" || tool.description !== void 0 && typeof tool.description !== "string" || !isRecord3(tool.format) || !hasOnlyKeys(tool.format, ["type", "syntax", "definition"]) || tool.format.type !== "grammar" || tool.format.syntax !== "lark" || typeof tool.format.definition !== "string")
82879
+ return void 0;
82880
+ continue;
82881
+ }
82876
82882
  if (tool.type === "web_search") {
82877
82883
  if (!hasOnlyKeys(tool, ["type", "external_web_access"]) || tool.external_web_access !== void 0 && typeof tool.external_web_access !== "boolean")
82878
82884
  return void 0;
@@ -82937,7 +82943,7 @@ function translateResponsesRequest(body) {
82937
82943
  if (body.include !== void 0 && (!Array.isArray(body.include) || body.include.some((value) => value !== "reasoning.encrypted_content"))) {
82938
82944
  return { ok: false, error: "unsupported_include" };
82939
82945
  }
82940
- if (body.reasoning !== void 0 && (!isRecord3(body.reasoning) || !hasOnlyKeys(body.reasoning, ["summary"]) || body.reasoning.summary !== void 0 && !["auto", "concise", "detailed"].includes(String(body.reasoning.summary)))) {
82946
+ if (body.reasoning !== void 0 && (!isRecord3(body.reasoning) || !hasOnlyKeys(body.reasoning, ["effort", "summary"]) || body.reasoning.effort !== void 0 && body.reasoning.effort !== "none" || body.reasoning.summary !== void 0 && !["none", "auto", "concise", "detailed"].includes(String(body.reasoning.summary)))) {
82941
82947
  return { ok: false, error: "unsupported_reasoning_controls" };
82942
82948
  }
82943
82949
  if (body.parallel_tool_calls !== void 0 && typeof body.parallel_tool_calls !== "boolean") {
@@ -83477,6 +83483,35 @@ async function runBaseRegisteredTrialExchange(options) {
83477
83483
 
83478
83484
  // dist/cli.js
83479
83485
  import { BASE_SEPOLIA_NETWORK as BASE_SEPOLIA_NETWORK2 } from "@zk-credits/x402-zk-prepaid";
83486
+
83487
+ // dist/gateway-root-check.js
83488
+ function isRecord5(value) {
83489
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
83490
+ }
83491
+ async function requireGatewayKnownRoot(root, origin, fetcher = fetch) {
83492
+ let response;
83493
+ try {
83494
+ response = await fetcher(new URL("/v1/root-known", origin), {
83495
+ method: "POST",
83496
+ headers: { accept: "application/json", "content-type": "application/json" },
83497
+ body: JSON.stringify({ root }),
83498
+ signal: AbortSignal.timeout(1e4)
83499
+ });
83500
+ } catch {
83501
+ throw new Error("The gateway could not confirm that the activated credential root is known");
83502
+ }
83503
+ let body;
83504
+ try {
83505
+ body = await response.json();
83506
+ } catch {
83507
+ body = void 0;
83508
+ }
83509
+ if (response.status !== 200 || !isRecord5(body) || body.known !== true) {
83510
+ throw new Error("The activated credential root is not in the gateway known-root set; stop setup and reconcile the V2 activation");
83511
+ }
83512
+ }
83513
+
83514
+ // dist/cli.js
83480
83515
  var DEFAULT_GATEWAY_URL = "https://zk-credits-gateway.onrender.com";
83481
83516
  var DEFAULT_PORT = 3210;
83482
83517
  function stateDirectory() {
@@ -83672,7 +83707,7 @@ var GATEWAY_COUNTER_NAMES = [
83672
83707
  ];
83673
83708
  var GATEWAY_CLAIM_COUNT_NAMES = ["reserved", "ready", "committed", "cancelled"];
83674
83709
  var GATEWAY_READINESS_CHECK_NAMES = /* @__PURE__ */ new Set(["launchControl", "database", "baseRoot", "baseRpc", "verifierAssets", "provider"]);
83675
- function isRecord5(value) {
83710
+ function isRecord6(value) {
83676
83711
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
83677
83712
  }
83678
83713
  function safeCount(value) {
@@ -83699,42 +83734,15 @@ async function readGatewayJson(url, headers) {
83699
83734
  return { status: null };
83700
83735
  }
83701
83736
  }
83702
- async function requireGatewayKnownRoot(root) {
83703
- const origin = gatewayOrigin();
83704
- const token = process.env.BILLING_INTERNAL_TOKEN?.trim() || await readHiddenValue("Gateway admin token: ");
83705
- if (!token)
83706
- throw new Error("Base Sepolia V2 setup requires gateway admin access to check the activated credential root");
83707
- let response;
83708
- try {
83709
- response = await fetch(new URL("/v1/admin/root-known", origin), {
83710
- method: "POST",
83711
- headers: {
83712
- accept: "application/json",
83713
- authorization: `Bearer ${token}`,
83714
- "content-type": "application/json"
83715
- },
83716
- body: JSON.stringify({ root }),
83717
- signal: AbortSignal.timeout(1e4)
83718
- });
83719
- } catch {
83720
- throw new Error("The gateway could not confirm that the activated credential root is known");
83721
- }
83722
- let body;
83723
- try {
83724
- body = await response.json();
83725
- } catch {
83726
- body = void 0;
83727
- }
83728
- if (response.status !== 200 || !isRecord5(body) || body.known !== true) {
83729
- throw new Error("The activated credential root is not in the gateway known-root set; stop setup and reconcile the V2 activation");
83730
- }
83737
+ async function requireGatewayKnownRoot2(root) {
83738
+ await requireGatewayKnownRoot(root, gatewayOrigin());
83731
83739
  }
83732
83740
  async function gatewayReadiness(origin) {
83733
83741
  const response = await readGatewayJson(new URL("/ready", origin), { accept: "application/json" });
83734
- const report = isRecord5(response.body) ? response.body : void 0;
83742
+ const report = isRecord6(response.body) ? response.body : void 0;
83735
83743
  const checks = Array.isArray(report?.checks) ? report.checks : [];
83736
- const failedChecks = checks.flatMap((check) => isRecord5(check) && check.ok === true ? [] : [isRecord5(check) && typeof check.name === "string" && GATEWAY_READINESS_CHECK_NAMES.has(check.name) ? check.name : "unknown"]);
83737
- const hasLaunchCheck = checks.some((check) => isRecord5(check) && check.name === "launchControl" && check.ok === true);
83744
+ const failedChecks = checks.flatMap((check) => isRecord6(check) && check.ok === true ? [] : [isRecord6(check) && typeof check.name === "string" && GATEWAY_READINESS_CHECK_NAMES.has(check.name) ? check.name : "unknown"]);
83745
+ const hasLaunchCheck = checks.some((check) => isRecord6(check) && check.name === "launchControl" && check.ok === true);
83738
83746
  return {
83739
83747
  status: response.status,
83740
83748
  passed: response.status === 200 && report?.ready === true && failedChecks.length === 0 && hasLaunchCheck,
@@ -83746,12 +83754,12 @@ async function gatewayTrialSnapshot(origin, token) {
83746
83754
  accept: "application/json",
83747
83755
  authorization: `Bearer ${token}`
83748
83756
  });
83749
- const body = isRecord5(response.body) ? response.body : void 0;
83750
- const launch = isRecord5(body?.launchControl) ? body.launchControl : void 0;
83751
- const base = isRecord5(body?.base) ? body.base : void 0;
83752
- const spend = isRecord5(body?.spend) ? body.spend : void 0;
83753
- const rawMetrics = isRecord5(body?.metrics) ? body.metrics : void 0;
83754
- const rawClaims = isRecord5(body?.claims) ? body.claims : void 0;
83757
+ const body = isRecord6(response.body) ? response.body : void 0;
83758
+ const launch = isRecord6(body?.launchControl) ? body.launchControl : void 0;
83759
+ const base = isRecord6(body?.base) ? body.base : void 0;
83760
+ const spend = isRecord6(body?.spend) ? body.spend : void 0;
83761
+ const rawMetrics = isRecord6(body?.metrics) ? body.metrics : void 0;
83762
+ const rawClaims = isRecord6(body?.claims) ? body.claims : void 0;
83755
83763
  const metrics = {};
83756
83764
  const claims = {};
83757
83765
  let countersValid = Boolean(rawMetrics && rawClaims);
@@ -84039,7 +84047,7 @@ async function main() {
84039
84047
  const provider = await witnessProviderForSource(source, join7(stateDirectory(), "base-event-sync.json"));
84040
84048
  const witness = validateBaseCreditWitness(await provider.witnessForCredential(credential));
84041
84049
  if (manifest.deployment)
84042
- await requireGatewayKnownRoot(witness.root);
84050
+ await requireGatewayKnownRoot2(witness.root);
84043
84051
  },
84044
84052
  chooseCandidate: chooseSetupCandidate
84045
84053
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zk-credits",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "Loopback x402 zk-prepaid transport for private Base API credits.",
5
5
  "homepage": "https://feature-zk-api-credits-gadillacers-projects.vercel.app",
6
6
  "repository": {