@blockrun/llm 3.13.6 → 3.14.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.cjs CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  APIError: () => APIError,
34
+ API_KEY_URL: () => API_KEY_URL,
34
35
  AnthropicClient: () => AnthropicClient,
35
36
  BASE_CHAIN_ID: () => BASE_CHAIN_ID,
36
37
  BlockrunClient: () => BlockrunClient,
@@ -42,6 +43,7 @@ __export(index_exports, {
42
43
  NETWORK_ALIASES: () => NETWORK_ALIASES,
43
44
  OpenAI: () => OpenAI,
44
45
  PHONE_PRICES: () => PHONE_PRICES,
46
+ PORTAL_URL: () => PORTAL_URL,
45
47
  PORTRAIT_ENROLLMENT_PRICE_USD: () => PORTRAIT_ENROLLMENT_PRICE_USD,
46
48
  PaymentError: () => PaymentError,
47
49
  PhoneClient: () => PhoneClient,
@@ -99,6 +101,7 @@ __export(index_exports, {
99
101
  scanSolanaWallets: () => scanSolanaWallets,
100
102
  scanWallets: () => scanWallets2,
101
103
  setCache: () => setCache,
104
+ setupAgentClient: () => setupAgentClient,
102
105
  setupAgentSolanaWallet: () => setupAgentSolanaWallet,
103
106
  setupAgentWallet: () => setupAgentWallet,
104
107
  solanaClient: () => solanaClient,
@@ -112,9 +115,6 @@ __export(index_exports, {
112
115
  });
113
116
  module.exports = __toCommonJS(index_exports);
114
117
 
115
- // src/client.ts
116
- var import_accounts2 = require("viem/accounts");
117
-
118
118
  // src/types.ts
119
119
  var BlockrunError = class extends Error {
120
120
  constructor(message) {
@@ -136,6 +136,8 @@ var PaymentError = class extends BlockrunError {
136
136
  };
137
137
  var APIError = class extends BlockrunError {
138
138
  statusCode;
139
+ /** Retry-After header returned by the account API. */
140
+ retryAfter;
139
141
  response;
140
142
  constructor(message, statusCode, response) {
141
143
  super(message);
@@ -145,6 +147,248 @@ var APIError = class extends BlockrunError {
145
147
  }
146
148
  };
147
149
 
150
+ // src/validation.ts
151
+ var LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
152
+ var KNOWN_PROVIDERS = /* @__PURE__ */ new Set([
153
+ "openai",
154
+ "anthropic",
155
+ "google",
156
+ "deepseek",
157
+ "mistralai",
158
+ "meta-llama",
159
+ "together",
160
+ "xai",
161
+ "moonshot",
162
+ "nvidia",
163
+ "minimax",
164
+ "zai"
165
+ ]);
166
+ function validateModel(model) {
167
+ if (!model || typeof model !== "string") {
168
+ throw new Error("Model must be a non-empty string");
169
+ }
170
+ }
171
+ function validateMaxTokens(maxTokens) {
172
+ if (maxTokens === void 0 || maxTokens === null) {
173
+ return;
174
+ }
175
+ if (typeof maxTokens !== "number" || !Number.isInteger(maxTokens)) {
176
+ throw new Error("maxTokens must be an integer");
177
+ }
178
+ if (maxTokens < 1) {
179
+ throw new Error("maxTokens must be positive (minimum: 1)");
180
+ }
181
+ }
182
+ function validateTemperature(temperature) {
183
+ if (temperature === void 0 || temperature === null) {
184
+ return;
185
+ }
186
+ if (typeof temperature !== "number") {
187
+ throw new Error("temperature must be a number");
188
+ }
189
+ if (temperature < 0 || temperature > 2) {
190
+ throw new Error("temperature must be between 0 and 2");
191
+ }
192
+ }
193
+ function validateTopP(topP) {
194
+ if (topP === void 0 || topP === null) {
195
+ return;
196
+ }
197
+ if (typeof topP !== "number") {
198
+ throw new Error("topP must be a number");
199
+ }
200
+ if (topP < 0 || topP > 1) {
201
+ throw new Error("topP must be between 0 and 1");
202
+ }
203
+ }
204
+ function validatePrivateKey(key) {
205
+ if (typeof key !== "string") {
206
+ throw new Error("Private key must be a string");
207
+ }
208
+ if (!key.startsWith("0x")) {
209
+ throw new Error("Private key must start with 0x");
210
+ }
211
+ if (key.length !== 66) {
212
+ throw new Error(
213
+ "Private key must be 66 characters (0x + 64 hexadecimal characters)"
214
+ );
215
+ }
216
+ if (!/^0x[0-9a-fA-F]{64}$/.test(key)) {
217
+ throw new Error(
218
+ "Private key must contain only hexadecimal characters (0-9, a-f, A-F)"
219
+ );
220
+ }
221
+ }
222
+ function validateApiUrl(url) {
223
+ let parsed;
224
+ try {
225
+ parsed = new URL(url);
226
+ } catch {
227
+ throw new Error("Invalid API URL format");
228
+ }
229
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
230
+ throw new Error(
231
+ `Invalid protocol: ${parsed.protocol}. Use http:// or https://`
232
+ );
233
+ }
234
+ const isLocalhost = LOCALHOST_DOMAINS.includes(parsed.hostname);
235
+ if (parsed.protocol !== "https:" && !isLocalhost) {
236
+ throw new Error(
237
+ `API URL must use HTTPS for non-localhost endpoints. Use https:// instead of ${parsed.protocol}//`
238
+ );
239
+ }
240
+ }
241
+ function sanitizeErrorResponse(errorBody) {
242
+ if (typeof errorBody !== "object" || errorBody === null) {
243
+ return { message: "API request failed" };
244
+ }
245
+ const body = errorBody;
246
+ return {
247
+ message: typeof body.error === "string" ? body.error : "API request failed",
248
+ code: typeof body.code === "string" ? body.code : void 0
249
+ };
250
+ }
251
+ function validateResourceUrl(url, baseUrl) {
252
+ try {
253
+ const parsed = new URL(url);
254
+ const baseParsed = new URL(baseUrl);
255
+ if (parsed.hostname !== baseParsed.hostname) {
256
+ console.warn(
257
+ `Resource URL hostname mismatch: ${parsed.hostname} vs ${baseParsed.hostname}. Using safe default instead.`
258
+ );
259
+ return `${baseUrl}/v1/chat/completions`;
260
+ }
261
+ if (parsed.protocol !== baseParsed.protocol) {
262
+ console.warn(
263
+ `Resource URL protocol mismatch: ${parsed.protocol} vs ${baseParsed.protocol}. Using safe default instead.`
264
+ );
265
+ return `${baseUrl}/v1/chat/completions`;
266
+ }
267
+ return url;
268
+ } catch {
269
+ console.warn(`Invalid resource URL format: ${url}. Using safe default.`);
270
+ return `${baseUrl}/v1/chat/completions`;
271
+ }
272
+ }
273
+
274
+ // src/api-key.ts
275
+ var TRANSIENT_STATUS = /* @__PURE__ */ new Set([502, 503, 504, 522, 524]);
276
+ var TRANSIENT_RETRIES = 2;
277
+ var TRANSIENT_BACKOFF_MS = 1e3;
278
+ var API_KEY_URL = "https://api.blockrun.ai";
279
+ var PORTAL_URL = "https://user.blockrun.ai";
280
+ function resolveApiKeyAuth(options) {
281
+ if (options.apiKey !== void 0 && options.privateKey !== void 0) {
282
+ throw new Error("Pass either apiKey or privateKey, not both.");
283
+ }
284
+ const key = options.apiKey ?? (options.privateKey === void 0 && typeof process !== "undefined" ? process.env?.BLOCKRUN_API_KEY : void 0);
285
+ if (key === void 0) return void 0;
286
+ if (!/^brk_[A-Za-z0-9_-]+$/.test(key.trim())) {
287
+ throw new Error(`Invalid BlockRun API key. Create one at ${PORTAL_URL}/dashboard/keys.`);
288
+ }
289
+ const base = options.apiUrl ?? (typeof process !== "undefined" ? process.env?.BLOCKRUN_API_BASE_URL : void 0) ?? API_KEY_URL;
290
+ return new ApiKeyAuth(key.trim(), base);
291
+ }
292
+ function requireWallet(value) {
293
+ if (value === void 0) throw new Error("This operation requires a wallet; the client uses API key account billing.");
294
+ return value;
295
+ }
296
+ var ApiKeyAuth = class {
297
+ apiUrl;
298
+ #key;
299
+ constructor(key, base) {
300
+ validateApiUrl(base);
301
+ const url = new URL(base);
302
+ if (url.username || url.password || url.search || url.hash) {
303
+ throw new Error("API base URL must not contain credentials, a query, or a fragment.");
304
+ }
305
+ this.apiUrl = base.replace(/\/+$/, "").replace(/\/v1$/, "");
306
+ this.#key = key;
307
+ }
308
+ /** Resolve gateway poll paths without forwarding credentials to another origin. */
309
+ resolveUrl(path6) {
310
+ const url = new URL(path6, this.apiUrl + "/");
311
+ if (url.origin !== new URL(this.apiUrl).origin || url.username || url.password) {
312
+ throw new Error("Refusing to send a BlockRun API key to a different origin.");
313
+ }
314
+ if (new URL(this.apiUrl).pathname === "/" && url.pathname.startsWith("/api/v1/")) url.pathname = url.pathname.slice(4);
315
+ return url.href;
316
+ }
317
+ async fetch(input, init, raiseErrors = true) {
318
+ const request = input instanceof Request ? input : void 0;
319
+ const url = this.resolveUrl(request?.url ?? String(input));
320
+ const headers = new Headers(init?.headers ?? request?.headers);
321
+ for (const name of [...headers.keys()]) {
322
+ if (name.toLowerCase().includes("payment") || name.toLowerCase() === "x-api-key") headers.delete(name);
323
+ }
324
+ headers.set("authorization", `Bearer ${this.#key}`);
325
+ const method = (init?.method ?? request?.method ?? "GET").toUpperCase();
326
+ const retries = method === "GET" || method === "HEAD" ? TRANSIENT_RETRIES : 0;
327
+ let response;
328
+ for (let attempt = 0; ; attempt++) {
329
+ response = await globalThis.fetch(request ? new Request(url, request) : url, {
330
+ ...init,
331
+ headers,
332
+ redirect: "error"
333
+ });
334
+ if (attempt >= retries || !TRANSIENT_STATUS.has(response.status)) break;
335
+ await new Promise((resolve) => setTimeout(resolve, TRANSIENT_BACKOFF_MS * (attempt + 1)));
336
+ }
337
+ if (raiseErrors && !response.ok) {
338
+ let body;
339
+ try {
340
+ body = await response.json();
341
+ } catch {
342
+ body = void 0;
343
+ }
344
+ const outer = body && typeof body === "object" ? body : {};
345
+ const detail = outer.error && typeof outer.error === "object" ? outer.error : outer;
346
+ const safe = Object.fromEntries(["message", "code", "type", "param"].flatMap((name) => typeof detail[name] === "string" ? [[name, detail[name].split(this.#key).join("[REDACTED]")]] : []));
347
+ const hint = response.status === 402 ? ` Top up at ${PORTAL_URL}/dashboard/credits.` : response.status === 401 ? ` Check your key at ${PORTAL_URL}/dashboard/keys.` : "";
348
+ const error = new APIError(`BlockRun account API error: ${response.status}.${hint}`, response.status, safe);
349
+ error.retryAfter = response.headers.get("retry-after") ?? void 0;
350
+ throw error;
351
+ }
352
+ return response;
353
+ }
354
+ /** Poll an account-owned async job without ever entering the x402 signing path. */
355
+ async poll(response, timeout, interval) {
356
+ const deadline = Date.now() + timeout;
357
+ let data = await response.json();
358
+ if (["failed", "cancelled", "canceled"].includes(String(data.status))) {
359
+ throw new APIError("Account API job failed or was cancelled", 502);
360
+ }
361
+ const pollPath = data.poll_url;
362
+ if (typeof pollPath !== "string") {
363
+ if (response.status === 202 || ["queued", "in_progress", "processing"].includes(String(data.status))) {
364
+ throw new APIError("Async response missing poll_url", response.status);
365
+ }
366
+ return data;
367
+ }
368
+ const url = this.resolveUrl(pollPath);
369
+ while (Date.now() < deadline) {
370
+ if (data.status === "completed") return data;
371
+ if (["failed", "cancelled", "canceled"].includes(String(data.status))) {
372
+ throw new APIError("Account API job failed or was cancelled", 502, sanitizeErrorResponse(data));
373
+ }
374
+ await new Promise((resolve) => setTimeout(resolve, Math.min(interval, Math.max(0, deadline - Date.now()))));
375
+ const remaining = deadline - Date.now();
376
+ if (remaining <= 0) break;
377
+ try {
378
+ const res = await this.fetch(url, { signal: AbortSignal.timeout(remaining) });
379
+ data = await res.json();
380
+ } catch (err) {
381
+ if (!(err instanceof APIError) || !TRANSIENT_STATUS.has(err.statusCode)) throw err;
382
+ }
383
+ }
384
+ if (data.status === "completed") return data;
385
+ throw new APIError("Account API job polling timed out; check the job before submitting again.", 504, { poll_url: url });
386
+ }
387
+ };
388
+
389
+ // src/client.ts
390
+ var import_accounts2 = require("viem/accounts");
391
+
148
392
  // node_modules/.pnpm/@blockrun+router-core@https+++codeload.github.com+BlockRunAI+router-core+tar.gz+814fd3b6bc788_xq5fkcckbb2p7dtp6dodey4yri/node_modules/@blockrun/router-core/dist/index.js
149
393
  function scoreTokenCount(estimatedTokens, thresholds) {
150
394
  if (estimatedTokens < thresholds.simple) {
@@ -4275,9 +4519,11 @@ function parsePaymentRequired(headerValue) {
4275
4519
  if (error.message.includes("Invalid payment required structure")) {
4276
4520
  throw error;
4277
4521
  }
4278
- throw new Error("Failed to parse payment required header: invalid format");
4522
+ throw new Error("Failed to parse payment required header: invalid format", {
4523
+ cause: error
4524
+ });
4279
4525
  }
4280
- throw new Error("Failed to parse payment required header");
4526
+ throw new Error("Failed to parse payment required header", { cause: error });
4281
4527
  }
4282
4528
  }
4283
4529
  function extractPaymentDetails(paymentRequired, preferredNetwork) {
@@ -4308,130 +4554,6 @@ function extractPaymentDetails(paymentRequired, preferredNetwork) {
4308
4554
  };
4309
4555
  }
4310
4556
 
4311
- // src/validation.ts
4312
- var LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
4313
- var KNOWN_PROVIDERS = /* @__PURE__ */ new Set([
4314
- "openai",
4315
- "anthropic",
4316
- "google",
4317
- "deepseek",
4318
- "mistralai",
4319
- "meta-llama",
4320
- "together",
4321
- "xai",
4322
- "moonshot",
4323
- "nvidia",
4324
- "minimax",
4325
- "zai"
4326
- ]);
4327
- function validateModel(model) {
4328
- if (!model || typeof model !== "string") {
4329
- throw new Error("Model must be a non-empty string");
4330
- }
4331
- }
4332
- function validateMaxTokens(maxTokens) {
4333
- if (maxTokens === void 0 || maxTokens === null) {
4334
- return;
4335
- }
4336
- if (typeof maxTokens !== "number" || !Number.isInteger(maxTokens)) {
4337
- throw new Error("maxTokens must be an integer");
4338
- }
4339
- if (maxTokens < 1) {
4340
- throw new Error("maxTokens must be positive (minimum: 1)");
4341
- }
4342
- }
4343
- function validateTemperature(temperature) {
4344
- if (temperature === void 0 || temperature === null) {
4345
- return;
4346
- }
4347
- if (typeof temperature !== "number") {
4348
- throw new Error("temperature must be a number");
4349
- }
4350
- if (temperature < 0 || temperature > 2) {
4351
- throw new Error("temperature must be between 0 and 2");
4352
- }
4353
- }
4354
- function validateTopP(topP) {
4355
- if (topP === void 0 || topP === null) {
4356
- return;
4357
- }
4358
- if (typeof topP !== "number") {
4359
- throw new Error("topP must be a number");
4360
- }
4361
- if (topP < 0 || topP > 1) {
4362
- throw new Error("topP must be between 0 and 1");
4363
- }
4364
- }
4365
- function validatePrivateKey(key) {
4366
- if (typeof key !== "string") {
4367
- throw new Error("Private key must be a string");
4368
- }
4369
- if (!key.startsWith("0x")) {
4370
- throw new Error("Private key must start with 0x");
4371
- }
4372
- if (key.length !== 66) {
4373
- throw new Error(
4374
- "Private key must be 66 characters (0x + 64 hexadecimal characters)"
4375
- );
4376
- }
4377
- if (!/^0x[0-9a-fA-F]{64}$/.test(key)) {
4378
- throw new Error(
4379
- "Private key must contain only hexadecimal characters (0-9, a-f, A-F)"
4380
- );
4381
- }
4382
- }
4383
- function validateApiUrl(url) {
4384
- let parsed;
4385
- try {
4386
- parsed = new URL(url);
4387
- } catch {
4388
- throw new Error("Invalid API URL format");
4389
- }
4390
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
4391
- throw new Error(
4392
- `Invalid protocol: ${parsed.protocol}. Use http:// or https://`
4393
- );
4394
- }
4395
- const isLocalhost = LOCALHOST_DOMAINS.includes(parsed.hostname);
4396
- if (parsed.protocol !== "https:" && !isLocalhost) {
4397
- throw new Error(
4398
- `API URL must use HTTPS for non-localhost endpoints. Use https:// instead of ${parsed.protocol}//`
4399
- );
4400
- }
4401
- }
4402
- function sanitizeErrorResponse(errorBody) {
4403
- if (typeof errorBody !== "object" || errorBody === null) {
4404
- return { message: "API request failed" };
4405
- }
4406
- const body = errorBody;
4407
- return {
4408
- message: typeof body.error === "string" ? body.error : "API request failed",
4409
- code: typeof body.code === "string" ? body.code : void 0
4410
- };
4411
- }
4412
- function validateResourceUrl(url, baseUrl) {
4413
- try {
4414
- const parsed = new URL(url);
4415
- const baseParsed = new URL(baseUrl);
4416
- if (parsed.hostname !== baseParsed.hostname) {
4417
- console.warn(
4418
- `Resource URL hostname mismatch: ${parsed.hostname} vs ${baseParsed.hostname}. Using safe default instead.`
4419
- );
4420
- return `${baseUrl}/v1/chat/completions`;
4421
- }
4422
- if (parsed.protocol !== baseParsed.protocol) {
4423
- console.warn(
4424
- `Resource URL protocol mismatch: ${parsed.protocol} vs ${baseParsed.protocol}. Using safe default instead.`
4425
- );
4426
- return `${baseUrl}/v1/chat/completions`;
4427
- }
4428
- return url;
4429
- } catch {
4430
- console.warn(`Invalid resource URL format: ${url}. Using safe default.`);
4431
- return `${baseUrl}/v1/chat/completions`;
4432
- }
4433
- }
4434
-
4435
4557
  // src/cost-log.ts
4436
4558
  var fs = __toESM(require("fs"), 1);
4437
4559
  var path = __toESM(require("path"), 1);
@@ -4478,7 +4600,7 @@ function getCostSummary() {
4478
4600
  }
4479
4601
 
4480
4602
  // src/version.ts
4481
- var SDK_VERSION = "3.13.6";
4603
+ var SDK_VERSION = "3.14.0";
4482
4604
  var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
4483
4605
 
4484
4606
  // src/client.ts
@@ -4526,8 +4648,19 @@ function resolveDefaultTimeout() {
4526
4648
  var DEFAULT_TIMEOUT = resolveDefaultTimeout();
4527
4649
  var LLMClient = class _LLMClient {
4528
4650
  static DEFAULT_API_URL = DEFAULT_API_URL;
4529
- account;
4530
- privateKey;
4651
+ _account;
4652
+ get account() {
4653
+ return requireWallet(this._account);
4654
+ }
4655
+ apiAuth;
4656
+ /** Active billing mode. */
4657
+ get authMode() {
4658
+ return this.apiAuth ? "api-key" : "wallet";
4659
+ }
4660
+ _privateKey;
4661
+ get privateKey() {
4662
+ return requireWallet(this._privateKey);
4663
+ }
4531
4664
  apiUrl;
4532
4665
  timeout;
4533
4666
  sessionTotalUsd = 0;
@@ -4545,17 +4678,20 @@ var LLMClient = class _LLMClient {
4545
4678
  * @param options - Client configuration options (optional if BASE_CHAIN_WALLET_KEY env var is set)
4546
4679
  */
4547
4680
  constructor(options = {}) {
4548
- const envKey = typeof process !== "undefined" && process.env ? process.env.BASE_CHAIN_WALLET_KEY : void 0;
4549
- const privateKey = options.privateKey || envKey;
4550
- if (!privateKey) {
4551
- throw new Error(
4552
- "Private key required. Pass privateKey in options or set BASE_CHAIN_WALLET_KEY environment variable."
4553
- );
4681
+ this.apiAuth = resolveApiKeyAuth(options);
4682
+ if (!this.apiAuth) {
4683
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BASE_CHAIN_WALLET_KEY : void 0;
4684
+ const privateKey = options.privateKey || envKey;
4685
+ if (!privateKey) {
4686
+ throw new Error(
4687
+ "Private key required. Pass privateKey in options or set BASE_CHAIN_WALLET_KEY environment variable."
4688
+ );
4689
+ }
4690
+ validatePrivateKey(privateKey);
4691
+ this._privateKey = privateKey;
4692
+ this._account = (0, import_accounts2.privateKeyToAccount)(privateKey);
4554
4693
  }
4555
- validatePrivateKey(privateKey);
4556
- this.privateKey = privateKey;
4557
- this.account = (0, import_accounts2.privateKeyToAccount)(privateKey);
4558
- const apiUrl = options.apiUrl || DEFAULT_API_URL;
4694
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL;
4559
4695
  validateApiUrl(apiUrl);
4560
4696
  this.apiUrl = apiUrl.replace(/\/$/, "");
4561
4697
  this.timeout = options.timeout || DEFAULT_TIMEOUT;
@@ -4596,7 +4732,7 @@ var LLMClient = class _LLMClient {
4596
4732
  systemPrompt,
4597
4733
  maxOutputTokens,
4598
4734
  await this.getModelPricing(),
4599
- { ...options, minimumPaymentUsd: BASE_MINIMUM_PAYMENT_USD }
4735
+ { ...options, minimumPaymentUsd: this.apiAuth ? 0 : BASE_MINIMUM_PAYMENT_USD }
4600
4736
  );
4601
4737
  }
4602
4738
  /**
@@ -5182,6 +5318,7 @@ var LLMClient = class _LLMClient {
5182
5318
  sanitizeErrorResponse(errorBody)
5183
5319
  );
5184
5320
  }
5321
+ if (this.apiAuth && endpoint.startsWith("/v1/images/")) return this.apiAuth.poll(response, this.timeout, 2e3);
5185
5322
  return response.json();
5186
5323
  }
5187
5324
  /**
@@ -5434,7 +5571,7 @@ var LLMClient = class _LLMClient {
5434
5571
  const controller = new AbortController();
5435
5572
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
5436
5573
  try {
5437
- const response = await fetch(url, {
5574
+ const response = await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, {
5438
5575
  ...options,
5439
5576
  signal: controller.signal
5440
5577
  });
@@ -5935,6 +6072,7 @@ var LLMClient = class _LLMClient {
5935
6072
  * console.log(`Spent $${spending.totalUsd.toFixed(4)} across ${spending.calls} calls`);
5936
6073
  */
5937
6074
  getSpending() {
6075
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
5938
6076
  return {
5939
6077
  totalUsd: this.sessionTotalUsd,
5940
6078
  calls: this.sessionCalls
@@ -5958,8 +6096,19 @@ var DEFAULT_TIMEOUT2 = 2e5;
5958
6096
  var POLL_INTERVAL_MS = 3e3;
5959
6097
  var POLL_MAX_DURATION_MS = 3e5;
5960
6098
  var ImageClient = class {
5961
- account;
5962
- privateKey;
6099
+ _account;
6100
+ get account() {
6101
+ return requireWallet(this._account);
6102
+ }
6103
+ apiAuth;
6104
+ /** Active billing mode. */
6105
+ get authMode() {
6106
+ return this.apiAuth ? "api-key" : "wallet";
6107
+ }
6108
+ _privateKey;
6109
+ get privateKey() {
6110
+ return requireWallet(this._privateKey);
6111
+ }
5963
6112
  apiUrl;
5964
6113
  timeout;
5965
6114
  sessionTotalUsd = 0;
@@ -5970,17 +6119,20 @@ var ImageClient = class {
5970
6119
  * @param options - Client configuration options
5971
6120
  */
5972
6121
  constructor(options = {}) {
5973
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
5974
- const privateKey = options.privateKey || envKey;
5975
- if (!privateKey) {
5976
- throw new Error(
5977
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
5978
- );
6122
+ this.apiAuth = resolveApiKeyAuth(options);
6123
+ if (!this.apiAuth) {
6124
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6125
+ const privateKey = options.privateKey || envKey;
6126
+ if (!privateKey) {
6127
+ throw new Error(
6128
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6129
+ );
6130
+ }
6131
+ validatePrivateKey(privateKey);
6132
+ this._privateKey = privateKey;
6133
+ this._account = (0, import_accounts3.privateKeyToAccount)(privateKey);
5979
6134
  }
5980
- validatePrivateKey(privateKey);
5981
- this.privateKey = privateKey;
5982
- this.account = (0, import_accounts3.privateKeyToAccount)(privateKey);
5983
- const apiUrl = options.apiUrl || DEFAULT_API_URL2;
6135
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL2;
5984
6136
  validateApiUrl(apiUrl);
5985
6137
  this.apiUrl = apiUrl.replace(/\/$/, "");
5986
6138
  this.timeout = options.timeout || DEFAULT_TIMEOUT2;
@@ -6107,6 +6259,7 @@ var ImageClient = class {
6107
6259
  sanitizeErrorResponse(errorBody)
6108
6260
  );
6109
6261
  }
6262
+ if (this.apiAuth) return this.apiAuth.poll(response, POLL_MAX_DURATION_MS, POLL_INTERVAL_MS);
6110
6263
  return response.json();
6111
6264
  }
6112
6265
  /**
@@ -6244,7 +6397,7 @@ var ImageClient = class {
6244
6397
  const controller = new AbortController();
6245
6398
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
6246
6399
  try {
6247
- const response = await fetch(url, {
6400
+ const response = await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, {
6248
6401
  ...options,
6249
6402
  signal: controller.signal
6250
6403
  });
@@ -6263,6 +6416,7 @@ var ImageClient = class {
6263
6416
  * Get session spending information.
6264
6417
  */
6265
6418
  getSpending() {
6419
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
6266
6420
  return {
6267
6421
  totalUsd: this.sessionTotalUsd,
6268
6422
  calls: this.sessionCalls
@@ -6276,24 +6430,38 @@ var DEFAULT_API_URL3 = "https://blockrun.ai/api";
6276
6430
  var DEFAULT_MODEL2 = "minimax/music-2.5+";
6277
6431
  var DEFAULT_TIMEOUT3 = 21e4;
6278
6432
  var MusicClient = class {
6279
- account;
6280
- privateKey;
6433
+ _account;
6434
+ get account() {
6435
+ return requireWallet(this._account);
6436
+ }
6437
+ apiAuth;
6438
+ /** Active billing mode. */
6439
+ get authMode() {
6440
+ return this.apiAuth ? "api-key" : "wallet";
6441
+ }
6442
+ _privateKey;
6443
+ get privateKey() {
6444
+ return requireWallet(this._privateKey);
6445
+ }
6281
6446
  apiUrl;
6282
6447
  timeout;
6283
6448
  sessionTotalUsd = 0;
6284
6449
  sessionCalls = 0;
6285
6450
  constructor(options = {}) {
6286
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6287
- const privateKey = options.privateKey || envKey;
6288
- if (!privateKey) {
6289
- throw new Error(
6290
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6291
- );
6451
+ this.apiAuth = resolveApiKeyAuth(options);
6452
+ if (!this.apiAuth) {
6453
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6454
+ const privateKey = options.privateKey || envKey;
6455
+ if (!privateKey) {
6456
+ throw new Error(
6457
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6458
+ );
6459
+ }
6460
+ validatePrivateKey(privateKey);
6461
+ this._privateKey = privateKey;
6462
+ this._account = (0, import_accounts4.privateKeyToAccount)(privateKey);
6292
6463
  }
6293
- validatePrivateKey(privateKey);
6294
- this.privateKey = privateKey;
6295
- this.account = (0, import_accounts4.privateKeyToAccount)(privateKey);
6296
- const apiUrl = options.apiUrl || DEFAULT_API_URL3;
6464
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL3;
6297
6465
  validateApiUrl(apiUrl);
6298
6466
  this.apiUrl = apiUrl.replace(/\/$/, "");
6299
6467
  this.timeout = options.timeout || DEFAULT_TIMEOUT3;
@@ -6350,6 +6518,7 @@ var MusicClient = class {
6350
6518
  }
6351
6519
  throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
6352
6520
  }
6521
+ if (this.apiAuth) return this.apiAuth.poll(response, this.timeout, 5e3);
6353
6522
  return response.json();
6354
6523
  }
6355
6524
  async handlePaymentAndRetry(url, body, response) {
@@ -6412,7 +6581,7 @@ var MusicClient = class {
6412
6581
  const controller = new AbortController();
6413
6582
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
6414
6583
  try {
6415
- return await fetch(url, { ...options, signal: controller.signal });
6584
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...options, signal: controller.signal });
6416
6585
  } finally {
6417
6586
  clearTimeout(timeoutId);
6418
6587
  }
@@ -6421,6 +6590,7 @@ var MusicClient = class {
6421
6590
  return this.account.address;
6422
6591
  }
6423
6592
  getSpending() {
6593
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
6424
6594
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
6425
6595
  }
6426
6596
  };
@@ -6432,24 +6602,38 @@ var DEFAULT_MODEL3 = "elevenlabs/flash-v2.5";
6432
6602
  var DEFAULT_SOUNDFX_MODEL = "elevenlabs/sound-effects";
6433
6603
  var DEFAULT_TIMEOUT4 = 12e4;
6434
6604
  var SpeechClient = class {
6435
- account;
6436
- privateKey;
6605
+ _account;
6606
+ get account() {
6607
+ return requireWallet(this._account);
6608
+ }
6609
+ apiAuth;
6610
+ /** Active billing mode. */
6611
+ get authMode() {
6612
+ return this.apiAuth ? "api-key" : "wallet";
6613
+ }
6614
+ _privateKey;
6615
+ get privateKey() {
6616
+ return requireWallet(this._privateKey);
6617
+ }
6437
6618
  apiUrl;
6438
6619
  timeout;
6439
6620
  sessionTotalUsd = 0;
6440
6621
  sessionCalls = 0;
6441
6622
  constructor(options = {}) {
6442
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6443
- const privateKey = options.privateKey || envKey;
6444
- if (!privateKey) {
6445
- throw new Error(
6446
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6447
- );
6623
+ this.apiAuth = resolveApiKeyAuth(options);
6624
+ if (!this.apiAuth) {
6625
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6626
+ const privateKey = options.privateKey || envKey;
6627
+ if (!privateKey) {
6628
+ throw new Error(
6629
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6630
+ );
6631
+ }
6632
+ validatePrivateKey(privateKey);
6633
+ this._privateKey = privateKey;
6634
+ this._account = (0, import_accounts5.privateKeyToAccount)(privateKey);
6448
6635
  }
6449
- validatePrivateKey(privateKey);
6450
- this.privateKey = privateKey;
6451
- this.account = (0, import_accounts5.privateKeyToAccount)(privateKey);
6452
- const apiUrl = options.apiUrl || DEFAULT_API_URL4;
6636
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL4;
6453
6637
  validateApiUrl(apiUrl);
6454
6638
  this.apiUrl = apiUrl.replace(/\/$/, "");
6455
6639
  this.timeout = options.timeout || DEFAULT_TIMEOUT4;
@@ -6611,7 +6795,7 @@ var SpeechClient = class {
6611
6795
  const controller = new AbortController();
6612
6796
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
6613
6797
  try {
6614
- return await fetch(url, { ...options, signal: controller.signal });
6798
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...options, signal: controller.signal });
6615
6799
  } finally {
6616
6800
  clearTimeout(timeoutId);
6617
6801
  }
@@ -6620,6 +6804,7 @@ var SpeechClient = class {
6620
6804
  return this.account.address;
6621
6805
  }
6622
6806
  getSpending() {
6807
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
6623
6808
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
6624
6809
  }
6625
6810
  };
@@ -6634,24 +6819,38 @@ var DEFAULT_GENERATE_BUDGET_MS = 9e5;
6634
6819
  var MAX_TIMEOUT_SECONDS = 600;
6635
6820
  var MAX_POLL_RESIGNS = 2;
6636
6821
  var VideoClient = class {
6637
- account;
6638
- privateKey;
6822
+ _account;
6823
+ get account() {
6824
+ return requireWallet(this._account);
6825
+ }
6826
+ apiAuth;
6827
+ /** Active billing mode. */
6828
+ get authMode() {
6829
+ return this.apiAuth ? "api-key" : "wallet";
6830
+ }
6831
+ _privateKey;
6832
+ get privateKey() {
6833
+ return requireWallet(this._privateKey);
6834
+ }
6639
6835
  apiUrl;
6640
6836
  timeout;
6641
6837
  sessionTotalUsd = 0;
6642
6838
  sessionCalls = 0;
6643
6839
  constructor(options = {}) {
6644
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6645
- const privateKey = options.privateKey || envKey;
6646
- if (!privateKey) {
6647
- throw new Error(
6648
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6649
- );
6840
+ this.apiAuth = resolveApiKeyAuth(options);
6841
+ if (!this.apiAuth) {
6842
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6843
+ const privateKey = options.privateKey || envKey;
6844
+ if (!privateKey) {
6845
+ throw new Error(
6846
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6847
+ );
6848
+ }
6849
+ validatePrivateKey(privateKey);
6850
+ this._privateKey = privateKey;
6851
+ this._account = (0, import_accounts6.privateKeyToAccount)(privateKey);
6650
6852
  }
6651
- validatePrivateKey(privateKey);
6652
- this.privateKey = privateKey;
6653
- this.account = (0, import_accounts6.privateKeyToAccount)(privateKey);
6654
- const apiUrl = options.apiUrl || DEFAULT_API_URL5;
6853
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL5;
6655
6854
  validateApiUrl(apiUrl);
6656
6855
  this.apiUrl = apiUrl.replace(/\/$/, "");
6657
6856
  this.timeout = options.timeout || DEFAULT_TIMEOUT5;
@@ -6777,6 +6976,7 @@ var VideoClient = class {
6777
6976
  headers: { "Content-Type": "application/json" },
6778
6977
  body: JSON.stringify(body)
6779
6978
  });
6979
+ if (this.apiAuth) return this.apiAuth.poll(resp402, budgetMs, POLL_INTERVAL_MS2);
6780
6980
  if (resp402.status !== 402) {
6781
6981
  await this.throwApiError(resp402, "Expected 402 on first POST");
6782
6982
  }
@@ -6924,7 +7124,7 @@ var VideoClient = class {
6924
7124
  const controller = new AbortController();
6925
7125
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
6926
7126
  try {
6927
- return await fetch(url, { ...options, signal: controller.signal });
7127
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...options, signal: controller.signal });
6928
7128
  } finally {
6929
7129
  clearTimeout(timeoutId);
6930
7130
  }
@@ -6933,6 +7133,7 @@ var VideoClient = class {
6933
7133
  return this.account.address;
6934
7134
  }
6935
7135
  getSpending() {
7136
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
6936
7137
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
6937
7138
  }
6938
7139
  };
@@ -6944,24 +7145,38 @@ var DEFAULT_TIMEOUT6 = 6e4;
6944
7145
  var CALL_PRICE_USD = 0.54;
6945
7146
  var VALID_MODELS = /* @__PURE__ */ new Set(["base", "enhanced", "turbo"]);
6946
7147
  var VoiceClient = class {
6947
- account;
6948
- privateKey;
7148
+ _account;
7149
+ get account() {
7150
+ return requireWallet(this._account);
7151
+ }
7152
+ apiAuth;
7153
+ /** Active billing mode. */
7154
+ get authMode() {
7155
+ return this.apiAuth ? "api-key" : "wallet";
7156
+ }
7157
+ _privateKey;
7158
+ get privateKey() {
7159
+ return requireWallet(this._privateKey);
7160
+ }
6949
7161
  apiUrl;
6950
7162
  timeout;
6951
7163
  sessionTotalUsd = 0;
6952
7164
  sessionCalls = 0;
6953
7165
  constructor(options = {}) {
6954
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
6955
- const privateKey = options.privateKey || envKey;
6956
- if (!privateKey) {
6957
- throw new Error(
6958
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
6959
- );
7166
+ this.apiAuth = resolveApiKeyAuth(options);
7167
+ if (!this.apiAuth) {
7168
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7169
+ const privateKey = options.privateKey || envKey;
7170
+ if (!privateKey) {
7171
+ throw new Error(
7172
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7173
+ );
7174
+ }
7175
+ validatePrivateKey(privateKey);
7176
+ this._privateKey = privateKey;
7177
+ this._account = (0, import_accounts7.privateKeyToAccount)(privateKey);
6960
7178
  }
6961
- validatePrivateKey(privateKey);
6962
- this.privateKey = privateKey;
6963
- this.account = (0, import_accounts7.privateKeyToAccount)(privateKey);
6964
- const apiUrl = options.apiUrl || DEFAULT_API_URL6;
7179
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL6;
6965
7180
  validateApiUrl(apiUrl);
6966
7181
  this.apiUrl = apiUrl.replace(/\/$/, "");
6967
7182
  this.timeout = options.timeout || DEFAULT_TIMEOUT6;
@@ -7125,7 +7340,7 @@ var VoiceClient = class {
7125
7340
  const controller = new AbortController();
7126
7341
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
7127
7342
  try {
7128
- return await fetch(url, { ...options, signal: controller.signal });
7343
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...options, signal: controller.signal });
7129
7344
  } finally {
7130
7345
  clearTimeout(timeoutId);
7131
7346
  }
@@ -7134,6 +7349,7 @@ var VoiceClient = class {
7134
7349
  return this.account.address;
7135
7350
  }
7136
7351
  getSpending() {
7352
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
7137
7353
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
7138
7354
  }
7139
7355
  };
@@ -7163,24 +7379,38 @@ function requireE164(value) {
7163
7379
  return v;
7164
7380
  }
7165
7381
  var PhoneClient = class {
7166
- account;
7167
- privateKey;
7382
+ _account;
7383
+ get account() {
7384
+ return requireWallet(this._account);
7385
+ }
7386
+ apiAuth;
7387
+ /** Active billing mode. */
7388
+ get authMode() {
7389
+ return this.apiAuth ? "api-key" : "wallet";
7390
+ }
7391
+ _privateKey;
7392
+ get privateKey() {
7393
+ return requireWallet(this._privateKey);
7394
+ }
7168
7395
  apiUrl;
7169
7396
  timeout;
7170
7397
  sessionTotalUsd = 0;
7171
7398
  sessionCalls = 0;
7172
7399
  constructor(options = {}) {
7173
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7174
- const privateKey = options.privateKey || envKey;
7175
- if (!privateKey) {
7176
- throw new Error(
7177
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7178
- );
7400
+ this.apiAuth = resolveApiKeyAuth(options);
7401
+ if (!this.apiAuth) {
7402
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7403
+ const privateKey = options.privateKey || envKey;
7404
+ if (!privateKey) {
7405
+ throw new Error(
7406
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7407
+ );
7408
+ }
7409
+ validatePrivateKey(privateKey);
7410
+ this._privateKey = privateKey;
7411
+ this._account = (0, import_accounts8.privateKeyToAccount)(privateKey);
7179
7412
  }
7180
- validatePrivateKey(privateKey);
7181
- this.privateKey = privateKey;
7182
- this.account = (0, import_accounts8.privateKeyToAccount)(privateKey);
7183
- const apiUrl = options.apiUrl || DEFAULT_API_URL7;
7413
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL7;
7184
7414
  validateApiUrl(apiUrl);
7185
7415
  this.apiUrl = apiUrl.replace(/\/$/, "");
7186
7416
  this.timeout = options.timeout || DEFAULT_TIMEOUT7;
@@ -7191,6 +7421,7 @@ var PhoneClient = class {
7191
7421
  }
7192
7422
  /** Session-cumulative USD spend + call count across this client instance. */
7193
7423
  getSpending() {
7424
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
7194
7425
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
7195
7426
  }
7196
7427
  // ─── Lookup ────────────────────────────────────────────────────────────
@@ -7350,7 +7581,7 @@ var PhoneClient = class {
7350
7581
  const controller = new AbortController();
7351
7582
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
7352
7583
  try {
7353
- return await fetch(url, { ...init, signal: controller.signal });
7584
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...init, signal: controller.signal });
7354
7585
  } finally {
7355
7586
  clearTimeout(timeoutId);
7356
7587
  }
@@ -7363,24 +7594,38 @@ var DEFAULT_API_URL8 = "https://blockrun.ai/api";
7363
7594
  var DEFAULT_TIMEOUT8 = 6e4;
7364
7595
  var PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
7365
7596
  var PortraitClient = class {
7366
- account;
7367
- privateKey;
7597
+ _account;
7598
+ get account() {
7599
+ return requireWallet(this._account);
7600
+ }
7601
+ apiAuth;
7602
+ /** Active billing mode. */
7603
+ get authMode() {
7604
+ return this.apiAuth ? "api-key" : "wallet";
7605
+ }
7606
+ _privateKey;
7607
+ get privateKey() {
7608
+ return requireWallet(this._privateKey);
7609
+ }
7368
7610
  apiUrl;
7369
7611
  timeout;
7370
7612
  sessionTotalUsd = 0;
7371
7613
  sessionCalls = 0;
7372
7614
  constructor(options = {}) {
7373
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7374
- const privateKey = options.privateKey || envKey;
7375
- if (!privateKey) {
7376
- throw new Error(
7377
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7378
- );
7615
+ this.apiAuth = resolveApiKeyAuth(options);
7616
+ if (!this.apiAuth) {
7617
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7618
+ const privateKey = options.privateKey || envKey;
7619
+ if (!privateKey) {
7620
+ throw new Error(
7621
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7622
+ );
7623
+ }
7624
+ validatePrivateKey(privateKey);
7625
+ this._privateKey = privateKey;
7626
+ this._account = (0, import_accounts9.privateKeyToAccount)(privateKey);
7379
7627
  }
7380
- validatePrivateKey(privateKey);
7381
- this.privateKey = privateKey;
7382
- this.account = (0, import_accounts9.privateKeyToAccount)(privateKey);
7383
- const apiUrl = options.apiUrl || DEFAULT_API_URL8;
7628
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL8;
7384
7629
  validateApiUrl(apiUrl);
7385
7630
  this.apiUrl = apiUrl.replace(/\/$/, "");
7386
7631
  this.timeout = options.timeout || DEFAULT_TIMEOUT8;
@@ -7391,6 +7636,7 @@ var PortraitClient = class {
7391
7636
  }
7392
7637
  /** Session-cumulative USD spend + call count across this client instance. */
7393
7638
  getSpending() {
7639
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
7394
7640
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
7395
7641
  }
7396
7642
  /**
@@ -7504,7 +7750,7 @@ var PortraitClient = class {
7504
7750
  const controller = new AbortController();
7505
7751
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
7506
7752
  try {
7507
- return await fetch(url, { ...init, signal: controller.signal });
7753
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...init, signal: controller.signal });
7508
7754
  } finally {
7509
7755
  clearTimeout(timeoutId);
7510
7756
  }
@@ -7516,22 +7762,36 @@ var import_accounts10 = require("viem/accounts");
7516
7762
  var DEFAULT_API_URL9 = "https://blockrun.ai/api";
7517
7763
  var DEFAULT_TIMEOUT9 = 6e4;
7518
7764
  var SearchClient = class {
7519
- account;
7520
- privateKey;
7765
+ _account;
7766
+ get account() {
7767
+ return requireWallet(this._account);
7768
+ }
7769
+ apiAuth;
7770
+ /** Active billing mode. */
7771
+ get authMode() {
7772
+ return this.apiAuth ? "api-key" : "wallet";
7773
+ }
7774
+ _privateKey;
7775
+ get privateKey() {
7776
+ return requireWallet(this._privateKey);
7777
+ }
7521
7778
  apiUrl;
7522
7779
  timeout;
7523
7780
  constructor(options = {}) {
7524
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7525
- const privateKey = options.privateKey || envKey;
7526
- if (!privateKey) {
7527
- throw new Error(
7528
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7529
- );
7781
+ this.apiAuth = resolveApiKeyAuth(options);
7782
+ if (!this.apiAuth) {
7783
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7784
+ const privateKey = options.privateKey || envKey;
7785
+ if (!privateKey) {
7786
+ throw new Error(
7787
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7788
+ );
7789
+ }
7790
+ validatePrivateKey(privateKey);
7791
+ this._privateKey = privateKey;
7792
+ this._account = (0, import_accounts10.privateKeyToAccount)(privateKey);
7530
7793
  }
7531
- validatePrivateKey(privateKey);
7532
- this.privateKey = privateKey;
7533
- this.account = (0, import_accounts10.privateKeyToAccount)(privateKey);
7534
- const apiUrl = options.apiUrl || DEFAULT_API_URL9;
7794
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL9;
7535
7795
  validateApiUrl(apiUrl);
7536
7796
  this.apiUrl = apiUrl.replace(/\/$/, "");
7537
7797
  this.timeout = options.timeout || DEFAULT_TIMEOUT9;
@@ -7637,7 +7897,7 @@ var SearchClient = class {
7637
7897
  const controller = new AbortController();
7638
7898
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
7639
7899
  try {
7640
- return await fetch(url, { ...init, signal: controller.signal });
7900
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...init, signal: controller.signal });
7641
7901
  } finally {
7642
7902
  clearTimeout(timeoutId);
7643
7903
  }
@@ -7652,15 +7912,20 @@ var import_accounts11 = require("viem/accounts");
7652
7912
  var DEFAULT_API_URL10 = "https://blockrun.ai/api";
7653
7913
  var DEFAULT_TIMEOUT10 = 3e4;
7654
7914
  var PriceClient = class {
7915
+ apiAuth;
7916
+ get authMode() {
7917
+ return this.apiAuth ? "api-key" : "wallet";
7918
+ }
7655
7919
  account = null;
7656
7920
  privateKey = null;
7657
7921
  apiUrl;
7658
7922
  timeout;
7659
7923
  constructor(options = {}) {
7924
+ this.apiAuth = resolveApiKeyAuth(options);
7660
7925
  const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7661
- const privateKey = options.privateKey || envKey;
7662
- const requireWallet = options.requireWallet ?? true;
7663
- if (!privateKey && requireWallet) {
7926
+ const privateKey = this.apiAuth ? void 0 : options.privateKey || envKey;
7927
+ const requireWallet2 = options.requireWallet ?? true;
7928
+ if (!this.apiAuth && !privateKey && requireWallet2) {
7664
7929
  throw new Error(
7665
7930
  "Private key required for paid endpoints. Pass privateKey in options, set BLOCKRUN_WALLET_KEY, or pass requireWallet: false for free-only usage."
7666
7931
  );
@@ -7670,7 +7935,7 @@ var PriceClient = class {
7670
7935
  this.privateKey = privateKey;
7671
7936
  this.account = (0, import_accounts11.privateKeyToAccount)(privateKey);
7672
7937
  }
7673
- const apiUrl = options.apiUrl || DEFAULT_API_URL10;
7938
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL10;
7674
7939
  validateApiUrl(apiUrl);
7675
7940
  this.apiUrl = apiUrl.replace(/\/$/, "");
7676
7941
  this.timeout = options.timeout || DEFAULT_TIMEOUT10;
@@ -7823,7 +8088,7 @@ var PriceClient = class {
7823
8088
  const controller = new AbortController();
7824
8089
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
7825
8090
  try {
7826
- return await fetch(url, { ...init, signal: controller.signal });
8091
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...init, signal: controller.signal });
7827
8092
  } finally {
7828
8093
  clearTimeout(timeoutId);
7829
8094
  }
@@ -7857,22 +8122,36 @@ var DEFAULT_API_URL11 = "https://blockrun.ai/api";
7857
8122
  var DEFAULT_TIMEOUT11 = 6e4;
7858
8123
  var SURF_PREFIX = "/v1/surf";
7859
8124
  var SurfClient = class {
7860
- account;
7861
- privateKey;
8125
+ _account;
8126
+ get account() {
8127
+ return requireWallet(this._account);
8128
+ }
8129
+ apiAuth;
8130
+ /** Active billing mode. */
8131
+ get authMode() {
8132
+ return this.apiAuth ? "api-key" : "wallet";
8133
+ }
8134
+ _privateKey;
8135
+ get privateKey() {
8136
+ return requireWallet(this._privateKey);
8137
+ }
7862
8138
  apiUrl;
7863
8139
  timeout;
7864
8140
  constructor(options = {}) {
7865
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
7866
- const privateKey = options.privateKey || envKey;
7867
- if (!privateKey) {
7868
- throw new Error(
7869
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
7870
- );
8141
+ this.apiAuth = resolveApiKeyAuth(options);
8142
+ if (!this.apiAuth) {
8143
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
8144
+ const privateKey = options.privateKey || envKey;
8145
+ if (!privateKey) {
8146
+ throw new Error(
8147
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
8148
+ );
8149
+ }
8150
+ validatePrivateKey(privateKey);
8151
+ this._privateKey = privateKey;
8152
+ this._account = (0, import_accounts12.privateKeyToAccount)(privateKey);
7871
8153
  }
7872
- validatePrivateKey(privateKey);
7873
- this.privateKey = privateKey;
7874
- this.account = (0, import_accounts12.privateKeyToAccount)(privateKey);
7875
- const apiUrl = options.apiUrl || DEFAULT_API_URL11;
8154
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL11;
7876
8155
  validateApiUrl(apiUrl);
7877
8156
  this.apiUrl = apiUrl.replace(/\/$/, "");
7878
8157
  this.timeout = options.timeout || DEFAULT_TIMEOUT11;
@@ -7996,7 +8275,7 @@ var SurfClient = class {
7996
8275
  const controller = new AbortController();
7997
8276
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
7998
8277
  try {
7999
- return await fetch(url, { ...init, signal: controller.signal });
8278
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...init, signal: controller.signal });
8000
8279
  } finally {
8001
8280
  clearTimeout(timeoutId);
8002
8281
  }
@@ -8085,24 +8364,38 @@ var NETWORK_ALIASES = {
8085
8364
  zec: "zcash"
8086
8365
  };
8087
8366
  var RpcClient = class {
8088
- account;
8089
- privateKey;
8367
+ _account;
8368
+ get account() {
8369
+ return requireWallet(this._account);
8370
+ }
8371
+ apiAuth;
8372
+ /** Active billing mode. */
8373
+ get authMode() {
8374
+ return this.apiAuth ? "api-key" : "wallet";
8375
+ }
8376
+ _privateKey;
8377
+ get privateKey() {
8378
+ return requireWallet(this._privateKey);
8379
+ }
8090
8380
  apiUrl;
8091
8381
  timeout;
8092
8382
  sessionTotalUsd = 0;
8093
8383
  sessionCalls = 0;
8094
8384
  constructor(options = {}) {
8095
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
8096
- const privateKey = options.privateKey || envKey;
8097
- if (!privateKey) {
8098
- throw new Error(
8099
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
8100
- );
8385
+ this.apiAuth = resolveApiKeyAuth(options);
8386
+ if (!this.apiAuth) {
8387
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
8388
+ const privateKey = options.privateKey || envKey;
8389
+ if (!privateKey) {
8390
+ throw new Error(
8391
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
8392
+ );
8393
+ }
8394
+ validatePrivateKey(privateKey);
8395
+ this._privateKey = privateKey;
8396
+ this._account = (0, import_accounts13.privateKeyToAccount)(privateKey);
8101
8397
  }
8102
- validatePrivateKey(privateKey);
8103
- this.privateKey = privateKey;
8104
- this.account = (0, import_accounts13.privateKeyToAccount)(privateKey);
8105
- const apiUrl = options.apiUrl || DEFAULT_API_URL12;
8398
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL12;
8106
8399
  validateApiUrl(apiUrl);
8107
8400
  this.apiUrl = apiUrl.replace(/\/$/, "");
8108
8401
  this.timeout = options.timeout || DEFAULT_TIMEOUT12;
@@ -8246,7 +8539,7 @@ var RpcClient = class {
8246
8539
  const controller = new AbortController();
8247
8540
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
8248
8541
  try {
8249
- return await fetch(url, { ...options, signal: controller.signal });
8542
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...options, signal: controller.signal });
8250
8543
  } finally {
8251
8544
  clearTimeout(timeoutId);
8252
8545
  }
@@ -8255,6 +8548,7 @@ var RpcClient = class {
8255
8548
  return this.account.address;
8256
8549
  }
8257
8550
  getSpending() {
8551
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
8258
8552
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
8259
8553
  }
8260
8554
  };
@@ -8267,24 +8561,38 @@ var DEFAULT_POLL_INTERVAL_MS = 5e3;
8267
8561
  var DEFAULT_POLL_BUDGET_MS = 3e5;
8268
8562
  var MAX_SIGNED_AUTH_SECONDS = 600;
8269
8563
  var BlockrunClient = class {
8270
- account;
8271
- privateKey;
8564
+ _account;
8565
+ get account() {
8566
+ return requireWallet(this._account);
8567
+ }
8568
+ apiAuth;
8569
+ /** Active billing mode. */
8570
+ get authMode() {
8571
+ return this.apiAuth ? "api-key" : "wallet";
8572
+ }
8573
+ _privateKey;
8574
+ get privateKey() {
8575
+ return requireWallet(this._privateKey);
8576
+ }
8272
8577
  apiUrl;
8273
8578
  timeout;
8274
8579
  sessionTotalUsd = 0;
8275
8580
  sessionCalls = 0;
8276
8581
  constructor(options = {}) {
8277
- const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
8278
- const privateKey = options.privateKey || envKey;
8279
- if (!privateKey) {
8280
- throw new Error(
8281
- "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
8282
- );
8582
+ this.apiAuth = resolveApiKeyAuth(options);
8583
+ if (!this.apiAuth) {
8584
+ const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
8585
+ const privateKey = options.privateKey || envKey;
8586
+ if (!privateKey) {
8587
+ throw new Error(
8588
+ "Private key required. Pass privateKey in options or set BLOCKRUN_WALLET_KEY environment variable."
8589
+ );
8590
+ }
8591
+ validatePrivateKey(privateKey);
8592
+ this._privateKey = privateKey;
8593
+ this._account = (0, import_accounts14.privateKeyToAccount)(privateKey);
8283
8594
  }
8284
- validatePrivateKey(privateKey);
8285
- this.privateKey = privateKey;
8286
- this.account = (0, import_accounts14.privateKeyToAccount)(privateKey);
8287
- const apiUrl = options.apiUrl || DEFAULT_API_URL13;
8595
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL13;
8288
8596
  validateApiUrl(apiUrl);
8289
8597
  this.apiUrl = apiUrl.replace(/\/$/, "");
8290
8598
  this.timeout = options.timeout || DEFAULT_TIMEOUT13;
@@ -8326,6 +8634,7 @@ var BlockrunClient = class {
8326
8634
  headers: { "Content-Type": "application/json" },
8327
8635
  body: JSON.stringify(body ?? {})
8328
8636
  });
8637
+ if (this.apiAuth) return this.apiAuth.poll(resp402, budgetMs, intervalMs);
8329
8638
  if (resp402.status === 200) {
8330
8639
  return resp402.json();
8331
8640
  }
@@ -8618,7 +8927,7 @@ var BlockrunClient = class {
8618
8927
  const controller = new AbortController();
8619
8928
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
8620
8929
  try {
8621
- return await fetch(url, { ...init, signal: controller.signal });
8930
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...init, signal: controller.signal });
8622
8931
  } finally {
8623
8932
  clearTimeout(timeoutId);
8624
8933
  }
@@ -8630,6 +8939,7 @@ var BlockrunClient = class {
8630
8939
  return this.account.address;
8631
8940
  }
8632
8941
  getSpending() {
8942
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
8633
8943
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
8634
8944
  }
8635
8945
  };
@@ -8640,7 +8950,7 @@ function sleep(ms) {
8640
8950
  // src/wallet.ts
8641
8951
  var import_accounts16 = require("viem/accounts");
8642
8952
 
8643
- // node_modules/.pnpm/@blockrun+core@0.1.1_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@3.25.76/node_modules/@blockrun/core/dist/config.js
8953
+ // node_modules/.pnpm/@blockrun+core@0.1.1_bufferutil@4.1.0_typescript@6.0.3_utf-8-validate@6.0.6_zod@3.25.76/node_modules/@blockrun/core/dist/config.js
8644
8954
  var fs2 = __toESM(require("fs"), 1);
8645
8955
  var os2 = __toESM(require("os"), 1);
8646
8956
  var path2 = __toESM(require("path"), 1);
@@ -8662,7 +8972,7 @@ function paths() {
8662
8972
  };
8663
8973
  }
8664
8974
 
8665
- // node_modules/.pnpm/@blockrun+core@0.1.1_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@3.25.76/node_modules/@blockrun/core/dist/wallet.js
8975
+ // node_modules/.pnpm/@blockrun+core@0.1.1_bufferutil@4.1.0_typescript@6.0.3_utf-8-validate@6.0.6_zod@3.25.76/node_modules/@blockrun/core/dist/wallet.js
8666
8976
  var fs3 = __toESM(require("fs"), 1);
8667
8977
  var path3 = __toESM(require("path"), 1);
8668
8978
  var import_accounts15 = require("viem/accounts");
@@ -8958,7 +9268,8 @@ async function solanaKeyToBytes(privateKey) {
8958
9268
  } catch (err) {
8959
9269
  const msg = err instanceof Error ? err.message : String(err);
8960
9270
  throw new Error(
8961
- `Invalid Solana private key: ${msg}. Expected a base58-encoded 64-byte key (standard Solana format), a 64-byte hex string, or a Solana CLI JSON byte array.`
9271
+ `Invalid Solana private key: ${msg}. Expected a base58-encoded 64-byte key (standard Solana format), a 64-byte hex string, or a Solana CLI JSON byte array.`,
9272
+ { cause: err }
8962
9273
  );
8963
9274
  }
8964
9275
  }
@@ -9104,7 +9415,7 @@ async function solanaPublicKeyFrom(privateKey, source) {
9104
9415
  return await solanaPublicKey(privateKey);
9105
9416
  } catch (err) {
9106
9417
  const msg = err instanceof Error ? err.message : String(err);
9107
- throw new Error(`${msg} (key loaded from ${source})`);
9418
+ throw new Error(`${msg} (key loaded from ${source})`, { cause: err });
9108
9419
  }
9109
9420
  }
9110
9421
  async function getOrCreateSolanaWallet() {
@@ -9218,7 +9529,14 @@ function resolveRpcConfig(rpcUrl, rpcHeaders) {
9218
9529
  }
9219
9530
  var SolanaLLMClient = class {
9220
9531
  static SOLANA_API_URL = SOLANA_API_URL;
9221
- privateKey;
9532
+ apiAuth;
9533
+ get authMode() {
9534
+ return this.apiAuth ? "api-key" : "wallet";
9535
+ }
9536
+ _privateKey;
9537
+ get privateKey() {
9538
+ return requireWallet(this._privateKey);
9539
+ }
9222
9540
  apiUrl;
9223
9541
  rpcUrl;
9224
9542
  rpcHeaders;
@@ -9229,15 +9547,18 @@ var SolanaLLMClient = class {
9229
9547
  modelPricingCache = null;
9230
9548
  modelPricingPromise = null;
9231
9549
  constructor(options = {}) {
9232
- const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
9233
- const privateKey = options.privateKey || envKey;
9234
- if (!privateKey) {
9235
- throw new Error(
9236
- "Private key required. Pass privateKey in options or set SOLANA_WALLET_KEY environment variable."
9237
- );
9550
+ this.apiAuth = resolveApiKeyAuth(options);
9551
+ if (!this.apiAuth) {
9552
+ const envKey = typeof process !== "undefined" && process.env ? process.env.SOLANA_WALLET_KEY : void 0;
9553
+ const privateKey = options.privateKey || envKey;
9554
+ if (!privateKey) {
9555
+ throw new Error(
9556
+ "Private key required. Pass privateKey in options or set SOLANA_WALLET_KEY environment variable."
9557
+ );
9558
+ }
9559
+ this._privateKey = privateKey;
9238
9560
  }
9239
- this.privateKey = privateKey;
9240
- const apiUrl = options.apiUrl || SOLANA_API_URL;
9561
+ const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || SOLANA_API_URL;
9241
9562
  validateApiUrl(apiUrl);
9242
9563
  this.apiUrl = apiUrl.replace(/\/$/, "");
9243
9564
  const rpc = resolveRpcConfig(options.rpcUrl, options.rpcHeaders);
@@ -9350,7 +9671,7 @@ var SolanaLLMClient = class {
9350
9671
  {
9351
9672
  routingProfile: options?.routingProfile,
9352
9673
  requiresStructuredOutput: options?.responseFormat !== void 0,
9353
- minimumPaymentUsd: SOLANA_MINIMUM_PAYMENT_USD
9674
+ minimumPaymentUsd: this.apiAuth ? 0 : SOLANA_MINIMUM_PAYMENT_USD
9354
9675
  }
9355
9676
  );
9356
9677
  }
@@ -9379,7 +9700,7 @@ var SolanaLLMClient = class {
9379
9700
  toolChoice: options.toolChoice,
9380
9701
  conversationChars,
9381
9702
  hasVision,
9382
- minimumPaymentUsd: SOLANA_MINIMUM_PAYMENT_USD
9703
+ minimumPaymentUsd: this.apiAuth ? 0 : SOLANA_MINIMUM_PAYMENT_USD
9383
9704
  }
9384
9705
  );
9385
9706
  const response = await this.chatCompletion(decision.model, messages, {
@@ -9632,6 +9953,7 @@ var SolanaLLMClient = class {
9632
9953
  }
9633
9954
  /** Get session spending. */
9634
9955
  getSpending() {
9956
+ if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
9635
9957
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
9636
9958
  }
9637
9959
  /** True if using sol.blockrun.ai. */
@@ -9768,6 +10090,7 @@ var SolanaLLMClient = class {
9768
10090
  }
9769
10091
  throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
9770
10092
  }
10093
+ if (this.apiAuth && endpoint.startsWith("/v1/images/")) return this.apiAuth.poll(response, this.timeout, 2e3);
9771
10094
  return response.json();
9772
10095
  }
9773
10096
  }
@@ -9954,7 +10277,7 @@ var SolanaLLMClient = class {
9954
10277
  const controller = new AbortController();
9955
10278
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
9956
10279
  try {
9957
- return await fetch(url, { ...options, signal: controller.signal });
10280
+ return await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, { ...options, signal: controller.signal });
9958
10281
  } finally {
9959
10282
  clearTimeout(timeoutId);
9960
10283
  }
@@ -10153,6 +10476,9 @@ function getCostLogSummary() {
10153
10476
  }
10154
10477
 
10155
10478
  // src/setup.ts
10479
+ var import_node_fs = require("fs");
10480
+ var import_node_os = require("os");
10481
+ var import_node_path = require("path");
10156
10482
  function setupAgentWallet(options) {
10157
10483
  const { address, privateKey, isNew } = getOrCreateWallet();
10158
10484
  if (isNew) {
@@ -10195,6 +10521,24 @@ async function status() {
10195
10521
  console.log(`Balance: $${balance.toFixed(2)} USDC`);
10196
10522
  return { address, balance };
10197
10523
  }
10524
+ async function setupAgentClient(options = {}) {
10525
+ if (resolveApiKeyAuth(options)) return new LLMClient({ apiKey: options.apiKey });
10526
+ let chain = options.chain;
10527
+ if (!chain) {
10528
+ for (const file of ["payment-chain", ".chain"]) {
10529
+ try {
10530
+ const saved = (0, import_node_fs.readFileSync)((0, import_node_path.join)((0, import_node_os.homedir)(), ".blockrun", file), "utf8").trim();
10531
+ if (saved === "solana" || saved === "base") {
10532
+ chain = saved;
10533
+ break;
10534
+ }
10535
+ } catch {
10536
+ }
10537
+ }
10538
+ }
10539
+ chain ??= !loadSolanaWallet() && loadWallet() ? "base" : "solana";
10540
+ return chain === "solana" ? setupAgentSolanaWallet(options) : setupAgentWallet(options);
10541
+ }
10198
10542
 
10199
10543
  // src/openai-compat.ts
10200
10544
  var StreamingResponse = class {
@@ -10326,13 +10670,17 @@ var Chat = class {
10326
10670
  };
10327
10671
  var OpenAI = class {
10328
10672
  chat;
10673
+ get authMode() {
10674
+ return this.client.authMode;
10675
+ }
10329
10676
  client;
10330
10677
  constructor(options = {}) {
10331
10678
  const privateKey = options.walletKey || options.privateKey;
10332
- const apiUrl = options.baseURL || "https://blockrun.ai/api";
10679
+ const apiUrl = resolveApiKeyAuth({ apiKey: options.apiKey, privateKey, apiUrl: options.baseURL })?.apiUrl ?? options.baseURL ?? "https://blockrun.ai/api";
10333
10680
  const timeout = options.timeout ?? DEFAULT_TIMEOUT;
10334
10681
  this.client = new LLMClient({
10335
10682
  privateKey,
10683
+ apiKey: options.apiKey,
10336
10684
  apiUrl,
10337
10685
  timeout
10338
10686
  });
@@ -10351,17 +10699,29 @@ var import_accounts17 = require("viem/accounts");
10351
10699
  var AnthropicClient = class {
10352
10700
  _client = null;
10353
10701
  _clientPromise = null;
10354
- _privateKey;
10355
- _account;
10702
+ apiAuth;
10703
+ get authMode() {
10704
+ return this.apiAuth ? "api-key" : "wallet";
10705
+ }
10706
+ walletKey;
10707
+ get _privateKey() {
10708
+ return requireWallet(this.walletKey);
10709
+ }
10710
+ walletAccount;
10711
+ get _account() {
10712
+ return requireWallet(this.walletAccount);
10713
+ }
10356
10714
  _apiUrl;
10357
10715
  _timeout;
10358
10716
  constructor(options = {}) {
10359
- const wallet = getOrCreateWallet();
10360
- const key = options.privateKey ?? wallet.privateKey;
10361
- validatePrivateKey(key);
10362
- this._privateKey = key;
10363
- this._account = (0, import_accounts17.privateKeyToAccount)(this._privateKey);
10364
- const apiUrl = options.apiUrl ?? "https://blockrun.ai/api";
10717
+ this.apiAuth = resolveApiKeyAuth(options);
10718
+ if (!this.apiAuth) {
10719
+ const key = options.privateKey ?? getOrCreateWallet().privateKey;
10720
+ validatePrivateKey(key);
10721
+ this.walletKey = key;
10722
+ this.walletAccount = (0, import_accounts17.privateKeyToAccount)(this.walletKey);
10723
+ }
10724
+ const apiUrl = this.apiAuth?.apiUrl ?? options.apiUrl ?? "https://blockrun.ai/api";
10365
10725
  validateApiUrl(apiUrl);
10366
10726
  this._apiUrl = apiUrl.replace(/\/$/, "");
10367
10727
  this._timeout = options.timeout ?? DEFAULT_TIMEOUT;
@@ -10385,6 +10745,7 @@ var AnthropicClient = class {
10385
10745
  const timeoutId = setTimeout(() => controller.abort(), this._timeout);
10386
10746
  try {
10387
10747
  const mergedInit = { ...init, signal: controller.signal };
10748
+ if (this.apiAuth) return await this.apiAuth.fetch(input, mergedInit, false);
10388
10749
  let response = await globalThis.fetch(input, mergedInit);
10389
10750
  if (response.status === 402) {
10390
10751
  let paymentHeader = response.headers.get("payment-required");
@@ -10457,6 +10818,7 @@ var AnthropicClient = class {
10457
10818
  // Annotate the CommonJS export names for ESM import in node:
10458
10819
  0 && (module.exports = {
10459
10820
  APIError,
10821
+ API_KEY_URL,
10460
10822
  AnthropicClient,
10461
10823
  BASE_CHAIN_ID,
10462
10824
  BlockrunClient,
@@ -10468,6 +10830,7 @@ var AnthropicClient = class {
10468
10830
  NETWORK_ALIASES,
10469
10831
  OpenAI,
10470
10832
  PHONE_PRICES,
10833
+ PORTAL_URL,
10471
10834
  PORTRAIT_ENROLLMENT_PRICE_USD,
10472
10835
  PaymentError,
10473
10836
  PhoneClient,
@@ -10524,6 +10887,7 @@ var AnthropicClient = class {
10524
10887
  scanSolanaWallets,
10525
10888
  scanWallets,
10526
10889
  setCache,
10890
+ setupAgentClient,
10527
10891
  setupAgentSolanaWallet,
10528
10892
  setupAgentWallet,
10529
10893
  solanaClient,