@blockrun/llm 3.13.5 → 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/README.md +99 -37
- package/dist/index.cjs +725 -348
- package/dist/index.d.cts +133 -469
- package/dist/index.d.ts +133 -469
- package/dist/index.js +722 -348
- package/package.json +12 -9
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,7 +147,249 @@ var APIError = class extends BlockrunError {
|
|
|
145
147
|
}
|
|
146
148
|
};
|
|
147
149
|
|
|
148
|
-
//
|
|
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
|
+
|
|
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) {
|
|
151
395
|
return { name: "tokenCount", score: -1, signal: `short (${estimatedTokens} tokens)` };
|
|
@@ -668,6 +912,13 @@ var DEFAULT_MODEL_CAPABILITIES = Object.freeze({
|
|
|
668
912
|
supportsTools: true,
|
|
669
913
|
supportsVision: true
|
|
670
914
|
},
|
|
915
|
+
"cohere/north-mini-code": {
|
|
916
|
+
// supportsTools: not probed — fails closed
|
|
917
|
+
contextWindow: 256e3,
|
|
918
|
+
maxOutputTokens: 16384,
|
|
919
|
+
supportsTools: false,
|
|
920
|
+
supportsVision: false
|
|
921
|
+
},
|
|
671
922
|
"deepseek/deepseek-chat": {
|
|
672
923
|
contextWindow: 1048576,
|
|
673
924
|
maxOutputTokens: 65536,
|
|
@@ -758,8 +1009,15 @@ var DEFAULT_MODEL_CAPABILITIES = Object.freeze({
|
|
|
758
1009
|
supportsTools: true,
|
|
759
1010
|
supportsVision: true
|
|
760
1011
|
},
|
|
761
|
-
"nvidia/
|
|
762
|
-
// supportsTools:
|
|
1012
|
+
"nvidia/llama-3.2-11b-vision": {
|
|
1013
|
+
// supportsTools: not probed — fails closed
|
|
1014
|
+
contextWindow: 128e3,
|
|
1015
|
+
maxOutputTokens: 16384,
|
|
1016
|
+
supportsTools: false,
|
|
1017
|
+
supportsVision: true
|
|
1018
|
+
},
|
|
1019
|
+
"nvidia/nemotron-3-nano-30b": {
|
|
1020
|
+
// supportsTools: not probed — fails closed
|
|
763
1021
|
contextWindow: 131072,
|
|
764
1022
|
maxOutputTokens: 16384,
|
|
765
1023
|
supportsTools: false,
|
|
@@ -771,21 +1029,16 @@ var DEFAULT_MODEL_CAPABILITIES = Object.freeze({
|
|
|
771
1029
|
supportsTools: false,
|
|
772
1030
|
supportsVision: true
|
|
773
1031
|
},
|
|
774
|
-
"nvidia/nemotron-
|
|
775
|
-
// supportsTools:
|
|
776
|
-
contextWindow:
|
|
777
|
-
maxOutputTokens: 16384,
|
|
778
|
-
supportsTools: false,
|
|
779
|
-
supportsVision: true
|
|
780
|
-
},
|
|
781
|
-
"nvidia/nemotron-nano-9b-v2": {
|
|
782
|
-
contextWindow: 131072,
|
|
1032
|
+
"nvidia/nemotron-3-ultra-550b": {
|
|
1033
|
+
// supportsTools: not probed — fails closed
|
|
1034
|
+
contextWindow: 1e6,
|
|
783
1035
|
maxOutputTokens: 16384,
|
|
784
1036
|
supportsTools: false,
|
|
785
1037
|
supportsVision: false
|
|
786
1038
|
},
|
|
787
|
-
"nvidia/
|
|
788
|
-
|
|
1039
|
+
"nvidia/nemotron-3.5-lightning": {
|
|
1040
|
+
// supportsTools: not probed — fails closed
|
|
1041
|
+
contextWindow: 1e6,
|
|
789
1042
|
maxOutputTokens: 16384,
|
|
790
1043
|
supportsTools: false,
|
|
791
1044
|
supportsVision: false
|
|
@@ -845,13 +1098,6 @@ var DEFAULT_MODEL_CAPABILITIES = Object.freeze({
|
|
|
845
1098
|
supportsTools: false,
|
|
846
1099
|
supportsVision: true
|
|
847
1100
|
},
|
|
848
|
-
"openai/gpt-5.3": {
|
|
849
|
-
// supportsTools: gateway unavailable at probe time — fails closed
|
|
850
|
-
contextWindow: 128e3,
|
|
851
|
-
maxOutputTokens: 128e3,
|
|
852
|
-
supportsTools: false,
|
|
853
|
-
supportsVision: true
|
|
854
|
-
},
|
|
855
1101
|
"openai/gpt-5.3-codex": {
|
|
856
1102
|
// supportsTools: gateway unavailable at probe time — fails closed; override: 2026-08-29 probe: every request (6 plain + 3 tool attempts) returned a gateway 500, so the probe measured an incident, not the model. Codex's function calling is established by the 2026-07 Terminal-Bench / tau2 calibration trajectories in portfolio.ts. Hosts observing the 500s should drop it with RouterOptions.unavailableModels rather than this snapshot claiming the model cannot call tools.
|
|
857
1103
|
contextWindow: 4e5,
|
|
@@ -957,6 +1203,13 @@ var DEFAULT_MODEL_CAPABILITIES = Object.freeze({
|
|
|
957
1203
|
supportsTools: true,
|
|
958
1204
|
supportsVision: false
|
|
959
1205
|
},
|
|
1206
|
+
"poolside/laguna-xs-2.1": {
|
|
1207
|
+
// supportsTools: not probed — fails closed
|
|
1208
|
+
contextWindow: 131072,
|
|
1209
|
+
maxOutputTokens: 16384,
|
|
1210
|
+
supportsTools: false,
|
|
1211
|
+
supportsVision: false
|
|
1212
|
+
},
|
|
960
1213
|
"qwen/qwen3.7-flash": {
|
|
961
1214
|
contextWindow: 1e6,
|
|
962
1215
|
maxOutputTokens: 65536,
|
|
@@ -3498,8 +3751,8 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
3498
3751
|
// $0.20/$1.25, 1M ctx
|
|
3499
3752
|
"google/gemini-2.5-flash-lite",
|
|
3500
3753
|
// $0.10/$0.40
|
|
3501
|
-
"nvidia/
|
|
3502
|
-
// FREE backstop — NVIDIA free tier (probed 2026-08-
|
|
3754
|
+
"nvidia/nemotron-3.5-lightning"
|
|
3755
|
+
// FREE backstop — NVIDIA free tier (probed 2026-08-30)
|
|
3503
3756
|
]
|
|
3504
3757
|
},
|
|
3505
3758
|
MEDIUM: {
|
|
@@ -3588,15 +3841,19 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
3588
3841
|
// Eco tier configs - absolute cheapest (blockrun/eco)
|
|
3589
3842
|
ecoTiers: {
|
|
3590
3843
|
SIMPLE: {
|
|
3591
|
-
primary: "nvidia/
|
|
3592
|
-
// FREE — NVIDIA free tier flagship
|
|
3844
|
+
primary: "nvidia/nemotron-3.5-lightning",
|
|
3845
|
+
// FREE — NVIDIA free tier flagship, 1M ctx
|
|
3593
3846
|
fallback: [
|
|
3594
|
-
"nvidia/nemotron-nano-
|
|
3595
|
-
// FREE —
|
|
3847
|
+
"nvidia/nemotron-3-nano-30b",
|
|
3848
|
+
// FREE — fastest free model (~121 tok/s)
|
|
3596
3849
|
// The free head keeps rotting with NVIDIA's hosting (deepseek-v4-flash
|
|
3597
3850
|
// 410 2026-08-12, seed-oss-36b 410 2026-08-03, gpt-oss-120b/20b 400
|
|
3598
|
-
// 2026-08-21
|
|
3599
|
-
//
|
|
3851
|
+
// 2026-08-21, and on 2026-08-30 FOUR of the five visible free models at
|
|
3852
|
+
// once — step-3.7-flash, nemotron-nano-9b-v2 and nemotron-nano-12b-v2-vl
|
|
3853
|
+
// all 410, mistral-nemotron hung). Each retirement retargets the two
|
|
3854
|
+
// free rungs to the current free tier; the paid rungs below never move.
|
|
3855
|
+
// The head follows blockrun's own redirect of the model it replaces, so
|
|
3856
|
+
// the router and the gateway never name different models.
|
|
3600
3857
|
"google/gemini-2.5-flash-lite",
|
|
3601
3858
|
// $0.10/$0.40 — cheapest paid rung
|
|
3602
3859
|
"zai/glm-5.3-flash",
|
|
@@ -3740,7 +3997,7 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
3740
3997
|
// strongest open-weight reasoner
|
|
3741
3998
|
"deepseek/deepseek-chat",
|
|
3742
3999
|
// Cheap, reliable
|
|
3743
|
-
"nvidia/
|
|
4000
|
+
"nvidia/nemotron-3.5-lightning"
|
|
3744
4001
|
// NVIDIA free ultimate backstop
|
|
3745
4002
|
]
|
|
3746
4003
|
},
|
|
@@ -3844,7 +4101,7 @@ var DEFAULT_ROUTING_CONFIG = {
|
|
|
3844
4101
|
// retail high-risk 3/3
|
|
3845
4102
|
"deepseek/deepseek-chat",
|
|
3846
4103
|
// cheap, reliable
|
|
3847
|
-
"nvidia/
|
|
4104
|
+
"nvidia/nemotron-3.5-lightning"
|
|
3848
4105
|
// NVIDIA free ultimate backstop
|
|
3849
4106
|
]
|
|
3850
4107
|
},
|
|
@@ -4262,9 +4519,11 @@ function parsePaymentRequired(headerValue) {
|
|
|
4262
4519
|
if (error.message.includes("Invalid payment required structure")) {
|
|
4263
4520
|
throw error;
|
|
4264
4521
|
}
|
|
4265
|
-
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
|
+
});
|
|
4266
4525
|
}
|
|
4267
|
-
throw new Error("Failed to parse payment required header");
|
|
4526
|
+
throw new Error("Failed to parse payment required header", { cause: error });
|
|
4268
4527
|
}
|
|
4269
4528
|
}
|
|
4270
4529
|
function extractPaymentDetails(paymentRequired, preferredNetwork) {
|
|
@@ -4295,130 +4554,6 @@ function extractPaymentDetails(paymentRequired, preferredNetwork) {
|
|
|
4295
4554
|
};
|
|
4296
4555
|
}
|
|
4297
4556
|
|
|
4298
|
-
// src/validation.ts
|
|
4299
|
-
var LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
|
|
4300
|
-
var KNOWN_PROVIDERS = /* @__PURE__ */ new Set([
|
|
4301
|
-
"openai",
|
|
4302
|
-
"anthropic",
|
|
4303
|
-
"google",
|
|
4304
|
-
"deepseek",
|
|
4305
|
-
"mistralai",
|
|
4306
|
-
"meta-llama",
|
|
4307
|
-
"together",
|
|
4308
|
-
"xai",
|
|
4309
|
-
"moonshot",
|
|
4310
|
-
"nvidia",
|
|
4311
|
-
"minimax",
|
|
4312
|
-
"zai"
|
|
4313
|
-
]);
|
|
4314
|
-
function validateModel(model) {
|
|
4315
|
-
if (!model || typeof model !== "string") {
|
|
4316
|
-
throw new Error("Model must be a non-empty string");
|
|
4317
|
-
}
|
|
4318
|
-
}
|
|
4319
|
-
function validateMaxTokens(maxTokens) {
|
|
4320
|
-
if (maxTokens === void 0 || maxTokens === null) {
|
|
4321
|
-
return;
|
|
4322
|
-
}
|
|
4323
|
-
if (typeof maxTokens !== "number" || !Number.isInteger(maxTokens)) {
|
|
4324
|
-
throw new Error("maxTokens must be an integer");
|
|
4325
|
-
}
|
|
4326
|
-
if (maxTokens < 1) {
|
|
4327
|
-
throw new Error("maxTokens must be positive (minimum: 1)");
|
|
4328
|
-
}
|
|
4329
|
-
}
|
|
4330
|
-
function validateTemperature(temperature) {
|
|
4331
|
-
if (temperature === void 0 || temperature === null) {
|
|
4332
|
-
return;
|
|
4333
|
-
}
|
|
4334
|
-
if (typeof temperature !== "number") {
|
|
4335
|
-
throw new Error("temperature must be a number");
|
|
4336
|
-
}
|
|
4337
|
-
if (temperature < 0 || temperature > 2) {
|
|
4338
|
-
throw new Error("temperature must be between 0 and 2");
|
|
4339
|
-
}
|
|
4340
|
-
}
|
|
4341
|
-
function validateTopP(topP) {
|
|
4342
|
-
if (topP === void 0 || topP === null) {
|
|
4343
|
-
return;
|
|
4344
|
-
}
|
|
4345
|
-
if (typeof topP !== "number") {
|
|
4346
|
-
throw new Error("topP must be a number");
|
|
4347
|
-
}
|
|
4348
|
-
if (topP < 0 || topP > 1) {
|
|
4349
|
-
throw new Error("topP must be between 0 and 1");
|
|
4350
|
-
}
|
|
4351
|
-
}
|
|
4352
|
-
function validatePrivateKey(key) {
|
|
4353
|
-
if (typeof key !== "string") {
|
|
4354
|
-
throw new Error("Private key must be a string");
|
|
4355
|
-
}
|
|
4356
|
-
if (!key.startsWith("0x")) {
|
|
4357
|
-
throw new Error("Private key must start with 0x");
|
|
4358
|
-
}
|
|
4359
|
-
if (key.length !== 66) {
|
|
4360
|
-
throw new Error(
|
|
4361
|
-
"Private key must be 66 characters (0x + 64 hexadecimal characters)"
|
|
4362
|
-
);
|
|
4363
|
-
}
|
|
4364
|
-
if (!/^0x[0-9a-fA-F]{64}$/.test(key)) {
|
|
4365
|
-
throw new Error(
|
|
4366
|
-
"Private key must contain only hexadecimal characters (0-9, a-f, A-F)"
|
|
4367
|
-
);
|
|
4368
|
-
}
|
|
4369
|
-
}
|
|
4370
|
-
function validateApiUrl(url) {
|
|
4371
|
-
let parsed;
|
|
4372
|
-
try {
|
|
4373
|
-
parsed = new URL(url);
|
|
4374
|
-
} catch {
|
|
4375
|
-
throw new Error("Invalid API URL format");
|
|
4376
|
-
}
|
|
4377
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
4378
|
-
throw new Error(
|
|
4379
|
-
`Invalid protocol: ${parsed.protocol}. Use http:// or https://`
|
|
4380
|
-
);
|
|
4381
|
-
}
|
|
4382
|
-
const isLocalhost = LOCALHOST_DOMAINS.includes(parsed.hostname);
|
|
4383
|
-
if (parsed.protocol !== "https:" && !isLocalhost) {
|
|
4384
|
-
throw new Error(
|
|
4385
|
-
`API URL must use HTTPS for non-localhost endpoints. Use https:// instead of ${parsed.protocol}//`
|
|
4386
|
-
);
|
|
4387
|
-
}
|
|
4388
|
-
}
|
|
4389
|
-
function sanitizeErrorResponse(errorBody) {
|
|
4390
|
-
if (typeof errorBody !== "object" || errorBody === null) {
|
|
4391
|
-
return { message: "API request failed" };
|
|
4392
|
-
}
|
|
4393
|
-
const body = errorBody;
|
|
4394
|
-
return {
|
|
4395
|
-
message: typeof body.error === "string" ? body.error : "API request failed",
|
|
4396
|
-
code: typeof body.code === "string" ? body.code : void 0
|
|
4397
|
-
};
|
|
4398
|
-
}
|
|
4399
|
-
function validateResourceUrl(url, baseUrl) {
|
|
4400
|
-
try {
|
|
4401
|
-
const parsed = new URL(url);
|
|
4402
|
-
const baseParsed = new URL(baseUrl);
|
|
4403
|
-
if (parsed.hostname !== baseParsed.hostname) {
|
|
4404
|
-
console.warn(
|
|
4405
|
-
`Resource URL hostname mismatch: ${parsed.hostname} vs ${baseParsed.hostname}. Using safe default instead.`
|
|
4406
|
-
);
|
|
4407
|
-
return `${baseUrl}/v1/chat/completions`;
|
|
4408
|
-
}
|
|
4409
|
-
if (parsed.protocol !== baseParsed.protocol) {
|
|
4410
|
-
console.warn(
|
|
4411
|
-
`Resource URL protocol mismatch: ${parsed.protocol} vs ${baseParsed.protocol}. Using safe default instead.`
|
|
4412
|
-
);
|
|
4413
|
-
return `${baseUrl}/v1/chat/completions`;
|
|
4414
|
-
}
|
|
4415
|
-
return url;
|
|
4416
|
-
} catch {
|
|
4417
|
-
console.warn(`Invalid resource URL format: ${url}. Using safe default.`);
|
|
4418
|
-
return `${baseUrl}/v1/chat/completions`;
|
|
4419
|
-
}
|
|
4420
|
-
}
|
|
4421
|
-
|
|
4422
4557
|
// src/cost-log.ts
|
|
4423
4558
|
var fs = __toESM(require("fs"), 1);
|
|
4424
4559
|
var path = __toESM(require("path"), 1);
|
|
@@ -4465,7 +4600,7 @@ function getCostSummary() {
|
|
|
4465
4600
|
}
|
|
4466
4601
|
|
|
4467
4602
|
// src/version.ts
|
|
4468
|
-
var SDK_VERSION = "3.
|
|
4603
|
+
var SDK_VERSION = "3.14.0";
|
|
4469
4604
|
var USER_AGENT = `blockrun-ts/${SDK_VERSION}`;
|
|
4470
4605
|
|
|
4471
4606
|
// src/client.ts
|
|
@@ -4513,8 +4648,19 @@ function resolveDefaultTimeout() {
|
|
|
4513
4648
|
var DEFAULT_TIMEOUT = resolveDefaultTimeout();
|
|
4514
4649
|
var LLMClient = class _LLMClient {
|
|
4515
4650
|
static DEFAULT_API_URL = DEFAULT_API_URL;
|
|
4516
|
-
|
|
4517
|
-
|
|
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
|
+
}
|
|
4518
4664
|
apiUrl;
|
|
4519
4665
|
timeout;
|
|
4520
4666
|
sessionTotalUsd = 0;
|
|
@@ -4532,17 +4678,20 @@ var LLMClient = class _LLMClient {
|
|
|
4532
4678
|
* @param options - Client configuration options (optional if BASE_CHAIN_WALLET_KEY env var is set)
|
|
4533
4679
|
*/
|
|
4534
4680
|
constructor(options = {}) {
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
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);
|
|
4541
4693
|
}
|
|
4542
|
-
|
|
4543
|
-
this.privateKey = privateKey;
|
|
4544
|
-
this.account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
4545
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL;
|
|
4694
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL;
|
|
4546
4695
|
validateApiUrl(apiUrl);
|
|
4547
4696
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
4548
4697
|
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
@@ -4583,7 +4732,7 @@ var LLMClient = class _LLMClient {
|
|
|
4583
4732
|
systemPrompt,
|
|
4584
4733
|
maxOutputTokens,
|
|
4585
4734
|
await this.getModelPricing(),
|
|
4586
|
-
{ ...options, minimumPaymentUsd: BASE_MINIMUM_PAYMENT_USD }
|
|
4735
|
+
{ ...options, minimumPaymentUsd: this.apiAuth ? 0 : BASE_MINIMUM_PAYMENT_USD }
|
|
4587
4736
|
);
|
|
4588
4737
|
}
|
|
4589
4738
|
/**
|
|
@@ -5169,6 +5318,7 @@ var LLMClient = class _LLMClient {
|
|
|
5169
5318
|
sanitizeErrorResponse(errorBody)
|
|
5170
5319
|
);
|
|
5171
5320
|
}
|
|
5321
|
+
if (this.apiAuth && endpoint.startsWith("/v1/images/")) return this.apiAuth.poll(response, this.timeout, 2e3);
|
|
5172
5322
|
return response.json();
|
|
5173
5323
|
}
|
|
5174
5324
|
/**
|
|
@@ -5421,7 +5571,7 @@ var LLMClient = class _LLMClient {
|
|
|
5421
5571
|
const controller = new AbortController();
|
|
5422
5572
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
5423
5573
|
try {
|
|
5424
|
-
const response = await fetch(url, {
|
|
5574
|
+
const response = await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, {
|
|
5425
5575
|
...options,
|
|
5426
5576
|
signal: controller.signal
|
|
5427
5577
|
});
|
|
@@ -5922,6 +6072,7 @@ var LLMClient = class _LLMClient {
|
|
|
5922
6072
|
* console.log(`Spent $${spending.totalUsd.toFixed(4)} across ${spending.calls} calls`);
|
|
5923
6073
|
*/
|
|
5924
6074
|
getSpending() {
|
|
6075
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
5925
6076
|
return {
|
|
5926
6077
|
totalUsd: this.sessionTotalUsd,
|
|
5927
6078
|
calls: this.sessionCalls
|
|
@@ -5945,8 +6096,19 @@ var DEFAULT_TIMEOUT2 = 2e5;
|
|
|
5945
6096
|
var POLL_INTERVAL_MS = 3e3;
|
|
5946
6097
|
var POLL_MAX_DURATION_MS = 3e5;
|
|
5947
6098
|
var ImageClient = class {
|
|
5948
|
-
|
|
5949
|
-
|
|
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
|
+
}
|
|
5950
6112
|
apiUrl;
|
|
5951
6113
|
timeout;
|
|
5952
6114
|
sessionTotalUsd = 0;
|
|
@@ -5957,17 +6119,20 @@ var ImageClient = class {
|
|
|
5957
6119
|
* @param options - Client configuration options
|
|
5958
6120
|
*/
|
|
5959
6121
|
constructor(options = {}) {
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
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);
|
|
5966
6134
|
}
|
|
5967
|
-
|
|
5968
|
-
this.privateKey = privateKey;
|
|
5969
|
-
this.account = (0, import_accounts3.privateKeyToAccount)(privateKey);
|
|
5970
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL2;
|
|
6135
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL2;
|
|
5971
6136
|
validateApiUrl(apiUrl);
|
|
5972
6137
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
5973
6138
|
this.timeout = options.timeout || DEFAULT_TIMEOUT2;
|
|
@@ -6094,6 +6259,7 @@ var ImageClient = class {
|
|
|
6094
6259
|
sanitizeErrorResponse(errorBody)
|
|
6095
6260
|
);
|
|
6096
6261
|
}
|
|
6262
|
+
if (this.apiAuth) return this.apiAuth.poll(response, POLL_MAX_DURATION_MS, POLL_INTERVAL_MS);
|
|
6097
6263
|
return response.json();
|
|
6098
6264
|
}
|
|
6099
6265
|
/**
|
|
@@ -6231,7 +6397,7 @@ var ImageClient = class {
|
|
|
6231
6397
|
const controller = new AbortController();
|
|
6232
6398
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
6233
6399
|
try {
|
|
6234
|
-
const response = await fetch(url, {
|
|
6400
|
+
const response = await (this.apiAuth ? this.apiAuth.fetch.bind(this.apiAuth) : fetch)(url, {
|
|
6235
6401
|
...options,
|
|
6236
6402
|
signal: controller.signal
|
|
6237
6403
|
});
|
|
@@ -6250,6 +6416,7 @@ var ImageClient = class {
|
|
|
6250
6416
|
* Get session spending information.
|
|
6251
6417
|
*/
|
|
6252
6418
|
getSpending() {
|
|
6419
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
6253
6420
|
return {
|
|
6254
6421
|
totalUsd: this.sessionTotalUsd,
|
|
6255
6422
|
calls: this.sessionCalls
|
|
@@ -6263,24 +6430,38 @@ var DEFAULT_API_URL3 = "https://blockrun.ai/api";
|
|
|
6263
6430
|
var DEFAULT_MODEL2 = "minimax/music-2.5+";
|
|
6264
6431
|
var DEFAULT_TIMEOUT3 = 21e4;
|
|
6265
6432
|
var MusicClient = class {
|
|
6266
|
-
|
|
6267
|
-
|
|
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
|
+
}
|
|
6268
6446
|
apiUrl;
|
|
6269
6447
|
timeout;
|
|
6270
6448
|
sessionTotalUsd = 0;
|
|
6271
6449
|
sessionCalls = 0;
|
|
6272
6450
|
constructor(options = {}) {
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
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);
|
|
6279
6463
|
}
|
|
6280
|
-
|
|
6281
|
-
this.privateKey = privateKey;
|
|
6282
|
-
this.account = (0, import_accounts4.privateKeyToAccount)(privateKey);
|
|
6283
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL3;
|
|
6464
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL3;
|
|
6284
6465
|
validateApiUrl(apiUrl);
|
|
6285
6466
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
6286
6467
|
this.timeout = options.timeout || DEFAULT_TIMEOUT3;
|
|
@@ -6337,6 +6518,7 @@ var MusicClient = class {
|
|
|
6337
6518
|
}
|
|
6338
6519
|
throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
|
|
6339
6520
|
}
|
|
6521
|
+
if (this.apiAuth) return this.apiAuth.poll(response, this.timeout, 5e3);
|
|
6340
6522
|
return response.json();
|
|
6341
6523
|
}
|
|
6342
6524
|
async handlePaymentAndRetry(url, body, response) {
|
|
@@ -6399,7 +6581,7 @@ var MusicClient = class {
|
|
|
6399
6581
|
const controller = new AbortController();
|
|
6400
6582
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
6401
6583
|
try {
|
|
6402
|
-
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 });
|
|
6403
6585
|
} finally {
|
|
6404
6586
|
clearTimeout(timeoutId);
|
|
6405
6587
|
}
|
|
@@ -6408,6 +6590,7 @@ var MusicClient = class {
|
|
|
6408
6590
|
return this.account.address;
|
|
6409
6591
|
}
|
|
6410
6592
|
getSpending() {
|
|
6593
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
6411
6594
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
6412
6595
|
}
|
|
6413
6596
|
};
|
|
@@ -6419,24 +6602,38 @@ var DEFAULT_MODEL3 = "elevenlabs/flash-v2.5";
|
|
|
6419
6602
|
var DEFAULT_SOUNDFX_MODEL = "elevenlabs/sound-effects";
|
|
6420
6603
|
var DEFAULT_TIMEOUT4 = 12e4;
|
|
6421
6604
|
var SpeechClient = class {
|
|
6422
|
-
|
|
6423
|
-
|
|
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
|
+
}
|
|
6424
6618
|
apiUrl;
|
|
6425
6619
|
timeout;
|
|
6426
6620
|
sessionTotalUsd = 0;
|
|
6427
6621
|
sessionCalls = 0;
|
|
6428
6622
|
constructor(options = {}) {
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
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);
|
|
6435
6635
|
}
|
|
6436
|
-
|
|
6437
|
-
this.privateKey = privateKey;
|
|
6438
|
-
this.account = (0, import_accounts5.privateKeyToAccount)(privateKey);
|
|
6439
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL4;
|
|
6636
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL4;
|
|
6440
6637
|
validateApiUrl(apiUrl);
|
|
6441
6638
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
6442
6639
|
this.timeout = options.timeout || DEFAULT_TIMEOUT4;
|
|
@@ -6598,7 +6795,7 @@ var SpeechClient = class {
|
|
|
6598
6795
|
const controller = new AbortController();
|
|
6599
6796
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
6600
6797
|
try {
|
|
6601
|
-
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 });
|
|
6602
6799
|
} finally {
|
|
6603
6800
|
clearTimeout(timeoutId);
|
|
6604
6801
|
}
|
|
@@ -6607,6 +6804,7 @@ var SpeechClient = class {
|
|
|
6607
6804
|
return this.account.address;
|
|
6608
6805
|
}
|
|
6609
6806
|
getSpending() {
|
|
6807
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
6610
6808
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
6611
6809
|
}
|
|
6612
6810
|
};
|
|
@@ -6621,24 +6819,38 @@ var DEFAULT_GENERATE_BUDGET_MS = 9e5;
|
|
|
6621
6819
|
var MAX_TIMEOUT_SECONDS = 600;
|
|
6622
6820
|
var MAX_POLL_RESIGNS = 2;
|
|
6623
6821
|
var VideoClient = class {
|
|
6624
|
-
|
|
6625
|
-
|
|
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
|
+
}
|
|
6626
6835
|
apiUrl;
|
|
6627
6836
|
timeout;
|
|
6628
6837
|
sessionTotalUsd = 0;
|
|
6629
6838
|
sessionCalls = 0;
|
|
6630
6839
|
constructor(options = {}) {
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
6634
|
-
|
|
6635
|
-
|
|
6636
|
-
|
|
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);
|
|
6637
6852
|
}
|
|
6638
|
-
|
|
6639
|
-
this.privateKey = privateKey;
|
|
6640
|
-
this.account = (0, import_accounts6.privateKeyToAccount)(privateKey);
|
|
6641
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL5;
|
|
6853
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL5;
|
|
6642
6854
|
validateApiUrl(apiUrl);
|
|
6643
6855
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
6644
6856
|
this.timeout = options.timeout || DEFAULT_TIMEOUT5;
|
|
@@ -6764,6 +6976,7 @@ var VideoClient = class {
|
|
|
6764
6976
|
headers: { "Content-Type": "application/json" },
|
|
6765
6977
|
body: JSON.stringify(body)
|
|
6766
6978
|
});
|
|
6979
|
+
if (this.apiAuth) return this.apiAuth.poll(resp402, budgetMs, POLL_INTERVAL_MS2);
|
|
6767
6980
|
if (resp402.status !== 402) {
|
|
6768
6981
|
await this.throwApiError(resp402, "Expected 402 on first POST");
|
|
6769
6982
|
}
|
|
@@ -6911,7 +7124,7 @@ var VideoClient = class {
|
|
|
6911
7124
|
const controller = new AbortController();
|
|
6912
7125
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
6913
7126
|
try {
|
|
6914
|
-
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 });
|
|
6915
7128
|
} finally {
|
|
6916
7129
|
clearTimeout(timeoutId);
|
|
6917
7130
|
}
|
|
@@ -6920,6 +7133,7 @@ var VideoClient = class {
|
|
|
6920
7133
|
return this.account.address;
|
|
6921
7134
|
}
|
|
6922
7135
|
getSpending() {
|
|
7136
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
6923
7137
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
6924
7138
|
}
|
|
6925
7139
|
};
|
|
@@ -6931,24 +7145,38 @@ var DEFAULT_TIMEOUT6 = 6e4;
|
|
|
6931
7145
|
var CALL_PRICE_USD = 0.54;
|
|
6932
7146
|
var VALID_MODELS = /* @__PURE__ */ new Set(["base", "enhanced", "turbo"]);
|
|
6933
7147
|
var VoiceClient = class {
|
|
6934
|
-
|
|
6935
|
-
|
|
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
|
+
}
|
|
6936
7161
|
apiUrl;
|
|
6937
7162
|
timeout;
|
|
6938
7163
|
sessionTotalUsd = 0;
|
|
6939
7164
|
sessionCalls = 0;
|
|
6940
7165
|
constructor(options = {}) {
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
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);
|
|
6947
7178
|
}
|
|
6948
|
-
|
|
6949
|
-
this.privateKey = privateKey;
|
|
6950
|
-
this.account = (0, import_accounts7.privateKeyToAccount)(privateKey);
|
|
6951
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL6;
|
|
7179
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL6;
|
|
6952
7180
|
validateApiUrl(apiUrl);
|
|
6953
7181
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
6954
7182
|
this.timeout = options.timeout || DEFAULT_TIMEOUT6;
|
|
@@ -7112,7 +7340,7 @@ var VoiceClient = class {
|
|
|
7112
7340
|
const controller = new AbortController();
|
|
7113
7341
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
7114
7342
|
try {
|
|
7115
|
-
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 });
|
|
7116
7344
|
} finally {
|
|
7117
7345
|
clearTimeout(timeoutId);
|
|
7118
7346
|
}
|
|
@@ -7121,6 +7349,7 @@ var VoiceClient = class {
|
|
|
7121
7349
|
return this.account.address;
|
|
7122
7350
|
}
|
|
7123
7351
|
getSpending() {
|
|
7352
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
7124
7353
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
7125
7354
|
}
|
|
7126
7355
|
};
|
|
@@ -7150,24 +7379,38 @@ function requireE164(value) {
|
|
|
7150
7379
|
return v;
|
|
7151
7380
|
}
|
|
7152
7381
|
var PhoneClient = class {
|
|
7153
|
-
|
|
7154
|
-
|
|
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
|
+
}
|
|
7155
7395
|
apiUrl;
|
|
7156
7396
|
timeout;
|
|
7157
7397
|
sessionTotalUsd = 0;
|
|
7158
7398
|
sessionCalls = 0;
|
|
7159
7399
|
constructor(options = {}) {
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
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);
|
|
7166
7412
|
}
|
|
7167
|
-
|
|
7168
|
-
this.privateKey = privateKey;
|
|
7169
|
-
this.account = (0, import_accounts8.privateKeyToAccount)(privateKey);
|
|
7170
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL7;
|
|
7413
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL7;
|
|
7171
7414
|
validateApiUrl(apiUrl);
|
|
7172
7415
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
7173
7416
|
this.timeout = options.timeout || DEFAULT_TIMEOUT7;
|
|
@@ -7178,6 +7421,7 @@ var PhoneClient = class {
|
|
|
7178
7421
|
}
|
|
7179
7422
|
/** Session-cumulative USD spend + call count across this client instance. */
|
|
7180
7423
|
getSpending() {
|
|
7424
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
7181
7425
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
7182
7426
|
}
|
|
7183
7427
|
// ─── Lookup ────────────────────────────────────────────────────────────
|
|
@@ -7337,7 +7581,7 @@ var PhoneClient = class {
|
|
|
7337
7581
|
const controller = new AbortController();
|
|
7338
7582
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
7339
7583
|
try {
|
|
7340
|
-
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 });
|
|
7341
7585
|
} finally {
|
|
7342
7586
|
clearTimeout(timeoutId);
|
|
7343
7587
|
}
|
|
@@ -7350,24 +7594,38 @@ var DEFAULT_API_URL8 = "https://blockrun.ai/api";
|
|
|
7350
7594
|
var DEFAULT_TIMEOUT8 = 6e4;
|
|
7351
7595
|
var PORTRAIT_ENROLLMENT_PRICE_USD = 0.01;
|
|
7352
7596
|
var PortraitClient = class {
|
|
7353
|
-
|
|
7354
|
-
|
|
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
|
+
}
|
|
7355
7610
|
apiUrl;
|
|
7356
7611
|
timeout;
|
|
7357
7612
|
sessionTotalUsd = 0;
|
|
7358
7613
|
sessionCalls = 0;
|
|
7359
7614
|
constructor(options = {}) {
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
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);
|
|
7366
7627
|
}
|
|
7367
|
-
|
|
7368
|
-
this.privateKey = privateKey;
|
|
7369
|
-
this.account = (0, import_accounts9.privateKeyToAccount)(privateKey);
|
|
7370
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL8;
|
|
7628
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL8;
|
|
7371
7629
|
validateApiUrl(apiUrl);
|
|
7372
7630
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
7373
7631
|
this.timeout = options.timeout || DEFAULT_TIMEOUT8;
|
|
@@ -7378,6 +7636,7 @@ var PortraitClient = class {
|
|
|
7378
7636
|
}
|
|
7379
7637
|
/** Session-cumulative USD spend + call count across this client instance. */
|
|
7380
7638
|
getSpending() {
|
|
7639
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
7381
7640
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
7382
7641
|
}
|
|
7383
7642
|
/**
|
|
@@ -7491,7 +7750,7 @@ var PortraitClient = class {
|
|
|
7491
7750
|
const controller = new AbortController();
|
|
7492
7751
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
7493
7752
|
try {
|
|
7494
|
-
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 });
|
|
7495
7754
|
} finally {
|
|
7496
7755
|
clearTimeout(timeoutId);
|
|
7497
7756
|
}
|
|
@@ -7503,22 +7762,36 @@ var import_accounts10 = require("viem/accounts");
|
|
|
7503
7762
|
var DEFAULT_API_URL9 = "https://blockrun.ai/api";
|
|
7504
7763
|
var DEFAULT_TIMEOUT9 = 6e4;
|
|
7505
7764
|
var SearchClient = class {
|
|
7506
|
-
|
|
7507
|
-
|
|
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
|
+
}
|
|
7508
7778
|
apiUrl;
|
|
7509
7779
|
timeout;
|
|
7510
7780
|
constructor(options = {}) {
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
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);
|
|
7517
7793
|
}
|
|
7518
|
-
|
|
7519
|
-
this.privateKey = privateKey;
|
|
7520
|
-
this.account = (0, import_accounts10.privateKeyToAccount)(privateKey);
|
|
7521
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL9;
|
|
7794
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL9;
|
|
7522
7795
|
validateApiUrl(apiUrl);
|
|
7523
7796
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
7524
7797
|
this.timeout = options.timeout || DEFAULT_TIMEOUT9;
|
|
@@ -7624,7 +7897,7 @@ var SearchClient = class {
|
|
|
7624
7897
|
const controller = new AbortController();
|
|
7625
7898
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
7626
7899
|
try {
|
|
7627
|
-
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 });
|
|
7628
7901
|
} finally {
|
|
7629
7902
|
clearTimeout(timeoutId);
|
|
7630
7903
|
}
|
|
@@ -7639,15 +7912,20 @@ var import_accounts11 = require("viem/accounts");
|
|
|
7639
7912
|
var DEFAULT_API_URL10 = "https://blockrun.ai/api";
|
|
7640
7913
|
var DEFAULT_TIMEOUT10 = 3e4;
|
|
7641
7914
|
var PriceClient = class {
|
|
7915
|
+
apiAuth;
|
|
7916
|
+
get authMode() {
|
|
7917
|
+
return this.apiAuth ? "api-key" : "wallet";
|
|
7918
|
+
}
|
|
7642
7919
|
account = null;
|
|
7643
7920
|
privateKey = null;
|
|
7644
7921
|
apiUrl;
|
|
7645
7922
|
timeout;
|
|
7646
7923
|
constructor(options = {}) {
|
|
7924
|
+
this.apiAuth = resolveApiKeyAuth(options);
|
|
7647
7925
|
const envKey = typeof process !== "undefined" && process.env ? process.env.BLOCKRUN_WALLET_KEY || process.env.BASE_CHAIN_WALLET_KEY : void 0;
|
|
7648
|
-
const privateKey = options.privateKey || envKey;
|
|
7649
|
-
const
|
|
7650
|
-
if (!privateKey &&
|
|
7926
|
+
const privateKey = this.apiAuth ? void 0 : options.privateKey || envKey;
|
|
7927
|
+
const requireWallet2 = options.requireWallet ?? true;
|
|
7928
|
+
if (!this.apiAuth && !privateKey && requireWallet2) {
|
|
7651
7929
|
throw new Error(
|
|
7652
7930
|
"Private key required for paid endpoints. Pass privateKey in options, set BLOCKRUN_WALLET_KEY, or pass requireWallet: false for free-only usage."
|
|
7653
7931
|
);
|
|
@@ -7657,7 +7935,7 @@ var PriceClient = class {
|
|
|
7657
7935
|
this.privateKey = privateKey;
|
|
7658
7936
|
this.account = (0, import_accounts11.privateKeyToAccount)(privateKey);
|
|
7659
7937
|
}
|
|
7660
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL10;
|
|
7938
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL10;
|
|
7661
7939
|
validateApiUrl(apiUrl);
|
|
7662
7940
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
7663
7941
|
this.timeout = options.timeout || DEFAULT_TIMEOUT10;
|
|
@@ -7810,7 +8088,7 @@ var PriceClient = class {
|
|
|
7810
8088
|
const controller = new AbortController();
|
|
7811
8089
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
7812
8090
|
try {
|
|
7813
|
-
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 });
|
|
7814
8092
|
} finally {
|
|
7815
8093
|
clearTimeout(timeoutId);
|
|
7816
8094
|
}
|
|
@@ -7844,22 +8122,36 @@ var DEFAULT_API_URL11 = "https://blockrun.ai/api";
|
|
|
7844
8122
|
var DEFAULT_TIMEOUT11 = 6e4;
|
|
7845
8123
|
var SURF_PREFIX = "/v1/surf";
|
|
7846
8124
|
var SurfClient = class {
|
|
7847
|
-
|
|
7848
|
-
|
|
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
|
+
}
|
|
7849
8138
|
apiUrl;
|
|
7850
8139
|
timeout;
|
|
7851
8140
|
constructor(options = {}) {
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
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);
|
|
7858
8153
|
}
|
|
7859
|
-
|
|
7860
|
-
this.privateKey = privateKey;
|
|
7861
|
-
this.account = (0, import_accounts12.privateKeyToAccount)(privateKey);
|
|
7862
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL11;
|
|
8154
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL11;
|
|
7863
8155
|
validateApiUrl(apiUrl);
|
|
7864
8156
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
7865
8157
|
this.timeout = options.timeout || DEFAULT_TIMEOUT11;
|
|
@@ -7983,7 +8275,7 @@ var SurfClient = class {
|
|
|
7983
8275
|
const controller = new AbortController();
|
|
7984
8276
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
7985
8277
|
try {
|
|
7986
|
-
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 });
|
|
7987
8279
|
} finally {
|
|
7988
8280
|
clearTimeout(timeoutId);
|
|
7989
8281
|
}
|
|
@@ -8072,24 +8364,38 @@ var NETWORK_ALIASES = {
|
|
|
8072
8364
|
zec: "zcash"
|
|
8073
8365
|
};
|
|
8074
8366
|
var RpcClient = class {
|
|
8075
|
-
|
|
8076
|
-
|
|
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
|
+
}
|
|
8077
8380
|
apiUrl;
|
|
8078
8381
|
timeout;
|
|
8079
8382
|
sessionTotalUsd = 0;
|
|
8080
8383
|
sessionCalls = 0;
|
|
8081
8384
|
constructor(options = {}) {
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
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);
|
|
8088
8397
|
}
|
|
8089
|
-
|
|
8090
|
-
this.privateKey = privateKey;
|
|
8091
|
-
this.account = (0, import_accounts13.privateKeyToAccount)(privateKey);
|
|
8092
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL12;
|
|
8398
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL12;
|
|
8093
8399
|
validateApiUrl(apiUrl);
|
|
8094
8400
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
8095
8401
|
this.timeout = options.timeout || DEFAULT_TIMEOUT12;
|
|
@@ -8233,7 +8539,7 @@ var RpcClient = class {
|
|
|
8233
8539
|
const controller = new AbortController();
|
|
8234
8540
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
8235
8541
|
try {
|
|
8236
|
-
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 });
|
|
8237
8543
|
} finally {
|
|
8238
8544
|
clearTimeout(timeoutId);
|
|
8239
8545
|
}
|
|
@@ -8242,6 +8548,7 @@ var RpcClient = class {
|
|
|
8242
8548
|
return this.account.address;
|
|
8243
8549
|
}
|
|
8244
8550
|
getSpending() {
|
|
8551
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
8245
8552
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
8246
8553
|
}
|
|
8247
8554
|
};
|
|
@@ -8254,24 +8561,38 @@ var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
|
8254
8561
|
var DEFAULT_POLL_BUDGET_MS = 3e5;
|
|
8255
8562
|
var MAX_SIGNED_AUTH_SECONDS = 600;
|
|
8256
8563
|
var BlockrunClient = class {
|
|
8257
|
-
|
|
8258
|
-
|
|
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
|
+
}
|
|
8259
8577
|
apiUrl;
|
|
8260
8578
|
timeout;
|
|
8261
8579
|
sessionTotalUsd = 0;
|
|
8262
8580
|
sessionCalls = 0;
|
|
8263
8581
|
constructor(options = {}) {
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
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);
|
|
8270
8594
|
}
|
|
8271
|
-
|
|
8272
|
-
this.privateKey = privateKey;
|
|
8273
|
-
this.account = (0, import_accounts14.privateKeyToAccount)(privateKey);
|
|
8274
|
-
const apiUrl = options.apiUrl || DEFAULT_API_URL13;
|
|
8595
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || DEFAULT_API_URL13;
|
|
8275
8596
|
validateApiUrl(apiUrl);
|
|
8276
8597
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
8277
8598
|
this.timeout = options.timeout || DEFAULT_TIMEOUT13;
|
|
@@ -8313,6 +8634,7 @@ var BlockrunClient = class {
|
|
|
8313
8634
|
headers: { "Content-Type": "application/json" },
|
|
8314
8635
|
body: JSON.stringify(body ?? {})
|
|
8315
8636
|
});
|
|
8637
|
+
if (this.apiAuth) return this.apiAuth.poll(resp402, budgetMs, intervalMs);
|
|
8316
8638
|
if (resp402.status === 200) {
|
|
8317
8639
|
return resp402.json();
|
|
8318
8640
|
}
|
|
@@ -8605,7 +8927,7 @@ var BlockrunClient = class {
|
|
|
8605
8927
|
const controller = new AbortController();
|
|
8606
8928
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
8607
8929
|
try {
|
|
8608
|
-
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 });
|
|
8609
8931
|
} finally {
|
|
8610
8932
|
clearTimeout(timeoutId);
|
|
8611
8933
|
}
|
|
@@ -8617,6 +8939,7 @@ var BlockrunClient = class {
|
|
|
8617
8939
|
return this.account.address;
|
|
8618
8940
|
}
|
|
8619
8941
|
getSpending() {
|
|
8942
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
8620
8943
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
8621
8944
|
}
|
|
8622
8945
|
};
|
|
@@ -8627,7 +8950,7 @@ function sleep(ms) {
|
|
|
8627
8950
|
// src/wallet.ts
|
|
8628
8951
|
var import_accounts16 = require("viem/accounts");
|
|
8629
8952
|
|
|
8630
|
-
// node_modules/.pnpm/@blockrun+core@0.1.1_bufferutil@4.1.0_typescript@
|
|
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
|
|
8631
8954
|
var fs2 = __toESM(require("fs"), 1);
|
|
8632
8955
|
var os2 = __toESM(require("os"), 1);
|
|
8633
8956
|
var path2 = __toESM(require("path"), 1);
|
|
@@ -8649,7 +8972,7 @@ function paths() {
|
|
|
8649
8972
|
};
|
|
8650
8973
|
}
|
|
8651
8974
|
|
|
8652
|
-
// node_modules/.pnpm/@blockrun+core@0.1.1_bufferutil@4.1.0_typescript@
|
|
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
|
|
8653
8976
|
var fs3 = __toESM(require("fs"), 1);
|
|
8654
8977
|
var path3 = __toESM(require("path"), 1);
|
|
8655
8978
|
var import_accounts15 = require("viem/accounts");
|
|
@@ -8945,7 +9268,8 @@ async function solanaKeyToBytes(privateKey) {
|
|
|
8945
9268
|
} catch (err) {
|
|
8946
9269
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8947
9270
|
throw new Error(
|
|
8948
|
-
`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 }
|
|
8949
9273
|
);
|
|
8950
9274
|
}
|
|
8951
9275
|
}
|
|
@@ -9091,7 +9415,7 @@ async function solanaPublicKeyFrom(privateKey, source) {
|
|
|
9091
9415
|
return await solanaPublicKey(privateKey);
|
|
9092
9416
|
} catch (err) {
|
|
9093
9417
|
const msg = err instanceof Error ? err.message : String(err);
|
|
9094
|
-
throw new Error(`${msg} (key loaded from ${source})
|
|
9418
|
+
throw new Error(`${msg} (key loaded from ${source})`, { cause: err });
|
|
9095
9419
|
}
|
|
9096
9420
|
}
|
|
9097
9421
|
async function getOrCreateSolanaWallet() {
|
|
@@ -9205,7 +9529,14 @@ function resolveRpcConfig(rpcUrl, rpcHeaders) {
|
|
|
9205
9529
|
}
|
|
9206
9530
|
var SolanaLLMClient = class {
|
|
9207
9531
|
static SOLANA_API_URL = SOLANA_API_URL;
|
|
9208
|
-
|
|
9532
|
+
apiAuth;
|
|
9533
|
+
get authMode() {
|
|
9534
|
+
return this.apiAuth ? "api-key" : "wallet";
|
|
9535
|
+
}
|
|
9536
|
+
_privateKey;
|
|
9537
|
+
get privateKey() {
|
|
9538
|
+
return requireWallet(this._privateKey);
|
|
9539
|
+
}
|
|
9209
9540
|
apiUrl;
|
|
9210
9541
|
rpcUrl;
|
|
9211
9542
|
rpcHeaders;
|
|
@@ -9216,15 +9547,18 @@ var SolanaLLMClient = class {
|
|
|
9216
9547
|
modelPricingCache = null;
|
|
9217
9548
|
modelPricingPromise = null;
|
|
9218
9549
|
constructor(options = {}) {
|
|
9219
|
-
|
|
9220
|
-
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
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;
|
|
9225
9560
|
}
|
|
9226
|
-
this.
|
|
9227
|
-
const apiUrl = options.apiUrl || SOLANA_API_URL;
|
|
9561
|
+
const apiUrl = this.apiAuth?.apiUrl || options.apiUrl || SOLANA_API_URL;
|
|
9228
9562
|
validateApiUrl(apiUrl);
|
|
9229
9563
|
this.apiUrl = apiUrl.replace(/\/$/, "");
|
|
9230
9564
|
const rpc = resolveRpcConfig(options.rpcUrl, options.rpcHeaders);
|
|
@@ -9337,7 +9671,7 @@ var SolanaLLMClient = class {
|
|
|
9337
9671
|
{
|
|
9338
9672
|
routingProfile: options?.routingProfile,
|
|
9339
9673
|
requiresStructuredOutput: options?.responseFormat !== void 0,
|
|
9340
|
-
minimumPaymentUsd: SOLANA_MINIMUM_PAYMENT_USD
|
|
9674
|
+
minimumPaymentUsd: this.apiAuth ? 0 : SOLANA_MINIMUM_PAYMENT_USD
|
|
9341
9675
|
}
|
|
9342
9676
|
);
|
|
9343
9677
|
}
|
|
@@ -9366,7 +9700,7 @@ var SolanaLLMClient = class {
|
|
|
9366
9700
|
toolChoice: options.toolChoice,
|
|
9367
9701
|
conversationChars,
|
|
9368
9702
|
hasVision,
|
|
9369
|
-
minimumPaymentUsd: SOLANA_MINIMUM_PAYMENT_USD
|
|
9703
|
+
minimumPaymentUsd: this.apiAuth ? 0 : SOLANA_MINIMUM_PAYMENT_USD
|
|
9370
9704
|
}
|
|
9371
9705
|
);
|
|
9372
9706
|
const response = await this.chatCompletion(decision.model, messages, {
|
|
@@ -9619,6 +9953,7 @@ var SolanaLLMClient = class {
|
|
|
9619
9953
|
}
|
|
9620
9954
|
/** Get session spending. */
|
|
9621
9955
|
getSpending() {
|
|
9956
|
+
if (this.apiAuth) throw new Error("Account usage is available at https://user.blockrun.ai/dashboard; getSpending() tracks x402 settlements only.");
|
|
9622
9957
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
9623
9958
|
}
|
|
9624
9959
|
/** True if using sol.blockrun.ai. */
|
|
@@ -9755,6 +10090,7 @@ var SolanaLLMClient = class {
|
|
|
9755
10090
|
}
|
|
9756
10091
|
throw new APIError(`API error: ${response.status}`, response.status, sanitizeErrorResponse(errorBody));
|
|
9757
10092
|
}
|
|
10093
|
+
if (this.apiAuth && endpoint.startsWith("/v1/images/")) return this.apiAuth.poll(response, this.timeout, 2e3);
|
|
9758
10094
|
return response.json();
|
|
9759
10095
|
}
|
|
9760
10096
|
}
|
|
@@ -9941,7 +10277,7 @@ var SolanaLLMClient = class {
|
|
|
9941
10277
|
const controller = new AbortController();
|
|
9942
10278
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
9943
10279
|
try {
|
|
9944
|
-
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 });
|
|
9945
10281
|
} finally {
|
|
9946
10282
|
clearTimeout(timeoutId);
|
|
9947
10283
|
}
|
|
@@ -10140,6 +10476,9 @@ function getCostLogSummary() {
|
|
|
10140
10476
|
}
|
|
10141
10477
|
|
|
10142
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");
|
|
10143
10482
|
function setupAgentWallet(options) {
|
|
10144
10483
|
const { address, privateKey, isNew } = getOrCreateWallet();
|
|
10145
10484
|
if (isNew) {
|
|
@@ -10182,6 +10521,24 @@ async function status() {
|
|
|
10182
10521
|
console.log(`Balance: $${balance.toFixed(2)} USDC`);
|
|
10183
10522
|
return { address, balance };
|
|
10184
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
|
+
}
|
|
10185
10542
|
|
|
10186
10543
|
// src/openai-compat.ts
|
|
10187
10544
|
var StreamingResponse = class {
|
|
@@ -10313,13 +10670,17 @@ var Chat = class {
|
|
|
10313
10670
|
};
|
|
10314
10671
|
var OpenAI = class {
|
|
10315
10672
|
chat;
|
|
10673
|
+
get authMode() {
|
|
10674
|
+
return this.client.authMode;
|
|
10675
|
+
}
|
|
10316
10676
|
client;
|
|
10317
10677
|
constructor(options = {}) {
|
|
10318
10678
|
const privateKey = options.walletKey || options.privateKey;
|
|
10319
|
-
const apiUrl = options.baseURL
|
|
10679
|
+
const apiUrl = resolveApiKeyAuth({ apiKey: options.apiKey, privateKey, apiUrl: options.baseURL })?.apiUrl ?? options.baseURL ?? "https://blockrun.ai/api";
|
|
10320
10680
|
const timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
10321
10681
|
this.client = new LLMClient({
|
|
10322
10682
|
privateKey,
|
|
10683
|
+
apiKey: options.apiKey,
|
|
10323
10684
|
apiUrl,
|
|
10324
10685
|
timeout
|
|
10325
10686
|
});
|
|
@@ -10338,17 +10699,29 @@ var import_accounts17 = require("viem/accounts");
|
|
|
10338
10699
|
var AnthropicClient = class {
|
|
10339
10700
|
_client = null;
|
|
10340
10701
|
_clientPromise = null;
|
|
10341
|
-
|
|
10342
|
-
|
|
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
|
+
}
|
|
10343
10714
|
_apiUrl;
|
|
10344
10715
|
_timeout;
|
|
10345
10716
|
constructor(options = {}) {
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
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";
|
|
10352
10725
|
validateApiUrl(apiUrl);
|
|
10353
10726
|
this._apiUrl = apiUrl.replace(/\/$/, "");
|
|
10354
10727
|
this._timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
@@ -10372,6 +10745,7 @@ var AnthropicClient = class {
|
|
|
10372
10745
|
const timeoutId = setTimeout(() => controller.abort(), this._timeout);
|
|
10373
10746
|
try {
|
|
10374
10747
|
const mergedInit = { ...init, signal: controller.signal };
|
|
10748
|
+
if (this.apiAuth) return await this.apiAuth.fetch(input, mergedInit, false);
|
|
10375
10749
|
let response = await globalThis.fetch(input, mergedInit);
|
|
10376
10750
|
if (response.status === 402) {
|
|
10377
10751
|
let paymentHeader = response.headers.get("payment-required");
|
|
@@ -10444,6 +10818,7 @@ var AnthropicClient = class {
|
|
|
10444
10818
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10445
10819
|
0 && (module.exports = {
|
|
10446
10820
|
APIError,
|
|
10821
|
+
API_KEY_URL,
|
|
10447
10822
|
AnthropicClient,
|
|
10448
10823
|
BASE_CHAIN_ID,
|
|
10449
10824
|
BlockrunClient,
|
|
@@ -10455,6 +10830,7 @@ var AnthropicClient = class {
|
|
|
10455
10830
|
NETWORK_ALIASES,
|
|
10456
10831
|
OpenAI,
|
|
10457
10832
|
PHONE_PRICES,
|
|
10833
|
+
PORTAL_URL,
|
|
10458
10834
|
PORTRAIT_ENROLLMENT_PRICE_USD,
|
|
10459
10835
|
PaymentError,
|
|
10460
10836
|
PhoneClient,
|
|
@@ -10511,6 +10887,7 @@ var AnthropicClient = class {
|
|
|
10511
10887
|
scanSolanaWallets,
|
|
10512
10888
|
scanWallets,
|
|
10513
10889
|
setCache,
|
|
10890
|
+
setupAgentClient,
|
|
10514
10891
|
setupAgentSolanaWallet,
|
|
10515
10892
|
setupAgentWallet,
|
|
10516
10893
|
solanaClient,
|