zk-credits 0.2.9 → 0.2.11

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
@@ -1,248 +1,84 @@
1
- > Release candidate `0.2.9` is prepared for owner publication. Registry commands
2
- > below apply after publication; the existing `0.2.8` lacks this flow.
3
-
4
1
  # zk-credits
5
2
 
6
- Loopback sidecar that attaches a hash-pinned BN254 Groth16 proof to each
7
- coding-agent LLM request through the experimental x402 `zk-prepaid` scheme.
8
- Built for the invite-only experimental Base Sepolia pilot. Product calls use
9
- founder-provisioned test credits and have no product payment step; the circuit
10
- is not independently audited. External research participants in slots A and C
11
- receive $25 for a 30-minute session regardless of setup success. That payment
12
- is not product revenue or willingness-to-pay evidence.
3
+ API credits for Codex, Cline, and x402 agents. The local sidecar proves each
4
+ spend and forwards your request to the gateway.
13
5
 
14
- ```bash
15
- npm install --global zk-credits@0.2.9
16
- ```
6
+ Requires Node.js 20 or later. Runs on Base Sepolia.
17
7
 
18
- ## Pinned pilot versions
8
+ ## Quick start
19
9
 
20
- The pilot supports exactly these versions. Do not substitute another, and do
21
- not mix versions between the sidecar, the adapter package, and the gateway:
10
+ 1. [Activate your credits](https://hazecredits.vercel.app) and download your activated credential.
11
+ 2. Install the package and configure a Base Sepolia RPC endpoint:
22
12
 
23
- | Package | Version |
24
- | --- | --- |
25
- | `zk-credits` (this sidecar) | `0.2.9` |
26
- | `@zk-credits/x402-zk-prepaid` (adapter) | `0.1.0` |
27
- | `@zk-credits/shared` | `0.1.0` |
28
-
29
- The pinned Base Sepolia trial version is `0.2.9`. It includes passwordless
30
- OS credential storage, the hash-pinned proving archive, public Base Sepolia RPC
31
- by default, a narrow Codex Responses bridge, and the request-aware x402 adapter.
32
- Setup validates the public chain witness and gateway-known root. No private
33
- GitHub repository access or recovery password is required for the new flow.
34
-
35
- Verify the shipped artifacts before your first prove. The package's
36
- `circuits/manifest.json` fixes the SHA-256 of the frozen
37
- `private_credit_spend.wasm`, `private_credit_spend.zkey`, and
38
- `verification_key_private_credit.json`; compute the digest of each delivered
39
- file and compare it to the manifest. A mismatch is a proof failure, and the
40
- sidecar refuses to prove rather than sending a payment. The founder compares
41
- the same digests against the delivered set before inviting you.
42
-
43
- ## What one credit buys
44
-
45
- One credit buys one successfully committed response from the single service
46
- class `coding-deepseek-v4-flash-v1` (`deepseek/deepseek-v4-flash`). It is not
47
- an arbitrary API call, and the gateway enforces the class before it reserves
48
- the credit:
49
-
50
- - text messages, tool definitions, and tool calls, with one generated choice;
51
- - no provider streaming, images, files, audio, web search, model fallback,
52
- client-selected routing, or unknown cost-affecting fields;
53
- - input capped at 128,000 UTF-8 byte units (counted conservatively, never below the
54
- provider's token count), output at 4,000 tokens, request body at 256 KiB,
55
- encrypted replay at 1 MiB, and upstream timeout at 120 seconds.
56
-
57
- The requested `model` field is ignored: the gateway always dispatches the
58
- class model, so an OpenAI-compatible client configured with any model name
59
- still receives the class. A rejected request consumes no credit.
60
-
61
- ## First run
62
-
63
- 1. Sign in at https://hazecredits.vercel.app and redeem your invite. Save and
64
- reimport the passwordless recovery capsule, fund your pilot credential, then
65
- download the activated credential. Anyone possessing these files can spend
66
- their credits; keep them private.
67
- 2. Import the activated file and validate setup:
68
-
69
- ```bash
70
- export ZK_CREDITS_CREDENTIAL_PATH="$HOME/Downloads/zk-credits-credential.json"
71
- zk-credits setup codex
13
+ ```sh
14
+ npm install --global zk-credits
15
+ zk-credits config rpc
72
16
  ```
73
17
 
74
- For your own x402 agent, use `zk-credits setup x402` instead. Setup installs
75
- and verifies the packaged archive and artifact hashes, synchronizes public
76
- Base events from the manifest-pinned bond and deployment block, and checks
77
- the gateway-known root. Credentials enter OS secure storage: macOS Keychain,
78
- Windows Credential Manager, or persistent Linux Secret Service. Storage
79
- access approval may be needed; unavailable or denied storage fails closed.
80
- 3. Review consent, choose your task, and run `zk-credits codex` or
81
- `zk-credits x402-agent`. Subsequent launches use OS storage without a password
82
- or import file. The activated download remains a private recovery backup.
83
-
84
- The RPC defaults to https://sepolia.base.org. If the public endpoint is limited,
85
- run `zk-credits config rpc` and enter your own Base Sepolia endpoint in the hidden
86
- local prompt. Saved settings stay owner-only; `BASE_RPC_URL` takes precedence.
87
- Provider keys must not appear in chat or evidence. No gateway admin token is
88
- needed for operator setup.
89
-
90
- Existing encrypted exports require `zk-credits setup codex --legacy` (or
91
- `setup x402 --legacy`) and their original password in a hidden local prompt.
92
- A missing or altered proving artifact fails closed before payment creation.
93
- Setup and proving stay local; no supplied witness file is accepted for the
94
- manifest-pinned V2 deployment.
95
-
96
- The sidecar binds `127.0.0.1:3210` only. It does not modify `~/.cline` or
97
- `~/.codex`.
98
-
99
- ## Supported route
100
-
101
- The pilot serves one bounded upstream spend path: non-streaming
102
- `POST /v1/chat/completions`, either through this sidecar or through an
103
- x402-native agent that explicitly registers the project `zk-prepaid` adapter.
104
- The sidecar also accepts Codex `POST /v1/responses` requests with text input
105
- and function tools, translates them to that bounded chat request, and converts
106
- the committed result into Responses SSE events. It rejects unsupported fields
107
- before starting a proof. Generic x402 clients, public facilitators, Bazaar,
108
- MCP, and the standard `exact` rail are unsupported; the sidecar never falls
109
- back to another rail.
110
-
111
- | Route | Auth | Purpose |
112
- | --- | --- | --- |
113
- | `GET /health` | none | Liveness for the local launcher |
114
- | `GET /v1/models` | local token | Codex model discovery |
115
- | `GET /metrics` | local token | Aggregate proof metrics (below) |
116
- | `POST /v1/chat/completions` | local token | The only proving and spend path |
117
- | `POST /v1/responses` | local token | Codex bridge to the bounded chat spend path |
118
-
119
- The chat route rejects streaming bodies (`stream`, `stream_options`) and a
120
- missing `model` with a `4xx` before any proof. The Responses route requires
121
- `stream: true`, text-only message/function-call input, and the known Codex
122
- metadata fields; it rejects images, unsupported tools, and unknown controls
123
- before any proof. Its upstream request is always `stream: false`. Anthropic
124
- `/v1/messages` and unknown paths return `404 unsupported_openai_path`. The
125
- sidecar never substitutes a model and never falls back to another rail.
126
-
127
- ### Gateway responses and retries
128
-
129
- | Response | Meaning | What to do |
130
- | --- | --- | --- |
131
- | `402` | No usable authorization, or a stale or invalid one | Re-prove against the fresh challenge |
132
- | `409 claim_already_committed` | Your exact request already succeeded | Read `encryptedReplay` from the response, or fetch it from `POST /x402/replay`; do not re-prove |
133
- | `409 claim_commit_ambiguous` | The commit outcome is unknown | Retry the same request; never re-prove a different one |
134
- | `503 pilot_paused` | The operator paused the pilot | Wait. This is retryable, consumes no credit, and is not a proof failure |
135
- | `503 provider_spend_cap_exhausted` | The provider-spend cap paused the pilot | Wait for the operator to review. No credit was consumed |
136
- | `503 claim_store_unavailable` | Transient gateway fault | Retry with backoff |
137
-
138
- The gateway never asks you to re-prove for its own account. A `503` is
139
- retryable and free; a proof failure is local and never reaches the gateway.
140
-
141
- ## Proof path
142
-
143
- - Local artifacts only, hash-pinned against the shipped manifest.
144
- - One prove at a time per sidecar process, in a terminable child-process
145
- worker with a 10-second deadline. (snarkjs cannot run inside a Node
146
- `worker_threads` worker: its `web-worker` polyfill re-enters itself there.)
147
- - Every proof is self-verified locally with the pinned verification key
148
- before `PAYMENT-SIGNATURE` can be emitted, and its six public signals must
149
- exactly match `[root, timestamp, domain, requestSignal, nullifier, share]`.
150
- - A failed attempt retries with the same slot, request signal, nonce,
151
- response key, and gateway `issuedAt` while more than ten seconds remain in
152
- the challenge window.
153
- - A slot is provisional during proving and recorded in the durable local
154
- ledger (`$ZK_CREDITS_HOME/base-slots.json`) only after self-verification.
155
- Proof misses, timeouts, hash failures, and verification failures release
156
- it.
157
-
158
- ## `GET /metrics`
159
-
160
- Aggregate only, authenticated with the same local token:
161
-
162
- ```json
163
- {
164
- "attempts": 12,
165
- "successes": 11,
166
- "failures": 1,
167
- "retries": 1,
168
- "failuresByCategory": { "timeout": 1, "artifact_hash_mismatch": 0, "...": 0 },
169
- "hotProve": { "samples": 11, "p50Ms": 1180.4, "p95Ms": 1902.7 },
170
- "updatedAt": "2026-09-20T14:00:00.000Z"
171
- }
172
- ```
18
+ 3. Import your credential and connect Codex:
19
+
20
+ ```sh
21
+ ZK_CREDITS_CREDENTIAL_PATH=/path/to/activated-credential.json zk-credits setup codex
22
+ zk-credits codex
23
+ ```
173
24
 
174
- The first prove in a process is the cold sample and is excluded from the hot
175
- percentiles. Proofs, public signals, nullifiers, credentials, requests, and
176
- any identifying label are never recorded or exposed.
25
+ Setup stores your credential in OS secure storage. Keep your recovery file
26
+ private: anyone with it can spend your credits.
177
27
 
178
28
  ## Commands
179
29
 
180
- ```
181
- zk-credits cline [cline arguments...]
182
- zk-credits setup codex [--model <model>] [--legacy]
183
- zk-credits setup x402 [--legacy]
184
- zk-credits config rpc
185
- zk-credits codex [codex arguments...]
186
- zk-credits status
187
- zk-credits serve [--port <port>] [--internal-trial-one-proof]
188
- zk-credits x402-agent
189
- zk-credits founder-demo-agent
190
- zk-credits trial-registered-adapter
191
- eval "$(zk-credits env)"
30
+ | Command | Purpose |
31
+ | --- | --- |
32
+ | `zk-credits setup codex` | Import a credential and configure Codex |
33
+ | `zk-credits setup x402` | Prepare an x402 agent |
34
+ | `zk-credits codex [args...]` | Start Codex with the local sidecar |
35
+ | `zk-credits cline [args...]` | Start Cline with the local sidecar |
36
+ | `zk-credits x402-agent` | Run the included x402 agent |
37
+ | `zk-credits serve` | Run the sidecar in the foreground |
38
+ | `zk-credits doctor` | Inspect the service, PID, setup, RPC source, and log location |
39
+ | `zk-credits stop` | Stop the local sidecar |
40
+ | `zk-credits status` | Check the Codex configuration and sidecar |
41
+ | `zk-credits config rpc` | Save or change your Base Sepolia RPC endpoint |
42
+ | `zk-credits --help` | Show command and troubleshooting guidance |
43
+
44
+ `doctor` and `stop` are available in version 0.2.11. They work before setup.
45
+ The default port is `3210`; set `ZK_CREDITS_SIDECAR_PORT` to select another port.
46
+ Automatic startup logs are saved to `~/.zk-credits/sidecar.log`, or
47
+ `$ZK_CREDITS_HOME/sidecar.log` when set.
48
+
49
+ ## Troubleshooting
50
+
51
+ **Sidecar stopped or setup missing:** Run `zk-credits doctor`. If setup is
52
+ missing, import your activated credential with the setup command above.
53
+ Otherwise run `zk-credits serve` and read its output.
54
+
55
+ **Port occupied or “Server is not running”:** `x402-agent` starts its own local
56
+ server. Run `zk-credits stop` before switching from `serve` to `x402-agent`.
57
+ For older versions, inspect the listener before stopping it:
58
+
59
+ ```sh
60
+ lsof -nP -iTCP:3210 -sTCP:LISTEN
61
+ ps -p <PID> -o pid,ppid,etime,command
62
+ kill -TERM <PID>
192
63
  ```
193
64
 
194
- `serve --internal-trial-one-proof` is an opt-in maintainer mode for the
195
- internal Base Sepolia trial. During that process lifetime, one authenticated,
196
- valid spend request may reach the prepaid transport and the proof factory may
197
- attempt one proof. A later valid request receives HTTP 409 with
198
- `internal_trial_limit_reached`; ordinary `serve` behavior is unchanged without
199
- the flag.
200
-
201
- `trial-registered-adapter` is a maintainer-only internal trial command. It
202
- requires the locally recovered credential and pinned proving bundle, prompts
203
- for the credential password and gateway admin token without echo when they are
204
- not already configured, and requires an explicit confirmation before sending
205
- one billable request. It checks gateway readiness, authenticated admin status,
206
- Base root agreement, Codex profile/sidecar status, and remaining local slot
207
- capacity, then reports only the exchange phases and aggregate counter deltas.
208
- Run it only after recovery is complete and with the same `ZK_CREDITS_HOME`
209
- used by the sidecar; it registers `zk-prepaid` directly through the official
210
- x402 client adapter and reuses the durable slot ledger.
211
-
212
- Codex SDK:
213
-
214
- ```ts
215
- import { buildCodexSdkOptions, buildCodexThreadOptions } from 'zk-credits/codex';
216
- ```
65
+ Check the PID and command to confirm it is your sidecar. For a foreground
66
+ process, press Ctrl+C. `stop` authenticates the service and lets active requests
67
+ finish before exit.
217
68
 
218
- `zk-credits/x402` exports `createLocalX402Agent` for an operator who is
219
- integrating the adapter into their own x402 agent. It loads the same local
220
- credential, pinned proof artifacts, public witness, proof engine, and slot
221
- ledger used by the sidecar. The request-aware client binds the actual method,
222
- URL, and body into each spend; its metrics endpoint exposes authenticated
223
- aggregate counters on loopback. See
224
- [`docs/onboarding/base-zk-credits-x402-agent.md`](../../docs/onboarding/base-zk-credits-x402-agent.md)
225
- for integration and measured-call steps. The included `zk-credits x402-agent`
226
- command is a small task-running starter for the founder demo and local
227
- rehearsal; external slot C uses their own agent.
228
-
229
- The credential secret is loaded from OS secure storage only into local memory. The sidecar cache
230
- contains public Base event leaves and never stores the secret, prompt, response,
231
- proof, account, or wallet.
232
-
233
- ## Validation
234
-
235
- ```bash
236
- npm test # unit + fixture suites
237
- npm run build # tsc + bundled CLI
238
- ZK_CREDITS_ARTIFACT_DIR="$PWD/circuits/artifacts" \
239
- npx vitest run pinned-artifacts # opt-in real fullProve + self-verify
240
- ```
69
+ **Base witness synchronization failed:** Run `zk-credits config rpc` and enter
70
+ a Base Sepolia endpoint (chain ID `84532`). Stop and restart the sidecar, or
71
+ retry setup if it failed. `BASE_RPC_URL` overrides the saved endpoint.
72
+ A missing funded credential or rejected root can require activation checks;
73
+ changing the RPC may not resolve it.
74
+
75
+ ## Clients and privacy
76
+
77
+ Codex and Cline use the local OpenAI-compatible transport. Your own x402 agent
78
+ must register the custom `zk-prepaid` adapter; generic x402 clients do not
79
+ support this scheme automatically. See the [x402 integration guide](https://github.com/mangekyou-labs/haze-api/blob/main/docs/onboarding/base-zk-credits-x402-agent.md).
241
80
 
242
- The opt-in artifact test needs an installed bundle and the built
243
- `dist/proof-child.js`. CI stays deterministic through injected worker and
244
- crypto fixtures; the default suites stay green with no bundle installed.
81
+ Your credential stays on your device. Proofs are sent to authorize each spend. The gateway and model provider receive request content and
82
+ can observe traffic metadata. This does not hide your IP address.
245
83
 
246
- Base Sepolia only. The circuit is experimental and not independently audited.
247
- Development proving material is not suitable for mainnet; the repository's
248
- release gates require an audited production circuit and ceremony.
84
+ Base Sepolia test credits only. The circuit is not independently audited.
package/dist/cli.js CHANGED
@@ -15,6 +15,7 @@ import { createZkPrepaidLifecycleMetrics } from '@zk-credits/x402-zk-prepaid';
15
15
  import { BaseSlotLedger } from './slot-ledger.js';
16
16
  import { nativeCredentialStore, importCredentialPath, readStoredCredential } from './credential-store.js';
17
17
  import { applyRpcConfig, checkBaseSepoliaRpc, writeRpcConfig, RPC_GUIDANCE, resolveBaseSepoliaRpc } from './rpc-config.js';
18
+ import { diagnoseSidecar, stopSidecar } from './sidecar-diagnostics.js';
18
19
  import { runCliCommand } from './cli-runtime.js';
19
20
  import { createNodeSidecarLifecycle } from './node-sidecar-lifecycle.js';
20
21
  import { activateSidecarServer } from './server-startup.js';
@@ -145,6 +146,8 @@ function printHelp() {
145
146
  zk-credits setup [codex|x402] [--legacy] [--model <model>]
146
147
  zk-credits codex [codex arguments...]
147
148
  zk-credits status
149
+ zk-credits doctor
150
+ zk-credits stop
148
151
  zk-credits serve [--port <port>] [--internal-trial-one-proof]
149
152
  zk-credits x402-agent
150
153
  zk-credits founder-demo-agent
@@ -159,12 +162,24 @@ the request-aware x402 adapter and local proof engine. It requires explicit
159
162
  confirmation before one billable internal exchange; the task and response are
160
163
  displayed locally and never added to activation evidence.
161
164
  "zk-credits x402-agent" is a small task-running starter for the participant's
162
- own x402 agent loop. It asks for tasks locally and sends each through the same
165
+ own x402 agent loop. It starts its own metrics server on the selected sidecar port;
166
+ stop an existing sidecar before launching it. It asks for tasks locally and sends each through the same
163
167
  request-aware adapter and local proof engine; aggregate metrics stay on the
164
168
  loopback-only authenticated endpoint.
165
169
  "zk-credits serve --internal-trial-one-proof" limits this sidecar process to
166
170
  one authenticated, valid spend request and one local proof attempt.
167
- Base Sepolia uses https://sepolia.base.org automatically. Public RPC endpoints
171
+ "zk-credits doctor" reports health, authenticated PID, setup and RPC configuration
172
+ presence, and log location without starting a server or revealing secrets.
173
+ "zk-credits stop" gracefully drains the authenticated sidecar. For older versions,
174
+ inspect the listener with lsof -nP -iTCP:3210 -sTCP:LISTEN, verify its PID with
175
+ ps -p <PID> -o pid,ppid,etime,command, then kill -TERM <PID>. Foreground: Ctrl+C.
176
+ Use ZK_CREDITS_SIDECAR_PORT for doctor, stop, status and env with a custom port.
177
+ If serve reports missing setup, run:
178
+ ZK_CREDITS_CREDENTIAL_PATH=/path/to/activated-credential.json zk-credits setup
179
+ If the sidecar is stopped after setup, run zk-credits serve.
180
+ For RPC witness synchronization failures, run zk-credits config rpc and then
181
+ zk-credits stop followed by zk-credits serve. BASE_RPC_URL overrides the saved RPC.
182
+ Base Sepolia uses the launch endpoint baked into the package automatically. RPC endpoints
168
183
  are rate-limited; run "zk-credits config rpc" to use your own endpoint.
169
184
  Provider guide: https://docs.base.org/base-chain/node-operators/node-providers
170
185
  Set ZK_CREDITS_CREDENTIAL_PATH to the activated browser download for first setup.
@@ -182,7 +197,7 @@ async function loadBaseClientRuntime() {
182
197
  const witnessPath = process.env.ZK_CREDITS_WITNESS_PATH;
183
198
  const artifactDirectory = process.env.ZK_CREDITS_ARTIFACT_DIR;
184
199
  if (!artifactDirectory) {
185
- throw new Error('Set ZK_CREDITS_ARTIFACT_DIR to the directory holding the installed pinned proving bundle');
200
+ throw new Error('Proving bundle is not configured. Run zk-credits setup first; use ZK_CREDITS_CREDENTIAL_PATH=/path/to/activated-credential.json zk-credits setup for first import. Run zk-credits doctor to inspect setup.');
186
201
  }
187
202
  const baseRpcUrl = process.env.BASE_RPC_URL;
188
203
  const baseContractAddress = process.env.BASE_PRIVATE_CREDIT_BOND_ADDRESS;
@@ -581,6 +596,12 @@ async function serve(args) {
581
596
  prepaidClient: prepaid.client,
582
597
  internalTrialOneProof,
583
598
  metrics: () => ({ ...proofMetrics.snapshot(), exchange: exchangeMetrics.snapshot() }),
599
+ onShutdown: () => {
600
+ void shutdown().catch((error) => {
601
+ console.error(error instanceof Error ? error.message : 'Sidecar shutdown failed');
602
+ process.exitCode = 1;
603
+ });
604
+ },
584
605
  });
585
606
  let address;
586
607
  try {
@@ -595,20 +616,33 @@ async function serve(args) {
595
616
  }
596
617
  console.log(`ZK Credits sidecar listening on ${address}/v1`);
597
618
  console.log('Run eval "$(zk-credits env)" in the client shell.');
598
- const shutdown = async () => {
599
- await sidecar.close();
600
- process.exit(0);
619
+ let shutdownPromise;
620
+ const shutdown = () => {
621
+ shutdownPromise ??= sidecar.close().then(() => { process.exit(0); });
622
+ return shutdownPromise;
601
623
  };
602
624
  process.once('SIGINT', () => { void shutdown(); });
603
625
  process.once('SIGTERM', () => { void shutdown(); });
604
626
  }
605
627
  async function main() {
606
628
  const args = process.argv.slice(2);
607
- if (args[0] === '--help' || args[0] === '-h' || !args[0]) {
629
+ const localHelp = ['doctor', 'stop', 'status', 'serve', 'setup', 'config'].includes(args[0] ?? '')
630
+ && args.slice(1).some((arg) => arg === '--help' || arg === '-h');
631
+ if (args[0] === '--help' || args[0] === '-h' || !args[0] || localHelp) {
608
632
  printHelp();
609
633
  return;
610
634
  }
611
635
  const sidecarHome = stateDirectory();
636
+ if (args[0] === 'doctor' || args[0] === 'stop') {
637
+ if (args.length !== 1)
638
+ throw new Error(`Usage: zk-credits ${args[0]} (use ZK_CREDITS_SIDECAR_PORT to select a port)`);
639
+ const options = { baseUrl: loopbackBaseUrl(), stateDirectory: sidecarHome, write: (line) => console.log(line) };
640
+ if (args[0] === 'doctor')
641
+ await diagnoseSidecar(options);
642
+ else
643
+ await stopSidecar(options);
644
+ return;
645
+ }
612
646
  if (args[0] === 'config' && args[1] === 'rpc' && args.length === 2) {
613
647
  console.log(RPC_GUIDANCE);
614
648
  const rpc = await checkBaseSepoliaRpc(await readHiddenValue('Base Sepolia RPC URL (hidden): '));
@@ -717,6 +751,11 @@ async function main() {
717
751
  process.exitCode = exitCode;
718
752
  }
719
753
  void main().catch((error) => {
720
- console.error(error instanceof Error ? error.message : 'zk-credits failed');
754
+ if (error?.code === 'EADDRINUSE') {
755
+ console.error('The local port is already occupied. Run zk-credits doctor to identify the listener. Stop the existing sidecar with zk-credits stop (older sidecars: inspect the PID before kill -TERM <PID>), then retry. x402-agent starts its own local metrics server and does not reuse serve.');
756
+ }
757
+ else {
758
+ console.error(error instanceof Error ? error.message : 'zk-credits failed');
759
+ }
721
760
  process.exitCode = 1;
722
761
  });
@@ -46,7 +46,7 @@ export async function importStoredCredential(file, store, legacyPassword) {
46
46
  export async function readStoredCredential(store) {
47
47
  const raw = await store.read();
48
48
  if (!raw)
49
- throw new Error('No credential in OS storage. Download your activated credential and run zk-credits setup first.');
49
+ throw new Error('No credential in OS storage. Download your activated credential and run zk-credits setup first: ZK_CREDITS_CREDENTIAL_PATH=/path/to/activated-credential.json zk-credits setup.');
50
50
  try {
51
51
  const saved = JSON.parse(raw);
52
52
  if (saved.version !== 1 || !saved.credential)
@@ -165490,7 +165490,7 @@ function nativeCredentialStore(stateDirectory) {
165490
165490
  async function readStoredCredential(store) {
165491
165491
  const raw = await store.read();
165492
165492
  if (!raw)
165493
- throw new Error("No credential in OS storage. Download your activated credential and run zk-credits setup first.");
165493
+ throw new Error("No credential in OS storage. Download your activated credential and run zk-credits setup first: ZK_CREDITS_CREDENTIAL_PATH=/path/to/activated-credential.json zk-credits setup.");
165494
165494
  try {
165495
165495
  const saved = JSON.parse(raw);
165496
165496
  if (saved.version !== 1 || !saved.credential)
@@ -165511,11 +165511,14 @@ async function readStoredCredential(store) {
165511
165511
  // dist/rpc-config.js
165512
165512
  import { chmod, lstat, mkdir, open, readFile, rename, rm } from "node:fs/promises";
165513
165513
  import { dirname, join } from "node:path";
165514
- var DEFAULT_BASE_SEPOLIA_RPC_URL = "https://sepolia.base.org";
165514
+ var DEFAULT_BASE_SEPOLIA_RPC_URL = "https://base-sepolia.infura.io/v3/4d7561cbe56f49fe8cdf30d46f609806";
165515
165515
  function resolveBaseSepoliaRpc(environment, legacyRpc) {
165516
- return environment.BASE_RPC_URL?.trim() || legacyRpc?.trim() || DEFAULT_BASE_SEPOLIA_RPC_URL;
165516
+ const rpc = environment.BASE_RPC_URL?.trim() || legacyRpc?.trim() || DEFAULT_BASE_SEPOLIA_RPC_URL;
165517
+ if (rpc === "__ZK_CREDITS_RELEASE_RPC_URL__")
165518
+ throw new Error("Release RPC has not been baked. Set BASE_RPC_URL or build the release package.");
165519
+ return rpc;
165517
165520
  }
165518
- var RPC_GUIDANCE = "The built-in public Base Sepolia endpoint is rate-limited. To use your own endpoint (chain ID 84532), run zk-credits config rpc. Providers: https://docs.base.org/base-chain/node-operators/node-providers .";
165521
+ var RPC_GUIDANCE = "The package uses the release Base Sepolia endpoint by default. To use your own endpoint (chain ID 84532), run zk-credits config rpc. After changing the RPC, run zk-credits stop then zk-credits serve; retry setup if it has not completed. BASE_RPC_URL overrides the saved setting. Providers: https://docs.base.org/base-chain/node-operators/node-providers .";
165519
165522
  function validateRpcUrl(value) {
165520
165523
  try {
165521
165524
  const url = new URL(value.trim());
@@ -167308,6 +167311,23 @@ function createSidecarServer(options) {
167308
167311
  return;
167309
167312
  }
167310
167313
  const token = extractLocalToken(req);
167314
+ if (req.method === "GET" && pathname === "/runtime" || req.method === "POST" && pathname === "/shutdown") {
167315
+ if (token !== options.localToken) {
167316
+ sendJson(res, 401, { error: "invalid_local_token" });
167317
+ return;
167318
+ }
167319
+ if (pathname === "/runtime") {
167320
+ sendJson(res, 200, { service: "zk-credits-sidecar", pid: process.pid });
167321
+ } else if (options.onShutdown) {
167322
+ res.once("finish", () => {
167323
+ setImmediate(() => options.onShutdown());
167324
+ });
167325
+ sendJson(res, 202, { service: "zk-credits-sidecar", status: "stopping" });
167326
+ } else {
167327
+ sendJson(res, 404, { error: "shutdown_unavailable" });
167328
+ }
167329
+ return;
167330
+ }
167311
167331
  if (req.method === "GET" && pathname === "/v1/models") {
167312
167332
  if (token !== options.localToken) {
167313
167333
  sendJson(res, 401, { error: "invalid_local_token" });
@@ -167406,6 +167426,10 @@ function createSidecarServer(options) {
167406
167426
  return;
167407
167427
  const activeServer = server;
167408
167428
  server = null;
167429
+ if (!activeServer.listening) {
167430
+ await Promise.all(inFlight);
167431
+ return;
167432
+ }
167409
167433
  await new Promise((resolve4, reject) => activeServer.close((error) => {
167410
167434
  if (error)
167411
167435
  reject(error);
@@ -1,6 +1,6 @@
1
- export declare const DEFAULT_BASE_SEPOLIA_RPC_URL = "https://sepolia.base.org";
1
+ export declare const DEFAULT_BASE_SEPOLIA_RPC_URL = "__ZK_CREDITS_RELEASE_RPC_URL__";
2
2
  export declare function resolveBaseSepoliaRpc(environment: NodeJS.ProcessEnv, legacyRpc?: string): string;
3
- export declare const RPC_GUIDANCE = "The built-in public Base Sepolia endpoint is rate-limited. To use your own endpoint (chain ID 84532), run zk-credits config rpc. Providers: https://docs.base.org/base-chain/node-operators/node-providers .";
3
+ export declare const RPC_GUIDANCE = "The package uses the release Base Sepolia endpoint by default. To use your own endpoint (chain ID 84532), run zk-credits config rpc. After changing the RPC, run zk-credits stop then zk-credits serve; retry setup if it has not completed. BASE_RPC_URL overrides the saved setting. Providers: https://docs.base.org/base-chain/node-operators/node-providers .";
4
4
  export declare function validateRpcUrl(value: string): string;
5
5
  export declare function checkBaseSepoliaRpc(value: string, request?: typeof fetch): Promise<string>;
6
6
  export declare function readRpcConfig(directory: string): Promise<string | undefined>;
@@ -1,11 +1,14 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { chmod, lstat, mkdir, open, readFile, rename, rm } from 'node:fs/promises';
3
3
  import { dirname, join } from 'node:path';
4
- export const DEFAULT_BASE_SEPOLIA_RPC_URL = 'https://sepolia.base.org';
4
+ export const DEFAULT_BASE_SEPOLIA_RPC_URL = "https://base-sepolia.infura.io/v3/4d7561cbe56f49fe8cdf30d46f609806";
5
5
  export function resolveBaseSepoliaRpc(environment, legacyRpc) {
6
- return environment.BASE_RPC_URL?.trim() || legacyRpc?.trim() || DEFAULT_BASE_SEPOLIA_RPC_URL;
6
+ const rpc = environment.BASE_RPC_URL?.trim() || legacyRpc?.trim() || DEFAULT_BASE_SEPOLIA_RPC_URL;
7
+ if (rpc === '__ZK_CREDITS_RELEASE_RPC_URL__')
8
+ throw new Error('Release RPC has not been baked. Set BASE_RPC_URL or build the release package.');
9
+ return rpc;
7
10
  }
8
- export const RPC_GUIDANCE = 'The built-in public Base Sepolia endpoint is rate-limited. To use your own endpoint (chain ID 84532), run zk-credits config rpc. Providers: https://docs.base.org/base-chain/node-operators/node-providers .';
11
+ export const RPC_GUIDANCE = 'The package uses the release Base Sepolia endpoint by default. To use your own endpoint (chain ID 84532), run zk-credits config rpc. After changing the RPC, run zk-credits stop then zk-credits serve; retry setup if it has not completed. BASE_RPC_URL overrides the saved setting. Providers: https://docs.base.org/base-chain/node-operators/node-providers .';
9
12
  export function validateRpcUrl(value) {
10
13
  try {
11
14
  const url = new URL(value.trim());
@@ -201,7 +201,7 @@ async function resolveWitnessSource(options, saved) {
201
201
  const explicitPath = environment.ZK_CREDITS_WITNESS_PATH?.trim();
202
202
  if (explicitPath) {
203
203
  if (options.manifest.deployment) {
204
- throw new Error('Base Sepolia V2 setup requires a witness synchronized from the pinned public Base events');
204
+ throw new Error('Base Sepolia V2 setup requires a witness synchronized from the pinned public Base events. Unset ZK_CREDITS_WITNESS_PATH, run zk-credits config rpc, and retry zk-credits setup');
205
205
  }
206
206
  const source = {
207
207
  kind: 'file',
@@ -239,7 +239,7 @@ async function resolveWitnessSource(options, saved) {
239
239
  }
240
240
  }
241
241
  if (options.manifest.deployment) {
242
- throw new Error('Base Sepolia V2 setup requires BASE_RPC_URL to sync the pinned V2 bond from its deployment block');
242
+ throw new Error('Base Sepolia V2 setup requires BASE_RPC_URL to sync the pinned V2 bond from its deployment block. Run zk-credits config rpc, then retry zk-credits setup');
243
243
  }
244
244
  if (saved?.witness.kind === 'file') {
245
245
  try {
@@ -0,0 +1,7 @@
1
+ export interface DiagnosticOptions {
2
+ baseUrl: string;
3
+ stateDirectory: string;
4
+ write(line: string): void;
5
+ }
6
+ export declare function diagnoseSidecar(options: DiagnosticOptions): Promise<void>;
7
+ export declare function stopSidecar(options: DiagnosticOptions): Promise<void>;