@blockrun/clawrouter 0.12.255 → 0.12.257
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/cli.js +973 -614
- package/dist/index.d.ts +235 -113
- package/dist/index.js +959 -600
- package/docs/configuration.md +81 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -27426,8 +27426,8 @@ var init_parseUtil = __esm({
|
|
|
27426
27426
|
init_errors4();
|
|
27427
27427
|
init_en();
|
|
27428
27428
|
makeIssue = (params) => {
|
|
27429
|
-
const { data, path:
|
|
27430
|
-
const fullPath = [...
|
|
27429
|
+
const { data, path: path5, errorMaps, issueData } = params;
|
|
27430
|
+
const fullPath = [...path5, ...issueData.path || []];
|
|
27431
27431
|
const fullIssue = {
|
|
27432
27432
|
...issueData,
|
|
27433
27433
|
path: fullPath
|
|
@@ -27738,11 +27738,11 @@ var init_types = __esm({
|
|
|
27738
27738
|
init_parseUtil();
|
|
27739
27739
|
init_util();
|
|
27740
27740
|
ParseInputLazyPath = class {
|
|
27741
|
-
constructor(parent, value,
|
|
27741
|
+
constructor(parent, value, path5, key2) {
|
|
27742
27742
|
this._cachedPath = [];
|
|
27743
27743
|
this.parent = parent;
|
|
27744
27744
|
this.data = value;
|
|
27745
|
-
this._path =
|
|
27745
|
+
this._path = path5;
|
|
27746
27746
|
this._key = key2;
|
|
27747
27747
|
}
|
|
27748
27748
|
get path() {
|
|
@@ -32235,6 +32235,613 @@ var init_max_tokens = __esm({
|
|
|
32235
32235
|
}
|
|
32236
32236
|
});
|
|
32237
32237
|
|
|
32238
|
+
// src/fs-read.ts
|
|
32239
|
+
import { open } from "fs/promises";
|
|
32240
|
+
import { openSync, readSync, closeSync, fstatSync } from "fs";
|
|
32241
|
+
async function readTextFile(filePath) {
|
|
32242
|
+
const fh = await open(filePath, "r");
|
|
32243
|
+
try {
|
|
32244
|
+
const size5 = (await fh.stat()).size;
|
|
32245
|
+
const buf = Buffer.alloc(size5);
|
|
32246
|
+
let offset = 0;
|
|
32247
|
+
while (offset < size5) {
|
|
32248
|
+
const { bytesRead } = await fh.read(buf, offset, size5 - offset, offset);
|
|
32249
|
+
if (bytesRead === 0) break;
|
|
32250
|
+
offset += bytesRead;
|
|
32251
|
+
}
|
|
32252
|
+
return buf.subarray(0, offset).toString("utf-8");
|
|
32253
|
+
} finally {
|
|
32254
|
+
await fh.close();
|
|
32255
|
+
}
|
|
32256
|
+
}
|
|
32257
|
+
function readTextFileSync(filePath) {
|
|
32258
|
+
const fd = openSync(filePath, "r");
|
|
32259
|
+
try {
|
|
32260
|
+
const size5 = fstatSync(fd).size;
|
|
32261
|
+
const buf = Buffer.alloc(size5);
|
|
32262
|
+
let offset = 0;
|
|
32263
|
+
while (offset < size5) {
|
|
32264
|
+
const bytesRead = readSync(fd, buf, offset, size5 - offset, offset);
|
|
32265
|
+
if (bytesRead === 0) break;
|
|
32266
|
+
offset += bytesRead;
|
|
32267
|
+
}
|
|
32268
|
+
return buf.subarray(0, offset).toString("utf-8");
|
|
32269
|
+
} finally {
|
|
32270
|
+
closeSync(fd);
|
|
32271
|
+
}
|
|
32272
|
+
}
|
|
32273
|
+
var init_fs_read = __esm({
|
|
32274
|
+
"src/fs-read.ts"() {
|
|
32275
|
+
"use strict";
|
|
32276
|
+
}
|
|
32277
|
+
});
|
|
32278
|
+
|
|
32279
|
+
// src/spend-control.ts
|
|
32280
|
+
import * as fs from "fs";
|
|
32281
|
+
import * as path from "path";
|
|
32282
|
+
import { homedir } from "os";
|
|
32283
|
+
function normalizePayee(value) {
|
|
32284
|
+
return EVM_ADDRESS.test(value) ? value.toLowerCase() : value;
|
|
32285
|
+
}
|
|
32286
|
+
function isAddressList(list) {
|
|
32287
|
+
return ADDRESS_LISTS.includes(list);
|
|
32288
|
+
}
|
|
32289
|
+
function normalizePolicyValues(list, values) {
|
|
32290
|
+
return isAddressList(list) ? values.map(normalizePayee) : [...values];
|
|
32291
|
+
}
|
|
32292
|
+
function isValidPolicyValues(values) {
|
|
32293
|
+
return Array.isArray(values) && values.every((v) => typeof v === "string" && v.length > 0);
|
|
32294
|
+
}
|
|
32295
|
+
function isPolicyList(value) {
|
|
32296
|
+
return POLICY_LISTS.includes(value);
|
|
32297
|
+
}
|
|
32298
|
+
function cloneLimits(limits) {
|
|
32299
|
+
const clone = { ...limits };
|
|
32300
|
+
for (const key2 of POLICY_LISTS) {
|
|
32301
|
+
const val = limits[key2];
|
|
32302
|
+
if (val !== void 0) {
|
|
32303
|
+
clone[key2] = [...val];
|
|
32304
|
+
}
|
|
32305
|
+
}
|
|
32306
|
+
return clone;
|
|
32307
|
+
}
|
|
32308
|
+
function parseQuotedAmountUsd(selected) {
|
|
32309
|
+
const raw = selected.amount ?? selected.maxAmountRequired;
|
|
32310
|
+
if (typeof raw !== "string" || !CANONICAL_AMOUNT.test(raw)) {
|
|
32311
|
+
return void 0;
|
|
32312
|
+
}
|
|
32313
|
+
const micros = Number(raw);
|
|
32314
|
+
if (!Number.isSafeInteger(micros)) {
|
|
32315
|
+
return void 0;
|
|
32316
|
+
}
|
|
32317
|
+
return micros / 1e6;
|
|
32318
|
+
}
|
|
32319
|
+
function assertSpendPolicyAllows(control, selected) {
|
|
32320
|
+
const quoted = parseQuotedAmountUsd(selected);
|
|
32321
|
+
if (quoted === void 0 && control.hasAmountLimits()) {
|
|
32322
|
+
throw new SpendPolicyError(
|
|
32323
|
+
`Payment quote carries no usable amount (${JSON.stringify(
|
|
32324
|
+
selected.amount ?? selected.maxAmountRequired
|
|
32325
|
+
)}); refusing to sign against a configured spend limit`
|
|
32326
|
+
);
|
|
32327
|
+
}
|
|
32328
|
+
const estimatedCost2 = quoted ?? 0;
|
|
32329
|
+
const result = control.check(estimatedCost2, {
|
|
32330
|
+
payTo: selected.payTo,
|
|
32331
|
+
network: selected.network,
|
|
32332
|
+
asset: selected.asset
|
|
32333
|
+
});
|
|
32334
|
+
if (!result.allowed) {
|
|
32335
|
+
throw new SpendPolicyError(result.reason ?? "blocked by spend policy", {
|
|
32336
|
+
blockedBy: result.blockedBy,
|
|
32337
|
+
blockedByPolicy: result.blockedByPolicy
|
|
32338
|
+
});
|
|
32339
|
+
}
|
|
32340
|
+
if (!control.hasAggregateLimits()) {
|
|
32341
|
+
return void 0;
|
|
32342
|
+
}
|
|
32343
|
+
return control.reserve(estimatedCost2);
|
|
32344
|
+
}
|
|
32345
|
+
function registerSpendPolicyHook(x402, control) {
|
|
32346
|
+
const reservations = /* @__PURE__ */ new WeakMap();
|
|
32347
|
+
x402.onBeforePaymentCreation(async (ctx) => {
|
|
32348
|
+
const selected = ctx.selectedRequirements;
|
|
32349
|
+
const reservationId = assertSpendPolicyAllows(control, selected);
|
|
32350
|
+
if (reservationId !== void 0) {
|
|
32351
|
+
reservations.set(ctx.selectedRequirements, reservationId);
|
|
32352
|
+
}
|
|
32353
|
+
});
|
|
32354
|
+
x402.onAfterPaymentCreation(async (ctx) => {
|
|
32355
|
+
const key2 = ctx.selectedRequirements;
|
|
32356
|
+
const id2 = reservations.get(key2);
|
|
32357
|
+
if (id2 !== void 0) {
|
|
32358
|
+
reservations.delete(key2);
|
|
32359
|
+
control.settleReservation(id2, { action: "x402 payment" });
|
|
32360
|
+
}
|
|
32361
|
+
});
|
|
32362
|
+
x402.onPaymentCreationFailure(async (ctx) => {
|
|
32363
|
+
const key2 = ctx.selectedRequirements;
|
|
32364
|
+
const id2 = reservations.get(key2);
|
|
32365
|
+
if (id2 !== void 0) {
|
|
32366
|
+
reservations.delete(key2);
|
|
32367
|
+
control.releaseReservation(id2);
|
|
32368
|
+
}
|
|
32369
|
+
});
|
|
32370
|
+
}
|
|
32371
|
+
function formatDuration(seconds) {
|
|
32372
|
+
if (seconds < 60) {
|
|
32373
|
+
return `${seconds}s`;
|
|
32374
|
+
} else if (seconds < 3600) {
|
|
32375
|
+
const mins = Math.ceil(seconds / 60);
|
|
32376
|
+
return `${mins} min`;
|
|
32377
|
+
} else {
|
|
32378
|
+
const hours = Math.floor(seconds / 3600);
|
|
32379
|
+
const mins = Math.ceil(seconds % 3600 / 60);
|
|
32380
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
32381
|
+
}
|
|
32382
|
+
}
|
|
32383
|
+
var WALLET_DIR, HOUR_MS, DAY_MS, CAIP2_BASE, CAIP2_SOLANA_MAINNET, POLICY_LISTS, ADDRESS_LISTS, EVM_ADDRESS, MalformedSpendPolicyError, FileSpendControlStorage, InMemorySpendControlStorage, RESERVATION_TTL_MS, SpendControl, SpendPolicyError, CANONICAL_AMOUNT;
|
|
32384
|
+
var init_spend_control = __esm({
|
|
32385
|
+
"src/spend-control.ts"() {
|
|
32386
|
+
"use strict";
|
|
32387
|
+
init_fs_read();
|
|
32388
|
+
WALLET_DIR = path.join(homedir(), ".openclaw", "blockrun");
|
|
32389
|
+
HOUR_MS = 60 * 60 * 1e3;
|
|
32390
|
+
DAY_MS = 24 * HOUR_MS;
|
|
32391
|
+
CAIP2_BASE = "eip155:8453";
|
|
32392
|
+
CAIP2_SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
32393
|
+
POLICY_LISTS = [
|
|
32394
|
+
"allowedPayees",
|
|
32395
|
+
"blockedPayees",
|
|
32396
|
+
"allowedNetworks",
|
|
32397
|
+
"allowedAssets"
|
|
32398
|
+
];
|
|
32399
|
+
ADDRESS_LISTS = ["allowedPayees", "blockedPayees", "allowedAssets"];
|
|
32400
|
+
EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
32401
|
+
MalformedSpendPolicyError = class extends Error {
|
|
32402
|
+
constructor(key2) {
|
|
32403
|
+
super(
|
|
32404
|
+
`[ClawRouter] refusing to load spending.json: ${key2} is malformed; a corrupted policy file must not widen what the agent may pay`
|
|
32405
|
+
);
|
|
32406
|
+
this.name = "MalformedSpendPolicyError";
|
|
32407
|
+
}
|
|
32408
|
+
};
|
|
32409
|
+
FileSpendControlStorage = class {
|
|
32410
|
+
spendingFile;
|
|
32411
|
+
constructor() {
|
|
32412
|
+
this.spendingFile = path.join(WALLET_DIR, "spending.json");
|
|
32413
|
+
}
|
|
32414
|
+
load() {
|
|
32415
|
+
try {
|
|
32416
|
+
if (fs.existsSync(this.spendingFile)) {
|
|
32417
|
+
const data = JSON.parse(readTextFileSync(this.spendingFile));
|
|
32418
|
+
const rawLimits = data.limits ?? {};
|
|
32419
|
+
const rawHistory = data.history ?? [];
|
|
32420
|
+
const limits = {};
|
|
32421
|
+
for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
|
|
32422
|
+
const val = rawLimits[key2];
|
|
32423
|
+
if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
|
|
32424
|
+
limits[key2] = val;
|
|
32425
|
+
}
|
|
32426
|
+
}
|
|
32427
|
+
for (const key2 of POLICY_LISTS) {
|
|
32428
|
+
if (!Object.prototype.hasOwnProperty.call(rawLimits, key2)) continue;
|
|
32429
|
+
const val = rawLimits[key2];
|
|
32430
|
+
if (!isValidPolicyValues(val)) {
|
|
32431
|
+
throw new MalformedSpendPolicyError(key2);
|
|
32432
|
+
}
|
|
32433
|
+
if (val.length === 0) continue;
|
|
32434
|
+
limits[key2] = normalizePolicyValues(key2, val);
|
|
32435
|
+
}
|
|
32436
|
+
const history = [];
|
|
32437
|
+
if (Array.isArray(rawHistory)) {
|
|
32438
|
+
for (const r2 of rawHistory) {
|
|
32439
|
+
if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
|
|
32440
|
+
history.push({
|
|
32441
|
+
timestamp: r2.timestamp,
|
|
32442
|
+
amount: r2.amount,
|
|
32443
|
+
model: typeof r2.model === "string" ? r2.model : void 0,
|
|
32444
|
+
action: typeof r2.action === "string" ? r2.action : void 0
|
|
32445
|
+
});
|
|
32446
|
+
}
|
|
32447
|
+
}
|
|
32448
|
+
}
|
|
32449
|
+
return { limits, history };
|
|
32450
|
+
}
|
|
32451
|
+
} catch (err) {
|
|
32452
|
+
if (err instanceof MalformedSpendPolicyError) {
|
|
32453
|
+
throw err;
|
|
32454
|
+
}
|
|
32455
|
+
console.error(
|
|
32456
|
+
`[ClawRouter] Failed to load spending data, starting fresh (any configured spend policy is NOT in effect until this file is repaired): ${err}`
|
|
32457
|
+
);
|
|
32458
|
+
}
|
|
32459
|
+
return null;
|
|
32460
|
+
}
|
|
32461
|
+
save(data) {
|
|
32462
|
+
try {
|
|
32463
|
+
if (!fs.existsSync(WALLET_DIR)) {
|
|
32464
|
+
fs.mkdirSync(WALLET_DIR, { recursive: true, mode: 448 });
|
|
32465
|
+
}
|
|
32466
|
+
const tmp = `${this.spendingFile}.${process.pid}.tmp`;
|
|
32467
|
+
fs.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
32468
|
+
fs.renameSync(tmp, this.spendingFile);
|
|
32469
|
+
} catch (err) {
|
|
32470
|
+
console.error(`[ClawRouter] Failed to save spending data: ${err}`);
|
|
32471
|
+
}
|
|
32472
|
+
}
|
|
32473
|
+
/**
|
|
32474
|
+
* Persist history while leaving the stored limits exactly as they are on
|
|
32475
|
+
* disk. Recording spend must not rewrite policy: the proxy reads limits once
|
|
32476
|
+
* at startup, so writing its in-memory copy back on every payment would
|
|
32477
|
+
* erase an operator's hand-edit to spending.json seconds after they made it.
|
|
32478
|
+
*/
|
|
32479
|
+
saveHistory(history) {
|
|
32480
|
+
let storedLimits = {};
|
|
32481
|
+
try {
|
|
32482
|
+
const current = this.load();
|
|
32483
|
+
if (current) storedLimits = current.limits;
|
|
32484
|
+
} catch {
|
|
32485
|
+
return;
|
|
32486
|
+
}
|
|
32487
|
+
this.save({ limits: storedLimits, history });
|
|
32488
|
+
}
|
|
32489
|
+
};
|
|
32490
|
+
InMemorySpendControlStorage = class {
|
|
32491
|
+
data = null;
|
|
32492
|
+
load() {
|
|
32493
|
+
return this.data ? {
|
|
32494
|
+
limits: cloneLimits(this.data.limits),
|
|
32495
|
+
history: this.data.history.map((r2) => ({ ...r2 }))
|
|
32496
|
+
} : null;
|
|
32497
|
+
}
|
|
32498
|
+
save(data) {
|
|
32499
|
+
this.data = {
|
|
32500
|
+
limits: cloneLimits(data.limits),
|
|
32501
|
+
history: data.history.map((r2) => ({ ...r2 }))
|
|
32502
|
+
};
|
|
32503
|
+
}
|
|
32504
|
+
};
|
|
32505
|
+
RESERVATION_TTL_MS = 2 * 60 * 1e3;
|
|
32506
|
+
SpendControl = class {
|
|
32507
|
+
limits = {};
|
|
32508
|
+
history = [];
|
|
32509
|
+
sessionSpent = 0;
|
|
32510
|
+
sessionCalls = 0;
|
|
32511
|
+
pending = /* @__PURE__ */ new Map();
|
|
32512
|
+
reservationSeq = 0;
|
|
32513
|
+
/** Limits we loaded and have not changed; history-only saves must not clobber operator edits. */
|
|
32514
|
+
limitsDirty = false;
|
|
32515
|
+
/** Set when spending.json held an unusable policy list: refuse every payment. */
|
|
32516
|
+
policyFileBroken;
|
|
32517
|
+
storage;
|
|
32518
|
+
now;
|
|
32519
|
+
constructor(options) {
|
|
32520
|
+
this.storage = options?.storage ?? new FileSpendControlStorage();
|
|
32521
|
+
this.now = options?.now ?? (() => Date.now());
|
|
32522
|
+
this.load();
|
|
32523
|
+
}
|
|
32524
|
+
setLimit(window2, amount) {
|
|
32525
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
32526
|
+
throw new Error("Limit must be a finite positive number");
|
|
32527
|
+
}
|
|
32528
|
+
this.limits[window2] = amount;
|
|
32529
|
+
this.limitsDirty = true;
|
|
32530
|
+
this.save();
|
|
32531
|
+
}
|
|
32532
|
+
clearLimit(window2) {
|
|
32533
|
+
delete this.limits[window2];
|
|
32534
|
+
this.limitsDirty = true;
|
|
32535
|
+
this.save();
|
|
32536
|
+
}
|
|
32537
|
+
setPolicy(list, values) {
|
|
32538
|
+
if (!isPolicyList(list)) {
|
|
32539
|
+
throw new Error(`Unknown policy list: ${String(list)}`);
|
|
32540
|
+
}
|
|
32541
|
+
if (!isValidPolicyValues(values) || values.length === 0) {
|
|
32542
|
+
throw new Error("Policy list must be a non-empty array of non-empty strings");
|
|
32543
|
+
}
|
|
32544
|
+
this.limits[list] = normalizePolicyValues(list, values);
|
|
32545
|
+
this.limitsDirty = true;
|
|
32546
|
+
this.save();
|
|
32547
|
+
}
|
|
32548
|
+
clearPolicy(list) {
|
|
32549
|
+
if (!isPolicyList(list)) {
|
|
32550
|
+
throw new Error(`Unknown policy list: ${String(list)}`);
|
|
32551
|
+
}
|
|
32552
|
+
delete this.limits[list];
|
|
32553
|
+
this.limitsDirty = true;
|
|
32554
|
+
this.save();
|
|
32555
|
+
}
|
|
32556
|
+
getLimits() {
|
|
32557
|
+
return cloneLimits(this.limits);
|
|
32558
|
+
}
|
|
32559
|
+
check(estimatedCost2, counterparty) {
|
|
32560
|
+
if (this.policyFileBroken !== void 0) {
|
|
32561
|
+
return {
|
|
32562
|
+
allowed: false,
|
|
32563
|
+
reason: `Spend policy is unreadable, refusing all payments: ${this.policyFileBroken}`
|
|
32564
|
+
};
|
|
32565
|
+
}
|
|
32566
|
+
const payeePolicySet = this.limits.blockedPayees && this.limits.blockedPayees.length > 0 || this.limits.allowedPayees && this.limits.allowedPayees.length > 0;
|
|
32567
|
+
if (payeePolicySet) {
|
|
32568
|
+
if (counterparty?.payTo === void 0) {
|
|
32569
|
+
return {
|
|
32570
|
+
allowed: false,
|
|
32571
|
+
blockedByPolicy: this.limits.blockedPayees?.length ? "blockedPayees" : "allowedPayees",
|
|
32572
|
+
reason: "Payee policy is configured but no payTo was provided to check()"
|
|
32573
|
+
};
|
|
32574
|
+
}
|
|
32575
|
+
const payTo = normalizePayee(counterparty.payTo);
|
|
32576
|
+
if (this.limits.blockedPayees?.includes(payTo)) {
|
|
32577
|
+
return {
|
|
32578
|
+
allowed: false,
|
|
32579
|
+
blockedByPolicy: "blockedPayees",
|
|
32580
|
+
reason: `Payee is blocked by policy: ${counterparty.payTo}`
|
|
32581
|
+
};
|
|
32582
|
+
}
|
|
32583
|
+
if (this.limits.allowedPayees && this.limits.allowedPayees.length > 0 && !this.limits.allowedPayees.includes(payTo)) {
|
|
32584
|
+
return {
|
|
32585
|
+
allowed: false,
|
|
32586
|
+
blockedByPolicy: "allowedPayees",
|
|
32587
|
+
reason: `Payee is not in the configured allowlist: ${counterparty.payTo}`
|
|
32588
|
+
};
|
|
32589
|
+
}
|
|
32590
|
+
}
|
|
32591
|
+
if (this.limits.allowedNetworks && this.limits.allowedNetworks.length > 0) {
|
|
32592
|
+
if (counterparty?.network === void 0) {
|
|
32593
|
+
return {
|
|
32594
|
+
allowed: false,
|
|
32595
|
+
blockedByPolicy: "allowedNetworks",
|
|
32596
|
+
reason: "Network policy is configured but no network was provided to check()"
|
|
32597
|
+
};
|
|
32598
|
+
}
|
|
32599
|
+
if (!this.limits.allowedNetworks.includes(counterparty.network)) {
|
|
32600
|
+
return {
|
|
32601
|
+
allowed: false,
|
|
32602
|
+
blockedByPolicy: "allowedNetworks",
|
|
32603
|
+
reason: `Network is not in the configured allowlist: ${counterparty.network}`
|
|
32604
|
+
};
|
|
32605
|
+
}
|
|
32606
|
+
}
|
|
32607
|
+
if (this.limits.allowedAssets && this.limits.allowedAssets.length > 0) {
|
|
32608
|
+
if (counterparty?.asset === void 0) {
|
|
32609
|
+
return {
|
|
32610
|
+
allowed: false,
|
|
32611
|
+
blockedByPolicy: "allowedAssets",
|
|
32612
|
+
reason: "Asset policy is configured but no asset was provided to check()"
|
|
32613
|
+
};
|
|
32614
|
+
}
|
|
32615
|
+
if (!this.limits.allowedAssets.includes(normalizePayee(counterparty.asset))) {
|
|
32616
|
+
return {
|
|
32617
|
+
allowed: false,
|
|
32618
|
+
blockedByPolicy: "allowedAssets",
|
|
32619
|
+
reason: `Asset is not in the configured allowlist: ${counterparty.asset}`
|
|
32620
|
+
};
|
|
32621
|
+
}
|
|
32622
|
+
}
|
|
32623
|
+
const now2 = this.now();
|
|
32624
|
+
if (this.limits.perRequest !== void 0) {
|
|
32625
|
+
if (estimatedCost2 > this.limits.perRequest) {
|
|
32626
|
+
return {
|
|
32627
|
+
allowed: false,
|
|
32628
|
+
blockedBy: "perRequest",
|
|
32629
|
+
remaining: this.limits.perRequest,
|
|
32630
|
+
reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
|
|
32631
|
+
};
|
|
32632
|
+
}
|
|
32633
|
+
}
|
|
32634
|
+
if (this.limits.hourly !== void 0) {
|
|
32635
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32636
|
+
const remaining = this.limits.hourly - hourlySpent;
|
|
32637
|
+
if (estimatedCost2 > remaining) {
|
|
32638
|
+
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
32639
|
+
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
|
|
32640
|
+
return {
|
|
32641
|
+
allowed: false,
|
|
32642
|
+
blockedBy: "hourly",
|
|
32643
|
+
remaining,
|
|
32644
|
+
reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
|
|
32645
|
+
resetIn
|
|
32646
|
+
};
|
|
32647
|
+
}
|
|
32648
|
+
}
|
|
32649
|
+
if (this.limits.daily !== void 0) {
|
|
32650
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32651
|
+
const remaining = this.limits.daily - dailySpent;
|
|
32652
|
+
if (estimatedCost2 > remaining) {
|
|
32653
|
+
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
32654
|
+
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
|
|
32655
|
+
return {
|
|
32656
|
+
allowed: false,
|
|
32657
|
+
blockedBy: "daily",
|
|
32658
|
+
remaining,
|
|
32659
|
+
reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
|
|
32660
|
+
resetIn
|
|
32661
|
+
};
|
|
32662
|
+
}
|
|
32663
|
+
}
|
|
32664
|
+
if (this.limits.session !== void 0) {
|
|
32665
|
+
const sessionSpent = this.sessionSpent + this.pendingTotal();
|
|
32666
|
+
const remaining = this.limits.session - sessionSpent;
|
|
32667
|
+
if (estimatedCost2 > remaining) {
|
|
32668
|
+
return {
|
|
32669
|
+
allowed: false,
|
|
32670
|
+
blockedBy: "session",
|
|
32671
|
+
remaining,
|
|
32672
|
+
reason: `Session limit exceeded: $${(sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
|
|
32673
|
+
};
|
|
32674
|
+
}
|
|
32675
|
+
}
|
|
32676
|
+
return { allowed: true };
|
|
32677
|
+
}
|
|
32678
|
+
record(amount, metadata) {
|
|
32679
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
32680
|
+
throw new Error("Record amount must be a non-negative finite number");
|
|
32681
|
+
}
|
|
32682
|
+
const record = {
|
|
32683
|
+
timestamp: this.now(),
|
|
32684
|
+
amount,
|
|
32685
|
+
model: metadata?.model,
|
|
32686
|
+
action: metadata?.action
|
|
32687
|
+
};
|
|
32688
|
+
this.history.push(record);
|
|
32689
|
+
this.sessionSpent += amount;
|
|
32690
|
+
this.sessionCalls += 1;
|
|
32691
|
+
this.cleanup();
|
|
32692
|
+
this.save();
|
|
32693
|
+
}
|
|
32694
|
+
/** True when any window that this module can compare an amount against is set. */
|
|
32695
|
+
hasAmountLimits() {
|
|
32696
|
+
return this.limits.perRequest !== void 0 || this.limits.hourly !== void 0 || this.limits.daily !== void 0 || this.limits.session !== void 0;
|
|
32697
|
+
}
|
|
32698
|
+
/** True when a window spans more than one request, so reservations matter. */
|
|
32699
|
+
hasAggregateLimits() {
|
|
32700
|
+
return this.limits.hourly !== void 0 || this.limits.daily !== void 0 || this.limits.session !== void 0;
|
|
32701
|
+
}
|
|
32702
|
+
/**
|
|
32703
|
+
* Hold `amount` against the aggregate windows before a payment is signed.
|
|
32704
|
+
*
|
|
32705
|
+
* Reservations live in memory only and are never persisted: an unsettled
|
|
32706
|
+
* reservation is not spend, and writing it to disk is what made a failed
|
|
32707
|
+
* signer permanently consume budget. They expire on their own so a caller
|
|
32708
|
+
* that never settles or releases (process killed mid-payment, a transport
|
|
32709
|
+
* that hangs past the payment timeout) cannot wedge the window shut.
|
|
32710
|
+
*/
|
|
32711
|
+
reserve(amount) {
|
|
32712
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
32713
|
+
throw new Error("Reservation amount must be a non-negative finite number");
|
|
32714
|
+
}
|
|
32715
|
+
const id2 = `${this.now()}-${this.reservationSeq += 1}`;
|
|
32716
|
+
this.pending.set(id2, { amount, expiresAt: this.now() + RESERVATION_TTL_MS });
|
|
32717
|
+
return id2;
|
|
32718
|
+
}
|
|
32719
|
+
/** Convert a reservation into recorded spend (the payment was signed). */
|
|
32720
|
+
settleReservation(id2, metadata) {
|
|
32721
|
+
const held = this.pending.get(id2);
|
|
32722
|
+
if (!held) return;
|
|
32723
|
+
this.pending.delete(id2);
|
|
32724
|
+
this.record(held.amount, metadata);
|
|
32725
|
+
}
|
|
32726
|
+
/** Drop a reservation without recording spend (the payment was never signed). */
|
|
32727
|
+
releaseReservation(id2) {
|
|
32728
|
+
this.pending.delete(id2);
|
|
32729
|
+
}
|
|
32730
|
+
/** Total currently held but not yet settled. */
|
|
32731
|
+
pendingTotal() {
|
|
32732
|
+
this.expireReservations();
|
|
32733
|
+
let total = 0;
|
|
32734
|
+
for (const held of this.pending.values()) {
|
|
32735
|
+
total += held.amount;
|
|
32736
|
+
}
|
|
32737
|
+
return total;
|
|
32738
|
+
}
|
|
32739
|
+
expireReservations() {
|
|
32740
|
+
const now2 = this.now();
|
|
32741
|
+
for (const [id2, held] of this.pending) {
|
|
32742
|
+
if (held.expiresAt <= now2) {
|
|
32743
|
+
this.pending.delete(id2);
|
|
32744
|
+
}
|
|
32745
|
+
}
|
|
32746
|
+
}
|
|
32747
|
+
getSpendingInWindow(from15, to) {
|
|
32748
|
+
const recorded = this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
32749
|
+
return recorded + (to >= this.now() ? this.pendingTotal() : 0);
|
|
32750
|
+
}
|
|
32751
|
+
getSpending(window2) {
|
|
32752
|
+
const now2 = this.now();
|
|
32753
|
+
switch (window2) {
|
|
32754
|
+
case "hourly":
|
|
32755
|
+
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32756
|
+
case "daily":
|
|
32757
|
+
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32758
|
+
case "session":
|
|
32759
|
+
return this.sessionSpent + this.pendingTotal();
|
|
32760
|
+
}
|
|
32761
|
+
}
|
|
32762
|
+
getRemaining(window2) {
|
|
32763
|
+
const limit = this.limits[window2];
|
|
32764
|
+
if (limit === void 0) return null;
|
|
32765
|
+
return Math.max(0, limit - this.getSpending(window2));
|
|
32766
|
+
}
|
|
32767
|
+
getStatus() {
|
|
32768
|
+
const now2 = this.now();
|
|
32769
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
32770
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
32771
|
+
return {
|
|
32772
|
+
limits: cloneLimits(this.limits),
|
|
32773
|
+
spending: {
|
|
32774
|
+
hourly: hourlySpent,
|
|
32775
|
+
daily: dailySpent,
|
|
32776
|
+
session: this.sessionSpent
|
|
32777
|
+
},
|
|
32778
|
+
remaining: {
|
|
32779
|
+
hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
|
|
32780
|
+
daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
|
|
32781
|
+
session: this.limits.session !== void 0 ? this.limits.session - (this.sessionSpent + this.pendingTotal()) : null
|
|
32782
|
+
},
|
|
32783
|
+
calls: this.sessionCalls
|
|
32784
|
+
};
|
|
32785
|
+
}
|
|
32786
|
+
getHistory(limit) {
|
|
32787
|
+
const records = [...this.history].reverse();
|
|
32788
|
+
return limit ? records.slice(0, limit) : records;
|
|
32789
|
+
}
|
|
32790
|
+
resetSession() {
|
|
32791
|
+
this.sessionSpent = 0;
|
|
32792
|
+
this.sessionCalls = 0;
|
|
32793
|
+
}
|
|
32794
|
+
cleanup() {
|
|
32795
|
+
const cutoff = this.now() - DAY_MS;
|
|
32796
|
+
this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
|
|
32797
|
+
}
|
|
32798
|
+
save() {
|
|
32799
|
+
if (this.policyFileBroken !== void 0) {
|
|
32800
|
+
return;
|
|
32801
|
+
}
|
|
32802
|
+
if (!this.limitsDirty && this.storage.saveHistory) {
|
|
32803
|
+
this.storage.saveHistory([...this.history]);
|
|
32804
|
+
return;
|
|
32805
|
+
}
|
|
32806
|
+
this.storage.save({
|
|
32807
|
+
limits: cloneLimits(this.limits),
|
|
32808
|
+
history: [...this.history]
|
|
32809
|
+
});
|
|
32810
|
+
}
|
|
32811
|
+
load() {
|
|
32812
|
+
let data;
|
|
32813
|
+
try {
|
|
32814
|
+
data = this.storage.load();
|
|
32815
|
+
} catch (err) {
|
|
32816
|
+
if (!(err instanceof MalformedSpendPolicyError)) throw err;
|
|
32817
|
+
this.policyFileBroken = err.message;
|
|
32818
|
+
console.error(`[ClawRouter] ${err.message}`);
|
|
32819
|
+
console.error(
|
|
32820
|
+
"[ClawRouter] All paid requests will be refused until spending.json is repaired. Free models are unaffected."
|
|
32821
|
+
);
|
|
32822
|
+
return;
|
|
32823
|
+
}
|
|
32824
|
+
if (data) {
|
|
32825
|
+
this.limits = cloneLimits(data.limits);
|
|
32826
|
+
this.history = data.history;
|
|
32827
|
+
this.cleanup();
|
|
32828
|
+
}
|
|
32829
|
+
}
|
|
32830
|
+
};
|
|
32831
|
+
SpendPolicyError = class extends Error {
|
|
32832
|
+
blockedBy;
|
|
32833
|
+
blockedByPolicy;
|
|
32834
|
+
constructor(reason, blocked) {
|
|
32835
|
+
super(`Payment creation aborted: ${reason}`);
|
|
32836
|
+
this.name = "SpendPolicyError";
|
|
32837
|
+
this.blockedBy = blocked?.blockedBy;
|
|
32838
|
+
this.blockedByPolicy = blocked?.blockedByPolicy;
|
|
32839
|
+
}
|
|
32840
|
+
};
|
|
32841
|
+
CANONICAL_AMOUNT = /^\d+$/;
|
|
32842
|
+
}
|
|
32843
|
+
});
|
|
32844
|
+
|
|
32238
32845
|
// src/payment-preauth.ts
|
|
32239
32846
|
function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, options) {
|
|
32240
32847
|
const httpClient = new x402HTTPClient(client);
|
|
@@ -32279,8 +32886,11 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
|
|
|
32279
32886
|
return response2;
|
|
32280
32887
|
}
|
|
32281
32888
|
cache2.delete(cacheKey2);
|
|
32282
|
-
} catch {
|
|
32889
|
+
} catch (err) {
|
|
32283
32890
|
cache2.delete(cacheKey2);
|
|
32891
|
+
if (err instanceof SpendPolicyError) {
|
|
32892
|
+
throw err;
|
|
32893
|
+
}
|
|
32284
32894
|
}
|
|
32285
32895
|
}
|
|
32286
32896
|
const clonedRequest = request2.clone();
|
|
@@ -32324,6 +32934,7 @@ var init_payment_preauth = __esm({
|
|
|
32324
32934
|
"use strict";
|
|
32325
32935
|
init_esm4();
|
|
32326
32936
|
init_max_tokens();
|
|
32937
|
+
init_spend_control();
|
|
32327
32938
|
DEFAULT_TTL_MS = 36e5;
|
|
32328
32939
|
}
|
|
32329
32940
|
});
|
|
@@ -38908,8 +39519,8 @@ var init_models = __esm({
|
|
|
38908
39519
|
|
|
38909
39520
|
// src/logger.ts
|
|
38910
39521
|
import { appendFile, mkdir } from "fs/promises";
|
|
38911
|
-
import { join as
|
|
38912
|
-
import { homedir } from "os";
|
|
39522
|
+
import { join as join3 } from "path";
|
|
39523
|
+
import { homedir as homedir2 } from "os";
|
|
38913
39524
|
async function ensureDir() {
|
|
38914
39525
|
if (dirReady) return;
|
|
38915
39526
|
await mkdir(LOG_DIR, { recursive: true });
|
|
@@ -38919,7 +39530,7 @@ async function logUsage(entry) {
|
|
|
38919
39530
|
try {
|
|
38920
39531
|
await ensureDir();
|
|
38921
39532
|
const date = entry.timestamp.slice(0, 10);
|
|
38922
|
-
const file =
|
|
39533
|
+
const file = join3(LOG_DIR, `usage-${date}.jsonl`);
|
|
38923
39534
|
await appendFile(file, JSON.stringify(entry) + "\n");
|
|
38924
39535
|
} catch {
|
|
38925
39536
|
}
|
|
@@ -38928,56 +39539,15 @@ var LOG_DIR, dirReady;
|
|
|
38928
39539
|
var init_logger = __esm({
|
|
38929
39540
|
"src/logger.ts"() {
|
|
38930
39541
|
"use strict";
|
|
38931
|
-
LOG_DIR =
|
|
39542
|
+
LOG_DIR = join3(homedir2(), ".openclaw", "blockrun", "logs");
|
|
38932
39543
|
dirReady = false;
|
|
38933
39544
|
}
|
|
38934
39545
|
});
|
|
38935
39546
|
|
|
38936
|
-
// src/fs-read.ts
|
|
38937
|
-
import { open } from "fs/promises";
|
|
38938
|
-
import { openSync, readSync, closeSync, fstatSync } from "fs";
|
|
38939
|
-
async function readTextFile(filePath) {
|
|
38940
|
-
const fh = await open(filePath, "r");
|
|
38941
|
-
try {
|
|
38942
|
-
const size5 = (await fh.stat()).size;
|
|
38943
|
-
const buf = Buffer.alloc(size5);
|
|
38944
|
-
let offset = 0;
|
|
38945
|
-
while (offset < size5) {
|
|
38946
|
-
const { bytesRead } = await fh.read(buf, offset, size5 - offset, offset);
|
|
38947
|
-
if (bytesRead === 0) break;
|
|
38948
|
-
offset += bytesRead;
|
|
38949
|
-
}
|
|
38950
|
-
return buf.subarray(0, offset).toString("utf-8");
|
|
38951
|
-
} finally {
|
|
38952
|
-
await fh.close();
|
|
38953
|
-
}
|
|
38954
|
-
}
|
|
38955
|
-
function readTextFileSync(filePath) {
|
|
38956
|
-
const fd = openSync(filePath, "r");
|
|
38957
|
-
try {
|
|
38958
|
-
const size5 = fstatSync(fd).size;
|
|
38959
|
-
const buf = Buffer.alloc(size5);
|
|
38960
|
-
let offset = 0;
|
|
38961
|
-
while (offset < size5) {
|
|
38962
|
-
const bytesRead = readSync(fd, buf, offset, size5 - offset, offset);
|
|
38963
|
-
if (bytesRead === 0) break;
|
|
38964
|
-
offset += bytesRead;
|
|
38965
|
-
}
|
|
38966
|
-
return buf.subarray(0, offset).toString("utf-8");
|
|
38967
|
-
} finally {
|
|
38968
|
-
closeSync(fd);
|
|
38969
|
-
}
|
|
38970
|
-
}
|
|
38971
|
-
var init_fs_read = __esm({
|
|
38972
|
-
"src/fs-read.ts"() {
|
|
38973
|
-
"use strict";
|
|
38974
|
-
}
|
|
38975
|
-
});
|
|
38976
|
-
|
|
38977
39547
|
// src/version.ts
|
|
38978
39548
|
import { createRequire } from "module";
|
|
38979
39549
|
import { fileURLToPath } from "url";
|
|
38980
|
-
import { dirname, join as
|
|
39550
|
+
import { dirname, join as join4 } from "path";
|
|
38981
39551
|
function clientTag() {
|
|
38982
39552
|
const raw = (process.env.CLAWROUTER_CLIENT ?? "").trim();
|
|
38983
39553
|
if (!raw) return "";
|
|
@@ -38991,7 +39561,7 @@ var init_version4 = __esm({
|
|
|
38991
39561
|
__filename2 = fileURLToPath(import.meta.url);
|
|
38992
39562
|
__dirname = dirname(__filename2);
|
|
38993
39563
|
require2 = createRequire(import.meta.url);
|
|
38994
|
-
pkg = require2(
|
|
39564
|
+
pkg = require2(join4(__dirname, "..", "package.json"));
|
|
38995
39565
|
VERSION = pkg.version;
|
|
38996
39566
|
USER_AGENT = `clawrouter/${VERSION}${clientTag()}`;
|
|
38997
39567
|
}
|
|
@@ -38999,8 +39569,8 @@ var init_version4 = __esm({
|
|
|
38999
39569
|
|
|
39000
39570
|
// src/stats.ts
|
|
39001
39571
|
import { readdir, unlink } from "fs/promises";
|
|
39002
|
-
import { join as
|
|
39003
|
-
import { homedir as
|
|
39572
|
+
import { join as join5 } from "path";
|
|
39573
|
+
import { homedir as homedir3 } from "os";
|
|
39004
39574
|
async function parseLogFile(filePath) {
|
|
39005
39575
|
try {
|
|
39006
39576
|
const content = await readTextFile(filePath);
|
|
@@ -39072,7 +39642,7 @@ async function getStats(days = 7) {
|
|
|
39072
39642
|
let totalLatency = 0;
|
|
39073
39643
|
for (const file of filesToRead) {
|
|
39074
39644
|
const date = file.replace("usage-", "").replace(".jsonl", "");
|
|
39075
|
-
const filePath =
|
|
39645
|
+
const filePath = join5(LOG_DIR2, file);
|
|
39076
39646
|
const entries = await parseLogFile(filePath);
|
|
39077
39647
|
if (entries.length === 0) continue;
|
|
39078
39648
|
const dayStats = aggregateDay(date, entries);
|
|
@@ -39191,7 +39761,7 @@ async function formatRecentLogs(days = 1) {
|
|
|
39191
39761
|
const filesToRead = logFiles.slice(0, days);
|
|
39192
39762
|
const allEntries = [];
|
|
39193
39763
|
for (const file of filesToRead) {
|
|
39194
|
-
const entries = await parseLogFile(
|
|
39764
|
+
const entries = await parseLogFile(join5(LOG_DIR2, file));
|
|
39195
39765
|
allEntries.push(...entries);
|
|
39196
39766
|
}
|
|
39197
39767
|
allEntries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
@@ -39236,7 +39806,7 @@ async function clearStats() {
|
|
|
39236
39806
|
try {
|
|
39237
39807
|
const files = await readdir(LOG_DIR2);
|
|
39238
39808
|
const logFiles = files.filter((f) => f.startsWith("usage-") && f.endsWith(".jsonl"));
|
|
39239
|
-
await Promise.all(logFiles.map((f) => unlink(
|
|
39809
|
+
await Promise.all(logFiles.map((f) => unlink(join5(LOG_DIR2, f))));
|
|
39240
39810
|
return { deletedFiles: logFiles.length };
|
|
39241
39811
|
} catch {
|
|
39242
39812
|
return { deletedFiles: 0 };
|
|
@@ -39248,7 +39818,27 @@ var init_stats = __esm({
|
|
|
39248
39818
|
"use strict";
|
|
39249
39819
|
init_fs_read();
|
|
39250
39820
|
init_version4();
|
|
39251
|
-
LOG_DIR2 =
|
|
39821
|
+
LOG_DIR2 = join5(homedir3(), ".openclaw", "blockrun", "logs");
|
|
39822
|
+
}
|
|
39823
|
+
});
|
|
39824
|
+
|
|
39825
|
+
// src/timestamp-strip.ts
|
|
39826
|
+
function stripLeadingTextBlockTimestamp(blocks) {
|
|
39827
|
+
let stripped = false;
|
|
39828
|
+
return blocks.map((block) => {
|
|
39829
|
+
if (!stripped && block !== null && typeof block === "object" && block.type === "text" && typeof block.text === "string") {
|
|
39830
|
+
stripped = true;
|
|
39831
|
+
const b = block;
|
|
39832
|
+
return { ...b, text: b.text.replace(TIMESTAMP_PATTERN, "") };
|
|
39833
|
+
}
|
|
39834
|
+
return block;
|
|
39835
|
+
});
|
|
39836
|
+
}
|
|
39837
|
+
var TIMESTAMP_PATTERN;
|
|
39838
|
+
var init_timestamp_strip = __esm({
|
|
39839
|
+
"src/timestamp-strip.ts"() {
|
|
39840
|
+
"use strict";
|
|
39841
|
+
TIMESTAMP_PATTERN = /^\[\w{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+\w+\]\s*/;
|
|
39252
39842
|
}
|
|
39253
39843
|
});
|
|
39254
39844
|
|
|
@@ -39278,19 +39868,21 @@ function stripTimestamps(obj) {
|
|
|
39278
39868
|
for (const [key2, value] of Object.entries(obj)) {
|
|
39279
39869
|
if (key2 === "content" && typeof value === "string") {
|
|
39280
39870
|
result[key2] = value.replace(TIMESTAMP_PATTERN, "");
|
|
39871
|
+
} else if (key2 === "content" && Array.isArray(value)) {
|
|
39872
|
+
result[key2] = stripLeadingTextBlockTimestamp(value.map(stripTimestamps));
|
|
39281
39873
|
} else {
|
|
39282
39874
|
result[key2] = stripTimestamps(value);
|
|
39283
39875
|
}
|
|
39284
39876
|
}
|
|
39285
39877
|
return result;
|
|
39286
39878
|
}
|
|
39287
|
-
var DEFAULT_TTL_MS2, MAX_BODY_SIZE,
|
|
39879
|
+
var DEFAULT_TTL_MS2, MAX_BODY_SIZE, RequestDeduplicator;
|
|
39288
39880
|
var init_dedup = __esm({
|
|
39289
39881
|
"src/dedup.ts"() {
|
|
39290
39882
|
"use strict";
|
|
39883
|
+
init_timestamp_strip();
|
|
39291
39884
|
DEFAULT_TTL_MS2 = 3e4;
|
|
39292
39885
|
MAX_BODY_SIZE = 1048576;
|
|
39293
|
-
TIMESTAMP_PATTERN = /^\[\w{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+\w+\]\s*/;
|
|
39294
39886
|
RequestDeduplicator = class {
|
|
39295
39887
|
inflight = /* @__PURE__ */ new Map();
|
|
39296
39888
|
completed = /* @__PURE__ */ new Map();
|
|
@@ -39408,7 +40000,10 @@ function normalizeForCache(obj) {
|
|
|
39408
40000
|
if (typeof msg === "object" && msg !== null) {
|
|
39409
40001
|
const m = msg;
|
|
39410
40002
|
if (typeof m.content === "string") {
|
|
39411
|
-
return { ...m, content: m.content.replace(
|
|
40003
|
+
return { ...m, content: m.content.replace(TIMESTAMP_PATTERN, "") };
|
|
40004
|
+
}
|
|
40005
|
+
if (Array.isArray(m.content)) {
|
|
40006
|
+
return { ...m, content: stripLeadingTextBlockTimestamp(m.content) };
|
|
39412
40007
|
}
|
|
39413
40008
|
}
|
|
39414
40009
|
return msg;
|
|
@@ -39419,10 +40014,11 @@ function normalizeForCache(obj) {
|
|
|
39419
40014
|
}
|
|
39420
40015
|
return result;
|
|
39421
40016
|
}
|
|
39422
|
-
var DEFAULT_CONFIG,
|
|
40017
|
+
var DEFAULT_CONFIG, ResponseCache;
|
|
39423
40018
|
var init_response_cache = __esm({
|
|
39424
40019
|
"src/response-cache.ts"() {
|
|
39425
40020
|
"use strict";
|
|
40021
|
+
init_timestamp_strip();
|
|
39426
40022
|
DEFAULT_CONFIG = {
|
|
39427
40023
|
maxSize: 200,
|
|
39428
40024
|
defaultTTL: 600,
|
|
@@ -39430,7 +40026,6 @@ var init_response_cache = __esm({
|
|
|
39430
40026
|
// 1MB
|
|
39431
40027
|
enabled: true
|
|
39432
40028
|
};
|
|
39433
|
-
TIMESTAMP_PATTERN2 = /^\[\w{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+\w+\]\s*/;
|
|
39434
40029
|
ResponseCache = class {
|
|
39435
40030
|
cache = /* @__PURE__ */ new Map();
|
|
39436
40031
|
expirationHeap = [];
|
|
@@ -43042,7 +43637,7 @@ function alphabet2(letters) {
|
|
|
43042
43637
|
};
|
|
43043
43638
|
}
|
|
43044
43639
|
// @__NO_SIDE_EFFECTS__
|
|
43045
|
-
function
|
|
43640
|
+
function join6(separator = "") {
|
|
43046
43641
|
astr2("join", separator);
|
|
43047
43642
|
return {
|
|
43048
43643
|
encode: (from15) => {
|
|
@@ -43152,7 +43747,7 @@ var genBase58, base58, createBase58check;
|
|
|
43152
43747
|
var init_base3 = __esm({
|
|
43153
43748
|
"node_modules/@scure/base/index.js"() {
|
|
43154
43749
|
"use strict";
|
|
43155
|
-
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */
|
|
43750
|
+
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join6(""));
|
|
43156
43751
|
base58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"));
|
|
43157
43752
|
createBase58check = (sha25610) => {
|
|
43158
43753
|
afn2(sha25610);
|
|
@@ -43301,14 +43896,14 @@ var init_bip32 = __esm({
|
|
|
43301
43896
|
}
|
|
43302
43897
|
this.pubHash = hash160(this._publicKey);
|
|
43303
43898
|
}
|
|
43304
|
-
derive(
|
|
43305
|
-
if (!/^[mM]'?/.test(
|
|
43899
|
+
derive(path5) {
|
|
43900
|
+
if (!/^[mM]'?/.test(path5)) {
|
|
43306
43901
|
throw new Error('Path must start with "m" or "M"');
|
|
43307
43902
|
}
|
|
43308
|
-
if (/^[mM]'?$/.test(
|
|
43903
|
+
if (/^[mM]'?$/.test(path5)) {
|
|
43309
43904
|
return this;
|
|
43310
43905
|
}
|
|
43311
|
-
const parts =
|
|
43906
|
+
const parts = path5.replace(/^[mM]'?\//, "").split("/");
|
|
43312
43907
|
let child = this;
|
|
43313
43908
|
for (const c of parts) {
|
|
43314
43909
|
const m = /^(\d+)('?)$/.exec(c);
|
|
@@ -51598,14 +52193,14 @@ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
|
|
|
51598
52193
|
} else {
|
|
51599
52194
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
51600
52195
|
}
|
|
51601
|
-
const
|
|
52196
|
+
const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
51602
52197
|
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
51603
52198
|
argumentLabel,
|
|
51604
52199
|
keyPath,
|
|
51605
52200
|
methodName,
|
|
51606
|
-
optionalPathLabel:
|
|
52201
|
+
optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
|
|
51607
52202
|
value,
|
|
51608
|
-
...
|
|
52203
|
+
...path5 !== void 0 ? { path: path5 } : void 0
|
|
51609
52204
|
});
|
|
51610
52205
|
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);
|
|
51611
52206
|
return error;
|
|
@@ -56269,14 +56864,14 @@ function createSolanaJsonRpcIntegerOverflowError2(methodName, keyPath, value) {
|
|
|
56269
56864
|
} else {
|
|
56270
56865
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
56271
56866
|
}
|
|
56272
|
-
const
|
|
56867
|
+
const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
56273
56868
|
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
56274
56869
|
argumentLabel,
|
|
56275
56870
|
keyPath,
|
|
56276
56871
|
methodName,
|
|
56277
|
-
optionalPathLabel:
|
|
56872
|
+
optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
|
|
56278
56873
|
value,
|
|
56279
|
-
...
|
|
56874
|
+
...path5 !== void 0 ? { path: path5 } : void 0
|
|
56280
56875
|
});
|
|
56281
56876
|
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError2);
|
|
56282
56877
|
return error;
|
|
@@ -58356,8 +58951,8 @@ __export(auth_exports, {
|
|
|
58356
58951
|
setupSolana: () => setupSolana
|
|
58357
58952
|
});
|
|
58358
58953
|
import { writeFile, mkdir as mkdir2 } from "fs/promises";
|
|
58359
|
-
import { join as
|
|
58360
|
-
import { homedir as
|
|
58954
|
+
import { join as join7 } from "path";
|
|
58955
|
+
import { homedir as homedir4 } from "os";
|
|
58361
58956
|
async function loadSavedWallet() {
|
|
58362
58957
|
try {
|
|
58363
58958
|
const key2 = (await readTextFile(WALLET_FILE)).trim();
|
|
@@ -58406,7 +59001,7 @@ async function loadMnemonic() {
|
|
|
58406
59001
|
return void 0;
|
|
58407
59002
|
}
|
|
58408
59003
|
async function saveMnemonic(mnemonic) {
|
|
58409
|
-
await mkdir2(
|
|
59004
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58410
59005
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
58411
59006
|
}
|
|
58412
59007
|
async function generateAndSaveWallet() {
|
|
@@ -58425,7 +59020,7 @@ Then run: npx @blockrun/clawrouter`
|
|
|
58425
59020
|
}
|
|
58426
59021
|
const mnemonic = generateWalletMnemonic();
|
|
58427
59022
|
const derived = deriveAllKeys(mnemonic);
|
|
58428
|
-
await mkdir2(
|
|
59023
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58429
59024
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
58430
59025
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
58431
59026
|
try {
|
|
@@ -58558,7 +59153,7 @@ async function recoverWalletFromMnemonic() {
|
|
|
58558
59153
|
console.log(`[ClawRouter] wallet, recovery is safe to proceed.`);
|
|
58559
59154
|
console.log(`[ClawRouter] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`);
|
|
58560
59155
|
console.log(`[ClawRouter]`);
|
|
58561
|
-
await mkdir2(
|
|
59156
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58562
59157
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
58563
59158
|
console.log(`[ClawRouter] \u2713 wallet.key restored at ${WALLET_FILE}`);
|
|
58564
59159
|
console.log(`[ClawRouter] Run: npx @blockrun/clawrouter`);
|
|
@@ -58584,7 +59179,7 @@ async function setupSolana() {
|
|
|
58584
59179
|
return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
|
|
58585
59180
|
}
|
|
58586
59181
|
async function savePaymentChain(chain3) {
|
|
58587
|
-
await mkdir2(
|
|
59182
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58588
59183
|
await writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
|
|
58589
59184
|
}
|
|
58590
59185
|
async function loadPaymentChain() {
|
|
@@ -58601,17 +59196,17 @@ async function resolvePaymentChain() {
|
|
|
58601
59196
|
if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
|
|
58602
59197
|
return loadPaymentChain();
|
|
58603
59198
|
}
|
|
58604
|
-
var
|
|
59199
|
+
var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
|
|
58605
59200
|
var init_auth = __esm({
|
|
58606
59201
|
"src/auth.ts"() {
|
|
58607
59202
|
"use strict";
|
|
58608
59203
|
init_fs_read();
|
|
58609
59204
|
init_accounts();
|
|
58610
59205
|
init_wallet2();
|
|
58611
|
-
|
|
58612
|
-
WALLET_FILE =
|
|
58613
|
-
MNEMONIC_FILE =
|
|
58614
|
-
CHAIN_FILE =
|
|
59206
|
+
WALLET_DIR2 = join7(homedir4(), ".openclaw", "blockrun");
|
|
59207
|
+
WALLET_FILE = join7(WALLET_DIR2, "wallet.key");
|
|
59208
|
+
MNEMONIC_FILE = join7(WALLET_DIR2, "mnemonic");
|
|
59209
|
+
CHAIN_FILE = join7(WALLET_DIR2, "payment-chain");
|
|
58615
59210
|
}
|
|
58616
59211
|
});
|
|
58617
59212
|
|
|
@@ -58770,7 +59365,7 @@ function generateCodebookHeader(usedCodes, pathMap = {}) {
|
|
|
58770
59365
|
parts.push(`[Dict: ${codeEntries}]`);
|
|
58771
59366
|
}
|
|
58772
59367
|
if (Object.keys(pathMap).length > 0) {
|
|
58773
|
-
const pathEntries = Object.entries(pathMap).map(([code,
|
|
59368
|
+
const pathEntries = Object.entries(pathMap).map(([code, path5]) => `${code}=${path5}`).join(", ");
|
|
58774
59369
|
parts.push(`[Paths: ${pathEntries}]`);
|
|
58775
59370
|
}
|
|
58776
59371
|
return parts.join("\n");
|
|
@@ -58918,8 +59513,8 @@ function extractPaths(messages) {
|
|
|
58918
59513
|
}
|
|
58919
59514
|
function findFrequentPrefixes(paths) {
|
|
58920
59515
|
const prefixCounts = /* @__PURE__ */ new Map();
|
|
58921
|
-
for (const
|
|
58922
|
-
const parts =
|
|
59516
|
+
for (const path5 of paths) {
|
|
59517
|
+
const parts = path5.split("/").filter(Boolean);
|
|
58923
59518
|
for (let i = 2; i < parts.length; i++) {
|
|
58924
59519
|
const prefix = "/" + parts.slice(0, i).join("/") + "/";
|
|
58925
59520
|
prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1);
|
|
@@ -59703,9 +60298,9 @@ var init_updater = __esm({
|
|
|
59703
60298
|
});
|
|
59704
60299
|
|
|
59705
60300
|
// src/exclude-models.ts
|
|
59706
|
-
import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
|
|
59707
|
-
import { join as
|
|
59708
|
-
import { homedir as
|
|
60301
|
+
import { readFileSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
60302
|
+
import { join as join8, dirname as dirname2 } from "path";
|
|
60303
|
+
import { homedir as homedir5 } from "os";
|
|
59709
60304
|
function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
59710
60305
|
try {
|
|
59711
60306
|
const mtimeMs = statSync(filePath).mtimeMs;
|
|
@@ -59726,8 +60321,8 @@ function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
|
59726
60321
|
function saveExcludeList(set, filePath) {
|
|
59727
60322
|
const sorted = [...set].sort();
|
|
59728
60323
|
const dir = dirname2(filePath);
|
|
59729
|
-
|
|
59730
|
-
|
|
60324
|
+
mkdirSync2(dir, { recursive: true });
|
|
60325
|
+
writeFileSync2(filePath, JSON.stringify(sorted, null, 2) + "\n", "utf-8");
|
|
59731
60326
|
loadCache.delete(filePath);
|
|
59732
60327
|
}
|
|
59733
60328
|
function addExclusion(model, filePath = DEFAULT_FILE_PATH) {
|
|
@@ -59754,7 +60349,7 @@ var init_exclude_models = __esm({
|
|
|
59754
60349
|
"src/exclude-models.ts"() {
|
|
59755
60350
|
"use strict";
|
|
59756
60351
|
init_models();
|
|
59757
|
-
DEFAULT_FILE_PATH =
|
|
60352
|
+
DEFAULT_FILE_PATH = join8(homedir5(), ".openclaw", "blockrun", "exclude-models.json");
|
|
59758
60353
|
loadCache = /* @__PURE__ */ new Map();
|
|
59759
60354
|
}
|
|
59760
60355
|
});
|
|
@@ -61059,14 +61654,14 @@ var require_util = __commonJS({
|
|
|
61059
61654
|
}
|
|
61060
61655
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
61061
61656
|
let origin2 = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
61062
|
-
let
|
|
61657
|
+
let path5 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
61063
61658
|
if (origin2[origin2.length - 1] === "/") {
|
|
61064
61659
|
origin2 = origin2.slice(0, origin2.length - 1);
|
|
61065
61660
|
}
|
|
61066
|
-
if (
|
|
61067
|
-
|
|
61661
|
+
if (path5 && path5[0] !== "/") {
|
|
61662
|
+
path5 = `/${path5}`;
|
|
61068
61663
|
}
|
|
61069
|
-
return new URL(`${origin2}${
|
|
61664
|
+
return new URL(`${origin2}${path5}`);
|
|
61070
61665
|
}
|
|
61071
61666
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
61072
61667
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -61937,9 +62532,9 @@ var require_diagnostics = __commonJS({
|
|
|
61937
62532
|
"undici:client:sendHeaders",
|
|
61938
62533
|
(evt) => {
|
|
61939
62534
|
const {
|
|
61940
|
-
request: { method, path:
|
|
62535
|
+
request: { method, path: path5, origin: origin2 }
|
|
61941
62536
|
} = evt;
|
|
61942
|
-
debugLog("sending request to %s %s%s", method, origin2,
|
|
62537
|
+
debugLog("sending request to %s %s%s", method, origin2, path5);
|
|
61943
62538
|
}
|
|
61944
62539
|
);
|
|
61945
62540
|
}
|
|
@@ -61957,14 +62552,14 @@ var require_diagnostics = __commonJS({
|
|
|
61957
62552
|
"undici:request:headers",
|
|
61958
62553
|
(evt) => {
|
|
61959
62554
|
const {
|
|
61960
|
-
request: { method, path:
|
|
62555
|
+
request: { method, path: path5, origin: origin2 },
|
|
61961
62556
|
response: { statusCode }
|
|
61962
62557
|
} = evt;
|
|
61963
62558
|
debugLog(
|
|
61964
62559
|
"received response to %s %s%s - HTTP %d",
|
|
61965
62560
|
method,
|
|
61966
62561
|
origin2,
|
|
61967
|
-
|
|
62562
|
+
path5,
|
|
61968
62563
|
statusCode
|
|
61969
62564
|
);
|
|
61970
62565
|
}
|
|
@@ -61973,23 +62568,23 @@ var require_diagnostics = __commonJS({
|
|
|
61973
62568
|
"undici:request:trailers",
|
|
61974
62569
|
(evt) => {
|
|
61975
62570
|
const {
|
|
61976
|
-
request: { method, path:
|
|
62571
|
+
request: { method, path: path5, origin: origin2 }
|
|
61977
62572
|
} = evt;
|
|
61978
|
-
debugLog("trailers received from %s %s%s", method, origin2,
|
|
62573
|
+
debugLog("trailers received from %s %s%s", method, origin2, path5);
|
|
61979
62574
|
}
|
|
61980
62575
|
);
|
|
61981
62576
|
diagnosticsChannel.subscribe(
|
|
61982
62577
|
"undici:request:error",
|
|
61983
62578
|
(evt) => {
|
|
61984
62579
|
const {
|
|
61985
|
-
request: { method, path:
|
|
62580
|
+
request: { method, path: path5, origin: origin2 },
|
|
61986
62581
|
error
|
|
61987
62582
|
} = evt;
|
|
61988
62583
|
debugLog(
|
|
61989
62584
|
"request to %s %s%s errored - %s",
|
|
61990
62585
|
method,
|
|
61991
62586
|
origin2,
|
|
61992
|
-
|
|
62587
|
+
path5,
|
|
61993
62588
|
error.message
|
|
61994
62589
|
);
|
|
61995
62590
|
}
|
|
@@ -62144,7 +62739,7 @@ var require_request = __commonJS({
|
|
|
62144
62739
|
};
|
|
62145
62740
|
var Request2 = class {
|
|
62146
62741
|
constructor(origin2, {
|
|
62147
|
-
path:
|
|
62742
|
+
path: path5,
|
|
62148
62743
|
method,
|
|
62149
62744
|
body,
|
|
62150
62745
|
headers,
|
|
@@ -62161,11 +62756,11 @@ var require_request = __commonJS({
|
|
|
62161
62756
|
maxRedirections,
|
|
62162
62757
|
typeOfService
|
|
62163
62758
|
}, handler) {
|
|
62164
|
-
if (typeof
|
|
62759
|
+
if (typeof path5 !== "string") {
|
|
62165
62760
|
throw new InvalidArgumentError("path must be a string");
|
|
62166
|
-
} else if (
|
|
62761
|
+
} else if (path5[0] !== "/" && !(path5.startsWith("http://") || path5.startsWith("https://")) && method !== "CONNECT") {
|
|
62167
62762
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
62168
|
-
} else if (invalidPathRegex.test(
|
|
62763
|
+
} else if (invalidPathRegex.test(path5)) {
|
|
62169
62764
|
throw new InvalidArgumentError("invalid request path");
|
|
62170
62765
|
}
|
|
62171
62766
|
if (typeof method !== "string") {
|
|
@@ -62240,7 +62835,7 @@ var require_request = __commonJS({
|
|
|
62240
62835
|
this.completed = false;
|
|
62241
62836
|
this.aborted = false;
|
|
62242
62837
|
this.upgrade = upgrade || null;
|
|
62243
|
-
this.path = query ? serializePathWithQuery(
|
|
62838
|
+
this.path = query ? serializePathWithQuery(path5, query) : path5;
|
|
62244
62839
|
this.origin = origin2;
|
|
62245
62840
|
this.protocol = getProtocolFromUrlString(origin2);
|
|
62246
62841
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" || method === "QUERY" : idempotent;
|
|
@@ -67326,7 +67921,7 @@ var require_client_h1 = __commonJS({
|
|
|
67326
67921
|
}
|
|
67327
67922
|
}
|
|
67328
67923
|
function writeH1(client, request2) {
|
|
67329
|
-
const { method, path:
|
|
67924
|
+
const { method, path: path5, host, upgrade, blocking, reset } = request2;
|
|
67330
67925
|
let { body, headers, contentLength } = request2;
|
|
67331
67926
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
67332
67927
|
if (util5.isFormDataLike(body)) {
|
|
@@ -67402,7 +67997,7 @@ var require_client_h1 = __commonJS({
|
|
|
67402
67997
|
socket[kBlocking] = true;
|
|
67403
67998
|
}
|
|
67404
67999
|
setTypeOfService(socket, request2);
|
|
67405
|
-
let header = `${method} ${
|
|
68000
|
+
let header = `${method} ${path5} HTTP/1.1\r
|
|
67406
68001
|
`;
|
|
67407
68002
|
if (typeof host === "string") {
|
|
67408
68003
|
header += `host: ${host}\r
|
|
@@ -68483,7 +69078,7 @@ var require_client_h2 = __commonJS({
|
|
|
68483
69078
|
const headersTimeout = request2.headersTimeout ?? client[kHeadersTimeout];
|
|
68484
69079
|
const bodyTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
|
|
68485
69080
|
const session = client[kHTTP2Session];
|
|
68486
|
-
const { method, path:
|
|
69081
|
+
const { method, path: path5, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
|
|
68487
69082
|
if (upgrade != null && upgrade !== "websocket") {
|
|
68488
69083
|
util5.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
68489
69084
|
return false;
|
|
@@ -68546,7 +69141,7 @@ var require_client_h2 = __commonJS({
|
|
|
68546
69141
|
}
|
|
68547
69142
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
68548
69143
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
68549
|
-
headers[HTTP2_HEADER_PATH] =
|
|
69144
|
+
headers[HTTP2_HEADER_PATH] = path5;
|
|
68550
69145
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
68551
69146
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
68552
69147
|
} else {
|
|
@@ -68568,7 +69163,7 @@ var require_client_h2 = __commonJS({
|
|
|
68568
69163
|
setupUpgradeStream(stream4, state);
|
|
68569
69164
|
return true;
|
|
68570
69165
|
}
|
|
68571
|
-
headers[HTTP2_HEADER_PATH] =
|
|
69166
|
+
headers[HTTP2_HEADER_PATH] = path5;
|
|
68572
69167
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
68573
69168
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
68574
69169
|
let body = state.body;
|
|
@@ -71238,10 +71833,10 @@ var require_proxy_agent = __commonJS({
|
|
|
71238
71833
|
};
|
|
71239
71834
|
const {
|
|
71240
71835
|
origin: origin2,
|
|
71241
|
-
path:
|
|
71836
|
+
path: path5 = "/",
|
|
71242
71837
|
headers = {}
|
|
71243
71838
|
} = opts;
|
|
71244
|
-
opts.path = origin2 +
|
|
71839
|
+
opts.path = origin2 + path5;
|
|
71245
71840
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
71246
71841
|
const { host } = new URL(origin2);
|
|
71247
71842
|
headers.host = host;
|
|
@@ -73506,20 +74101,20 @@ var require_mock_utils = __commonJS({
|
|
|
73506
74101
|
}
|
|
73507
74102
|
return normalizedQp;
|
|
73508
74103
|
}
|
|
73509
|
-
function safeUrl(
|
|
73510
|
-
if (typeof
|
|
73511
|
-
return
|
|
74104
|
+
function safeUrl(path5) {
|
|
74105
|
+
if (typeof path5 !== "string") {
|
|
74106
|
+
return path5;
|
|
73512
74107
|
}
|
|
73513
|
-
const pathSegments =
|
|
74108
|
+
const pathSegments = path5.split("?", 3);
|
|
73514
74109
|
if (pathSegments.length !== 2) {
|
|
73515
|
-
return
|
|
74110
|
+
return path5;
|
|
73516
74111
|
}
|
|
73517
74112
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
73518
74113
|
qp.sort();
|
|
73519
74114
|
return [...pathSegments, qp.toString()].join("?");
|
|
73520
74115
|
}
|
|
73521
|
-
function matchKey(mockDispatch2, { path:
|
|
73522
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
74116
|
+
function matchKey(mockDispatch2, { path: path5, method, body, headers }) {
|
|
74117
|
+
const pathMatch = matchValue(mockDispatch2.path, path5);
|
|
73523
74118
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
73524
74119
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
73525
74120
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -73546,8 +74141,8 @@ var require_mock_utils = __commonJS({
|
|
|
73546
74141
|
const basePath = key2.query ? serializePathWithQuery(key2.path, key2.query) : key2.path;
|
|
73547
74142
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
73548
74143
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
73549
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
73550
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
74144
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path5, ignoreTrailingSlash }) => {
|
|
74145
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path5)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path5), resolvedPath);
|
|
73551
74146
|
});
|
|
73552
74147
|
if (matchedMockDispatches.length === 0) {
|
|
73553
74148
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -73586,22 +74181,22 @@ var require_mock_utils = __commonJS({
|
|
|
73586
74181
|
mockDispatches.splice(index2, 1);
|
|
73587
74182
|
}
|
|
73588
74183
|
}
|
|
73589
|
-
function removeTrailingSlash(
|
|
73590
|
-
if (typeof
|
|
73591
|
-
return
|
|
74184
|
+
function removeTrailingSlash(path5) {
|
|
74185
|
+
if (typeof path5 !== "string") {
|
|
74186
|
+
return path5;
|
|
73592
74187
|
}
|
|
73593
|
-
while (
|
|
73594
|
-
|
|
74188
|
+
while (path5.endsWith("/")) {
|
|
74189
|
+
path5 = path5.slice(0, -1);
|
|
73595
74190
|
}
|
|
73596
|
-
if (
|
|
73597
|
-
|
|
74191
|
+
if (path5.length === 0) {
|
|
74192
|
+
path5 = "/";
|
|
73598
74193
|
}
|
|
73599
|
-
return
|
|
74194
|
+
return path5;
|
|
73600
74195
|
}
|
|
73601
74196
|
function buildKey(opts) {
|
|
73602
|
-
const { path:
|
|
74197
|
+
const { path: path5, method, body, headers, query } = opts;
|
|
73603
74198
|
return {
|
|
73604
|
-
path:
|
|
74199
|
+
path: path5,
|
|
73605
74200
|
method,
|
|
73606
74201
|
body,
|
|
73607
74202
|
headers,
|
|
@@ -74472,10 +75067,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
74472
75067
|
}
|
|
74473
75068
|
format(pendingInterceptors) {
|
|
74474
75069
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
74475
|
-
({ method, path:
|
|
75070
|
+
({ method, path: path5, data: { statusCode }, persist, times, timesInvoked, origin: origin2 }) => ({
|
|
74476
75071
|
Method: method,
|
|
74477
75072
|
Origin: origin2,
|
|
74478
|
-
Path:
|
|
75073
|
+
Path: path5,
|
|
74479
75074
|
"Status code": statusCode,
|
|
74480
75075
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
74481
75076
|
Invocations: timesInvoked,
|
|
@@ -74557,9 +75152,9 @@ var require_mock_agent = __commonJS({
|
|
|
74557
75152
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
74558
75153
|
const dispatchOpts = { ...opts };
|
|
74559
75154
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
74560
|
-
const [
|
|
75155
|
+
const [path5, searchParams] = dispatchOpts.path.split("?");
|
|
74561
75156
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
74562
|
-
dispatchOpts.path = `${
|
|
75157
|
+
dispatchOpts.path = `${path5}?${normalizedSearchParams}`;
|
|
74563
75158
|
}
|
|
74564
75159
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
74565
75160
|
}
|
|
@@ -74975,12 +75570,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
74975
75570
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
74976
75571
|
*/
|
|
74977
75572
|
async loadSnapshots(filePath) {
|
|
74978
|
-
const
|
|
74979
|
-
if (!
|
|
75573
|
+
const path5 = filePath || this.#snapshotPath;
|
|
75574
|
+
if (!path5) {
|
|
74980
75575
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
74981
75576
|
}
|
|
74982
75577
|
try {
|
|
74983
|
-
const data = await readFile3(resolve(
|
|
75578
|
+
const data = await readFile3(resolve(path5), "utf8");
|
|
74984
75579
|
const parsed = JSON.parse(data);
|
|
74985
75580
|
if (Array.isArray(parsed)) {
|
|
74986
75581
|
this.#snapshots.clear();
|
|
@@ -74994,7 +75589,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
74994
75589
|
if (error.code === "ENOENT") {
|
|
74995
75590
|
this.#snapshots.clear();
|
|
74996
75591
|
} else {
|
|
74997
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
75592
|
+
throw new UndiciError(`Failed to load snapshots from ${path5}`, { cause: error });
|
|
74998
75593
|
}
|
|
74999
75594
|
}
|
|
75000
75595
|
}
|
|
@@ -75005,11 +75600,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
75005
75600
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
75006
75601
|
*/
|
|
75007
75602
|
async saveSnapshots(filePath) {
|
|
75008
|
-
const
|
|
75009
|
-
if (!
|
|
75603
|
+
const path5 = filePath || this.#snapshotPath;
|
|
75604
|
+
if (!path5) {
|
|
75010
75605
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
75011
75606
|
}
|
|
75012
|
-
const resolvedPath = resolve(
|
|
75607
|
+
const resolvedPath = resolve(path5);
|
|
75013
75608
|
await mkdir5(dirname5(resolvedPath), { recursive: true });
|
|
75014
75609
|
const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
|
|
75015
75610
|
hash: hash5,
|
|
@@ -75646,15 +76241,15 @@ var require_redirect_handler = __commonJS({
|
|
|
75646
76241
|
return;
|
|
75647
76242
|
}
|
|
75648
76243
|
const { origin: origin2, pathname, search } = util5.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
75649
|
-
const
|
|
75650
|
-
const redirectUrlString = `${origin2}${
|
|
76244
|
+
const path5 = search ? `${pathname}${search}` : pathname;
|
|
76245
|
+
const redirectUrlString = `${origin2}${path5}`;
|
|
75651
76246
|
for (const historyUrl of this.history) {
|
|
75652
76247
|
if (historyUrl.toString() === redirectUrlString) {
|
|
75653
76248
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin2}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
75654
76249
|
}
|
|
75655
76250
|
}
|
|
75656
76251
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, this.opts.origin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect);
|
|
75657
|
-
this.opts.path =
|
|
76252
|
+
this.opts.path = path5;
|
|
75658
76253
|
this.opts.origin = origin2;
|
|
75659
76254
|
this.opts.query = null;
|
|
75660
76255
|
}
|
|
@@ -77482,10 +78077,10 @@ var require_cache_handler = __commonJS({
|
|
|
77482
78077
|
}
|
|
77483
78078
|
return locationUrl.pathname + locationUrl.search;
|
|
77484
78079
|
}
|
|
77485
|
-
function deleteCachedUri(store, cacheKey2,
|
|
78080
|
+
function deleteCachedUri(store, cacheKey2, path5) {
|
|
77486
78081
|
deleteCachedValue(store, {
|
|
77487
78082
|
...cacheKey2,
|
|
77488
|
-
path:
|
|
78083
|
+
path: path5
|
|
77489
78084
|
});
|
|
77490
78085
|
for (let i = 0; i < util5.safeHTTPMethods.length; i++) {
|
|
77491
78086
|
const method = util5.safeHTTPMethods[i];
|
|
@@ -77493,7 +78088,7 @@ var require_cache_handler = __commonJS({
|
|
|
77493
78088
|
deleteCachedValue(store, {
|
|
77494
78089
|
...cacheKey2,
|
|
77495
78090
|
method,
|
|
77496
|
-
path:
|
|
78091
|
+
path: path5
|
|
77497
78092
|
});
|
|
77498
78093
|
}
|
|
77499
78094
|
}
|
|
@@ -77504,9 +78099,9 @@ var require_cache_handler = __commonJS({
|
|
|
77504
78099
|
}
|
|
77505
78100
|
const values = Array.isArray(headerValue) ? headerValue : [headerValue];
|
|
77506
78101
|
for (let i = 0; i < values.length; i++) {
|
|
77507
|
-
const
|
|
77508
|
-
if (
|
|
77509
|
-
deleteCachedUri(store, cacheKey2,
|
|
78102
|
+
const path5 = getSameOriginPath(cacheKey2, values[i]);
|
|
78103
|
+
if (path5 !== void 0) {
|
|
78104
|
+
deleteCachedUri(store, cacheKey2, path5);
|
|
77510
78105
|
}
|
|
77511
78106
|
}
|
|
77512
78107
|
}
|
|
@@ -82503,13 +83098,13 @@ var require_fetch = __commonJS({
|
|
|
82503
83098
|
function dispatch({ body }) {
|
|
82504
83099
|
const url2 = requestCurrentURL(request2);
|
|
82505
83100
|
const agent = fetchParams.controller.dispatcher;
|
|
82506
|
-
const
|
|
83101
|
+
const path5 = url2.pathname + url2.search;
|
|
82507
83102
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
82508
83103
|
return dispatchWithProtocolPreference(body);
|
|
82509
83104
|
function dispatchWithProtocolPreference(body2, allowH2) {
|
|
82510
83105
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
82511
83106
|
{
|
|
82512
|
-
path: hasTrailingQuestionMark ? `${
|
|
83107
|
+
path: hasTrailingQuestionMark ? `${path5}?` : path5,
|
|
82513
83108
|
origin: url2.origin,
|
|
82514
83109
|
method: request2.method,
|
|
82515
83110
|
body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body2,
|
|
@@ -83421,9 +84016,9 @@ var require_util4 = __commonJS({
|
|
|
83421
84016
|
}
|
|
83422
84017
|
}
|
|
83423
84018
|
}
|
|
83424
|
-
function validateCookiePath(
|
|
83425
|
-
for (let i = 0; i <
|
|
83426
|
-
const code =
|
|
84019
|
+
function validateCookiePath(path5) {
|
|
84020
|
+
for (let i = 0; i < path5.length; ++i) {
|
|
84021
|
+
const code = path5.charCodeAt(i);
|
|
83427
84022
|
if (code < 32 || // exclude CTLs (0-31)
|
|
83428
84023
|
code > 126 || // exclude non-ascii and DEL
|
|
83429
84024
|
code === 59) {
|
|
@@ -86795,11 +87390,11 @@ var require_undici = __commonJS({
|
|
|
86795
87390
|
if (typeof opts.path !== "string") {
|
|
86796
87391
|
throw new InvalidArgumentError("invalid opts.path");
|
|
86797
87392
|
}
|
|
86798
|
-
let
|
|
87393
|
+
let path5 = opts.path;
|
|
86799
87394
|
if (!opts.path.startsWith("/")) {
|
|
86800
|
-
|
|
87395
|
+
path5 = `/${path5}`;
|
|
86801
87396
|
}
|
|
86802
|
-
url2 = new URL(util5.parseOrigin(url2).origin +
|
|
87397
|
+
url2 = new URL(util5.parseOrigin(url2).origin + path5);
|
|
86803
87398
|
} else {
|
|
86804
87399
|
if (!opts) {
|
|
86805
87400
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -87345,8 +87940,8 @@ var init_textual_tool_calls = __esm({
|
|
|
87345
87940
|
|
|
87346
87941
|
// src/response-store.ts
|
|
87347
87942
|
import { appendFile as appendFile2, mkdir as mkdir3, readFile, readdir as readdir2 } from "fs/promises";
|
|
87348
|
-
import { homedir as
|
|
87349
|
-
import { join as
|
|
87943
|
+
import { homedir as homedir6 } from "os";
|
|
87944
|
+
import { join as join9 } from "path";
|
|
87350
87945
|
import { randomBytes as randomBytes7 } from "crypto";
|
|
87351
87946
|
function isEnabled() {
|
|
87352
87947
|
const v = process.env.BLOCKRUN_RESPONSE_STORE;
|
|
@@ -87359,7 +87954,7 @@ async function ensureDir2() {
|
|
|
87359
87954
|
}
|
|
87360
87955
|
function dailyFile(date = /* @__PURE__ */ new Date()) {
|
|
87361
87956
|
const iso = date.toISOString().slice(0, 10);
|
|
87362
|
-
return
|
|
87957
|
+
return join9(STORE_DIR, `responses-${iso}.jsonl`);
|
|
87363
87958
|
}
|
|
87364
87959
|
function genId() {
|
|
87365
87960
|
return `resp_${Date.now()}_${randomBytes7(3).toString("hex")}`;
|
|
@@ -87409,7 +88004,7 @@ async function listRecent(limit = 20, daysBack = 7) {
|
|
|
87409
88004
|
d.setUTCDate(d.getUTCDate() - i);
|
|
87410
88005
|
const iso = d.toISOString().slice(0, 10);
|
|
87411
88006
|
const name = `responses-${iso}.jsonl`;
|
|
87412
|
-
if (files.includes(name)) candidateFiles.push(
|
|
88007
|
+
if (files.includes(name)) candidateFiles.push(join9(STORE_DIR, name));
|
|
87413
88008
|
}
|
|
87414
88009
|
const all3 = [];
|
|
87415
88010
|
for (const f of candidateFiles) {
|
|
@@ -87438,7 +88033,7 @@ var STORE_DIR, dirReady2;
|
|
|
87438
88033
|
var init_response_store = __esm({
|
|
87439
88034
|
"src/response-store.ts"() {
|
|
87440
88035
|
"use strict";
|
|
87441
|
-
STORE_DIR =
|
|
88036
|
+
STORE_DIR = join9(homedir6(), ".openclaw", "blockrun", "responses");
|
|
87442
88037
|
dirReady2 = false;
|
|
87443
88038
|
}
|
|
87444
88039
|
});
|
|
@@ -89088,10 +89683,10 @@ var init_client3 = __esm({
|
|
|
89088
89683
|
import { AsyncLocalStorage } from "async_hooks";
|
|
89089
89684
|
import { createServer } from "http";
|
|
89090
89685
|
import { finished } from "stream";
|
|
89091
|
-
import { homedir as
|
|
89092
|
-
import { join as
|
|
89686
|
+
import { homedir as homedir7 } from "os";
|
|
89687
|
+
import { join as join10 } from "path";
|
|
89093
89688
|
import { mkdir as mkdir4, writeFile as writeFile2, readFile as readFile2, stat as fsStat } from "fs/promises";
|
|
89094
|
-
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
89689
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
89095
89690
|
function pickFreeModel(excludeList) {
|
|
89096
89691
|
for (const m of FREE_MODELS) {
|
|
89097
89692
|
if (!excludeList?.has(m)) return m;
|
|
@@ -89857,8 +90452,8 @@ async function proxyPaidApiRequest(req, res, apiBase, payFetch, getActualPayment
|
|
|
89857
90452
|
});
|
|
89858
90453
|
}
|
|
89859
90454
|
function readImageFileAsDataUri(filePath) {
|
|
89860
|
-
const resolved = filePath.startsWith("~/") ?
|
|
89861
|
-
if (!
|
|
90455
|
+
const resolved = filePath.startsWith("~/") ? join10(homedir7(), filePath.slice(2)) : filePath;
|
|
90456
|
+
if (!existsSync2(resolved)) {
|
|
89862
90457
|
throw new Error(`Image file not found: ${resolved}`);
|
|
89863
90458
|
}
|
|
89864
90459
|
const ext = resolved.split(".").pop()?.toLowerCase() ?? "png";
|
|
@@ -89972,6 +90567,8 @@ async function startProxy(options) {
|
|
|
89972
90567
|
const evmPublicClient = createPublicClient({ chain: base, transport: http() });
|
|
89973
90568
|
const evmSigner = toClientEvmSigner(account, evmPublicClient);
|
|
89974
90569
|
const x402 = new x402Client();
|
|
90570
|
+
const spendControl = options.spendControl ?? new SpendControl();
|
|
90571
|
+
registerSpendPolicyHook(x402, spendControl);
|
|
89975
90572
|
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
89976
90573
|
let solanaAddress;
|
|
89977
90574
|
if (solanaPrivateKeyBytes) {
|
|
@@ -90140,8 +90737,8 @@ async function startProxy(options) {
|
|
|
90140
90737
|
if (req.url?.startsWith("/share") && req.method === "GET") {
|
|
90141
90738
|
try {
|
|
90142
90739
|
const url2 = new URL(req.url, "http://localhost");
|
|
90143
|
-
const
|
|
90144
|
-
if (
|
|
90740
|
+
const path5 = url2.pathname;
|
|
90741
|
+
if (path5 === "/share/list") {
|
|
90145
90742
|
const limit = Math.min(parseInt(url2.searchParams.get("limit") || "20", 10), 100);
|
|
90146
90743
|
const entries = await listRecent(limit);
|
|
90147
90744
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -90159,7 +90756,7 @@ async function startProxy(options) {
|
|
|
90159
90756
|
);
|
|
90160
90757
|
return;
|
|
90161
90758
|
}
|
|
90162
|
-
if (
|
|
90759
|
+
if (path5 === "/share/last") {
|
|
90163
90760
|
const sessionId = url2.searchParams.get("sessionId") || void 0;
|
|
90164
90761
|
const entry = await getLast(sessionId);
|
|
90165
90762
|
if (!entry) {
|
|
@@ -90188,7 +90785,7 @@ async function startProxy(options) {
|
|
|
90188
90785
|
res.end(JSON.stringify(entry));
|
|
90189
90786
|
return;
|
|
90190
90787
|
}
|
|
90191
|
-
const idMatch =
|
|
90788
|
+
const idMatch = path5.match(/^\/share\/(resp_[A-Za-z0-9_]+)(?:\/render)?$/);
|
|
90192
90789
|
if (idMatch) {
|
|
90193
90790
|
const id2 = idMatch[1];
|
|
90194
90791
|
const entry = await getById(id2);
|
|
@@ -90234,7 +90831,7 @@ async function startProxy(options) {
|
|
|
90234
90831
|
res.end("Bad request");
|
|
90235
90832
|
return;
|
|
90236
90833
|
}
|
|
90237
|
-
const filePath =
|
|
90834
|
+
const filePath = join10(IMAGE_DIR, filename);
|
|
90238
90835
|
try {
|
|
90239
90836
|
const s3 = await fsStat(filePath);
|
|
90240
90837
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90265,7 +90862,7 @@ async function startProxy(options) {
|
|
|
90265
90862
|
res.end("Bad request");
|
|
90266
90863
|
return;
|
|
90267
90864
|
}
|
|
90268
|
-
const filePath =
|
|
90865
|
+
const filePath = join10(AUDIO_DIR, filename);
|
|
90269
90866
|
try {
|
|
90270
90867
|
const s3 = await fsStat(filePath);
|
|
90271
90868
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90295,7 +90892,7 @@ async function startProxy(options) {
|
|
|
90295
90892
|
res.end("Bad request");
|
|
90296
90893
|
return;
|
|
90297
90894
|
}
|
|
90298
|
-
const filePath =
|
|
90895
|
+
const filePath = join10(VIDEO_DIR, filename);
|
|
90299
90896
|
try {
|
|
90300
90897
|
const s3 = await fsStat(filePath);
|
|
90301
90898
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90436,7 +91033,7 @@ async function startProxy(options) {
|
|
|
90436
91033
|
const [, mimeType, b64] = dataUriMatch;
|
|
90437
91034
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
90438
91035
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90439
|
-
await writeFile2(
|
|
91036
|
+
await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
90440
91037
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90441
91038
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90442
91039
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
@@ -90447,7 +91044,7 @@ async function startProxy(options) {
|
|
|
90447
91044
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
90448
91045
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90449
91046
|
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
90450
|
-
await writeFile2(
|
|
91047
|
+
await writeFile2(join10(IMAGE_DIR, filename), buf);
|
|
90451
91048
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90452
91049
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
90453
91050
|
}
|
|
@@ -90559,7 +91156,7 @@ async function startProxy(options) {
|
|
|
90559
91156
|
const [, mimeType, b64] = dataUriMatch;
|
|
90560
91157
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
90561
91158
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90562
|
-
await writeFile2(
|
|
91159
|
+
await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
90563
91160
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90564
91161
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90565
91162
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
@@ -90570,7 +91167,7 @@ async function startProxy(options) {
|
|
|
90570
91167
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
90571
91168
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90572
91169
|
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
90573
|
-
await writeFile2(
|
|
91170
|
+
await writeFile2(join10(IMAGE_DIR, filename), buf);
|
|
90574
91171
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90575
91172
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
90576
91173
|
}
|
|
@@ -90656,7 +91253,7 @@ async function startProxy(options) {
|
|
|
90656
91253
|
const ext = contentType.includes("wav") ? "wav" : "mp3";
|
|
90657
91254
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90658
91255
|
const buf = Buffer.from(await audioResp.arrayBuffer());
|
|
90659
|
-
await writeFile2(
|
|
91256
|
+
await writeFile2(join10(AUDIO_DIR, filename), buf);
|
|
90660
91257
|
track.url = `http://localhost:${port2}/audio/${filename}`;
|
|
90661
91258
|
console.log(`[ClawRouter] Audio saved \u2192 ${track.url}`);
|
|
90662
91259
|
}
|
|
@@ -90816,7 +91413,7 @@ async function startProxy(options) {
|
|
|
90816
91413
|
const ext = contentType.includes("webm") ? "webm" : contentType.includes("quicktime") ? "mov" : "mp4";
|
|
90817
91414
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90818
91415
|
const buf = Buffer.from(await videoResp.arrayBuffer());
|
|
90819
|
-
await writeFile2(
|
|
91416
|
+
await writeFile2(join10(VIDEO_DIR, filename), buf);
|
|
90820
91417
|
clip.url = `http://localhost:${port2}/videos/${filename}`;
|
|
90821
91418
|
console.log(`[ClawRouter] Video saved \u2192 ${clip.url}`);
|
|
90822
91419
|
}
|
|
@@ -91156,6 +91753,17 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
|
|
|
91156
91753
|
return { success: true, response };
|
|
91157
91754
|
} catch (err) {
|
|
91158
91755
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
91756
|
+
if (err instanceof SpendPolicyError) {
|
|
91757
|
+
return {
|
|
91758
|
+
success: false,
|
|
91759
|
+
errorBody: JSON.stringify({
|
|
91760
|
+
error: { message: errorMsg, type: "spend_policy_denied", status: 403 }
|
|
91761
|
+
}),
|
|
91762
|
+
errorStatus: 403,
|
|
91763
|
+
isProviderError: false,
|
|
91764
|
+
errorCategory: "payment_error"
|
|
91765
|
+
};
|
|
91766
|
+
}
|
|
91159
91767
|
return {
|
|
91160
91768
|
success: false,
|
|
91161
91769
|
errorBody: errorMsg,
|
|
@@ -93342,6 +93950,7 @@ var init_proxy = __esm({
|
|
|
93342
93950
|
init_response_cache();
|
|
93343
93951
|
init_balance();
|
|
93344
93952
|
init_auth();
|
|
93953
|
+
init_spend_control();
|
|
93345
93954
|
init_compression();
|
|
93346
93955
|
init_version4();
|
|
93347
93956
|
init_session();
|
|
@@ -93357,9 +93966,9 @@ var init_proxy = __esm({
|
|
|
93357
93966
|
paymentStore = new AsyncLocalStorage();
|
|
93358
93967
|
BLOCKRUN_API = "https://blockrun.ai/api";
|
|
93359
93968
|
BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
|
|
93360
|
-
IMAGE_DIR =
|
|
93361
|
-
AUDIO_DIR =
|
|
93362
|
-
VIDEO_DIR =
|
|
93969
|
+
IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
|
|
93970
|
+
AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
|
|
93971
|
+
VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
|
|
93363
93972
|
AUTO_MODEL = "blockrun/auto";
|
|
93364
93973
|
ROUTING_PROFILES = /* @__PURE__ */ new Set([
|
|
93365
93974
|
"blockrun/eco",
|
|
@@ -94424,7 +95033,7 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94424
95033
|
required
|
|
94425
95034
|
},
|
|
94426
95035
|
execute: async (_toolCallId, params) => {
|
|
94427
|
-
let
|
|
95036
|
+
let path5;
|
|
94428
95037
|
const leftoverParams = {};
|
|
94429
95038
|
let dynamicMethod = "GET";
|
|
94430
95039
|
let dynamicBody = void 0;
|
|
@@ -94436,7 +95045,7 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94436
95045
|
`predexon_endpoint_call: invalid path '${rawPath}' \u2014 must begin with '/pm/' and contain no '..'`
|
|
94437
95046
|
);
|
|
94438
95047
|
}
|
|
94439
|
-
|
|
95048
|
+
path5 = `/v1${normalized}`;
|
|
94440
95049
|
if (typeof params.method === "string") {
|
|
94441
95050
|
const upper = params.method.toUpperCase();
|
|
94442
95051
|
if (upper !== "GET" && upper !== "POST") {
|
|
@@ -94485,19 +95094,19 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94485
95094
|
}
|
|
94486
95095
|
}
|
|
94487
95096
|
} else {
|
|
94488
|
-
|
|
95097
|
+
path5 = `/v1${service.proxyPath}`;
|
|
94489
95098
|
for (const [key2, value] of Object.entries(params)) {
|
|
94490
95099
|
if (value === void 0 || value === null) continue;
|
|
94491
95100
|
const placeholder = `:${key2}`;
|
|
94492
|
-
if (
|
|
94493
|
-
|
|
95101
|
+
if (path5.includes(placeholder)) {
|
|
95102
|
+
path5 = path5.replace(placeholder, encodeURIComponent(String(value)));
|
|
94494
95103
|
} else {
|
|
94495
95104
|
leftoverParams[key2] = value;
|
|
94496
95105
|
}
|
|
94497
95106
|
}
|
|
94498
95107
|
}
|
|
94499
95108
|
const effectiveMethod = service.proxyPath === "/pm/__dynamic__" ? dynamicMethod : service.method;
|
|
94500
|
-
let url2 = `${proxyBaseUrl}${
|
|
95109
|
+
let url2 = `${proxyBaseUrl}${path5}`;
|
|
94501
95110
|
if (effectiveMethod === "GET" && Object.keys(leftoverParams).length > 0) {
|
|
94502
95111
|
const qs = new URLSearchParams();
|
|
94503
95112
|
for (const [key2, value] of Object.entries(leftoverParams)) {
|
|
@@ -106176,11 +106785,11 @@ var require_mime_types = __commonJS({
|
|
|
106176
106785
|
}
|
|
106177
106786
|
return exts[0];
|
|
106178
106787
|
}
|
|
106179
|
-
function lookup(
|
|
106180
|
-
if (!
|
|
106788
|
+
function lookup(path5) {
|
|
106789
|
+
if (!path5 || typeof path5 !== "string") {
|
|
106181
106790
|
return false;
|
|
106182
106791
|
}
|
|
106183
|
-
var extension3 = extname("x." +
|
|
106792
|
+
var extension3 = extname("x." + path5).toLowerCase().substr(1);
|
|
106184
106793
|
if (!extension3) {
|
|
106185
106794
|
return false;
|
|
106186
106795
|
}
|
|
@@ -107295,7 +107904,7 @@ var require_form_data = __commonJS({
|
|
|
107295
107904
|
"use strict";
|
|
107296
107905
|
var CombinedStream = require_combined_stream();
|
|
107297
107906
|
var util5 = __require("util");
|
|
107298
|
-
var
|
|
107907
|
+
var path5 = __require("path");
|
|
107299
107908
|
var http5 = __require("http");
|
|
107300
107909
|
var https2 = __require("https");
|
|
107301
107910
|
var parseUrl3 = __require("url").parse;
|
|
@@ -107426,11 +108035,11 @@ var require_form_data = __commonJS({
|
|
|
107426
108035
|
FormData3.prototype._getContentDisposition = function(value, options) {
|
|
107427
108036
|
var filename;
|
|
107428
108037
|
if (typeof options.filepath === "string") {
|
|
107429
|
-
filename =
|
|
108038
|
+
filename = path5.normalize(options.filepath).replace(/\\/g, "/");
|
|
107430
108039
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
107431
|
-
filename =
|
|
108040
|
+
filename = path5.basename(options.filename || value && (value.name || value.path));
|
|
107432
108041
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
107433
|
-
filename =
|
|
108042
|
+
filename = path5.basename(value.client._httpMessage.path || "");
|
|
107434
108043
|
}
|
|
107435
108044
|
if (filename) {
|
|
107436
108045
|
return 'filename="' + escapeHeaderParam(filename) + '"';
|
|
@@ -107644,9 +108253,9 @@ function isVisitable(thing) {
|
|
|
107644
108253
|
function removeBrackets(key2) {
|
|
107645
108254
|
return utils_default.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
|
|
107646
108255
|
}
|
|
107647
|
-
function renderKey(
|
|
107648
|
-
if (!
|
|
107649
|
-
return
|
|
108256
|
+
function renderKey(path5, key2, dots) {
|
|
108257
|
+
if (!path5) return key2;
|
|
108258
|
+
return path5.concat(key2).map(function each(token, i) {
|
|
107650
108259
|
token = removeBrackets(token);
|
|
107651
108260
|
return !dots && i ? "[" + token + "]" : token;
|
|
107652
108261
|
}).join(dots ? "." : "");
|
|
@@ -107729,13 +108338,13 @@ function toFormData(obj, formData, options) {
|
|
|
107729
108338
|
return currentValue;
|
|
107730
108339
|
});
|
|
107731
108340
|
}
|
|
107732
|
-
function defaultVisitor(value, key2,
|
|
108341
|
+
function defaultVisitor(value, key2, path5) {
|
|
107733
108342
|
let arr = value;
|
|
107734
108343
|
if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
|
|
107735
|
-
formData.append(renderKey(
|
|
108344
|
+
formData.append(renderKey(path5, key2, dots), convertValue(value));
|
|
107736
108345
|
return false;
|
|
107737
108346
|
}
|
|
107738
|
-
if (value && !
|
|
108347
|
+
if (value && !path5 && typeof value === "object") {
|
|
107739
108348
|
if (utils_default.endsWith(key2, "{}")) {
|
|
107740
108349
|
key2 = metaTokens ? key2 : key2.slice(0, -2);
|
|
107741
108350
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -107754,7 +108363,7 @@ function toFormData(obj, formData, options) {
|
|
|
107754
108363
|
if (isVisitable(value)) {
|
|
107755
108364
|
return true;
|
|
107756
108365
|
}
|
|
107757
|
-
formData.append(renderKey(
|
|
108366
|
+
formData.append(renderKey(path5, key2, dots), convertValue(value));
|
|
107758
108367
|
return false;
|
|
107759
108368
|
}
|
|
107760
108369
|
const exposedHelpers = Object.assign(predicates, {
|
|
@@ -107762,17 +108371,17 @@ function toFormData(obj, formData, options) {
|
|
|
107762
108371
|
convertValue,
|
|
107763
108372
|
isVisitable
|
|
107764
108373
|
});
|
|
107765
|
-
function build(value,
|
|
108374
|
+
function build(value, path5, depth = 0) {
|
|
107766
108375
|
if (utils_default.isUndefined(value)) return;
|
|
107767
108376
|
throwIfMaxDepthExceeded(depth);
|
|
107768
108377
|
if (stack.indexOf(value) !== -1) {
|
|
107769
|
-
throw new Error("Circular reference detected in " +
|
|
108378
|
+
throw new Error("Circular reference detected in " + path5.join("."));
|
|
107770
108379
|
}
|
|
107771
108380
|
stack.push(value);
|
|
107772
108381
|
utils_default.forEach(value, function each(el, key2) {
|
|
107773
|
-
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2,
|
|
108382
|
+
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2, path5, exposedHelpers);
|
|
107774
108383
|
if (result === true) {
|
|
107775
|
-
build(el,
|
|
108384
|
+
build(el, path5 ? path5.concat(key2) : [key2], depth + 1);
|
|
107776
108385
|
}
|
|
107777
108386
|
});
|
|
107778
108387
|
stack.pop();
|
|
@@ -108051,7 +108660,7 @@ var init_platform = __esm({
|
|
|
108051
108660
|
// node_modules/axios/lib/helpers/toURLEncodedForm.js
|
|
108052
108661
|
function toURLEncodedForm(data, options) {
|
|
108053
108662
|
return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
|
|
108054
|
-
visitor: function(value, key2,
|
|
108663
|
+
visitor: function(value, key2, path5, helpers) {
|
|
108055
108664
|
if (platform_default.isNode && utils_default.isBuffer(value)) {
|
|
108056
108665
|
this.append(key2, value.toString("base64"));
|
|
108057
108666
|
return false;
|
|
@@ -108080,14 +108689,14 @@ function throwIfDepthExceeded(index2) {
|
|
|
108080
108689
|
}
|
|
108081
108690
|
}
|
|
108082
108691
|
function parsePropPath(name) {
|
|
108083
|
-
const
|
|
108692
|
+
const path5 = [];
|
|
108084
108693
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
108085
108694
|
let match;
|
|
108086
108695
|
while ((match = pattern.exec(name)) !== null) {
|
|
108087
|
-
throwIfDepthExceeded(
|
|
108088
|
-
|
|
108696
|
+
throwIfDepthExceeded(path5.length);
|
|
108697
|
+
path5.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
108089
108698
|
}
|
|
108090
|
-
return
|
|
108699
|
+
return path5;
|
|
108091
108700
|
}
|
|
108092
108701
|
function arrayToObject(arr) {
|
|
108093
108702
|
const obj = {};
|
|
@@ -108102,12 +108711,12 @@ function arrayToObject(arr) {
|
|
|
108102
108711
|
return obj;
|
|
108103
108712
|
}
|
|
108104
108713
|
function formDataToJSON(formData) {
|
|
108105
|
-
function buildPath(
|
|
108714
|
+
function buildPath(path5, value, target, index2) {
|
|
108106
108715
|
throwIfDepthExceeded(index2);
|
|
108107
|
-
let name =
|
|
108716
|
+
let name = path5[index2++];
|
|
108108
108717
|
if (name === "__proto__") return true;
|
|
108109
108718
|
const isNumericKey = Number.isFinite(+name);
|
|
108110
|
-
const isLast = index2 >=
|
|
108719
|
+
const isLast = index2 >= path5.length;
|
|
108111
108720
|
name = !name && utils_default.isArray(target) ? target.length : name;
|
|
108112
108721
|
if (isLast) {
|
|
108113
108722
|
if (utils_default.hasOwnProp(target, name)) {
|
|
@@ -108120,7 +108729,7 @@ function formDataToJSON(formData) {
|
|
|
108120
108729
|
if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
|
|
108121
108730
|
target[name] = [];
|
|
108122
108731
|
}
|
|
108123
|
-
const result = buildPath(
|
|
108732
|
+
const result = buildPath(path5, value, target[name], index2);
|
|
108124
108733
|
if (result && utils_default.isArray(target[name])) {
|
|
108125
108734
|
target[name] = arrayToObject(target[name]);
|
|
108126
108735
|
}
|
|
@@ -111667,9 +112276,9 @@ var init_http4 = __esm({
|
|
|
111667
112276
|
auth = urlUsername + ":" + urlPassword;
|
|
111668
112277
|
}
|
|
111669
112278
|
auth && headers.delete("authorization");
|
|
111670
|
-
let
|
|
112279
|
+
let path5;
|
|
111671
112280
|
try {
|
|
111672
|
-
|
|
112281
|
+
path5 = buildURL(
|
|
111673
112282
|
parsed.pathname + parsed.search,
|
|
111674
112283
|
own2("params"),
|
|
111675
112284
|
own2("paramsSerializer")
|
|
@@ -111688,7 +112297,7 @@ var init_http4 = __esm({
|
|
|
111688
112297
|
false
|
|
111689
112298
|
);
|
|
111690
112299
|
const options = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
111691
|
-
path:
|
|
112300
|
+
path: path5,
|
|
111692
112301
|
method,
|
|
111693
112302
|
headers: toByteStringHeaderObject(headers),
|
|
111694
112303
|
agents: { http: httpAgent, https: httpsAgent },
|
|
@@ -112105,14 +112714,14 @@ var init_cookies = __esm({
|
|
|
112105
112714
|
cookies_default = platform_default.hasStandardBrowserEnv ? (
|
|
112106
112715
|
// Standard browser envs support document.cookie
|
|
112107
112716
|
{
|
|
112108
|
-
write(name, value, expires,
|
|
112717
|
+
write(name, value, expires, path5, domain, secure, sameSite) {
|
|
112109
112718
|
if (typeof document === "undefined") return;
|
|
112110
112719
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
112111
112720
|
if (utils_default.isNumber(expires)) {
|
|
112112
112721
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
112113
112722
|
}
|
|
112114
|
-
if (utils_default.isString(
|
|
112115
|
-
cookie.push(`path=${
|
|
112723
|
+
if (utils_default.isString(path5)) {
|
|
112724
|
+
cookie.push(`path=${path5}`);
|
|
112116
112725
|
}
|
|
112117
112726
|
if (utils_default.isString(domain)) {
|
|
112118
112727
|
cookie.push(`domain=${domain}`);
|
|
@@ -115541,15 +116150,15 @@ var init_constants3 = __esm({
|
|
|
115541
116150
|
});
|
|
115542
116151
|
|
|
115543
116152
|
// src/polymarket/wallet-adapter.ts
|
|
115544
|
-
import
|
|
115545
|
-
import { homedir as
|
|
115546
|
-
import { join as
|
|
116153
|
+
import fs2 from "fs";
|
|
116154
|
+
import { homedir as homedir8 } from "os";
|
|
116155
|
+
import { join as join11 } from "path";
|
|
115547
116156
|
function getOrCreateWalletKey() {
|
|
115548
116157
|
const envKey = process.env.BLOCKRUN_WALLET_KEY?.trim();
|
|
115549
116158
|
if (envKey && /^0x[0-9a-fA-F]{64}$/.test(envKey)) return envKey;
|
|
115550
116159
|
let key2;
|
|
115551
116160
|
try {
|
|
115552
|
-
key2 =
|
|
116161
|
+
key2 = fs2.readFileSync(WALLET_FILE2, "utf-8").trim();
|
|
115553
116162
|
} catch (err) {
|
|
115554
116163
|
if (err.code === "ENOENT") {
|
|
115555
116164
|
throw new Error(
|
|
@@ -115591,7 +116200,7 @@ var init_wallet_adapter = __esm({
|
|
|
115591
116200
|
init_esm();
|
|
115592
116201
|
init_chains();
|
|
115593
116202
|
init_constants3();
|
|
115594
|
-
WALLET_FILE2 =
|
|
116203
|
+
WALLET_FILE2 = join11(homedir8(), ".openclaw", "blockrun", "wallet.key");
|
|
115595
116204
|
BASE_RPC_URLS = [
|
|
115596
116205
|
"https://mainnet.base.org",
|
|
115597
116206
|
"https://base.llamarpc.com",
|
|
@@ -115602,21 +116211,21 @@ var init_wallet_adapter = __esm({
|
|
|
115602
116211
|
});
|
|
115603
116212
|
|
|
115604
116213
|
// src/polymarket/creds.ts
|
|
115605
|
-
import
|
|
115606
|
-
import
|
|
116214
|
+
import fs3 from "fs";
|
|
116215
|
+
import path2 from "path";
|
|
115607
116216
|
import os from "os";
|
|
115608
116217
|
function readJsonFile(file) {
|
|
115609
116218
|
try {
|
|
115610
|
-
if (!
|
|
115611
|
-
const raw =
|
|
116219
|
+
if (!fs3.existsSync(file)) return null;
|
|
116220
|
+
const raw = fs3.readFileSync(file, "utf-8").trim();
|
|
115612
116221
|
return raw ? JSON.parse(raw) : null;
|
|
115613
116222
|
} catch {
|
|
115614
116223
|
return null;
|
|
115615
116224
|
}
|
|
115616
116225
|
}
|
|
115617
116226
|
function writeJsonFile(file, value) {
|
|
115618
|
-
|
|
115619
|
-
|
|
116227
|
+
fs3.mkdirSync(BLOCKRUN_DIR, { recursive: true });
|
|
116228
|
+
fs3.writeFileSync(file, JSON.stringify(value, null, 2), { mode: 384 });
|
|
115620
116229
|
}
|
|
115621
116230
|
function credsKey(address2, sigType) {
|
|
115622
116231
|
return `${address2.toLowerCase()}:${sigType}`;
|
|
@@ -115668,10 +116277,10 @@ var BLOCKRUN_DIR, CREDS_FILE, BUILDER_CREDS_FILE, STATE_FILE;
|
|
|
115668
116277
|
var init_creds = __esm({
|
|
115669
116278
|
"src/polymarket/creds.ts"() {
|
|
115670
116279
|
"use strict";
|
|
115671
|
-
BLOCKRUN_DIR =
|
|
115672
|
-
CREDS_FILE =
|
|
115673
|
-
BUILDER_CREDS_FILE =
|
|
115674
|
-
STATE_FILE =
|
|
116280
|
+
BLOCKRUN_DIR = path2.join(os.homedir(), ".openclaw", "blockrun");
|
|
116281
|
+
CREDS_FILE = path2.join(BLOCKRUN_DIR, ".polymarket-creds");
|
|
116282
|
+
BUILDER_CREDS_FILE = path2.join(BLOCKRUN_DIR, ".polymarket-builder-creds");
|
|
116283
|
+
STATE_FILE = path2.join(BLOCKRUN_DIR, ".polymarket.json");
|
|
115675
116284
|
}
|
|
115676
116285
|
});
|
|
115677
116286
|
|
|
@@ -116853,13 +117462,13 @@ function __disposeResources(env) {
|
|
|
116853
117462
|
}
|
|
116854
117463
|
return next();
|
|
116855
117464
|
}
|
|
116856
|
-
function __rewriteRelativeImportExtension(
|
|
116857
|
-
if (typeof
|
|
116858
|
-
return
|
|
117465
|
+
function __rewriteRelativeImportExtension(path5, preserveJsx) {
|
|
117466
|
+
if (typeof path5 === "string" && /^\.\.?\//.test(path5)) {
|
|
117467
|
+
return path5.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
|
|
116859
117468
|
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
|
|
116860
117469
|
});
|
|
116861
117470
|
}
|
|
116862
|
-
return
|
|
117471
|
+
return path5;
|
|
116863
117472
|
}
|
|
116864
117473
|
var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
|
|
116865
117474
|
var init_tslib_es6 = __esm({
|
|
@@ -149156,9 +149765,9 @@ var require_setupKzg = __commonJS({
|
|
|
149156
149765
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
149157
149766
|
exports.setupKzg = setupKzg;
|
|
149158
149767
|
var defineKzg_js_1 = require_defineKzg();
|
|
149159
|
-
function setupKzg(parameters,
|
|
149768
|
+
function setupKzg(parameters, path5) {
|
|
149160
149769
|
try {
|
|
149161
|
-
parameters.loadTrustedSetup(
|
|
149770
|
+
parameters.loadTrustedSetup(path5);
|
|
149162
149771
|
} catch (e7) {
|
|
149163
149772
|
const error = e7;
|
|
149164
149773
|
if (!error.message.includes("trusted setup is already loaded"))
|
|
@@ -197243,12 +197852,12 @@ var init_fragments = __esm({
|
|
|
197243
197852
|
// node_modules/@ethersproject/abi/lib.esm/coders/abstract-coder.js
|
|
197244
197853
|
function checkResultErrors(result) {
|
|
197245
197854
|
const errors = [];
|
|
197246
|
-
const checkErrors = function(
|
|
197855
|
+
const checkErrors = function(path5, object) {
|
|
197247
197856
|
if (!Array.isArray(object)) {
|
|
197248
197857
|
return;
|
|
197249
197858
|
}
|
|
197250
197859
|
for (let key2 in object) {
|
|
197251
|
-
const childPath =
|
|
197860
|
+
const childPath = path5.slice();
|
|
197252
197861
|
childPath.push(key2);
|
|
197253
197862
|
try {
|
|
197254
197863
|
checkErrors(childPath, object[key2]);
|
|
@@ -203066,8 +203675,8 @@ function createCommonjsModule(fn, basedir, module) {
|
|
|
203066
203675
|
return module = {
|
|
203067
203676
|
path: basedir,
|
|
203068
203677
|
exports: {},
|
|
203069
|
-
require: function(
|
|
203070
|
-
return commonjsRequire(
|
|
203678
|
+
require: function(path5, base3) {
|
|
203679
|
+
return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
|
|
203071
203680
|
}
|
|
203072
203681
|
}, fn(module, module.exports), module.exports;
|
|
203073
203682
|
}
|
|
@@ -206917,9 +207526,9 @@ var init_lib23 = __esm({
|
|
|
206917
207526
|
if (index2 > 4294967295) {
|
|
206918
207527
|
throw new Error("invalid index - " + String(index2));
|
|
206919
207528
|
}
|
|
206920
|
-
let
|
|
206921
|
-
if (
|
|
206922
|
-
|
|
207529
|
+
let path5 = this.path;
|
|
207530
|
+
if (path5) {
|
|
207531
|
+
path5 += "/" + (index2 & ~HardenedBit);
|
|
206923
207532
|
}
|
|
206924
207533
|
const data = new Uint8Array(37);
|
|
206925
207534
|
if (index2 & HardenedBit) {
|
|
@@ -206927,8 +207536,8 @@ var init_lib23 = __esm({
|
|
|
206927
207536
|
throw new Error("cannot derive child of neutered node");
|
|
206928
207537
|
}
|
|
206929
207538
|
data.set(arrayify(this.privateKey), 1);
|
|
206930
|
-
if (
|
|
206931
|
-
|
|
207539
|
+
if (path5) {
|
|
207540
|
+
path5 += "'";
|
|
206932
207541
|
}
|
|
206933
207542
|
} else {
|
|
206934
207543
|
data.set(arrayify(this.publicKey));
|
|
@@ -206947,21 +207556,21 @@ var init_lib23 = __esm({
|
|
|
206947
207556
|
const ek = new SigningKey(hexlify(IL));
|
|
206948
207557
|
Ki = ek._addPoint(this.publicKey);
|
|
206949
207558
|
}
|
|
206950
|
-
let mnemonicOrPath =
|
|
207559
|
+
let mnemonicOrPath = path5;
|
|
206951
207560
|
const srcMnemonic = this.mnemonic;
|
|
206952
207561
|
if (srcMnemonic) {
|
|
206953
207562
|
mnemonicOrPath = Object.freeze({
|
|
206954
207563
|
phrase: srcMnemonic.phrase,
|
|
206955
|
-
path:
|
|
207564
|
+
path: path5,
|
|
206956
207565
|
locale: srcMnemonic.locale || "en"
|
|
206957
207566
|
});
|
|
206958
207567
|
}
|
|
206959
207568
|
return new _HDNode(_constructorGuard4, ki, Ki, this.fingerprint, bytes32(IR), index2, this.depth + 1, mnemonicOrPath);
|
|
206960
207569
|
}
|
|
206961
|
-
derivePath(
|
|
206962
|
-
const components =
|
|
207570
|
+
derivePath(path5) {
|
|
207571
|
+
const components = path5.split("/");
|
|
206963
207572
|
if (components.length === 0 || components[0] === "m" && this.depth !== 0) {
|
|
206964
|
-
throw new Error("invalid path - " +
|
|
207573
|
+
throw new Error("invalid path - " + path5);
|
|
206965
207574
|
}
|
|
206966
207575
|
if (components[0] === "m") {
|
|
206967
207576
|
components.shift();
|
|
@@ -207696,9 +208305,9 @@ function getPassword(password) {
|
|
|
207696
208305
|
}
|
|
207697
208306
|
return arrayify(password);
|
|
207698
208307
|
}
|
|
207699
|
-
function searchPath(object,
|
|
208308
|
+
function searchPath(object, path5) {
|
|
207700
208309
|
let currentChild = object;
|
|
207701
|
-
const comps =
|
|
208310
|
+
const comps = path5.toLowerCase().split("/");
|
|
207702
208311
|
for (let i = 0; i < comps.length; i++) {
|
|
207703
208312
|
let matchingChild = null;
|
|
207704
208313
|
for (const key2 in currentChild) {
|
|
@@ -208347,12 +208956,12 @@ function _getAccount(data, key2) {
|
|
|
208347
208956
|
const mnemonicIv = looseArrayify(searchPath(data, "x-ethers/mnemonicCounter"));
|
|
208348
208957
|
const mnemonicCounter = new import_aes_js2.default.Counter(mnemonicIv);
|
|
208349
208958
|
const mnemonicAesCtr = new import_aes_js2.default.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
|
208350
|
-
const
|
|
208959
|
+
const path5 = searchPath(data, "x-ethers/path") || defaultPath;
|
|
208351
208960
|
const locale = searchPath(data, "x-ethers/locale") || "en";
|
|
208352
208961
|
const entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));
|
|
208353
208962
|
try {
|
|
208354
208963
|
const mnemonic = entropyToMnemonic2(entropy, locale);
|
|
208355
|
-
const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(
|
|
208964
|
+
const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path5);
|
|
208356
208965
|
if (node.privateKey != account.privateKey) {
|
|
208357
208966
|
throw new Error("mnemonic mismatch");
|
|
208358
208967
|
}
|
|
@@ -208452,12 +209061,12 @@ function encrypt(account, password, options, progressCallback) {
|
|
|
208452
209061
|
const privateKey = arrayify(account.privateKey);
|
|
208453
209062
|
const passwordBytes = getPassword(password);
|
|
208454
209063
|
let entropy = null;
|
|
208455
|
-
let
|
|
209064
|
+
let path5 = null;
|
|
208456
209065
|
let locale = null;
|
|
208457
209066
|
if (hasMnemonic(account)) {
|
|
208458
209067
|
const srcMnemonic = account.mnemonic;
|
|
208459
209068
|
entropy = arrayify(mnemonicToEntropy2(srcMnemonic.phrase, srcMnemonic.locale || "en"));
|
|
208460
|
-
|
|
209069
|
+
path5 = srcMnemonic.path || defaultPath;
|
|
208461
209070
|
locale = srcMnemonic.locale || "en";
|
|
208462
209071
|
}
|
|
208463
209072
|
let client = options.client;
|
|
@@ -208543,7 +209152,7 @@ function encrypt(account, password, options, progressCallback) {
|
|
|
208543
209152
|
gethFilename: "UTC--" + timestamp + "--" + data.address,
|
|
208544
209153
|
mnemonicCounter: hexlify(mnemonicIv).substring(2),
|
|
208545
209154
|
mnemonicCiphertext: hexlify(mnemonicCiphertext).substring(2),
|
|
208546
|
-
path:
|
|
209155
|
+
path: path5,
|
|
208547
209156
|
locale,
|
|
208548
209157
|
version: "0.1"
|
|
208549
209158
|
};
|
|
@@ -208837,11 +209446,11 @@ var init_lib26 = __esm({
|
|
|
208837
209446
|
static fromEncryptedJsonSync(json, password) {
|
|
208838
209447
|
return new _Wallet(decryptJsonWalletSync(json, password));
|
|
208839
209448
|
}
|
|
208840
|
-
static fromMnemonic(mnemonic,
|
|
208841
|
-
if (!
|
|
208842
|
-
|
|
209449
|
+
static fromMnemonic(mnemonic, path5, wordlist3) {
|
|
209450
|
+
if (!path5) {
|
|
209451
|
+
path5 = defaultPath;
|
|
208843
209452
|
}
|
|
208844
|
-
return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(
|
|
209453
|
+
return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(path5));
|
|
208845
209454
|
}
|
|
208846
209455
|
};
|
|
208847
209456
|
}
|
|
@@ -214837,21 +215446,21 @@ var init_web3_provider = __esm({
|
|
|
214837
215446
|
if (provider == null) {
|
|
214838
215447
|
logger43.throwArgumentError("missing provider", "provider", provider);
|
|
214839
215448
|
}
|
|
214840
|
-
let
|
|
215449
|
+
let path5 = null;
|
|
214841
215450
|
let jsonRpcFetchFunc = null;
|
|
214842
215451
|
let subprovider = null;
|
|
214843
215452
|
if (typeof provider === "function") {
|
|
214844
|
-
|
|
215453
|
+
path5 = "unknown:";
|
|
214845
215454
|
jsonRpcFetchFunc = provider;
|
|
214846
215455
|
} else {
|
|
214847
|
-
|
|
214848
|
-
if (!
|
|
214849
|
-
|
|
215456
|
+
path5 = provider.host || provider.path || "";
|
|
215457
|
+
if (!path5 && provider.isMetaMask) {
|
|
215458
|
+
path5 = "metamask";
|
|
214850
215459
|
}
|
|
214851
215460
|
subprovider = provider;
|
|
214852
215461
|
if (provider.request) {
|
|
214853
|
-
if (
|
|
214854
|
-
|
|
215462
|
+
if (path5 === "") {
|
|
215463
|
+
path5 = "eip-1193:";
|
|
214855
215464
|
}
|
|
214856
215465
|
jsonRpcFetchFunc = buildEip1193Fetcher(provider);
|
|
214857
215466
|
} else if (provider.sendAsync) {
|
|
@@ -214861,11 +215470,11 @@ var init_web3_provider = __esm({
|
|
|
214861
215470
|
} else {
|
|
214862
215471
|
logger43.throwArgumentError("unsupported provider", "provider", provider);
|
|
214863
215472
|
}
|
|
214864
|
-
if (!
|
|
214865
|
-
|
|
215473
|
+
if (!path5) {
|
|
215474
|
+
path5 = "unknown:";
|
|
214866
215475
|
}
|
|
214867
215476
|
}
|
|
214868
|
-
super(
|
|
215477
|
+
super(path5, network);
|
|
214869
215478
|
defineReadOnly(this, "jsonRpcFetchFunc", jsonRpcFetchFunc);
|
|
214870
215479
|
defineReadOnly(this, "provider", subprovider);
|
|
214871
215480
|
}
|
|
@@ -215703,7 +216312,7 @@ var require_axios = __commonJS({
|
|
|
215703
216312
|
var https2 = __require("https");
|
|
215704
216313
|
var http23 = __require("http2");
|
|
215705
216314
|
var util5 = __require("util");
|
|
215706
|
-
var
|
|
216315
|
+
var path5 = __require("path");
|
|
215707
216316
|
var followRedirects2 = require_follow_redirects();
|
|
215708
216317
|
var zlib2 = __require("zlib");
|
|
215709
216318
|
var stream4 = __require("stream");
|
|
@@ -216771,9 +217380,9 @@ var require_axios = __commonJS({
|
|
|
216771
217380
|
function removeBrackets2(key2) {
|
|
216772
217381
|
return utils$1.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
|
|
216773
217382
|
}
|
|
216774
|
-
function renderKey2(
|
|
216775
|
-
if (!
|
|
216776
|
-
return
|
|
217383
|
+
function renderKey2(path6, key2, dots) {
|
|
217384
|
+
if (!path6) return key2;
|
|
217385
|
+
return path6.concat(key2).map(function each(token, i) {
|
|
216777
217386
|
token = removeBrackets2(token);
|
|
216778
217387
|
return !dots && i ? "[" + token + "]" : token;
|
|
216779
217388
|
}).join(dots ? "." : "");
|
|
@@ -216851,13 +217460,13 @@ var require_axios = __commonJS({
|
|
|
216851
217460
|
return currentValue;
|
|
216852
217461
|
});
|
|
216853
217462
|
}
|
|
216854
|
-
function defaultVisitor(value, key2,
|
|
217463
|
+
function defaultVisitor(value, key2, path6) {
|
|
216855
217464
|
let arr = value;
|
|
216856
217465
|
if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
|
|
216857
|
-
formData.append(renderKey2(
|
|
217466
|
+
formData.append(renderKey2(path6, key2, dots), convertValue(value));
|
|
216858
217467
|
return false;
|
|
216859
217468
|
}
|
|
216860
|
-
if (value && !
|
|
217469
|
+
if (value && !path6 && typeof value === "object") {
|
|
216861
217470
|
if (utils$1.endsWith(key2, "{}")) {
|
|
216862
217471
|
key2 = metaTokens ? key2 : key2.slice(0, -2);
|
|
216863
217472
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -216876,7 +217485,7 @@ var require_axios = __commonJS({
|
|
|
216876
217485
|
if (isVisitable2(value)) {
|
|
216877
217486
|
return true;
|
|
216878
217487
|
}
|
|
216879
|
-
formData.append(renderKey2(
|
|
217488
|
+
formData.append(renderKey2(path6, key2, dots), convertValue(value));
|
|
216880
217489
|
return false;
|
|
216881
217490
|
}
|
|
216882
217491
|
const exposedHelpers = Object.assign(predicates2, {
|
|
@@ -216884,17 +217493,17 @@ var require_axios = __commonJS({
|
|
|
216884
217493
|
convertValue,
|
|
216885
217494
|
isVisitable: isVisitable2
|
|
216886
217495
|
});
|
|
216887
|
-
function build(value,
|
|
217496
|
+
function build(value, path6, depth = 0) {
|
|
216888
217497
|
if (utils$1.isUndefined(value)) return;
|
|
216889
217498
|
throwIfMaxDepthExceeded(depth);
|
|
216890
217499
|
if (stack.indexOf(value) !== -1) {
|
|
216891
|
-
throw new Error("Circular reference detected in " +
|
|
217500
|
+
throw new Error("Circular reference detected in " + path6.join("."));
|
|
216892
217501
|
}
|
|
216893
217502
|
stack.push(value);
|
|
216894
217503
|
utils$1.forEach(value, function each(el, key2) {
|
|
216895
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2,
|
|
217504
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2, path6, exposedHelpers);
|
|
216896
217505
|
if (result === true) {
|
|
216897
|
-
build(el,
|
|
217506
|
+
build(el, path6 ? path6.concat(key2) : [key2], depth + 1);
|
|
216898
217507
|
}
|
|
216899
217508
|
});
|
|
216900
217509
|
stack.pop();
|
|
@@ -217083,7 +217692,7 @@ var require_axios = __commonJS({
|
|
|
217083
217692
|
};
|
|
217084
217693
|
function toURLEncodedForm2(data, options) {
|
|
217085
217694
|
return toFormData3(data, new platform2.classes.URLSearchParams(), {
|
|
217086
|
-
visitor: function(value, key2,
|
|
217695
|
+
visitor: function(value, key2, path6, helpers) {
|
|
217087
217696
|
if (platform2.isNode && utils$1.isBuffer(value)) {
|
|
217088
217697
|
this.append(key2, value.toString("base64"));
|
|
217089
217698
|
return false;
|
|
@@ -217100,14 +217709,14 @@ var require_axios = __commonJS({
|
|
|
217100
217709
|
}
|
|
217101
217710
|
}
|
|
217102
217711
|
function parsePropPath2(name) {
|
|
217103
|
-
const
|
|
217712
|
+
const path6 = [];
|
|
217104
217713
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
217105
217714
|
let match;
|
|
217106
217715
|
while ((match = pattern.exec(name)) !== null) {
|
|
217107
|
-
throwIfDepthExceeded2(
|
|
217108
|
-
|
|
217716
|
+
throwIfDepthExceeded2(path6.length);
|
|
217717
|
+
path6.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
217109
217718
|
}
|
|
217110
|
-
return
|
|
217719
|
+
return path6;
|
|
217111
217720
|
}
|
|
217112
217721
|
function arrayToObject2(arr) {
|
|
217113
217722
|
const obj = {};
|
|
@@ -217122,12 +217731,12 @@ var require_axios = __commonJS({
|
|
|
217122
217731
|
return obj;
|
|
217123
217732
|
}
|
|
217124
217733
|
function formDataToJSON2(formData) {
|
|
217125
|
-
function buildPath(
|
|
217734
|
+
function buildPath(path6, value, target, index2) {
|
|
217126
217735
|
throwIfDepthExceeded2(index2);
|
|
217127
|
-
let name =
|
|
217736
|
+
let name = path6[index2++];
|
|
217128
217737
|
if (name === "__proto__") return true;
|
|
217129
217738
|
const isNumericKey = Number.isFinite(+name);
|
|
217130
|
-
const isLast = index2 >=
|
|
217739
|
+
const isLast = index2 >= path6.length;
|
|
217131
217740
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
217132
217741
|
if (isLast) {
|
|
217133
217742
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -217140,7 +217749,7 @@ var require_axios = __commonJS({
|
|
|
217140
217749
|
if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
|
|
217141
217750
|
target[name] = [];
|
|
217142
217751
|
}
|
|
217143
|
-
const result = buildPath(
|
|
217752
|
+
const result = buildPath(path6, value, target[name], index2);
|
|
217144
217753
|
if (result && utils$1.isArray(target[name])) {
|
|
217145
217754
|
target[name] = arrayToObject2(target[name]);
|
|
217146
217755
|
}
|
|
@@ -218751,8 +219360,8 @@ var require_axios = __commonJS({
|
|
|
218751
219360
|
const allowedSocketPaths = own3("allowedSocketPaths");
|
|
218752
219361
|
if (allowedSocketPaths != null) {
|
|
218753
219362
|
const allowed = Array.isArray(allowedSocketPaths) ? allowedSocketPaths : [allowedSocketPaths];
|
|
218754
|
-
const resolvedSocket =
|
|
218755
|
-
const isAllowed = allowed.some((entry) => typeof entry === "string" &&
|
|
219363
|
+
const resolvedSocket = path5.resolve(socketPath);
|
|
219364
|
+
const isAllowed = allowed.some((entry) => typeof entry === "string" && path5.resolve(entry) === resolvedSocket);
|
|
218756
219365
|
if (!isAllowed) {
|
|
218757
219366
|
return reject(new AxiosError3(`socketPath "${socketPath}" is not permitted by allowedSocketPaths`, AxiosError3.ERR_BAD_OPTION_VALUE, config));
|
|
218758
219367
|
}
|
|
@@ -219051,14 +219660,14 @@ var require_axios = __commonJS({
|
|
|
219051
219660
|
var cookies = platform2.hasStandardBrowserEnv ? (
|
|
219052
219661
|
// Standard browser envs support document.cookie
|
|
219053
219662
|
{
|
|
219054
|
-
write(name, value, expires,
|
|
219663
|
+
write(name, value, expires, path6, domain, secure, sameSite) {
|
|
219055
219664
|
if (typeof document === "undefined") return;
|
|
219056
219665
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
219057
219666
|
if (utils$1.isNumber(expires)) {
|
|
219058
219667
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
219059
219668
|
}
|
|
219060
|
-
if (utils$1.isString(
|
|
219061
|
-
cookie.push(`path=${
|
|
219669
|
+
if (utils$1.isString(path6)) {
|
|
219670
|
+
cookie.push(`path=${path6}`);
|
|
219062
219671
|
}
|
|
219063
219672
|
if (utils$1.isString(domain)) {
|
|
219064
219673
|
cookie.push(`domain=${domain}`);
|
|
@@ -223547,18 +224156,18 @@ var require_client2 = __commonJS({
|
|
|
223547
224156
|
}
|
|
223548
224157
|
console.log(`Transaction not found or not in given states, timing out!`);
|
|
223549
224158
|
}
|
|
223550
|
-
async sendAuthedRequest(method,
|
|
224159
|
+
async sendAuthedRequest(method, path5, body) {
|
|
223551
224160
|
if (this.canBuilderAuth()) {
|
|
223552
|
-
const builderHeaders = await this._generateBuilderHeaders(method,
|
|
224161
|
+
const builderHeaders = await this._generateBuilderHeaders(method, path5, body);
|
|
223553
224162
|
if (builderHeaders !== void 0) {
|
|
223554
|
-
return this.send(
|
|
224163
|
+
return this.send(path5, method, { headers: builderHeaders, data: body });
|
|
223555
224164
|
}
|
|
223556
224165
|
}
|
|
223557
|
-
return this.send(
|
|
224166
|
+
return this.send(path5, method, { data: body });
|
|
223558
224167
|
}
|
|
223559
|
-
async _generateBuilderHeaders(method,
|
|
224168
|
+
async _generateBuilderHeaders(method, path5, body) {
|
|
223560
224169
|
if (this.builderConfig !== void 0) {
|
|
223561
|
-
const builderHeaders = await this.builderConfig.generateBuilderHeaders(method,
|
|
224170
|
+
const builderHeaders = await this.builderConfig.generateBuilderHeaders(method, path5, body);
|
|
223562
224171
|
if (builderHeaders == void 0) {
|
|
223563
224172
|
return void 0;
|
|
223564
224173
|
}
|
|
@@ -223649,12 +224258,12 @@ var require_signer = __commonJS({
|
|
|
223649
224258
|
constructor(creds) {
|
|
223650
224259
|
this.creds = creds;
|
|
223651
224260
|
}
|
|
223652
|
-
createBuilderHeaderPayload(method,
|
|
224261
|
+
createBuilderHeaderPayload(method, path5, body, timestamp) {
|
|
223653
224262
|
let ts = Math.floor(Date.now() / 1e3);
|
|
223654
224263
|
if (timestamp !== void 0) {
|
|
223655
224264
|
ts = timestamp;
|
|
223656
224265
|
}
|
|
223657
|
-
const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method,
|
|
224266
|
+
const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method, path5, body);
|
|
223658
224267
|
return {
|
|
223659
224268
|
POLY_BUILDER_API_KEY: this.creds.key,
|
|
223660
224269
|
POLY_BUILDER_PASSPHRASE: this.creds.passphrase,
|
|
@@ -223743,17 +224352,17 @@ var require_config2 = __commonJS({
|
|
|
223743
224352
|
* @param path
|
|
223744
224353
|
* @param body
|
|
223745
224354
|
*/
|
|
223746
|
-
async generateBuilderHeaders(method,
|
|
224355
|
+
async generateBuilderHeaders(method, path5, body, timestamp) {
|
|
223747
224356
|
this.ensureValid();
|
|
223748
224357
|
const builderType = this.getBuilderType();
|
|
223749
224358
|
if (builderType == types_1.BuilderType.LOCAL) {
|
|
223750
|
-
return Promise.resolve(this.signer?.createBuilderHeaderPayload(method,
|
|
224359
|
+
return Promise.resolve(this.signer?.createBuilderHeaderPayload(method, path5, body, timestamp));
|
|
223751
224360
|
}
|
|
223752
224361
|
if (builderType == types_1.BuilderType.REMOTE) {
|
|
223753
224362
|
const url2 = this.remoteBuilderConfig.url;
|
|
223754
224363
|
const payload = {
|
|
223755
224364
|
method,
|
|
223756
|
-
path:
|
|
224365
|
+
path: path5,
|
|
223757
224366
|
body,
|
|
223758
224367
|
timestamp
|
|
223759
224368
|
};
|
|
@@ -224535,11 +225144,11 @@ var init_withdraw = __esm({
|
|
|
224535
225144
|
});
|
|
224536
225145
|
|
|
224537
225146
|
// node_modules/@blockrun/llm/dist/index.js
|
|
224538
|
-
import * as
|
|
225147
|
+
import * as path3 from "path";
|
|
224539
225148
|
import * as os2 from "os";
|
|
224540
225149
|
import * as path22 from "path";
|
|
224541
225150
|
import * as os22 from "os";
|
|
224542
|
-
import * as
|
|
225151
|
+
import * as path32 from "path";
|
|
224543
225152
|
import * as os3 from "os";
|
|
224544
225153
|
import * as path4 from "path";
|
|
224545
225154
|
import * as os4 from "os";
|
|
@@ -224713,7 +225322,7 @@ function resolveDefaultTimeout() {
|
|
|
224713
225322
|
function sleep2(ms) {
|
|
224714
225323
|
return new Promise((r2) => setTimeout(r2, ms));
|
|
224715
225324
|
}
|
|
224716
|
-
var BlockrunError, PaymentError, APIError, BASE_CHAIN_ID2, USDC_BASE2, USDC_DOMAIN, TRANSFER_TYPES, BLOCKRUN_SERVICE_CODE2, LOCALHOST_DOMAINS, BLOCKRUN_DIR2, COST_LOG_FILE, SDK_VERSION, USER_AGENT2, DEFAULT_TIMEOUT, PHONE_PRICES, DEFAULT_API_URL13, DEFAULT_TIMEOUT13, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_BUDGET_MS, MAX_SIGNED_AUTH_SECONDS, BlockrunClient,
|
|
225325
|
+
var BlockrunError, PaymentError, APIError, BASE_CHAIN_ID2, USDC_BASE2, USDC_DOMAIN, TRANSFER_TYPES, BLOCKRUN_SERVICE_CODE2, LOCALHOST_DOMAINS, BLOCKRUN_DIR2, COST_LOG_FILE, SDK_VERSION, USER_AGENT2, DEFAULT_TIMEOUT, PHONE_PRICES, DEFAULT_API_URL13, DEFAULT_TIMEOUT13, DEFAULT_POLL_INTERVAL_MS, DEFAULT_POLL_BUDGET_MS, MAX_SIGNED_AUTH_SECONDS, BlockrunClient, WALLET_DIR3, WALLET_FILE3, WALLET_DIR22, SOLANA_WALLET_FILE, CACHE_DIR, DATA_DIR, COST_LOG_FILE2, DEFAULT_TTL;
|
|
224717
225326
|
var init_dist7 = __esm({
|
|
224718
225327
|
"node_modules/@blockrun/llm/dist/index.js"() {
|
|
224719
225328
|
"use strict";
|
|
@@ -224761,8 +225370,8 @@ var init_dist7 = __esm({
|
|
|
224761
225370
|
};
|
|
224762
225371
|
BLOCKRUN_SERVICE_CODE2 = "blockrun";
|
|
224763
225372
|
LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
|
|
224764
|
-
BLOCKRUN_DIR2 =
|
|
224765
|
-
COST_LOG_FILE =
|
|
225373
|
+
BLOCKRUN_DIR2 = path3.join(os2.homedir(), ".blockrun");
|
|
225374
|
+
COST_LOG_FILE = path3.join(BLOCKRUN_DIR2, "cost_log.jsonl");
|
|
224766
225375
|
SDK_VERSION = "3.10.0";
|
|
224767
225376
|
USER_AGENT2 = `blockrun-ts/${SDK_VERSION}`;
|
|
224768
225377
|
DEFAULT_TIMEOUT = resolveDefaultTimeout();
|
|
@@ -224807,15 +225416,15 @@ var init_dist7 = __esm({
|
|
|
224807
225416
|
* `/api` is tolerated and stripped). Query params are URL-encoded; arrays
|
|
224808
225417
|
* become repeated keys (`?a=1&a=2`); undefined/null are dropped.
|
|
224809
225418
|
*/
|
|
224810
|
-
async get(
|
|
224811
|
-
const url2 = this.buildUrl(
|
|
225419
|
+
async get(path5, params) {
|
|
225420
|
+
const url2 = this.buildUrl(path5, params);
|
|
224812
225421
|
return this.requestWithPayment(url2, "GET");
|
|
224813
225422
|
}
|
|
224814
225423
|
/**
|
|
224815
225424
|
* POST a BlockRun endpoint with a JSON body.
|
|
224816
225425
|
*/
|
|
224817
|
-
async post(
|
|
224818
|
-
const url2 = this.buildUrl(
|
|
225426
|
+
async post(path5, body) {
|
|
225427
|
+
const url2 = this.buildUrl(path5);
|
|
224819
225428
|
return this.requestWithPayment(url2, "POST", body);
|
|
224820
225429
|
}
|
|
224821
225430
|
/**
|
|
@@ -224830,8 +225439,8 @@ var init_dist7 = __esm({
|
|
|
224830
225439
|
* short-circuits and returns the body. Most long-running endpoints (image,
|
|
224831
225440
|
* video, music, voice) return 202 with a poll_url.
|
|
224832
225441
|
*/
|
|
224833
|
-
async poll(
|
|
224834
|
-
const submitUrl = this.buildUrl(
|
|
225442
|
+
async poll(path5, body, options) {
|
|
225443
|
+
const submitUrl = this.buildUrl(path5);
|
|
224835
225444
|
const budgetMs = options?.budgetMs ?? DEFAULT_POLL_BUDGET_MS;
|
|
224836
225445
|
const intervalMs = options?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
224837
225446
|
const resp402 = await this.fetchWithTimeout(submitUrl, {
|
|
@@ -224930,8 +225539,8 @@ var init_dist7 = __esm({
|
|
|
224930
225539
|
* process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
|
|
224931
225540
|
* }
|
|
224932
225541
|
*/
|
|
224933
|
-
async *stream(
|
|
224934
|
-
const url2 = this.buildUrl(
|
|
225542
|
+
async *stream(path5, body) {
|
|
225543
|
+
const url2 = this.buildUrl(path5);
|
|
224935
225544
|
const requestBody = JSON.stringify(body ?? {});
|
|
224936
225545
|
const resp402 = await this.fetchWithTimeout(url2, {
|
|
224937
225546
|
method: "POST",
|
|
@@ -224997,8 +225606,8 @@ var init_dist7 = __esm({
|
|
|
224997
225606
|
// --------------------------------------------------------------------
|
|
224998
225607
|
// Internal: shared infrastructure
|
|
224999
225608
|
// --------------------------------------------------------------------
|
|
225000
|
-
buildUrl(
|
|
225001
|
-
let normalized =
|
|
225609
|
+
buildUrl(path5, params) {
|
|
225610
|
+
let normalized = path5.startsWith("/") ? path5 : `/${path5}`;
|
|
225002
225611
|
if (normalized.startsWith("/api/")) {
|
|
225003
225612
|
normalized = normalized.slice(4);
|
|
225004
225613
|
}
|
|
@@ -225146,10 +225755,10 @@ var init_dist7 = __esm({
|
|
|
225146
225755
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
225147
225756
|
}
|
|
225148
225757
|
};
|
|
225149
|
-
|
|
225150
|
-
WALLET_FILE3 = path22.join(
|
|
225151
|
-
WALLET_DIR22 =
|
|
225152
|
-
SOLANA_WALLET_FILE =
|
|
225758
|
+
WALLET_DIR3 = path22.join(os22.homedir(), ".blockrun");
|
|
225759
|
+
WALLET_FILE3 = path22.join(WALLET_DIR3, ".session");
|
|
225760
|
+
WALLET_DIR22 = path32.join(os3.homedir(), ".blockrun");
|
|
225761
|
+
SOLANA_WALLET_FILE = path32.join(WALLET_DIR22, ".solana-session");
|
|
225153
225762
|
CACHE_DIR = path4.join(os4.homedir(), ".blockrun", "cache");
|
|
225154
225763
|
DATA_DIR = path4.join(os4.homedir(), ".blockrun", "data");
|
|
225155
225764
|
COST_LOG_FILE2 = path4.join(os4.homedir(), ".blockrun", "cost_log.jsonl");
|
|
@@ -225645,261 +226254,6 @@ var init_mcp_config = __esm({
|
|
|
225645
226254
|
}
|
|
225646
226255
|
});
|
|
225647
226256
|
|
|
225648
|
-
// src/spend-control.ts
|
|
225649
|
-
import * as fs3 from "fs";
|
|
225650
|
-
import * as path5 from "path";
|
|
225651
|
-
import { homedir as homedir12 } from "os";
|
|
225652
|
-
function formatDuration(seconds) {
|
|
225653
|
-
if (seconds < 60) {
|
|
225654
|
-
return `${seconds}s`;
|
|
225655
|
-
} else if (seconds < 3600) {
|
|
225656
|
-
const mins = Math.ceil(seconds / 60);
|
|
225657
|
-
return `${mins} min`;
|
|
225658
|
-
} else {
|
|
225659
|
-
const hours = Math.floor(seconds / 3600);
|
|
225660
|
-
const mins = Math.ceil(seconds % 3600 / 60);
|
|
225661
|
-
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
225662
|
-
}
|
|
225663
|
-
}
|
|
225664
|
-
var WALLET_DIR3, HOUR_MS, DAY_MS, FileSpendControlStorage, InMemorySpendControlStorage, SpendControl;
|
|
225665
|
-
var init_spend_control = __esm({
|
|
225666
|
-
"src/spend-control.ts"() {
|
|
225667
|
-
"use strict";
|
|
225668
|
-
init_fs_read();
|
|
225669
|
-
WALLET_DIR3 = path5.join(homedir12(), ".openclaw", "blockrun");
|
|
225670
|
-
HOUR_MS = 60 * 60 * 1e3;
|
|
225671
|
-
DAY_MS = 24 * HOUR_MS;
|
|
225672
|
-
FileSpendControlStorage = class {
|
|
225673
|
-
spendingFile;
|
|
225674
|
-
constructor() {
|
|
225675
|
-
this.spendingFile = path5.join(WALLET_DIR3, "spending.json");
|
|
225676
|
-
}
|
|
225677
|
-
load() {
|
|
225678
|
-
try {
|
|
225679
|
-
if (fs3.existsSync(this.spendingFile)) {
|
|
225680
|
-
const data = JSON.parse(readTextFileSync(this.spendingFile));
|
|
225681
|
-
const rawLimits = data.limits ?? {};
|
|
225682
|
-
const rawHistory = data.history ?? [];
|
|
225683
|
-
const limits = {};
|
|
225684
|
-
for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
|
|
225685
|
-
const val = rawLimits[key2];
|
|
225686
|
-
if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
|
|
225687
|
-
limits[key2] = val;
|
|
225688
|
-
}
|
|
225689
|
-
}
|
|
225690
|
-
const history = [];
|
|
225691
|
-
if (Array.isArray(rawHistory)) {
|
|
225692
|
-
for (const r2 of rawHistory) {
|
|
225693
|
-
if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
|
|
225694
|
-
history.push({
|
|
225695
|
-
timestamp: r2.timestamp,
|
|
225696
|
-
amount: r2.amount,
|
|
225697
|
-
model: typeof r2.model === "string" ? r2.model : void 0,
|
|
225698
|
-
action: typeof r2.action === "string" ? r2.action : void 0
|
|
225699
|
-
});
|
|
225700
|
-
}
|
|
225701
|
-
}
|
|
225702
|
-
}
|
|
225703
|
-
return { limits, history };
|
|
225704
|
-
}
|
|
225705
|
-
} catch (err) {
|
|
225706
|
-
console.error(`[ClawRouter] Failed to load spending data, starting fresh: ${err}`);
|
|
225707
|
-
}
|
|
225708
|
-
return null;
|
|
225709
|
-
}
|
|
225710
|
-
save(data) {
|
|
225711
|
-
try {
|
|
225712
|
-
if (!fs3.existsSync(WALLET_DIR3)) {
|
|
225713
|
-
fs3.mkdirSync(WALLET_DIR3, { recursive: true, mode: 448 });
|
|
225714
|
-
}
|
|
225715
|
-
fs3.writeFileSync(this.spendingFile, JSON.stringify(data, null, 2), {
|
|
225716
|
-
mode: 384
|
|
225717
|
-
});
|
|
225718
|
-
} catch (err) {
|
|
225719
|
-
console.error(`[ClawRouter] Failed to save spending data: ${err}`);
|
|
225720
|
-
}
|
|
225721
|
-
}
|
|
225722
|
-
};
|
|
225723
|
-
InMemorySpendControlStorage = class {
|
|
225724
|
-
data = null;
|
|
225725
|
-
load() {
|
|
225726
|
-
return this.data ? {
|
|
225727
|
-
limits: { ...this.data.limits },
|
|
225728
|
-
history: this.data.history.map((r2) => ({ ...r2 }))
|
|
225729
|
-
} : null;
|
|
225730
|
-
}
|
|
225731
|
-
save(data) {
|
|
225732
|
-
this.data = {
|
|
225733
|
-
limits: { ...data.limits },
|
|
225734
|
-
history: data.history.map((r2) => ({ ...r2 }))
|
|
225735
|
-
};
|
|
225736
|
-
}
|
|
225737
|
-
};
|
|
225738
|
-
SpendControl = class {
|
|
225739
|
-
limits = {};
|
|
225740
|
-
history = [];
|
|
225741
|
-
sessionSpent = 0;
|
|
225742
|
-
sessionCalls = 0;
|
|
225743
|
-
storage;
|
|
225744
|
-
now;
|
|
225745
|
-
constructor(options) {
|
|
225746
|
-
this.storage = options?.storage ?? new FileSpendControlStorage();
|
|
225747
|
-
this.now = options?.now ?? (() => Date.now());
|
|
225748
|
-
this.load();
|
|
225749
|
-
}
|
|
225750
|
-
setLimit(window2, amount) {
|
|
225751
|
-
if (!Number.isFinite(amount) || amount <= 0) {
|
|
225752
|
-
throw new Error("Limit must be a finite positive number");
|
|
225753
|
-
}
|
|
225754
|
-
this.limits[window2] = amount;
|
|
225755
|
-
this.save();
|
|
225756
|
-
}
|
|
225757
|
-
clearLimit(window2) {
|
|
225758
|
-
delete this.limits[window2];
|
|
225759
|
-
this.save();
|
|
225760
|
-
}
|
|
225761
|
-
getLimits() {
|
|
225762
|
-
return { ...this.limits };
|
|
225763
|
-
}
|
|
225764
|
-
check(estimatedCost2) {
|
|
225765
|
-
const now2 = this.now();
|
|
225766
|
-
if (this.limits.perRequest !== void 0) {
|
|
225767
|
-
if (estimatedCost2 > this.limits.perRequest) {
|
|
225768
|
-
return {
|
|
225769
|
-
allowed: false,
|
|
225770
|
-
blockedBy: "perRequest",
|
|
225771
|
-
remaining: this.limits.perRequest,
|
|
225772
|
-
reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
|
|
225773
|
-
};
|
|
225774
|
-
}
|
|
225775
|
-
}
|
|
225776
|
-
if (this.limits.hourly !== void 0) {
|
|
225777
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225778
|
-
const remaining = this.limits.hourly - hourlySpent;
|
|
225779
|
-
if (estimatedCost2 > remaining) {
|
|
225780
|
-
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
225781
|
-
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
|
|
225782
|
-
return {
|
|
225783
|
-
allowed: false,
|
|
225784
|
-
blockedBy: "hourly",
|
|
225785
|
-
remaining,
|
|
225786
|
-
reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
|
|
225787
|
-
resetIn
|
|
225788
|
-
};
|
|
225789
|
-
}
|
|
225790
|
-
}
|
|
225791
|
-
if (this.limits.daily !== void 0) {
|
|
225792
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225793
|
-
const remaining = this.limits.daily - dailySpent;
|
|
225794
|
-
if (estimatedCost2 > remaining) {
|
|
225795
|
-
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
225796
|
-
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
|
|
225797
|
-
return {
|
|
225798
|
-
allowed: false,
|
|
225799
|
-
blockedBy: "daily",
|
|
225800
|
-
remaining,
|
|
225801
|
-
reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
|
|
225802
|
-
resetIn
|
|
225803
|
-
};
|
|
225804
|
-
}
|
|
225805
|
-
}
|
|
225806
|
-
if (this.limits.session !== void 0) {
|
|
225807
|
-
const remaining = this.limits.session - this.sessionSpent;
|
|
225808
|
-
if (estimatedCost2 > remaining) {
|
|
225809
|
-
return {
|
|
225810
|
-
allowed: false,
|
|
225811
|
-
blockedBy: "session",
|
|
225812
|
-
remaining,
|
|
225813
|
-
reason: `Session limit exceeded: $${(this.sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
|
|
225814
|
-
};
|
|
225815
|
-
}
|
|
225816
|
-
}
|
|
225817
|
-
return { allowed: true };
|
|
225818
|
-
}
|
|
225819
|
-
record(amount, metadata) {
|
|
225820
|
-
if (!Number.isFinite(amount) || amount < 0) {
|
|
225821
|
-
throw new Error("Record amount must be a non-negative finite number");
|
|
225822
|
-
}
|
|
225823
|
-
const record = {
|
|
225824
|
-
timestamp: this.now(),
|
|
225825
|
-
amount,
|
|
225826
|
-
model: metadata?.model,
|
|
225827
|
-
action: metadata?.action
|
|
225828
|
-
};
|
|
225829
|
-
this.history.push(record);
|
|
225830
|
-
this.sessionSpent += amount;
|
|
225831
|
-
this.sessionCalls += 1;
|
|
225832
|
-
this.cleanup();
|
|
225833
|
-
this.save();
|
|
225834
|
-
}
|
|
225835
|
-
getSpendingInWindow(from15, to) {
|
|
225836
|
-
return this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
225837
|
-
}
|
|
225838
|
-
getSpending(window2) {
|
|
225839
|
-
const now2 = this.now();
|
|
225840
|
-
switch (window2) {
|
|
225841
|
-
case "hourly":
|
|
225842
|
-
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225843
|
-
case "daily":
|
|
225844
|
-
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225845
|
-
case "session":
|
|
225846
|
-
return this.sessionSpent;
|
|
225847
|
-
}
|
|
225848
|
-
}
|
|
225849
|
-
getRemaining(window2) {
|
|
225850
|
-
const limit = this.limits[window2];
|
|
225851
|
-
if (limit === void 0) return null;
|
|
225852
|
-
return Math.max(0, limit - this.getSpending(window2));
|
|
225853
|
-
}
|
|
225854
|
-
getStatus() {
|
|
225855
|
-
const now2 = this.now();
|
|
225856
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225857
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225858
|
-
return {
|
|
225859
|
-
limits: { ...this.limits },
|
|
225860
|
-
spending: {
|
|
225861
|
-
hourly: hourlySpent,
|
|
225862
|
-
daily: dailySpent,
|
|
225863
|
-
session: this.sessionSpent
|
|
225864
|
-
},
|
|
225865
|
-
remaining: {
|
|
225866
|
-
hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
|
|
225867
|
-
daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
|
|
225868
|
-
session: this.limits.session !== void 0 ? this.limits.session - this.sessionSpent : null
|
|
225869
|
-
},
|
|
225870
|
-
calls: this.sessionCalls
|
|
225871
|
-
};
|
|
225872
|
-
}
|
|
225873
|
-
getHistory(limit) {
|
|
225874
|
-
const records = [...this.history].reverse();
|
|
225875
|
-
return limit ? records.slice(0, limit) : records;
|
|
225876
|
-
}
|
|
225877
|
-
resetSession() {
|
|
225878
|
-
this.sessionSpent = 0;
|
|
225879
|
-
this.sessionCalls = 0;
|
|
225880
|
-
}
|
|
225881
|
-
cleanup() {
|
|
225882
|
-
const cutoff = this.now() - DAY_MS;
|
|
225883
|
-
this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
|
|
225884
|
-
}
|
|
225885
|
-
save() {
|
|
225886
|
-
this.storage.save({
|
|
225887
|
-
limits: { ...this.limits },
|
|
225888
|
-
history: [...this.history]
|
|
225889
|
-
});
|
|
225890
|
-
}
|
|
225891
|
-
load() {
|
|
225892
|
-
const data = this.storage.load();
|
|
225893
|
-
if (data) {
|
|
225894
|
-
this.limits = data.limits;
|
|
225895
|
-
this.history = data.history;
|
|
225896
|
-
this.cleanup();
|
|
225897
|
-
}
|
|
225898
|
-
}
|
|
225899
|
-
};
|
|
225900
|
-
}
|
|
225901
|
-
});
|
|
225902
|
-
|
|
225903
226257
|
// src/retry.ts
|
|
225904
226258
|
function sleep3(ms) {
|
|
225905
226259
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -225968,6 +226322,8 @@ __export(index_exports, {
|
|
|
225968
226322
|
BALANCE_THRESHOLDS: () => BALANCE_THRESHOLDS,
|
|
225969
226323
|
BLOCKRUN_MODELS: () => BLOCKRUN_MODELS,
|
|
225970
226324
|
BalanceMonitor: () => BalanceMonitor,
|
|
226325
|
+
CAIP2_BASE: () => CAIP2_BASE,
|
|
226326
|
+
CAIP2_SOLANA_MAINNET: () => CAIP2_SOLANA_MAINNET,
|
|
225971
226327
|
DEFAULT_RETRY_CONFIG: () => DEFAULT_RETRY_CONFIG,
|
|
225972
226328
|
DEFAULT_ROUTING_CONFIG: () => DEFAULT_ROUTING_CONFIG,
|
|
225973
226329
|
DEFAULT_SESSION_CONFIG: () => DEFAULT_SESSION_CONFIG,
|
|
@@ -225976,6 +226332,7 @@ __export(index_exports, {
|
|
|
225976
226332
|
InMemorySpendControlStorage: () => InMemorySpendControlStorage,
|
|
225977
226333
|
InsufficientFundsError: () => InsufficientFundsError2,
|
|
225978
226334
|
MODEL_ALIASES: () => MODEL_ALIASES,
|
|
226335
|
+
MalformedSpendPolicyError: () => MalformedSpendPolicyError,
|
|
225979
226336
|
OPENCLAW_MODELS: () => OPENCLAW_MODELS,
|
|
225980
226337
|
PARTNER_SERVICES: () => PARTNER_SERVICES,
|
|
225981
226338
|
RequestDeduplicator: () => RequestDeduplicator,
|
|
@@ -225984,6 +226341,7 @@ __export(index_exports, {
|
|
|
225984
226341
|
SessionStore: () => SessionStore,
|
|
225985
226342
|
SolanaBalanceMonitor: () => SolanaBalanceMonitor,
|
|
225986
226343
|
SpendControl: () => SpendControl,
|
|
226344
|
+
SpendPolicyError: () => SpendPolicyError,
|
|
225987
226345
|
VISIBLE_OPENCLAW_MODELS: () => VISIBLE_OPENCLAW_MODELS,
|
|
225988
226346
|
blockrunProvider: () => blockrunProvider,
|
|
225989
226347
|
buildImageGenerationProvider: () => buildImageGenerationProvider,
|
|
@@ -226023,6 +226381,7 @@ __export(index_exports, {
|
|
|
226023
226381
|
loadPaymentChain: () => loadPaymentChain,
|
|
226024
226382
|
logUsage: () => logUsage,
|
|
226025
226383
|
parseCallArgs: () => parseCallArgs,
|
|
226384
|
+
registerSpendPolicyHook: () => registerSpendPolicyHook,
|
|
226026
226385
|
resolveModelAlias: () => resolveModelAlias,
|
|
226027
226386
|
resolvePaymentChain: () => resolvePaymentChain,
|
|
226028
226387
|
route: () => route,
|
|
@@ -226037,7 +226396,7 @@ import {
|
|
|
226037
226396
|
readdirSync,
|
|
226038
226397
|
mkdirSync as mkdirSync3,
|
|
226039
226398
|
copyFileSync,
|
|
226040
|
-
renameSync
|
|
226399
|
+
renameSync as renameSync2
|
|
226041
226400
|
} from "fs";
|
|
226042
226401
|
import { readFile as readFileAsync } from "fs/promises";
|
|
226043
226402
|
import { homedir as homedir13 } from "os";
|
|
@@ -226315,7 +226674,7 @@ function injectModelsConfig(logger48, options = {}) {
|
|
|
226315
226674
|
try {
|
|
226316
226675
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
226317
226676
|
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
226318
|
-
|
|
226677
|
+
renameSync2(tmpPath, configPath);
|
|
226319
226678
|
logger48.info("Smart routing enabled (blockrun/auto)");
|
|
226320
226679
|
} catch (err) {
|
|
226321
226680
|
logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -226351,7 +226710,7 @@ function syncAgentModelCache(logger48, options = {}) {
|
|
|
226351
226710
|
entry.models = VISIBLE_OPENCLAW_MODELS;
|
|
226352
226711
|
const tmpPath = `${cachePath}.tmp.${process.pid}`;
|
|
226353
226712
|
writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
|
|
226354
|
-
|
|
226713
|
+
renameSync2(tmpPath, cachePath);
|
|
226355
226714
|
logger48.info(
|
|
226356
226715
|
`Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
|
|
226357
226716
|
);
|
|
@@ -227715,7 +228074,7 @@ ${errText}`
|
|
|
227715
228074
|
}
|
|
227716
228075
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
227717
228076
|
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
227718
|
-
|
|
228077
|
+
renameSync2(tmpPath, configPath);
|
|
227719
228078
|
api.logger.info("ClawRouter config cleaned up");
|
|
227720
228079
|
}
|
|
227721
228080
|
} catch (err) {
|
|
@@ -227810,7 +228169,7 @@ init_stats();
|
|
|
227810
228169
|
init_proxy();
|
|
227811
228170
|
init_version4();
|
|
227812
228171
|
import { platform, arch, freemem, totalmem } from "os";
|
|
227813
|
-
import { existsSync as
|
|
228172
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
227814
228173
|
function formatBytes(bytes) {
|
|
227815
228174
|
const gb = bytes / (1024 * 1024 * 1024);
|
|
227816
228175
|
return `${gb.toFixed(1)}GB`;
|
|
@@ -228099,7 +228458,7 @@ async function analyzeWithAI(diagnostics, userQuestion, model = "sonnet") {
|
|
|
228099
228458
|
const paymentChain = diagnostics.wallet.paymentChain;
|
|
228100
228459
|
if (paymentChain === "solana") {
|
|
228101
228460
|
try {
|
|
228102
|
-
if (!
|
|
228461
|
+
if (!existsSync3(MNEMONIC_FILE)) {
|
|
228103
228462
|
throw new Error(`mnemonic file missing at ${MNEMONIC_FILE}`);
|
|
228104
228463
|
}
|
|
228105
228464
|
const mnemonic = readFileSync3(MNEMONIC_FILE, "utf8").trim();
|
|
@@ -228262,8 +228621,8 @@ Environment Variables:
|
|
|
228262
228621
|
For more info: https://blockrun.ai/clawrouter.md
|
|
228263
228622
|
`);
|
|
228264
228623
|
}
|
|
228265
|
-
async function queryProxy(
|
|
228266
|
-
const res = await fetch(`http://127.0.0.1:${port}${
|
|
228624
|
+
async function queryProxy(path5, port) {
|
|
228625
|
+
const res = await fetch(`http://127.0.0.1:${port}${path5}`);
|
|
228267
228626
|
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
|
|
228268
228627
|
return res.json();
|
|
228269
228628
|
}
|
|
@@ -228343,8 +228702,8 @@ Use: clawrouter share <id> --as=<feishu|slack|discord|telegram|whatsapp|plain>
|
|
|
228343
228702
|
const { join: pjoin } = await import("path");
|
|
228344
228703
|
const paths = [];
|
|
228345
228704
|
for (const p of VALID_PRESETS) {
|
|
228346
|
-
const
|
|
228347
|
-
const result = await queryProxy(
|
|
228705
|
+
const path5 = idOrLast === "last" ? `/share/last?as=${p}` : `/share/${idOrLast}/render?as=${p}`;
|
|
228706
|
+
const result = await queryProxy(path5, port);
|
|
228348
228707
|
const file = pjoin(tmpdir(), `claw-share-${result.id}-${p}.txt`);
|
|
228349
228708
|
await writeFile3(file, result.rendered, "utf8");
|
|
228350
228709
|
paths.push(file);
|
|
@@ -228365,8 +228724,8 @@ Use: clawrouter share <id> --as=<feishu|slack|discord|telegram|whatsapp|plain>
|
|
|
228365
228724
|
process.exit(1);
|
|
228366
228725
|
}
|
|
228367
228726
|
try {
|
|
228368
|
-
const
|
|
228369
|
-
const result = await queryProxy(
|
|
228727
|
+
const path5 = idOrLast === "last" ? `/share/last?as=${chosenPreset}` : `/share/${idOrLast}/render?as=${chosenPreset}`;
|
|
228728
|
+
const result = await queryProxy(path5, port);
|
|
228370
228729
|
process.stdout.write(result.rendered);
|
|
228371
228730
|
if (!result.rendered.endsWith("\n")) process.stdout.write("\n");
|
|
228372
228731
|
const clipErr = await copyToClipboard(result.rendered);
|
|
@@ -228486,8 +228845,8 @@ Usage Stats (last ${days} days)
|
|
|
228486
228845
|
}
|
|
228487
228846
|
async function cmdPhone(port, subcommand, numbersAction, arg, areaCode) {
|
|
228488
228847
|
const base3 = `http://127.0.0.1:${port}`;
|
|
228489
|
-
async function postJson(
|
|
228490
|
-
const resp = await fetch(`${base3}${
|
|
228848
|
+
async function postJson(path5, body) {
|
|
228849
|
+
const resp = await fetch(`${base3}${path5}`, {
|
|
228491
228850
|
method: "POST",
|
|
228492
228851
|
headers: { "content-type": "application/json" },
|
|
228493
228852
|
body: JSON.stringify(body)
|
|
@@ -228589,12 +228948,12 @@ Releasing ${arg}...
|
|
|
228589
228948
|
console.error(`\u2717 Usage: clawrouter phone ${subcommand} <+E.164-number>`);
|
|
228590
228949
|
process.exit(1);
|
|
228591
228950
|
}
|
|
228592
|
-
const
|
|
228951
|
+
const path5 = subcommand === "fraud" ? "/v1/phone/lookup/fraud" : "/v1/phone/lookup";
|
|
228593
228952
|
const price = subcommand === "fraud" ? "$0.05" : "$0.01";
|
|
228594
228953
|
console.log(`
|
|
228595
228954
|
Looking up ${arg}... (${price})
|
|
228596
228955
|
`);
|
|
228597
|
-
const result = await postJson(
|
|
228956
|
+
const result = await postJson(path5, { phoneNumber: arg });
|
|
228598
228957
|
console.log(JSON.stringify(result, null, 2));
|
|
228599
228958
|
console.log();
|
|
228600
228959
|
}
|