@blockrun/clawrouter 0.12.256 → 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 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: path6, errorMaps, issueData } = params;
27430
- const fullPath = [...path6, ...issueData.path || []];
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, path6, key2) {
27741
+ constructor(parent, value, path5, key2) {
27742
27742
  this._cachedPath = [];
27743
27743
  this.parent = parent;
27744
27744
  this.data = value;
27745
- this._path = path6;
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 join2 } from "path";
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 = join2(LOG_DIR, `usage-${date}.jsonl`);
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 = join2(homedir(), ".openclaw", "blockrun", "logs");
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 join3 } from "path";
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(join3(__dirname, "..", "package.json"));
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 join4 } from "path";
39003
- import { homedir as homedir2 } from "os";
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 = join4(LOG_DIR2, file);
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(join4(LOG_DIR2, file));
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(join4(LOG_DIR2, f))));
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,7 @@ var init_stats = __esm({
39248
39818
  "use strict";
39249
39819
  init_fs_read();
39250
39820
  init_version4();
39251
- LOG_DIR2 = join4(homedir2(), ".openclaw", "blockrun", "logs");
39821
+ LOG_DIR2 = join5(homedir3(), ".openclaw", "blockrun", "logs");
39252
39822
  }
39253
39823
  });
39254
39824
 
@@ -43067,7 +43637,7 @@ function alphabet2(letters) {
43067
43637
  };
43068
43638
  }
43069
43639
  // @__NO_SIDE_EFFECTS__
43070
- function join5(separator = "") {
43640
+ function join6(separator = "") {
43071
43641
  astr2("join", separator);
43072
43642
  return {
43073
43643
  encode: (from15) => {
@@ -43177,7 +43747,7 @@ var genBase58, base58, createBase58check;
43177
43747
  var init_base3 = __esm({
43178
43748
  "node_modules/@scure/base/index.js"() {
43179
43749
  "use strict";
43180
- genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join5(""));
43750
+ genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join6(""));
43181
43751
  base58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"));
43182
43752
  createBase58check = (sha25610) => {
43183
43753
  afn2(sha25610);
@@ -43326,14 +43896,14 @@ var init_bip32 = __esm({
43326
43896
  }
43327
43897
  this.pubHash = hash160(this._publicKey);
43328
43898
  }
43329
- derive(path6) {
43330
- if (!/^[mM]'?/.test(path6)) {
43899
+ derive(path5) {
43900
+ if (!/^[mM]'?/.test(path5)) {
43331
43901
  throw new Error('Path must start with "m" or "M"');
43332
43902
  }
43333
- if (/^[mM]'?$/.test(path6)) {
43903
+ if (/^[mM]'?$/.test(path5)) {
43334
43904
  return this;
43335
43905
  }
43336
- const parts = path6.replace(/^[mM]'?\//, "").split("/");
43906
+ const parts = path5.replace(/^[mM]'?\//, "").split("/");
43337
43907
  let child = this;
43338
43908
  for (const c of parts) {
43339
43909
  const m = /^(\d+)('?)$/.exec(c);
@@ -51623,14 +52193,14 @@ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
51623
52193
  } else {
51624
52194
  argumentLabel = `\`${keyPath[0].toString()}\``;
51625
52195
  }
51626
- const path6 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
52196
+ const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
51627
52197
  const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
51628
52198
  argumentLabel,
51629
52199
  keyPath,
51630
52200
  methodName,
51631
- optionalPathLabel: path6 ? ` at path \`${path6}\`` : "",
52201
+ optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
51632
52202
  value,
51633
- ...path6 !== void 0 ? { path: path6 } : void 0
52203
+ ...path5 !== void 0 ? { path: path5 } : void 0
51634
52204
  });
51635
52205
  safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);
51636
52206
  return error;
@@ -56294,14 +56864,14 @@ function createSolanaJsonRpcIntegerOverflowError2(methodName, keyPath, value) {
56294
56864
  } else {
56295
56865
  argumentLabel = `\`${keyPath[0].toString()}\``;
56296
56866
  }
56297
- const path6 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
56867
+ const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
56298
56868
  const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
56299
56869
  argumentLabel,
56300
56870
  keyPath,
56301
56871
  methodName,
56302
- optionalPathLabel: path6 ? ` at path \`${path6}\`` : "",
56872
+ optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
56303
56873
  value,
56304
- ...path6 !== void 0 ? { path: path6 } : void 0
56874
+ ...path5 !== void 0 ? { path: path5 } : void 0
56305
56875
  });
56306
56876
  safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError2);
56307
56877
  return error;
@@ -58381,8 +58951,8 @@ __export(auth_exports, {
58381
58951
  setupSolana: () => setupSolana
58382
58952
  });
58383
58953
  import { writeFile, mkdir as mkdir2 } from "fs/promises";
58384
- import { join as join6 } from "path";
58385
- import { homedir as homedir3 } from "os";
58954
+ import { join as join7 } from "path";
58955
+ import { homedir as homedir4 } from "os";
58386
58956
  async function loadSavedWallet() {
58387
58957
  try {
58388
58958
  const key2 = (await readTextFile(WALLET_FILE)).trim();
@@ -58431,7 +59001,7 @@ async function loadMnemonic() {
58431
59001
  return void 0;
58432
59002
  }
58433
59003
  async function saveMnemonic(mnemonic) {
58434
- await mkdir2(WALLET_DIR, { recursive: true });
59004
+ await mkdir2(WALLET_DIR2, { recursive: true });
58435
59005
  await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
58436
59006
  }
58437
59007
  async function generateAndSaveWallet() {
@@ -58450,7 +59020,7 @@ Then run: npx @blockrun/clawrouter`
58450
59020
  }
58451
59021
  const mnemonic = generateWalletMnemonic();
58452
59022
  const derived = deriveAllKeys(mnemonic);
58453
- await mkdir2(WALLET_DIR, { recursive: true });
59023
+ await mkdir2(WALLET_DIR2, { recursive: true });
58454
59024
  await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
58455
59025
  await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
58456
59026
  try {
@@ -58583,7 +59153,7 @@ async function recoverWalletFromMnemonic() {
58583
59153
  console.log(`[ClawRouter] wallet, recovery is safe to proceed.`);
58584
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`);
58585
59155
  console.log(`[ClawRouter]`);
58586
- await mkdir2(WALLET_DIR, { recursive: true });
59156
+ await mkdir2(WALLET_DIR2, { recursive: true });
58587
59157
  await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
58588
59158
  console.log(`[ClawRouter] \u2713 wallet.key restored at ${WALLET_FILE}`);
58589
59159
  console.log(`[ClawRouter] Run: npx @blockrun/clawrouter`);
@@ -58609,7 +59179,7 @@ async function setupSolana() {
58609
59179
  return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
58610
59180
  }
58611
59181
  async function savePaymentChain(chain3) {
58612
- await mkdir2(WALLET_DIR, { recursive: true });
59182
+ await mkdir2(WALLET_DIR2, { recursive: true });
58613
59183
  await writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
58614
59184
  }
58615
59185
  async function loadPaymentChain() {
@@ -58626,17 +59196,17 @@ async function resolvePaymentChain() {
58626
59196
  if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
58627
59197
  return loadPaymentChain();
58628
59198
  }
58629
- var WALLET_DIR, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
59199
+ var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
58630
59200
  var init_auth = __esm({
58631
59201
  "src/auth.ts"() {
58632
59202
  "use strict";
58633
59203
  init_fs_read();
58634
59204
  init_accounts();
58635
59205
  init_wallet2();
58636
- WALLET_DIR = join6(homedir3(), ".openclaw", "blockrun");
58637
- WALLET_FILE = join6(WALLET_DIR, "wallet.key");
58638
- MNEMONIC_FILE = join6(WALLET_DIR, "mnemonic");
58639
- CHAIN_FILE = join6(WALLET_DIR, "payment-chain");
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");
58640
59210
  }
58641
59211
  });
58642
59212
 
@@ -58795,7 +59365,7 @@ function generateCodebookHeader(usedCodes, pathMap = {}) {
58795
59365
  parts.push(`[Dict: ${codeEntries}]`);
58796
59366
  }
58797
59367
  if (Object.keys(pathMap).length > 0) {
58798
- const pathEntries = Object.entries(pathMap).map(([code, path6]) => `${code}=${path6}`).join(", ");
59368
+ const pathEntries = Object.entries(pathMap).map(([code, path5]) => `${code}=${path5}`).join(", ");
58799
59369
  parts.push(`[Paths: ${pathEntries}]`);
58800
59370
  }
58801
59371
  return parts.join("\n");
@@ -58943,8 +59513,8 @@ function extractPaths(messages) {
58943
59513
  }
58944
59514
  function findFrequentPrefixes(paths) {
58945
59515
  const prefixCounts = /* @__PURE__ */ new Map();
58946
- for (const path6 of paths) {
58947
- const parts = path6.split("/").filter(Boolean);
59516
+ for (const path5 of paths) {
59517
+ const parts = path5.split("/").filter(Boolean);
58948
59518
  for (let i = 2; i < parts.length; i++) {
58949
59519
  const prefix = "/" + parts.slice(0, i).join("/") + "/";
58950
59520
  prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1);
@@ -59728,9 +60298,9 @@ var init_updater = __esm({
59728
60298
  });
59729
60299
 
59730
60300
  // src/exclude-models.ts
59731
- import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
59732
- import { join as join7, dirname as dirname2 } from "path";
59733
- import { homedir as homedir4 } from "os";
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";
59734
60304
  function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
59735
60305
  try {
59736
60306
  const mtimeMs = statSync(filePath).mtimeMs;
@@ -59751,8 +60321,8 @@ function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
59751
60321
  function saveExcludeList(set, filePath) {
59752
60322
  const sorted = [...set].sort();
59753
60323
  const dir = dirname2(filePath);
59754
- mkdirSync(dir, { recursive: true });
59755
- writeFileSync(filePath, JSON.stringify(sorted, null, 2) + "\n", "utf-8");
60324
+ mkdirSync2(dir, { recursive: true });
60325
+ writeFileSync2(filePath, JSON.stringify(sorted, null, 2) + "\n", "utf-8");
59756
60326
  loadCache.delete(filePath);
59757
60327
  }
59758
60328
  function addExclusion(model, filePath = DEFAULT_FILE_PATH) {
@@ -59779,7 +60349,7 @@ var init_exclude_models = __esm({
59779
60349
  "src/exclude-models.ts"() {
59780
60350
  "use strict";
59781
60351
  init_models();
59782
- DEFAULT_FILE_PATH = join7(homedir4(), ".openclaw", "blockrun", "exclude-models.json");
60352
+ DEFAULT_FILE_PATH = join8(homedir5(), ".openclaw", "blockrun", "exclude-models.json");
59783
60353
  loadCache = /* @__PURE__ */ new Map();
59784
60354
  }
59785
60355
  });
@@ -61084,14 +61654,14 @@ var require_util = __commonJS({
61084
61654
  }
61085
61655
  const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
61086
61656
  let origin2 = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
61087
- let path6 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
61657
+ let path5 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
61088
61658
  if (origin2[origin2.length - 1] === "/") {
61089
61659
  origin2 = origin2.slice(0, origin2.length - 1);
61090
61660
  }
61091
- if (path6 && path6[0] !== "/") {
61092
- path6 = `/${path6}`;
61661
+ if (path5 && path5[0] !== "/") {
61662
+ path5 = `/${path5}`;
61093
61663
  }
61094
- return new URL(`${origin2}${path6}`);
61664
+ return new URL(`${origin2}${path5}`);
61095
61665
  }
61096
61666
  if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
61097
61667
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -61962,9 +62532,9 @@ var require_diagnostics = __commonJS({
61962
62532
  "undici:client:sendHeaders",
61963
62533
  (evt) => {
61964
62534
  const {
61965
- request: { method, path: path6, origin: origin2 }
62535
+ request: { method, path: path5, origin: origin2 }
61966
62536
  } = evt;
61967
- debugLog("sending request to %s %s%s", method, origin2, path6);
62537
+ debugLog("sending request to %s %s%s", method, origin2, path5);
61968
62538
  }
61969
62539
  );
61970
62540
  }
@@ -61982,14 +62552,14 @@ var require_diagnostics = __commonJS({
61982
62552
  "undici:request:headers",
61983
62553
  (evt) => {
61984
62554
  const {
61985
- request: { method, path: path6, origin: origin2 },
62555
+ request: { method, path: path5, origin: origin2 },
61986
62556
  response: { statusCode }
61987
62557
  } = evt;
61988
62558
  debugLog(
61989
62559
  "received response to %s %s%s - HTTP %d",
61990
62560
  method,
61991
62561
  origin2,
61992
- path6,
62562
+ path5,
61993
62563
  statusCode
61994
62564
  );
61995
62565
  }
@@ -61998,23 +62568,23 @@ var require_diagnostics = __commonJS({
61998
62568
  "undici:request:trailers",
61999
62569
  (evt) => {
62000
62570
  const {
62001
- request: { method, path: path6, origin: origin2 }
62571
+ request: { method, path: path5, origin: origin2 }
62002
62572
  } = evt;
62003
- debugLog("trailers received from %s %s%s", method, origin2, path6);
62573
+ debugLog("trailers received from %s %s%s", method, origin2, path5);
62004
62574
  }
62005
62575
  );
62006
62576
  diagnosticsChannel.subscribe(
62007
62577
  "undici:request:error",
62008
62578
  (evt) => {
62009
62579
  const {
62010
- request: { method, path: path6, origin: origin2 },
62580
+ request: { method, path: path5, origin: origin2 },
62011
62581
  error
62012
62582
  } = evt;
62013
62583
  debugLog(
62014
62584
  "request to %s %s%s errored - %s",
62015
62585
  method,
62016
62586
  origin2,
62017
- path6,
62587
+ path5,
62018
62588
  error.message
62019
62589
  );
62020
62590
  }
@@ -62169,7 +62739,7 @@ var require_request = __commonJS({
62169
62739
  };
62170
62740
  var Request2 = class {
62171
62741
  constructor(origin2, {
62172
- path: path6,
62742
+ path: path5,
62173
62743
  method,
62174
62744
  body,
62175
62745
  headers,
@@ -62186,11 +62756,11 @@ var require_request = __commonJS({
62186
62756
  maxRedirections,
62187
62757
  typeOfService
62188
62758
  }, handler) {
62189
- if (typeof path6 !== "string") {
62759
+ if (typeof path5 !== "string") {
62190
62760
  throw new InvalidArgumentError("path must be a string");
62191
- } else if (path6[0] !== "/" && !(path6.startsWith("http://") || path6.startsWith("https://")) && method !== "CONNECT") {
62761
+ } else if (path5[0] !== "/" && !(path5.startsWith("http://") || path5.startsWith("https://")) && method !== "CONNECT") {
62192
62762
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
62193
- } else if (invalidPathRegex.test(path6)) {
62763
+ } else if (invalidPathRegex.test(path5)) {
62194
62764
  throw new InvalidArgumentError("invalid request path");
62195
62765
  }
62196
62766
  if (typeof method !== "string") {
@@ -62265,7 +62835,7 @@ var require_request = __commonJS({
62265
62835
  this.completed = false;
62266
62836
  this.aborted = false;
62267
62837
  this.upgrade = upgrade || null;
62268
- this.path = query ? serializePathWithQuery(path6, query) : path6;
62838
+ this.path = query ? serializePathWithQuery(path5, query) : path5;
62269
62839
  this.origin = origin2;
62270
62840
  this.protocol = getProtocolFromUrlString(origin2);
62271
62841
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" || method === "QUERY" : idempotent;
@@ -67351,7 +67921,7 @@ var require_client_h1 = __commonJS({
67351
67921
  }
67352
67922
  }
67353
67923
  function writeH1(client, request2) {
67354
- const { method, path: path6, host, upgrade, blocking, reset } = request2;
67924
+ const { method, path: path5, host, upgrade, blocking, reset } = request2;
67355
67925
  let { body, headers, contentLength } = request2;
67356
67926
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
67357
67927
  if (util5.isFormDataLike(body)) {
@@ -67427,7 +67997,7 @@ var require_client_h1 = __commonJS({
67427
67997
  socket[kBlocking] = true;
67428
67998
  }
67429
67999
  setTypeOfService(socket, request2);
67430
- let header = `${method} ${path6} HTTP/1.1\r
68000
+ let header = `${method} ${path5} HTTP/1.1\r
67431
68001
  `;
67432
68002
  if (typeof host === "string") {
67433
68003
  header += `host: ${host}\r
@@ -68508,7 +69078,7 @@ var require_client_h2 = __commonJS({
68508
69078
  const headersTimeout = request2.headersTimeout ?? client[kHeadersTimeout];
68509
69079
  const bodyTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
68510
69080
  const session = client[kHTTP2Session];
68511
- const { method, path: path6, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
69081
+ const { method, path: path5, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
68512
69082
  if (upgrade != null && upgrade !== "websocket") {
68513
69083
  util5.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
68514
69084
  return false;
@@ -68571,7 +69141,7 @@ var require_client_h2 = __commonJS({
68571
69141
  }
68572
69142
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
68573
69143
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
68574
- headers[HTTP2_HEADER_PATH] = path6;
69144
+ headers[HTTP2_HEADER_PATH] = path5;
68575
69145
  if (protocol === "ws:" || protocol === "wss:") {
68576
69146
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
68577
69147
  } else {
@@ -68593,7 +69163,7 @@ var require_client_h2 = __commonJS({
68593
69163
  setupUpgradeStream(stream4, state);
68594
69164
  return true;
68595
69165
  }
68596
- headers[HTTP2_HEADER_PATH] = path6;
69166
+ headers[HTTP2_HEADER_PATH] = path5;
68597
69167
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
68598
69168
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
68599
69169
  let body = state.body;
@@ -71263,10 +71833,10 @@ var require_proxy_agent = __commonJS({
71263
71833
  };
71264
71834
  const {
71265
71835
  origin: origin2,
71266
- path: path6 = "/",
71836
+ path: path5 = "/",
71267
71837
  headers = {}
71268
71838
  } = opts;
71269
- opts.path = origin2 + path6;
71839
+ opts.path = origin2 + path5;
71270
71840
  if (!("host" in headers) && !("Host" in headers)) {
71271
71841
  const { host } = new URL(origin2);
71272
71842
  headers.host = host;
@@ -73531,20 +74101,20 @@ var require_mock_utils = __commonJS({
73531
74101
  }
73532
74102
  return normalizedQp;
73533
74103
  }
73534
- function safeUrl(path6) {
73535
- if (typeof path6 !== "string") {
73536
- return path6;
74104
+ function safeUrl(path5) {
74105
+ if (typeof path5 !== "string") {
74106
+ return path5;
73537
74107
  }
73538
- const pathSegments = path6.split("?", 3);
74108
+ const pathSegments = path5.split("?", 3);
73539
74109
  if (pathSegments.length !== 2) {
73540
- return path6;
74110
+ return path5;
73541
74111
  }
73542
74112
  const qp = new URLSearchParams(pathSegments.pop());
73543
74113
  qp.sort();
73544
74114
  return [...pathSegments, qp.toString()].join("?");
73545
74115
  }
73546
- function matchKey(mockDispatch2, { path: path6, method, body, headers }) {
73547
- const pathMatch = matchValue(mockDispatch2.path, path6);
74116
+ function matchKey(mockDispatch2, { path: path5, method, body, headers }) {
74117
+ const pathMatch = matchValue(mockDispatch2.path, path5);
73548
74118
  const methodMatch = matchValue(mockDispatch2.method, method);
73549
74119
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
73550
74120
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -73571,8 +74141,8 @@ var require_mock_utils = __commonJS({
73571
74141
  const basePath = key2.query ? serializePathWithQuery(key2.path, key2.query) : key2.path;
73572
74142
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
73573
74143
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
73574
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path6, ignoreTrailingSlash }) => {
73575
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path6)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path6), resolvedPath);
74144
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path5, ignoreTrailingSlash }) => {
74145
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path5)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path5), resolvedPath);
73576
74146
  });
73577
74147
  if (matchedMockDispatches.length === 0) {
73578
74148
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -73611,22 +74181,22 @@ var require_mock_utils = __commonJS({
73611
74181
  mockDispatches.splice(index2, 1);
73612
74182
  }
73613
74183
  }
73614
- function removeTrailingSlash(path6) {
73615
- if (typeof path6 !== "string") {
73616
- return path6;
74184
+ function removeTrailingSlash(path5) {
74185
+ if (typeof path5 !== "string") {
74186
+ return path5;
73617
74187
  }
73618
- while (path6.endsWith("/")) {
73619
- path6 = path6.slice(0, -1);
74188
+ while (path5.endsWith("/")) {
74189
+ path5 = path5.slice(0, -1);
73620
74190
  }
73621
- if (path6.length === 0) {
73622
- path6 = "/";
74191
+ if (path5.length === 0) {
74192
+ path5 = "/";
73623
74193
  }
73624
- return path6;
74194
+ return path5;
73625
74195
  }
73626
74196
  function buildKey(opts) {
73627
- const { path: path6, method, body, headers, query } = opts;
74197
+ const { path: path5, method, body, headers, query } = opts;
73628
74198
  return {
73629
- path: path6,
74199
+ path: path5,
73630
74200
  method,
73631
74201
  body,
73632
74202
  headers,
@@ -74497,10 +75067,10 @@ var require_pending_interceptors_formatter = __commonJS({
74497
75067
  }
74498
75068
  format(pendingInterceptors) {
74499
75069
  const withPrettyHeaders = pendingInterceptors.map(
74500
- ({ method, path: path6, data: { statusCode }, persist, times, timesInvoked, origin: origin2 }) => ({
75070
+ ({ method, path: path5, data: { statusCode }, persist, times, timesInvoked, origin: origin2 }) => ({
74501
75071
  Method: method,
74502
75072
  Origin: origin2,
74503
- Path: path6,
75073
+ Path: path5,
74504
75074
  "Status code": statusCode,
74505
75075
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
74506
75076
  Invocations: timesInvoked,
@@ -74582,9 +75152,9 @@ var require_mock_agent = __commonJS({
74582
75152
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
74583
75153
  const dispatchOpts = { ...opts };
74584
75154
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
74585
- const [path6, searchParams] = dispatchOpts.path.split("?");
75155
+ const [path5, searchParams] = dispatchOpts.path.split("?");
74586
75156
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
74587
- dispatchOpts.path = `${path6}?${normalizedSearchParams}`;
75157
+ dispatchOpts.path = `${path5}?${normalizedSearchParams}`;
74588
75158
  }
74589
75159
  return this[kAgent].dispatch(dispatchOpts, handler);
74590
75160
  }
@@ -75000,12 +75570,12 @@ var require_snapshot_recorder = __commonJS({
75000
75570
  * @return {Promise<void>} - Resolves when snapshots are loaded
75001
75571
  */
75002
75572
  async loadSnapshots(filePath) {
75003
- const path6 = filePath || this.#snapshotPath;
75004
- if (!path6) {
75573
+ const path5 = filePath || this.#snapshotPath;
75574
+ if (!path5) {
75005
75575
  throw new InvalidArgumentError("Snapshot path is required");
75006
75576
  }
75007
75577
  try {
75008
- const data = await readFile3(resolve(path6), "utf8");
75578
+ const data = await readFile3(resolve(path5), "utf8");
75009
75579
  const parsed = JSON.parse(data);
75010
75580
  if (Array.isArray(parsed)) {
75011
75581
  this.#snapshots.clear();
@@ -75019,7 +75589,7 @@ var require_snapshot_recorder = __commonJS({
75019
75589
  if (error.code === "ENOENT") {
75020
75590
  this.#snapshots.clear();
75021
75591
  } else {
75022
- throw new UndiciError(`Failed to load snapshots from ${path6}`, { cause: error });
75592
+ throw new UndiciError(`Failed to load snapshots from ${path5}`, { cause: error });
75023
75593
  }
75024
75594
  }
75025
75595
  }
@@ -75030,11 +75600,11 @@ var require_snapshot_recorder = __commonJS({
75030
75600
  * @returns {Promise<void>} - Resolves when snapshots are saved
75031
75601
  */
75032
75602
  async saveSnapshots(filePath) {
75033
- const path6 = filePath || this.#snapshotPath;
75034
- if (!path6) {
75603
+ const path5 = filePath || this.#snapshotPath;
75604
+ if (!path5) {
75035
75605
  throw new InvalidArgumentError("Snapshot path is required");
75036
75606
  }
75037
- const resolvedPath = resolve(path6);
75607
+ const resolvedPath = resolve(path5);
75038
75608
  await mkdir5(dirname5(resolvedPath), { recursive: true });
75039
75609
  const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
75040
75610
  hash: hash5,
@@ -75671,15 +76241,15 @@ var require_redirect_handler = __commonJS({
75671
76241
  return;
75672
76242
  }
75673
76243
  const { origin: origin2, pathname, search } = util5.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
75674
- const path6 = search ? `${pathname}${search}` : pathname;
75675
- const redirectUrlString = `${origin2}${path6}`;
76244
+ const path5 = search ? `${pathname}${search}` : pathname;
76245
+ const redirectUrlString = `${origin2}${path5}`;
75676
76246
  for (const historyUrl of this.history) {
75677
76247
  if (historyUrl.toString() === redirectUrlString) {
75678
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.`);
75679
76249
  }
75680
76250
  }
75681
76251
  this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, this.opts.origin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect);
75682
- this.opts.path = path6;
76252
+ this.opts.path = path5;
75683
76253
  this.opts.origin = origin2;
75684
76254
  this.opts.query = null;
75685
76255
  }
@@ -77507,10 +78077,10 @@ var require_cache_handler = __commonJS({
77507
78077
  }
77508
78078
  return locationUrl.pathname + locationUrl.search;
77509
78079
  }
77510
- function deleteCachedUri(store, cacheKey2, path6) {
78080
+ function deleteCachedUri(store, cacheKey2, path5) {
77511
78081
  deleteCachedValue(store, {
77512
78082
  ...cacheKey2,
77513
- path: path6
78083
+ path: path5
77514
78084
  });
77515
78085
  for (let i = 0; i < util5.safeHTTPMethods.length; i++) {
77516
78086
  const method = util5.safeHTTPMethods[i];
@@ -77518,7 +78088,7 @@ var require_cache_handler = __commonJS({
77518
78088
  deleteCachedValue(store, {
77519
78089
  ...cacheKey2,
77520
78090
  method,
77521
- path: path6
78091
+ path: path5
77522
78092
  });
77523
78093
  }
77524
78094
  }
@@ -77529,9 +78099,9 @@ var require_cache_handler = __commonJS({
77529
78099
  }
77530
78100
  const values = Array.isArray(headerValue) ? headerValue : [headerValue];
77531
78101
  for (let i = 0; i < values.length; i++) {
77532
- const path6 = getSameOriginPath(cacheKey2, values[i]);
77533
- if (path6 !== void 0) {
77534
- deleteCachedUri(store, cacheKey2, path6);
78102
+ const path5 = getSameOriginPath(cacheKey2, values[i]);
78103
+ if (path5 !== void 0) {
78104
+ deleteCachedUri(store, cacheKey2, path5);
77535
78105
  }
77536
78106
  }
77537
78107
  }
@@ -82528,13 +83098,13 @@ var require_fetch = __commonJS({
82528
83098
  function dispatch({ body }) {
82529
83099
  const url2 = requestCurrentURL(request2);
82530
83100
  const agent = fetchParams.controller.dispatcher;
82531
- const path6 = url2.pathname + url2.search;
83101
+ const path5 = url2.pathname + url2.search;
82532
83102
  const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
82533
83103
  return dispatchWithProtocolPreference(body);
82534
83104
  function dispatchWithProtocolPreference(body2, allowH2) {
82535
83105
  return new Promise((resolve, reject) => agent.dispatch(
82536
83106
  {
82537
- path: hasTrailingQuestionMark ? `${path6}?` : path6,
83107
+ path: hasTrailingQuestionMark ? `${path5}?` : path5,
82538
83108
  origin: url2.origin,
82539
83109
  method: request2.method,
82540
83110
  body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body2,
@@ -83446,9 +84016,9 @@ var require_util4 = __commonJS({
83446
84016
  }
83447
84017
  }
83448
84018
  }
83449
- function validateCookiePath(path6) {
83450
- for (let i = 0; i < path6.length; ++i) {
83451
- const code = path6.charCodeAt(i);
84019
+ function validateCookiePath(path5) {
84020
+ for (let i = 0; i < path5.length; ++i) {
84021
+ const code = path5.charCodeAt(i);
83452
84022
  if (code < 32 || // exclude CTLs (0-31)
83453
84023
  code > 126 || // exclude non-ascii and DEL
83454
84024
  code === 59) {
@@ -86820,11 +87390,11 @@ var require_undici = __commonJS({
86820
87390
  if (typeof opts.path !== "string") {
86821
87391
  throw new InvalidArgumentError("invalid opts.path");
86822
87392
  }
86823
- let path6 = opts.path;
87393
+ let path5 = opts.path;
86824
87394
  if (!opts.path.startsWith("/")) {
86825
- path6 = `/${path6}`;
87395
+ path5 = `/${path5}`;
86826
87396
  }
86827
- url2 = new URL(util5.parseOrigin(url2).origin + path6);
87397
+ url2 = new URL(util5.parseOrigin(url2).origin + path5);
86828
87398
  } else {
86829
87399
  if (!opts) {
86830
87400
  opts = typeof url2 === "object" ? url2 : {};
@@ -87370,8 +87940,8 @@ var init_textual_tool_calls = __esm({
87370
87940
 
87371
87941
  // src/response-store.ts
87372
87942
  import { appendFile as appendFile2, mkdir as mkdir3, readFile, readdir as readdir2 } from "fs/promises";
87373
- import { homedir as homedir5 } from "os";
87374
- import { join as join8 } from "path";
87943
+ import { homedir as homedir6 } from "os";
87944
+ import { join as join9 } from "path";
87375
87945
  import { randomBytes as randomBytes7 } from "crypto";
87376
87946
  function isEnabled() {
87377
87947
  const v = process.env.BLOCKRUN_RESPONSE_STORE;
@@ -87384,7 +87954,7 @@ async function ensureDir2() {
87384
87954
  }
87385
87955
  function dailyFile(date = /* @__PURE__ */ new Date()) {
87386
87956
  const iso = date.toISOString().slice(0, 10);
87387
- return join8(STORE_DIR, `responses-${iso}.jsonl`);
87957
+ return join9(STORE_DIR, `responses-${iso}.jsonl`);
87388
87958
  }
87389
87959
  function genId() {
87390
87960
  return `resp_${Date.now()}_${randomBytes7(3).toString("hex")}`;
@@ -87434,7 +88004,7 @@ async function listRecent(limit = 20, daysBack = 7) {
87434
88004
  d.setUTCDate(d.getUTCDate() - i);
87435
88005
  const iso = d.toISOString().slice(0, 10);
87436
88006
  const name = `responses-${iso}.jsonl`;
87437
- if (files.includes(name)) candidateFiles.push(join8(STORE_DIR, name));
88007
+ if (files.includes(name)) candidateFiles.push(join9(STORE_DIR, name));
87438
88008
  }
87439
88009
  const all3 = [];
87440
88010
  for (const f of candidateFiles) {
@@ -87463,7 +88033,7 @@ var STORE_DIR, dirReady2;
87463
88033
  var init_response_store = __esm({
87464
88034
  "src/response-store.ts"() {
87465
88035
  "use strict";
87466
- STORE_DIR = join8(homedir5(), ".openclaw", "blockrun", "responses");
88036
+ STORE_DIR = join9(homedir6(), ".openclaw", "blockrun", "responses");
87467
88037
  dirReady2 = false;
87468
88038
  }
87469
88039
  });
@@ -89113,10 +89683,10 @@ var init_client3 = __esm({
89113
89683
  import { AsyncLocalStorage } from "async_hooks";
89114
89684
  import { createServer } from "http";
89115
89685
  import { finished } from "stream";
89116
- import { homedir as homedir6 } from "os";
89117
- import { join as join9 } from "path";
89686
+ import { homedir as homedir7 } from "os";
89687
+ import { join as join10 } from "path";
89118
89688
  import { mkdir as mkdir4, writeFile as writeFile2, readFile as readFile2, stat as fsStat } from "fs/promises";
89119
- import { readFileSync as readFileSync2, existsSync } from "fs";
89689
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
89120
89690
  function pickFreeModel(excludeList) {
89121
89691
  for (const m of FREE_MODELS) {
89122
89692
  if (!excludeList?.has(m)) return m;
@@ -89882,8 +90452,8 @@ async function proxyPaidApiRequest(req, res, apiBase, payFetch, getActualPayment
89882
90452
  });
89883
90453
  }
89884
90454
  function readImageFileAsDataUri(filePath) {
89885
- const resolved = filePath.startsWith("~/") ? join9(homedir6(), filePath.slice(2)) : filePath;
89886
- if (!existsSync(resolved)) {
90455
+ const resolved = filePath.startsWith("~/") ? join10(homedir7(), filePath.slice(2)) : filePath;
90456
+ if (!existsSync2(resolved)) {
89887
90457
  throw new Error(`Image file not found: ${resolved}`);
89888
90458
  }
89889
90459
  const ext = resolved.split(".").pop()?.toLowerCase() ?? "png";
@@ -89997,6 +90567,8 @@ async function startProxy(options) {
89997
90567
  const evmPublicClient = createPublicClient({ chain: base, transport: http() });
89998
90568
  const evmSigner = toClientEvmSigner(account, evmPublicClient);
89999
90569
  const x402 = new x402Client();
90570
+ const spendControl = options.spendControl ?? new SpendControl();
90571
+ registerSpendPolicyHook(x402, spendControl);
90000
90572
  registerExactEvmScheme(x402, { signer: evmSigner });
90001
90573
  let solanaAddress;
90002
90574
  if (solanaPrivateKeyBytes) {
@@ -90165,8 +90737,8 @@ async function startProxy(options) {
90165
90737
  if (req.url?.startsWith("/share") && req.method === "GET") {
90166
90738
  try {
90167
90739
  const url2 = new URL(req.url, "http://localhost");
90168
- const path6 = url2.pathname;
90169
- if (path6 === "/share/list") {
90740
+ const path5 = url2.pathname;
90741
+ if (path5 === "/share/list") {
90170
90742
  const limit = Math.min(parseInt(url2.searchParams.get("limit") || "20", 10), 100);
90171
90743
  const entries = await listRecent(limit);
90172
90744
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -90184,7 +90756,7 @@ async function startProxy(options) {
90184
90756
  );
90185
90757
  return;
90186
90758
  }
90187
- if (path6 === "/share/last") {
90759
+ if (path5 === "/share/last") {
90188
90760
  const sessionId = url2.searchParams.get("sessionId") || void 0;
90189
90761
  const entry = await getLast(sessionId);
90190
90762
  if (!entry) {
@@ -90213,7 +90785,7 @@ async function startProxy(options) {
90213
90785
  res.end(JSON.stringify(entry));
90214
90786
  return;
90215
90787
  }
90216
- const idMatch = path6.match(/^\/share\/(resp_[A-Za-z0-9_]+)(?:\/render)?$/);
90788
+ const idMatch = path5.match(/^\/share\/(resp_[A-Za-z0-9_]+)(?:\/render)?$/);
90217
90789
  if (idMatch) {
90218
90790
  const id2 = idMatch[1];
90219
90791
  const entry = await getById(id2);
@@ -90259,7 +90831,7 @@ async function startProxy(options) {
90259
90831
  res.end("Bad request");
90260
90832
  return;
90261
90833
  }
90262
- const filePath = join9(IMAGE_DIR, filename);
90834
+ const filePath = join10(IMAGE_DIR, filename);
90263
90835
  try {
90264
90836
  const s3 = await fsStat(filePath);
90265
90837
  if (!s3.isFile()) throw new Error("not a file");
@@ -90290,7 +90862,7 @@ async function startProxy(options) {
90290
90862
  res.end("Bad request");
90291
90863
  return;
90292
90864
  }
90293
- const filePath = join9(AUDIO_DIR, filename);
90865
+ const filePath = join10(AUDIO_DIR, filename);
90294
90866
  try {
90295
90867
  const s3 = await fsStat(filePath);
90296
90868
  if (!s3.isFile()) throw new Error("not a file");
@@ -90320,7 +90892,7 @@ async function startProxy(options) {
90320
90892
  res.end("Bad request");
90321
90893
  return;
90322
90894
  }
90323
- const filePath = join9(VIDEO_DIR, filename);
90895
+ const filePath = join10(VIDEO_DIR, filename);
90324
90896
  try {
90325
90897
  const s3 = await fsStat(filePath);
90326
90898
  if (!s3.isFile()) throw new Error("not a file");
@@ -90461,7 +91033,7 @@ async function startProxy(options) {
90461
91033
  const [, mimeType, b64] = dataUriMatch;
90462
91034
  const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
90463
91035
  const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
90464
- await writeFile2(join9(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
91036
+ await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
90465
91037
  img.url = `http://localhost:${port2}/images/${filename}`;
90466
91038
  console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
90467
91039
  } else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
@@ -90472,7 +91044,7 @@ async function startProxy(options) {
90472
91044
  const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
90473
91045
  const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
90474
91046
  const buf = Buffer.from(await imgResp.arrayBuffer());
90475
- await writeFile2(join9(IMAGE_DIR, filename), buf);
91047
+ await writeFile2(join10(IMAGE_DIR, filename), buf);
90476
91048
  img.url = `http://localhost:${port2}/images/${filename}`;
90477
91049
  console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
90478
91050
  }
@@ -90584,7 +91156,7 @@ async function startProxy(options) {
90584
91156
  const [, mimeType, b64] = dataUriMatch;
90585
91157
  const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
90586
91158
  const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
90587
- await writeFile2(join9(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
91159
+ await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
90588
91160
  img.url = `http://localhost:${port2}/images/${filename}`;
90589
91161
  console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
90590
91162
  } else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
@@ -90595,7 +91167,7 @@ async function startProxy(options) {
90595
91167
  const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
90596
91168
  const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
90597
91169
  const buf = Buffer.from(await imgResp.arrayBuffer());
90598
- await writeFile2(join9(IMAGE_DIR, filename), buf);
91170
+ await writeFile2(join10(IMAGE_DIR, filename), buf);
90599
91171
  img.url = `http://localhost:${port2}/images/${filename}`;
90600
91172
  console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
90601
91173
  }
@@ -90681,7 +91253,7 @@ async function startProxy(options) {
90681
91253
  const ext = contentType.includes("wav") ? "wav" : "mp3";
90682
91254
  const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
90683
91255
  const buf = Buffer.from(await audioResp.arrayBuffer());
90684
- await writeFile2(join9(AUDIO_DIR, filename), buf);
91256
+ await writeFile2(join10(AUDIO_DIR, filename), buf);
90685
91257
  track.url = `http://localhost:${port2}/audio/${filename}`;
90686
91258
  console.log(`[ClawRouter] Audio saved \u2192 ${track.url}`);
90687
91259
  }
@@ -90841,7 +91413,7 @@ async function startProxy(options) {
90841
91413
  const ext = contentType.includes("webm") ? "webm" : contentType.includes("quicktime") ? "mov" : "mp4";
90842
91414
  const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
90843
91415
  const buf = Buffer.from(await videoResp.arrayBuffer());
90844
- await writeFile2(join9(VIDEO_DIR, filename), buf);
91416
+ await writeFile2(join10(VIDEO_DIR, filename), buf);
90845
91417
  clip.url = `http://localhost:${port2}/videos/${filename}`;
90846
91418
  console.log(`[ClawRouter] Video saved \u2192 ${clip.url}`);
90847
91419
  }
@@ -91181,6 +91753,17 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
91181
91753
  return { success: true, response };
91182
91754
  } catch (err) {
91183
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
+ }
91184
91767
  return {
91185
91768
  success: false,
91186
91769
  errorBody: errorMsg,
@@ -93367,6 +93950,7 @@ var init_proxy = __esm({
93367
93950
  init_response_cache();
93368
93951
  init_balance();
93369
93952
  init_auth();
93953
+ init_spend_control();
93370
93954
  init_compression();
93371
93955
  init_version4();
93372
93956
  init_session();
@@ -93382,9 +93966,9 @@ var init_proxy = __esm({
93382
93966
  paymentStore = new AsyncLocalStorage();
93383
93967
  BLOCKRUN_API = "https://blockrun.ai/api";
93384
93968
  BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
93385
- IMAGE_DIR = join9(homedir6(), ".openclaw", "blockrun", "images");
93386
- AUDIO_DIR = join9(homedir6(), ".openclaw", "blockrun", "audio");
93387
- VIDEO_DIR = join9(homedir6(), ".openclaw", "blockrun", "videos");
93969
+ IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
93970
+ AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
93971
+ VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
93388
93972
  AUTO_MODEL = "blockrun/auto";
93389
93973
  ROUTING_PROFILES = /* @__PURE__ */ new Set([
93390
93974
  "blockrun/eco",
@@ -94449,7 +95033,7 @@ function buildTool(service, proxyBaseUrl) {
94449
95033
  required
94450
95034
  },
94451
95035
  execute: async (_toolCallId, params) => {
94452
- let path6;
95036
+ let path5;
94453
95037
  const leftoverParams = {};
94454
95038
  let dynamicMethod = "GET";
94455
95039
  let dynamicBody = void 0;
@@ -94461,7 +95045,7 @@ function buildTool(service, proxyBaseUrl) {
94461
95045
  `predexon_endpoint_call: invalid path '${rawPath}' \u2014 must begin with '/pm/' and contain no '..'`
94462
95046
  );
94463
95047
  }
94464
- path6 = `/v1${normalized}`;
95048
+ path5 = `/v1${normalized}`;
94465
95049
  if (typeof params.method === "string") {
94466
95050
  const upper = params.method.toUpperCase();
94467
95051
  if (upper !== "GET" && upper !== "POST") {
@@ -94510,19 +95094,19 @@ function buildTool(service, proxyBaseUrl) {
94510
95094
  }
94511
95095
  }
94512
95096
  } else {
94513
- path6 = `/v1${service.proxyPath}`;
95097
+ path5 = `/v1${service.proxyPath}`;
94514
95098
  for (const [key2, value] of Object.entries(params)) {
94515
95099
  if (value === void 0 || value === null) continue;
94516
95100
  const placeholder = `:${key2}`;
94517
- if (path6.includes(placeholder)) {
94518
- path6 = path6.replace(placeholder, encodeURIComponent(String(value)));
95101
+ if (path5.includes(placeholder)) {
95102
+ path5 = path5.replace(placeholder, encodeURIComponent(String(value)));
94519
95103
  } else {
94520
95104
  leftoverParams[key2] = value;
94521
95105
  }
94522
95106
  }
94523
95107
  }
94524
95108
  const effectiveMethod = service.proxyPath === "/pm/__dynamic__" ? dynamicMethod : service.method;
94525
- let url2 = `${proxyBaseUrl}${path6}`;
95109
+ let url2 = `${proxyBaseUrl}${path5}`;
94526
95110
  if (effectiveMethod === "GET" && Object.keys(leftoverParams).length > 0) {
94527
95111
  const qs = new URLSearchParams();
94528
95112
  for (const [key2, value] of Object.entries(leftoverParams)) {
@@ -106201,11 +106785,11 @@ var require_mime_types = __commonJS({
106201
106785
  }
106202
106786
  return exts[0];
106203
106787
  }
106204
- function lookup(path6) {
106205
- if (!path6 || typeof path6 !== "string") {
106788
+ function lookup(path5) {
106789
+ if (!path5 || typeof path5 !== "string") {
106206
106790
  return false;
106207
106791
  }
106208
- var extension3 = extname("x." + path6).toLowerCase().substr(1);
106792
+ var extension3 = extname("x." + path5).toLowerCase().substr(1);
106209
106793
  if (!extension3) {
106210
106794
  return false;
106211
106795
  }
@@ -107320,7 +107904,7 @@ var require_form_data = __commonJS({
107320
107904
  "use strict";
107321
107905
  var CombinedStream = require_combined_stream();
107322
107906
  var util5 = __require("util");
107323
- var path6 = __require("path");
107907
+ var path5 = __require("path");
107324
107908
  var http5 = __require("http");
107325
107909
  var https2 = __require("https");
107326
107910
  var parseUrl3 = __require("url").parse;
@@ -107451,11 +108035,11 @@ var require_form_data = __commonJS({
107451
108035
  FormData3.prototype._getContentDisposition = function(value, options) {
107452
108036
  var filename;
107453
108037
  if (typeof options.filepath === "string") {
107454
- filename = path6.normalize(options.filepath).replace(/\\/g, "/");
108038
+ filename = path5.normalize(options.filepath).replace(/\\/g, "/");
107455
108039
  } else if (options.filename || value && (value.name || value.path)) {
107456
- filename = path6.basename(options.filename || value && (value.name || value.path));
108040
+ filename = path5.basename(options.filename || value && (value.name || value.path));
107457
108041
  } else if (value && value.readable && hasOwn(value, "httpVersion")) {
107458
- filename = path6.basename(value.client._httpMessage.path || "");
108042
+ filename = path5.basename(value.client._httpMessage.path || "");
107459
108043
  }
107460
108044
  if (filename) {
107461
108045
  return 'filename="' + escapeHeaderParam(filename) + '"';
@@ -107669,9 +108253,9 @@ function isVisitable(thing) {
107669
108253
  function removeBrackets(key2) {
107670
108254
  return utils_default.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
107671
108255
  }
107672
- function renderKey(path6, key2, dots) {
107673
- if (!path6) return key2;
107674
- return path6.concat(key2).map(function each(token, i) {
108256
+ function renderKey(path5, key2, dots) {
108257
+ if (!path5) return key2;
108258
+ return path5.concat(key2).map(function each(token, i) {
107675
108259
  token = removeBrackets(token);
107676
108260
  return !dots && i ? "[" + token + "]" : token;
107677
108261
  }).join(dots ? "." : "");
@@ -107754,13 +108338,13 @@ function toFormData(obj, formData, options) {
107754
108338
  return currentValue;
107755
108339
  });
107756
108340
  }
107757
- function defaultVisitor(value, key2, path6) {
108341
+ function defaultVisitor(value, key2, path5) {
107758
108342
  let arr = value;
107759
108343
  if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
107760
- formData.append(renderKey(path6, key2, dots), convertValue(value));
108344
+ formData.append(renderKey(path5, key2, dots), convertValue(value));
107761
108345
  return false;
107762
108346
  }
107763
- if (value && !path6 && typeof value === "object") {
108347
+ if (value && !path5 && typeof value === "object") {
107764
108348
  if (utils_default.endsWith(key2, "{}")) {
107765
108349
  key2 = metaTokens ? key2 : key2.slice(0, -2);
107766
108350
  value = stringifyWithDepthLimit(value, 1);
@@ -107779,7 +108363,7 @@ function toFormData(obj, formData, options) {
107779
108363
  if (isVisitable(value)) {
107780
108364
  return true;
107781
108365
  }
107782
- formData.append(renderKey(path6, key2, dots), convertValue(value));
108366
+ formData.append(renderKey(path5, key2, dots), convertValue(value));
107783
108367
  return false;
107784
108368
  }
107785
108369
  const exposedHelpers = Object.assign(predicates, {
@@ -107787,17 +108371,17 @@ function toFormData(obj, formData, options) {
107787
108371
  convertValue,
107788
108372
  isVisitable
107789
108373
  });
107790
- function build(value, path6, depth = 0) {
108374
+ function build(value, path5, depth = 0) {
107791
108375
  if (utils_default.isUndefined(value)) return;
107792
108376
  throwIfMaxDepthExceeded(depth);
107793
108377
  if (stack.indexOf(value) !== -1) {
107794
- throw new Error("Circular reference detected in " + path6.join("."));
108378
+ throw new Error("Circular reference detected in " + path5.join("."));
107795
108379
  }
107796
108380
  stack.push(value);
107797
108381
  utils_default.forEach(value, function each(el, key2) {
107798
- const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2, path6, exposedHelpers);
108382
+ const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2, path5, exposedHelpers);
107799
108383
  if (result === true) {
107800
- build(el, path6 ? path6.concat(key2) : [key2], depth + 1);
108384
+ build(el, path5 ? path5.concat(key2) : [key2], depth + 1);
107801
108385
  }
107802
108386
  });
107803
108387
  stack.pop();
@@ -108076,7 +108660,7 @@ var init_platform = __esm({
108076
108660
  // node_modules/axios/lib/helpers/toURLEncodedForm.js
108077
108661
  function toURLEncodedForm(data, options) {
108078
108662
  return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
108079
- visitor: function(value, key2, path6, helpers) {
108663
+ visitor: function(value, key2, path5, helpers) {
108080
108664
  if (platform_default.isNode && utils_default.isBuffer(value)) {
108081
108665
  this.append(key2, value.toString("base64"));
108082
108666
  return false;
@@ -108105,14 +108689,14 @@ function throwIfDepthExceeded(index2) {
108105
108689
  }
108106
108690
  }
108107
108691
  function parsePropPath(name) {
108108
- const path6 = [];
108692
+ const path5 = [];
108109
108693
  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
108110
108694
  let match;
108111
108695
  while ((match = pattern.exec(name)) !== null) {
108112
- throwIfDepthExceeded(path6.length);
108113
- path6.push(match[0] === "[]" ? "" : match[1] || match[0]);
108696
+ throwIfDepthExceeded(path5.length);
108697
+ path5.push(match[0] === "[]" ? "" : match[1] || match[0]);
108114
108698
  }
108115
- return path6;
108699
+ return path5;
108116
108700
  }
108117
108701
  function arrayToObject(arr) {
108118
108702
  const obj = {};
@@ -108127,12 +108711,12 @@ function arrayToObject(arr) {
108127
108711
  return obj;
108128
108712
  }
108129
108713
  function formDataToJSON(formData) {
108130
- function buildPath(path6, value, target, index2) {
108714
+ function buildPath(path5, value, target, index2) {
108131
108715
  throwIfDepthExceeded(index2);
108132
- let name = path6[index2++];
108716
+ let name = path5[index2++];
108133
108717
  if (name === "__proto__") return true;
108134
108718
  const isNumericKey = Number.isFinite(+name);
108135
- const isLast = index2 >= path6.length;
108719
+ const isLast = index2 >= path5.length;
108136
108720
  name = !name && utils_default.isArray(target) ? target.length : name;
108137
108721
  if (isLast) {
108138
108722
  if (utils_default.hasOwnProp(target, name)) {
@@ -108145,7 +108729,7 @@ function formDataToJSON(formData) {
108145
108729
  if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
108146
108730
  target[name] = [];
108147
108731
  }
108148
- const result = buildPath(path6, value, target[name], index2);
108732
+ const result = buildPath(path5, value, target[name], index2);
108149
108733
  if (result && utils_default.isArray(target[name])) {
108150
108734
  target[name] = arrayToObject(target[name]);
108151
108735
  }
@@ -111692,9 +112276,9 @@ var init_http4 = __esm({
111692
112276
  auth = urlUsername + ":" + urlPassword;
111693
112277
  }
111694
112278
  auth && headers.delete("authorization");
111695
- let path6;
112279
+ let path5;
111696
112280
  try {
111697
- path6 = buildURL(
112281
+ path5 = buildURL(
111698
112282
  parsed.pathname + parsed.search,
111699
112283
  own2("params"),
111700
112284
  own2("paramsSerializer")
@@ -111713,7 +112297,7 @@ var init_http4 = __esm({
111713
112297
  false
111714
112298
  );
111715
112299
  const options = Object.assign(/* @__PURE__ */ Object.create(null), {
111716
- path: path6,
112300
+ path: path5,
111717
112301
  method,
111718
112302
  headers: toByteStringHeaderObject(headers),
111719
112303
  agents: { http: httpAgent, https: httpsAgent },
@@ -112130,14 +112714,14 @@ var init_cookies = __esm({
112130
112714
  cookies_default = platform_default.hasStandardBrowserEnv ? (
112131
112715
  // Standard browser envs support document.cookie
112132
112716
  {
112133
- write(name, value, expires, path6, domain, secure, sameSite) {
112717
+ write(name, value, expires, path5, domain, secure, sameSite) {
112134
112718
  if (typeof document === "undefined") return;
112135
112719
  const cookie = [`${name}=${encodeURIComponent(value)}`];
112136
112720
  if (utils_default.isNumber(expires)) {
112137
112721
  cookie.push(`expires=${new Date(expires).toUTCString()}`);
112138
112722
  }
112139
- if (utils_default.isString(path6)) {
112140
- cookie.push(`path=${path6}`);
112723
+ if (utils_default.isString(path5)) {
112724
+ cookie.push(`path=${path5}`);
112141
112725
  }
112142
112726
  if (utils_default.isString(domain)) {
112143
112727
  cookie.push(`domain=${domain}`);
@@ -115566,15 +116150,15 @@ var init_constants3 = __esm({
115566
116150
  });
115567
116151
 
115568
116152
  // src/polymarket/wallet-adapter.ts
115569
- import fs from "fs";
115570
- import { homedir as homedir7 } from "os";
115571
- import { join as join10 } from "path";
116153
+ import fs2 from "fs";
116154
+ import { homedir as homedir8 } from "os";
116155
+ import { join as join11 } from "path";
115572
116156
  function getOrCreateWalletKey() {
115573
116157
  const envKey = process.env.BLOCKRUN_WALLET_KEY?.trim();
115574
116158
  if (envKey && /^0x[0-9a-fA-F]{64}$/.test(envKey)) return envKey;
115575
116159
  let key2;
115576
116160
  try {
115577
- key2 = fs.readFileSync(WALLET_FILE2, "utf-8").trim();
116161
+ key2 = fs2.readFileSync(WALLET_FILE2, "utf-8").trim();
115578
116162
  } catch (err) {
115579
116163
  if (err.code === "ENOENT") {
115580
116164
  throw new Error(
@@ -115616,7 +116200,7 @@ var init_wallet_adapter = __esm({
115616
116200
  init_esm();
115617
116201
  init_chains();
115618
116202
  init_constants3();
115619
- WALLET_FILE2 = join10(homedir7(), ".openclaw", "blockrun", "wallet.key");
116203
+ WALLET_FILE2 = join11(homedir8(), ".openclaw", "blockrun", "wallet.key");
115620
116204
  BASE_RPC_URLS = [
115621
116205
  "https://mainnet.base.org",
115622
116206
  "https://base.llamarpc.com",
@@ -115627,21 +116211,21 @@ var init_wallet_adapter = __esm({
115627
116211
  });
115628
116212
 
115629
116213
  // src/polymarket/creds.ts
115630
- import fs2 from "fs";
115631
- import path from "path";
116214
+ import fs3 from "fs";
116215
+ import path2 from "path";
115632
116216
  import os from "os";
115633
116217
  function readJsonFile(file) {
115634
116218
  try {
115635
- if (!fs2.existsSync(file)) return null;
115636
- const raw = fs2.readFileSync(file, "utf-8").trim();
116219
+ if (!fs3.existsSync(file)) return null;
116220
+ const raw = fs3.readFileSync(file, "utf-8").trim();
115637
116221
  return raw ? JSON.parse(raw) : null;
115638
116222
  } catch {
115639
116223
  return null;
115640
116224
  }
115641
116225
  }
115642
116226
  function writeJsonFile(file, value) {
115643
- fs2.mkdirSync(BLOCKRUN_DIR, { recursive: true });
115644
- fs2.writeFileSync(file, JSON.stringify(value, null, 2), { mode: 384 });
116227
+ fs3.mkdirSync(BLOCKRUN_DIR, { recursive: true });
116228
+ fs3.writeFileSync(file, JSON.stringify(value, null, 2), { mode: 384 });
115645
116229
  }
115646
116230
  function credsKey(address2, sigType) {
115647
116231
  return `${address2.toLowerCase()}:${sigType}`;
@@ -115693,10 +116277,10 @@ var BLOCKRUN_DIR, CREDS_FILE, BUILDER_CREDS_FILE, STATE_FILE;
115693
116277
  var init_creds = __esm({
115694
116278
  "src/polymarket/creds.ts"() {
115695
116279
  "use strict";
115696
- BLOCKRUN_DIR = path.join(os.homedir(), ".openclaw", "blockrun");
115697
- CREDS_FILE = path.join(BLOCKRUN_DIR, ".polymarket-creds");
115698
- BUILDER_CREDS_FILE = path.join(BLOCKRUN_DIR, ".polymarket-builder-creds");
115699
- STATE_FILE = path.join(BLOCKRUN_DIR, ".polymarket.json");
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");
115700
116284
  }
115701
116285
  });
115702
116286
 
@@ -116878,13 +117462,13 @@ function __disposeResources(env) {
116878
117462
  }
116879
117463
  return next();
116880
117464
  }
116881
- function __rewriteRelativeImportExtension(path6, preserveJsx) {
116882
- if (typeof path6 === "string" && /^\.\.?\//.test(path6)) {
116883
- return path6.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
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) {
116884
117468
  return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
116885
117469
  });
116886
117470
  }
116887
- return path6;
117471
+ return path5;
116888
117472
  }
116889
117473
  var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
116890
117474
  var init_tslib_es6 = __esm({
@@ -149181,9 +149765,9 @@ var require_setupKzg = __commonJS({
149181
149765
  Object.defineProperty(exports, "__esModule", { value: true });
149182
149766
  exports.setupKzg = setupKzg;
149183
149767
  var defineKzg_js_1 = require_defineKzg();
149184
- function setupKzg(parameters, path6) {
149768
+ function setupKzg(parameters, path5) {
149185
149769
  try {
149186
- parameters.loadTrustedSetup(path6);
149770
+ parameters.loadTrustedSetup(path5);
149187
149771
  } catch (e7) {
149188
149772
  const error = e7;
149189
149773
  if (!error.message.includes("trusted setup is already loaded"))
@@ -197268,12 +197852,12 @@ var init_fragments = __esm({
197268
197852
  // node_modules/@ethersproject/abi/lib.esm/coders/abstract-coder.js
197269
197853
  function checkResultErrors(result) {
197270
197854
  const errors = [];
197271
- const checkErrors = function(path6, object) {
197855
+ const checkErrors = function(path5, object) {
197272
197856
  if (!Array.isArray(object)) {
197273
197857
  return;
197274
197858
  }
197275
197859
  for (let key2 in object) {
197276
- const childPath = path6.slice();
197860
+ const childPath = path5.slice();
197277
197861
  childPath.push(key2);
197278
197862
  try {
197279
197863
  checkErrors(childPath, object[key2]);
@@ -203091,8 +203675,8 @@ function createCommonjsModule(fn, basedir, module) {
203091
203675
  return module = {
203092
203676
  path: basedir,
203093
203677
  exports: {},
203094
- require: function(path6, base3) {
203095
- return commonjsRequire(path6, base3 === void 0 || base3 === null ? module.path : base3);
203678
+ require: function(path5, base3) {
203679
+ return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
203096
203680
  }
203097
203681
  }, fn(module, module.exports), module.exports;
203098
203682
  }
@@ -206942,9 +207526,9 @@ var init_lib23 = __esm({
206942
207526
  if (index2 > 4294967295) {
206943
207527
  throw new Error("invalid index - " + String(index2));
206944
207528
  }
206945
- let path6 = this.path;
206946
- if (path6) {
206947
- path6 += "/" + (index2 & ~HardenedBit);
207529
+ let path5 = this.path;
207530
+ if (path5) {
207531
+ path5 += "/" + (index2 & ~HardenedBit);
206948
207532
  }
206949
207533
  const data = new Uint8Array(37);
206950
207534
  if (index2 & HardenedBit) {
@@ -206952,8 +207536,8 @@ var init_lib23 = __esm({
206952
207536
  throw new Error("cannot derive child of neutered node");
206953
207537
  }
206954
207538
  data.set(arrayify(this.privateKey), 1);
206955
- if (path6) {
206956
- path6 += "'";
207539
+ if (path5) {
207540
+ path5 += "'";
206957
207541
  }
206958
207542
  } else {
206959
207543
  data.set(arrayify(this.publicKey));
@@ -206972,21 +207556,21 @@ var init_lib23 = __esm({
206972
207556
  const ek = new SigningKey(hexlify(IL));
206973
207557
  Ki = ek._addPoint(this.publicKey);
206974
207558
  }
206975
- let mnemonicOrPath = path6;
207559
+ let mnemonicOrPath = path5;
206976
207560
  const srcMnemonic = this.mnemonic;
206977
207561
  if (srcMnemonic) {
206978
207562
  mnemonicOrPath = Object.freeze({
206979
207563
  phrase: srcMnemonic.phrase,
206980
- path: path6,
207564
+ path: path5,
206981
207565
  locale: srcMnemonic.locale || "en"
206982
207566
  });
206983
207567
  }
206984
207568
  return new _HDNode(_constructorGuard4, ki, Ki, this.fingerprint, bytes32(IR), index2, this.depth + 1, mnemonicOrPath);
206985
207569
  }
206986
- derivePath(path6) {
206987
- const components = path6.split("/");
207570
+ derivePath(path5) {
207571
+ const components = path5.split("/");
206988
207572
  if (components.length === 0 || components[0] === "m" && this.depth !== 0) {
206989
- throw new Error("invalid path - " + path6);
207573
+ throw new Error("invalid path - " + path5);
206990
207574
  }
206991
207575
  if (components[0] === "m") {
206992
207576
  components.shift();
@@ -207721,9 +208305,9 @@ function getPassword(password) {
207721
208305
  }
207722
208306
  return arrayify(password);
207723
208307
  }
207724
- function searchPath(object, path6) {
208308
+ function searchPath(object, path5) {
207725
208309
  let currentChild = object;
207726
- const comps = path6.toLowerCase().split("/");
208310
+ const comps = path5.toLowerCase().split("/");
207727
208311
  for (let i = 0; i < comps.length; i++) {
207728
208312
  let matchingChild = null;
207729
208313
  for (const key2 in currentChild) {
@@ -208372,12 +208956,12 @@ function _getAccount(data, key2) {
208372
208956
  const mnemonicIv = looseArrayify(searchPath(data, "x-ethers/mnemonicCounter"));
208373
208957
  const mnemonicCounter = new import_aes_js2.default.Counter(mnemonicIv);
208374
208958
  const mnemonicAesCtr = new import_aes_js2.default.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
208375
- const path6 = searchPath(data, "x-ethers/path") || defaultPath;
208959
+ const path5 = searchPath(data, "x-ethers/path") || defaultPath;
208376
208960
  const locale = searchPath(data, "x-ethers/locale") || "en";
208377
208961
  const entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));
208378
208962
  try {
208379
208963
  const mnemonic = entropyToMnemonic2(entropy, locale);
208380
- const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path6);
208964
+ const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path5);
208381
208965
  if (node.privateKey != account.privateKey) {
208382
208966
  throw new Error("mnemonic mismatch");
208383
208967
  }
@@ -208477,12 +209061,12 @@ function encrypt(account, password, options, progressCallback) {
208477
209061
  const privateKey = arrayify(account.privateKey);
208478
209062
  const passwordBytes = getPassword(password);
208479
209063
  let entropy = null;
208480
- let path6 = null;
209064
+ let path5 = null;
208481
209065
  let locale = null;
208482
209066
  if (hasMnemonic(account)) {
208483
209067
  const srcMnemonic = account.mnemonic;
208484
209068
  entropy = arrayify(mnemonicToEntropy2(srcMnemonic.phrase, srcMnemonic.locale || "en"));
208485
- path6 = srcMnemonic.path || defaultPath;
209069
+ path5 = srcMnemonic.path || defaultPath;
208486
209070
  locale = srcMnemonic.locale || "en";
208487
209071
  }
208488
209072
  let client = options.client;
@@ -208568,7 +209152,7 @@ function encrypt(account, password, options, progressCallback) {
208568
209152
  gethFilename: "UTC--" + timestamp + "--" + data.address,
208569
209153
  mnemonicCounter: hexlify(mnemonicIv).substring(2),
208570
209154
  mnemonicCiphertext: hexlify(mnemonicCiphertext).substring(2),
208571
- path: path6,
209155
+ path: path5,
208572
209156
  locale,
208573
209157
  version: "0.1"
208574
209158
  };
@@ -208862,11 +209446,11 @@ var init_lib26 = __esm({
208862
209446
  static fromEncryptedJsonSync(json, password) {
208863
209447
  return new _Wallet(decryptJsonWalletSync(json, password));
208864
209448
  }
208865
- static fromMnemonic(mnemonic, path6, wordlist3) {
208866
- if (!path6) {
208867
- path6 = defaultPath;
209449
+ static fromMnemonic(mnemonic, path5, wordlist3) {
209450
+ if (!path5) {
209451
+ path5 = defaultPath;
208868
209452
  }
208869
- return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(path6));
209453
+ return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(path5));
208870
209454
  }
208871
209455
  };
208872
209456
  }
@@ -214862,21 +215446,21 @@ var init_web3_provider = __esm({
214862
215446
  if (provider == null) {
214863
215447
  logger43.throwArgumentError("missing provider", "provider", provider);
214864
215448
  }
214865
- let path6 = null;
215449
+ let path5 = null;
214866
215450
  let jsonRpcFetchFunc = null;
214867
215451
  let subprovider = null;
214868
215452
  if (typeof provider === "function") {
214869
- path6 = "unknown:";
215453
+ path5 = "unknown:";
214870
215454
  jsonRpcFetchFunc = provider;
214871
215455
  } else {
214872
- path6 = provider.host || provider.path || "";
214873
- if (!path6 && provider.isMetaMask) {
214874
- path6 = "metamask";
215456
+ path5 = provider.host || provider.path || "";
215457
+ if (!path5 && provider.isMetaMask) {
215458
+ path5 = "metamask";
214875
215459
  }
214876
215460
  subprovider = provider;
214877
215461
  if (provider.request) {
214878
- if (path6 === "") {
214879
- path6 = "eip-1193:";
215462
+ if (path5 === "") {
215463
+ path5 = "eip-1193:";
214880
215464
  }
214881
215465
  jsonRpcFetchFunc = buildEip1193Fetcher(provider);
214882
215466
  } else if (provider.sendAsync) {
@@ -214886,11 +215470,11 @@ var init_web3_provider = __esm({
214886
215470
  } else {
214887
215471
  logger43.throwArgumentError("unsupported provider", "provider", provider);
214888
215472
  }
214889
- if (!path6) {
214890
- path6 = "unknown:";
215473
+ if (!path5) {
215474
+ path5 = "unknown:";
214891
215475
  }
214892
215476
  }
214893
- super(path6, network);
215477
+ super(path5, network);
214894
215478
  defineReadOnly(this, "jsonRpcFetchFunc", jsonRpcFetchFunc);
214895
215479
  defineReadOnly(this, "provider", subprovider);
214896
215480
  }
@@ -215728,7 +216312,7 @@ var require_axios = __commonJS({
215728
216312
  var https2 = __require("https");
215729
216313
  var http23 = __require("http2");
215730
216314
  var util5 = __require("util");
215731
- var path6 = __require("path");
216315
+ var path5 = __require("path");
215732
216316
  var followRedirects2 = require_follow_redirects();
215733
216317
  var zlib2 = __require("zlib");
215734
216318
  var stream4 = __require("stream");
@@ -216796,9 +217380,9 @@ var require_axios = __commonJS({
216796
217380
  function removeBrackets2(key2) {
216797
217381
  return utils$1.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
216798
217382
  }
216799
- function renderKey2(path7, key2, dots) {
216800
- if (!path7) return key2;
216801
- return path7.concat(key2).map(function each(token, i) {
217383
+ function renderKey2(path6, key2, dots) {
217384
+ if (!path6) return key2;
217385
+ return path6.concat(key2).map(function each(token, i) {
216802
217386
  token = removeBrackets2(token);
216803
217387
  return !dots && i ? "[" + token + "]" : token;
216804
217388
  }).join(dots ? "." : "");
@@ -216876,13 +217460,13 @@ var require_axios = __commonJS({
216876
217460
  return currentValue;
216877
217461
  });
216878
217462
  }
216879
- function defaultVisitor(value, key2, path7) {
217463
+ function defaultVisitor(value, key2, path6) {
216880
217464
  let arr = value;
216881
217465
  if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
216882
- formData.append(renderKey2(path7, key2, dots), convertValue(value));
217466
+ formData.append(renderKey2(path6, key2, dots), convertValue(value));
216883
217467
  return false;
216884
217468
  }
216885
- if (value && !path7 && typeof value === "object") {
217469
+ if (value && !path6 && typeof value === "object") {
216886
217470
  if (utils$1.endsWith(key2, "{}")) {
216887
217471
  key2 = metaTokens ? key2 : key2.slice(0, -2);
216888
217472
  value = stringifyWithDepthLimit(value, 1);
@@ -216901,7 +217485,7 @@ var require_axios = __commonJS({
216901
217485
  if (isVisitable2(value)) {
216902
217486
  return true;
216903
217487
  }
216904
- formData.append(renderKey2(path7, key2, dots), convertValue(value));
217488
+ formData.append(renderKey2(path6, key2, dots), convertValue(value));
216905
217489
  return false;
216906
217490
  }
216907
217491
  const exposedHelpers = Object.assign(predicates2, {
@@ -216909,17 +217493,17 @@ var require_axios = __commonJS({
216909
217493
  convertValue,
216910
217494
  isVisitable: isVisitable2
216911
217495
  });
216912
- function build(value, path7, depth = 0) {
217496
+ function build(value, path6, depth = 0) {
216913
217497
  if (utils$1.isUndefined(value)) return;
216914
217498
  throwIfMaxDepthExceeded(depth);
216915
217499
  if (stack.indexOf(value) !== -1) {
216916
- throw new Error("Circular reference detected in " + path7.join("."));
217500
+ throw new Error("Circular reference detected in " + path6.join("."));
216917
217501
  }
216918
217502
  stack.push(value);
216919
217503
  utils$1.forEach(value, function each(el, key2) {
216920
- const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2, path7, exposedHelpers);
217504
+ const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2, path6, exposedHelpers);
216921
217505
  if (result === true) {
216922
- build(el, path7 ? path7.concat(key2) : [key2], depth + 1);
217506
+ build(el, path6 ? path6.concat(key2) : [key2], depth + 1);
216923
217507
  }
216924
217508
  });
216925
217509
  stack.pop();
@@ -217108,7 +217692,7 @@ var require_axios = __commonJS({
217108
217692
  };
217109
217693
  function toURLEncodedForm2(data, options) {
217110
217694
  return toFormData3(data, new platform2.classes.URLSearchParams(), {
217111
- visitor: function(value, key2, path7, helpers) {
217695
+ visitor: function(value, key2, path6, helpers) {
217112
217696
  if (platform2.isNode && utils$1.isBuffer(value)) {
217113
217697
  this.append(key2, value.toString("base64"));
217114
217698
  return false;
@@ -217125,14 +217709,14 @@ var require_axios = __commonJS({
217125
217709
  }
217126
217710
  }
217127
217711
  function parsePropPath2(name) {
217128
- const path7 = [];
217712
+ const path6 = [];
217129
217713
  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
217130
217714
  let match;
217131
217715
  while ((match = pattern.exec(name)) !== null) {
217132
- throwIfDepthExceeded2(path7.length);
217133
- path7.push(match[0] === "[]" ? "" : match[1] || match[0]);
217716
+ throwIfDepthExceeded2(path6.length);
217717
+ path6.push(match[0] === "[]" ? "" : match[1] || match[0]);
217134
217718
  }
217135
- return path7;
217719
+ return path6;
217136
217720
  }
217137
217721
  function arrayToObject2(arr) {
217138
217722
  const obj = {};
@@ -217147,12 +217731,12 @@ var require_axios = __commonJS({
217147
217731
  return obj;
217148
217732
  }
217149
217733
  function formDataToJSON2(formData) {
217150
- function buildPath(path7, value, target, index2) {
217734
+ function buildPath(path6, value, target, index2) {
217151
217735
  throwIfDepthExceeded2(index2);
217152
- let name = path7[index2++];
217736
+ let name = path6[index2++];
217153
217737
  if (name === "__proto__") return true;
217154
217738
  const isNumericKey = Number.isFinite(+name);
217155
- const isLast = index2 >= path7.length;
217739
+ const isLast = index2 >= path6.length;
217156
217740
  name = !name && utils$1.isArray(target) ? target.length : name;
217157
217741
  if (isLast) {
217158
217742
  if (utils$1.hasOwnProp(target, name)) {
@@ -217165,7 +217749,7 @@ var require_axios = __commonJS({
217165
217749
  if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
217166
217750
  target[name] = [];
217167
217751
  }
217168
- const result = buildPath(path7, value, target[name], index2);
217752
+ const result = buildPath(path6, value, target[name], index2);
217169
217753
  if (result && utils$1.isArray(target[name])) {
217170
217754
  target[name] = arrayToObject2(target[name]);
217171
217755
  }
@@ -218776,8 +219360,8 @@ var require_axios = __commonJS({
218776
219360
  const allowedSocketPaths = own3("allowedSocketPaths");
218777
219361
  if (allowedSocketPaths != null) {
218778
219362
  const allowed = Array.isArray(allowedSocketPaths) ? allowedSocketPaths : [allowedSocketPaths];
218779
- const resolvedSocket = path6.resolve(socketPath);
218780
- const isAllowed = allowed.some((entry) => typeof entry === "string" && path6.resolve(entry) === resolvedSocket);
219363
+ const resolvedSocket = path5.resolve(socketPath);
219364
+ const isAllowed = allowed.some((entry) => typeof entry === "string" && path5.resolve(entry) === resolvedSocket);
218781
219365
  if (!isAllowed) {
218782
219366
  return reject(new AxiosError3(`socketPath "${socketPath}" is not permitted by allowedSocketPaths`, AxiosError3.ERR_BAD_OPTION_VALUE, config));
218783
219367
  }
@@ -219076,14 +219660,14 @@ var require_axios = __commonJS({
219076
219660
  var cookies = platform2.hasStandardBrowserEnv ? (
219077
219661
  // Standard browser envs support document.cookie
219078
219662
  {
219079
- write(name, value, expires, path7, domain, secure, sameSite) {
219663
+ write(name, value, expires, path6, domain, secure, sameSite) {
219080
219664
  if (typeof document === "undefined") return;
219081
219665
  const cookie = [`${name}=${encodeURIComponent(value)}`];
219082
219666
  if (utils$1.isNumber(expires)) {
219083
219667
  cookie.push(`expires=${new Date(expires).toUTCString()}`);
219084
219668
  }
219085
- if (utils$1.isString(path7)) {
219086
- cookie.push(`path=${path7}`);
219669
+ if (utils$1.isString(path6)) {
219670
+ cookie.push(`path=${path6}`);
219087
219671
  }
219088
219672
  if (utils$1.isString(domain)) {
219089
219673
  cookie.push(`domain=${domain}`);
@@ -223572,18 +224156,18 @@ var require_client2 = __commonJS({
223572
224156
  }
223573
224157
  console.log(`Transaction not found or not in given states, timing out!`);
223574
224158
  }
223575
- async sendAuthedRequest(method, path6, body) {
224159
+ async sendAuthedRequest(method, path5, body) {
223576
224160
  if (this.canBuilderAuth()) {
223577
- const builderHeaders = await this._generateBuilderHeaders(method, path6, body);
224161
+ const builderHeaders = await this._generateBuilderHeaders(method, path5, body);
223578
224162
  if (builderHeaders !== void 0) {
223579
- return this.send(path6, method, { headers: builderHeaders, data: body });
224163
+ return this.send(path5, method, { headers: builderHeaders, data: body });
223580
224164
  }
223581
224165
  }
223582
- return this.send(path6, method, { data: body });
224166
+ return this.send(path5, method, { data: body });
223583
224167
  }
223584
- async _generateBuilderHeaders(method, path6, body) {
224168
+ async _generateBuilderHeaders(method, path5, body) {
223585
224169
  if (this.builderConfig !== void 0) {
223586
- const builderHeaders = await this.builderConfig.generateBuilderHeaders(method, path6, body);
224170
+ const builderHeaders = await this.builderConfig.generateBuilderHeaders(method, path5, body);
223587
224171
  if (builderHeaders == void 0) {
223588
224172
  return void 0;
223589
224173
  }
@@ -223674,12 +224258,12 @@ var require_signer = __commonJS({
223674
224258
  constructor(creds) {
223675
224259
  this.creds = creds;
223676
224260
  }
223677
- createBuilderHeaderPayload(method, path6, body, timestamp) {
224261
+ createBuilderHeaderPayload(method, path5, body, timestamp) {
223678
224262
  let ts = Math.floor(Date.now() / 1e3);
223679
224263
  if (timestamp !== void 0) {
223680
224264
  ts = timestamp;
223681
224265
  }
223682
- const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method, path6, body);
224266
+ const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method, path5, body);
223683
224267
  return {
223684
224268
  POLY_BUILDER_API_KEY: this.creds.key,
223685
224269
  POLY_BUILDER_PASSPHRASE: this.creds.passphrase,
@@ -223768,17 +224352,17 @@ var require_config2 = __commonJS({
223768
224352
  * @param path
223769
224353
  * @param body
223770
224354
  */
223771
- async generateBuilderHeaders(method, path6, body, timestamp) {
224355
+ async generateBuilderHeaders(method, path5, body, timestamp) {
223772
224356
  this.ensureValid();
223773
224357
  const builderType = this.getBuilderType();
223774
224358
  if (builderType == types_1.BuilderType.LOCAL) {
223775
- return Promise.resolve(this.signer?.createBuilderHeaderPayload(method, path6, body, timestamp));
224359
+ return Promise.resolve(this.signer?.createBuilderHeaderPayload(method, path5, body, timestamp));
223776
224360
  }
223777
224361
  if (builderType == types_1.BuilderType.REMOTE) {
223778
224362
  const url2 = this.remoteBuilderConfig.url;
223779
224363
  const payload = {
223780
224364
  method,
223781
- path: path6,
224365
+ path: path5,
223782
224366
  body,
223783
224367
  timestamp
223784
224368
  };
@@ -224560,11 +225144,11 @@ var init_withdraw = __esm({
224560
225144
  });
224561
225145
 
224562
225146
  // node_modules/@blockrun/llm/dist/index.js
224563
- import * as path2 from "path";
225147
+ import * as path3 from "path";
224564
225148
  import * as os2 from "os";
224565
225149
  import * as path22 from "path";
224566
225150
  import * as os22 from "os";
224567
- import * as path3 from "path";
225151
+ import * as path32 from "path";
224568
225152
  import * as os3 from "os";
224569
225153
  import * as path4 from "path";
224570
225154
  import * as os4 from "os";
@@ -224738,7 +225322,7 @@ function resolveDefaultTimeout() {
224738
225322
  function sleep2(ms) {
224739
225323
  return new Promise((r2) => setTimeout(r2, ms));
224740
225324
  }
224741
- 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_DIR2, WALLET_FILE3, WALLET_DIR22, SOLANA_WALLET_FILE, CACHE_DIR, DATA_DIR, COST_LOG_FILE2, DEFAULT_TTL;
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;
224742
225326
  var init_dist7 = __esm({
224743
225327
  "node_modules/@blockrun/llm/dist/index.js"() {
224744
225328
  "use strict";
@@ -224786,8 +225370,8 @@ var init_dist7 = __esm({
224786
225370
  };
224787
225371
  BLOCKRUN_SERVICE_CODE2 = "blockrun";
224788
225372
  LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
224789
- BLOCKRUN_DIR2 = path2.join(os2.homedir(), ".blockrun");
224790
- COST_LOG_FILE = path2.join(BLOCKRUN_DIR2, "cost_log.jsonl");
225373
+ BLOCKRUN_DIR2 = path3.join(os2.homedir(), ".blockrun");
225374
+ COST_LOG_FILE = path3.join(BLOCKRUN_DIR2, "cost_log.jsonl");
224791
225375
  SDK_VERSION = "3.10.0";
224792
225376
  USER_AGENT2 = `blockrun-ts/${SDK_VERSION}`;
224793
225377
  DEFAULT_TIMEOUT = resolveDefaultTimeout();
@@ -224832,15 +225416,15 @@ var init_dist7 = __esm({
224832
225416
  * `/api` is tolerated and stripped). Query params are URL-encoded; arrays
224833
225417
  * become repeated keys (`?a=1&a=2`); undefined/null are dropped.
224834
225418
  */
224835
- async get(path52, params) {
224836
- const url2 = this.buildUrl(path52, params);
225419
+ async get(path5, params) {
225420
+ const url2 = this.buildUrl(path5, params);
224837
225421
  return this.requestWithPayment(url2, "GET");
224838
225422
  }
224839
225423
  /**
224840
225424
  * POST a BlockRun endpoint with a JSON body.
224841
225425
  */
224842
- async post(path52, body) {
224843
- const url2 = this.buildUrl(path52);
225426
+ async post(path5, body) {
225427
+ const url2 = this.buildUrl(path5);
224844
225428
  return this.requestWithPayment(url2, "POST", body);
224845
225429
  }
224846
225430
  /**
@@ -224855,8 +225439,8 @@ var init_dist7 = __esm({
224855
225439
  * short-circuits and returns the body. Most long-running endpoints (image,
224856
225440
  * video, music, voice) return 202 with a poll_url.
224857
225441
  */
224858
- async poll(path52, body, options) {
224859
- const submitUrl = this.buildUrl(path52);
225442
+ async poll(path5, body, options) {
225443
+ const submitUrl = this.buildUrl(path5);
224860
225444
  const budgetMs = options?.budgetMs ?? DEFAULT_POLL_BUDGET_MS;
224861
225445
  const intervalMs = options?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
224862
225446
  const resp402 = await this.fetchWithTimeout(submitUrl, {
@@ -224955,8 +225539,8 @@ var init_dist7 = __esm({
224955
225539
  * process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
224956
225540
  * }
224957
225541
  */
224958
- async *stream(path52, body) {
224959
- const url2 = this.buildUrl(path52);
225542
+ async *stream(path5, body) {
225543
+ const url2 = this.buildUrl(path5);
224960
225544
  const requestBody = JSON.stringify(body ?? {});
224961
225545
  const resp402 = await this.fetchWithTimeout(url2, {
224962
225546
  method: "POST",
@@ -225022,8 +225606,8 @@ var init_dist7 = __esm({
225022
225606
  // --------------------------------------------------------------------
225023
225607
  // Internal: shared infrastructure
225024
225608
  // --------------------------------------------------------------------
225025
- buildUrl(path52, params) {
225026
- let normalized = path52.startsWith("/") ? path52 : `/${path52}`;
225609
+ buildUrl(path5, params) {
225610
+ let normalized = path5.startsWith("/") ? path5 : `/${path5}`;
225027
225611
  if (normalized.startsWith("/api/")) {
225028
225612
  normalized = normalized.slice(4);
225029
225613
  }
@@ -225171,10 +225755,10 @@ var init_dist7 = __esm({
225171
225755
  return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
225172
225756
  }
225173
225757
  };
225174
- WALLET_DIR2 = path22.join(os22.homedir(), ".blockrun");
225175
- WALLET_FILE3 = path22.join(WALLET_DIR2, ".session");
225176
- WALLET_DIR22 = path3.join(os3.homedir(), ".blockrun");
225177
- SOLANA_WALLET_FILE = path3.join(WALLET_DIR22, ".solana-session");
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");
225178
225762
  CACHE_DIR = path4.join(os4.homedir(), ".blockrun", "cache");
225179
225763
  DATA_DIR = path4.join(os4.homedir(), ".blockrun", "data");
225180
225764
  COST_LOG_FILE2 = path4.join(os4.homedir(), ".blockrun", "cost_log.jsonl");
@@ -225670,261 +226254,6 @@ var init_mcp_config = __esm({
225670
226254
  }
225671
226255
  });
225672
226256
 
225673
- // src/spend-control.ts
225674
- import * as fs3 from "fs";
225675
- import * as path5 from "path";
225676
- import { homedir as homedir12 } from "os";
225677
- function formatDuration(seconds) {
225678
- if (seconds < 60) {
225679
- return `${seconds}s`;
225680
- } else if (seconds < 3600) {
225681
- const mins = Math.ceil(seconds / 60);
225682
- return `${mins} min`;
225683
- } else {
225684
- const hours = Math.floor(seconds / 3600);
225685
- const mins = Math.ceil(seconds % 3600 / 60);
225686
- return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
225687
- }
225688
- }
225689
- var WALLET_DIR3, HOUR_MS, DAY_MS, FileSpendControlStorage, InMemorySpendControlStorage, SpendControl;
225690
- var init_spend_control = __esm({
225691
- "src/spend-control.ts"() {
225692
- "use strict";
225693
- init_fs_read();
225694
- WALLET_DIR3 = path5.join(homedir12(), ".openclaw", "blockrun");
225695
- HOUR_MS = 60 * 60 * 1e3;
225696
- DAY_MS = 24 * HOUR_MS;
225697
- FileSpendControlStorage = class {
225698
- spendingFile;
225699
- constructor() {
225700
- this.spendingFile = path5.join(WALLET_DIR3, "spending.json");
225701
- }
225702
- load() {
225703
- try {
225704
- if (fs3.existsSync(this.spendingFile)) {
225705
- const data = JSON.parse(readTextFileSync(this.spendingFile));
225706
- const rawLimits = data.limits ?? {};
225707
- const rawHistory = data.history ?? [];
225708
- const limits = {};
225709
- for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
225710
- const val = rawLimits[key2];
225711
- if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
225712
- limits[key2] = val;
225713
- }
225714
- }
225715
- const history = [];
225716
- if (Array.isArray(rawHistory)) {
225717
- for (const r2 of rawHistory) {
225718
- if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
225719
- history.push({
225720
- timestamp: r2.timestamp,
225721
- amount: r2.amount,
225722
- model: typeof r2.model === "string" ? r2.model : void 0,
225723
- action: typeof r2.action === "string" ? r2.action : void 0
225724
- });
225725
- }
225726
- }
225727
- }
225728
- return { limits, history };
225729
- }
225730
- } catch (err) {
225731
- console.error(`[ClawRouter] Failed to load spending data, starting fresh: ${err}`);
225732
- }
225733
- return null;
225734
- }
225735
- save(data) {
225736
- try {
225737
- if (!fs3.existsSync(WALLET_DIR3)) {
225738
- fs3.mkdirSync(WALLET_DIR3, { recursive: true, mode: 448 });
225739
- }
225740
- fs3.writeFileSync(this.spendingFile, JSON.stringify(data, null, 2), {
225741
- mode: 384
225742
- });
225743
- } catch (err) {
225744
- console.error(`[ClawRouter] Failed to save spending data: ${err}`);
225745
- }
225746
- }
225747
- };
225748
- InMemorySpendControlStorage = class {
225749
- data = null;
225750
- load() {
225751
- return this.data ? {
225752
- limits: { ...this.data.limits },
225753
- history: this.data.history.map((r2) => ({ ...r2 }))
225754
- } : null;
225755
- }
225756
- save(data) {
225757
- this.data = {
225758
- limits: { ...data.limits },
225759
- history: data.history.map((r2) => ({ ...r2 }))
225760
- };
225761
- }
225762
- };
225763
- SpendControl = class {
225764
- limits = {};
225765
- history = [];
225766
- sessionSpent = 0;
225767
- sessionCalls = 0;
225768
- storage;
225769
- now;
225770
- constructor(options) {
225771
- this.storage = options?.storage ?? new FileSpendControlStorage();
225772
- this.now = options?.now ?? (() => Date.now());
225773
- this.load();
225774
- }
225775
- setLimit(window2, amount) {
225776
- if (!Number.isFinite(amount) || amount <= 0) {
225777
- throw new Error("Limit must be a finite positive number");
225778
- }
225779
- this.limits[window2] = amount;
225780
- this.save();
225781
- }
225782
- clearLimit(window2) {
225783
- delete this.limits[window2];
225784
- this.save();
225785
- }
225786
- getLimits() {
225787
- return { ...this.limits };
225788
- }
225789
- check(estimatedCost2) {
225790
- const now2 = this.now();
225791
- if (this.limits.perRequest !== void 0) {
225792
- if (estimatedCost2 > this.limits.perRequest) {
225793
- return {
225794
- allowed: false,
225795
- blockedBy: "perRequest",
225796
- remaining: this.limits.perRequest,
225797
- reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
225798
- };
225799
- }
225800
- }
225801
- if (this.limits.hourly !== void 0) {
225802
- const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
225803
- const remaining = this.limits.hourly - hourlySpent;
225804
- if (estimatedCost2 > remaining) {
225805
- const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
225806
- const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
225807
- return {
225808
- allowed: false,
225809
- blockedBy: "hourly",
225810
- remaining,
225811
- reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
225812
- resetIn
225813
- };
225814
- }
225815
- }
225816
- if (this.limits.daily !== void 0) {
225817
- const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
225818
- const remaining = this.limits.daily - dailySpent;
225819
- if (estimatedCost2 > remaining) {
225820
- const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
225821
- const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
225822
- return {
225823
- allowed: false,
225824
- blockedBy: "daily",
225825
- remaining,
225826
- reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
225827
- resetIn
225828
- };
225829
- }
225830
- }
225831
- if (this.limits.session !== void 0) {
225832
- const remaining = this.limits.session - this.sessionSpent;
225833
- if (estimatedCost2 > remaining) {
225834
- return {
225835
- allowed: false,
225836
- blockedBy: "session",
225837
- remaining,
225838
- reason: `Session limit exceeded: $${(this.sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
225839
- };
225840
- }
225841
- }
225842
- return { allowed: true };
225843
- }
225844
- record(amount, metadata) {
225845
- if (!Number.isFinite(amount) || amount < 0) {
225846
- throw new Error("Record amount must be a non-negative finite number");
225847
- }
225848
- const record = {
225849
- timestamp: this.now(),
225850
- amount,
225851
- model: metadata?.model,
225852
- action: metadata?.action
225853
- };
225854
- this.history.push(record);
225855
- this.sessionSpent += amount;
225856
- this.sessionCalls += 1;
225857
- this.cleanup();
225858
- this.save();
225859
- }
225860
- getSpendingInWindow(from15, to) {
225861
- return this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
225862
- }
225863
- getSpending(window2) {
225864
- const now2 = this.now();
225865
- switch (window2) {
225866
- case "hourly":
225867
- return this.getSpendingInWindow(now2 - HOUR_MS, now2);
225868
- case "daily":
225869
- return this.getSpendingInWindow(now2 - DAY_MS, now2);
225870
- case "session":
225871
- return this.sessionSpent;
225872
- }
225873
- }
225874
- getRemaining(window2) {
225875
- const limit = this.limits[window2];
225876
- if (limit === void 0) return null;
225877
- return Math.max(0, limit - this.getSpending(window2));
225878
- }
225879
- getStatus() {
225880
- const now2 = this.now();
225881
- const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
225882
- const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
225883
- return {
225884
- limits: { ...this.limits },
225885
- spending: {
225886
- hourly: hourlySpent,
225887
- daily: dailySpent,
225888
- session: this.sessionSpent
225889
- },
225890
- remaining: {
225891
- hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
225892
- daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
225893
- session: this.limits.session !== void 0 ? this.limits.session - this.sessionSpent : null
225894
- },
225895
- calls: this.sessionCalls
225896
- };
225897
- }
225898
- getHistory(limit) {
225899
- const records = [...this.history].reverse();
225900
- return limit ? records.slice(0, limit) : records;
225901
- }
225902
- resetSession() {
225903
- this.sessionSpent = 0;
225904
- this.sessionCalls = 0;
225905
- }
225906
- cleanup() {
225907
- const cutoff = this.now() - DAY_MS;
225908
- this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
225909
- }
225910
- save() {
225911
- this.storage.save({
225912
- limits: { ...this.limits },
225913
- history: [...this.history]
225914
- });
225915
- }
225916
- load() {
225917
- const data = this.storage.load();
225918
- if (data) {
225919
- this.limits = data.limits;
225920
- this.history = data.history;
225921
- this.cleanup();
225922
- }
225923
- }
225924
- };
225925
- }
225926
- });
225927
-
225928
226257
  // src/retry.ts
225929
226258
  function sleep3(ms) {
225930
226259
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -225993,6 +226322,8 @@ __export(index_exports, {
225993
226322
  BALANCE_THRESHOLDS: () => BALANCE_THRESHOLDS,
225994
226323
  BLOCKRUN_MODELS: () => BLOCKRUN_MODELS,
225995
226324
  BalanceMonitor: () => BalanceMonitor,
226325
+ CAIP2_BASE: () => CAIP2_BASE,
226326
+ CAIP2_SOLANA_MAINNET: () => CAIP2_SOLANA_MAINNET,
225996
226327
  DEFAULT_RETRY_CONFIG: () => DEFAULT_RETRY_CONFIG,
225997
226328
  DEFAULT_ROUTING_CONFIG: () => DEFAULT_ROUTING_CONFIG,
225998
226329
  DEFAULT_SESSION_CONFIG: () => DEFAULT_SESSION_CONFIG,
@@ -226001,6 +226332,7 @@ __export(index_exports, {
226001
226332
  InMemorySpendControlStorage: () => InMemorySpendControlStorage,
226002
226333
  InsufficientFundsError: () => InsufficientFundsError2,
226003
226334
  MODEL_ALIASES: () => MODEL_ALIASES,
226335
+ MalformedSpendPolicyError: () => MalformedSpendPolicyError,
226004
226336
  OPENCLAW_MODELS: () => OPENCLAW_MODELS,
226005
226337
  PARTNER_SERVICES: () => PARTNER_SERVICES,
226006
226338
  RequestDeduplicator: () => RequestDeduplicator,
@@ -226009,6 +226341,7 @@ __export(index_exports, {
226009
226341
  SessionStore: () => SessionStore,
226010
226342
  SolanaBalanceMonitor: () => SolanaBalanceMonitor,
226011
226343
  SpendControl: () => SpendControl,
226344
+ SpendPolicyError: () => SpendPolicyError,
226012
226345
  VISIBLE_OPENCLAW_MODELS: () => VISIBLE_OPENCLAW_MODELS,
226013
226346
  blockrunProvider: () => blockrunProvider,
226014
226347
  buildImageGenerationProvider: () => buildImageGenerationProvider,
@@ -226048,6 +226381,7 @@ __export(index_exports, {
226048
226381
  loadPaymentChain: () => loadPaymentChain,
226049
226382
  logUsage: () => logUsage,
226050
226383
  parseCallArgs: () => parseCallArgs,
226384
+ registerSpendPolicyHook: () => registerSpendPolicyHook,
226051
226385
  resolveModelAlias: () => resolveModelAlias,
226052
226386
  resolvePaymentChain: () => resolvePaymentChain,
226053
226387
  route: () => route,
@@ -226062,7 +226396,7 @@ import {
226062
226396
  readdirSync,
226063
226397
  mkdirSync as mkdirSync3,
226064
226398
  copyFileSync,
226065
- renameSync
226399
+ renameSync as renameSync2
226066
226400
  } from "fs";
226067
226401
  import { readFile as readFileAsync } from "fs/promises";
226068
226402
  import { homedir as homedir13 } from "os";
@@ -226340,7 +226674,7 @@ function injectModelsConfig(logger48, options = {}) {
226340
226674
  try {
226341
226675
  const tmpPath = `${configPath}.tmp.${process.pid}`;
226342
226676
  writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
226343
- renameSync(tmpPath, configPath);
226677
+ renameSync2(tmpPath, configPath);
226344
226678
  logger48.info("Smart routing enabled (blockrun/auto)");
226345
226679
  } catch (err) {
226346
226680
  logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
@@ -226376,7 +226710,7 @@ function syncAgentModelCache(logger48, options = {}) {
226376
226710
  entry.models = VISIBLE_OPENCLAW_MODELS;
226377
226711
  const tmpPath = `${cachePath}.tmp.${process.pid}`;
226378
226712
  writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
226379
- renameSync(tmpPath, cachePath);
226713
+ renameSync2(tmpPath, cachePath);
226380
226714
  logger48.info(
226381
226715
  `Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
226382
226716
  );
@@ -227740,7 +228074,7 @@ ${errText}`
227740
228074
  }
227741
228075
  const tmpPath = `${configPath}.tmp.${process.pid}`;
227742
228076
  writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
227743
- renameSync(tmpPath, configPath);
228077
+ renameSync2(tmpPath, configPath);
227744
228078
  api.logger.info("ClawRouter config cleaned up");
227745
228079
  }
227746
228080
  } catch (err) {
@@ -227835,7 +228169,7 @@ init_stats();
227835
228169
  init_proxy();
227836
228170
  init_version4();
227837
228171
  import { platform, arch, freemem, totalmem } from "os";
227838
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
228172
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
227839
228173
  function formatBytes(bytes) {
227840
228174
  const gb = bytes / (1024 * 1024 * 1024);
227841
228175
  return `${gb.toFixed(1)}GB`;
@@ -228124,7 +228458,7 @@ async function analyzeWithAI(diagnostics, userQuestion, model = "sonnet") {
228124
228458
  const paymentChain = diagnostics.wallet.paymentChain;
228125
228459
  if (paymentChain === "solana") {
228126
228460
  try {
228127
- if (!existsSync2(MNEMONIC_FILE)) {
228461
+ if (!existsSync3(MNEMONIC_FILE)) {
228128
228462
  throw new Error(`mnemonic file missing at ${MNEMONIC_FILE}`);
228129
228463
  }
228130
228464
  const mnemonic = readFileSync3(MNEMONIC_FILE, "utf8").trim();
@@ -228287,8 +228621,8 @@ Environment Variables:
228287
228621
  For more info: https://blockrun.ai/clawrouter.md
228288
228622
  `);
228289
228623
  }
228290
- async function queryProxy(path6, port) {
228291
- const res = await fetch(`http://127.0.0.1:${port}${path6}`);
228624
+ async function queryProxy(path5, port) {
228625
+ const res = await fetch(`http://127.0.0.1:${port}${path5}`);
228292
228626
  if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
228293
228627
  return res.json();
228294
228628
  }
@@ -228368,8 +228702,8 @@ Use: clawrouter share <id> --as=<feishu|slack|discord|telegram|whatsapp|plain>
228368
228702
  const { join: pjoin } = await import("path");
228369
228703
  const paths = [];
228370
228704
  for (const p of VALID_PRESETS) {
228371
- const path6 = idOrLast === "last" ? `/share/last?as=${p}` : `/share/${idOrLast}/render?as=${p}`;
228372
- const result = await queryProxy(path6, port);
228705
+ const path5 = idOrLast === "last" ? `/share/last?as=${p}` : `/share/${idOrLast}/render?as=${p}`;
228706
+ const result = await queryProxy(path5, port);
228373
228707
  const file = pjoin(tmpdir(), `claw-share-${result.id}-${p}.txt`);
228374
228708
  await writeFile3(file, result.rendered, "utf8");
228375
228709
  paths.push(file);
@@ -228390,8 +228724,8 @@ Use: clawrouter share <id> --as=<feishu|slack|discord|telegram|whatsapp|plain>
228390
228724
  process.exit(1);
228391
228725
  }
228392
228726
  try {
228393
- const path6 = idOrLast === "last" ? `/share/last?as=${chosenPreset}` : `/share/${idOrLast}/render?as=${chosenPreset}`;
228394
- const result = await queryProxy(path6, port);
228727
+ const path5 = idOrLast === "last" ? `/share/last?as=${chosenPreset}` : `/share/${idOrLast}/render?as=${chosenPreset}`;
228728
+ const result = await queryProxy(path5, port);
228395
228729
  process.stdout.write(result.rendered);
228396
228730
  if (!result.rendered.endsWith("\n")) process.stdout.write("\n");
228397
228731
  const clipErr = await copyToClipboard(result.rendered);
@@ -228511,8 +228845,8 @@ Usage Stats (last ${days} days)
228511
228845
  }
228512
228846
  async function cmdPhone(port, subcommand, numbersAction, arg, areaCode) {
228513
228847
  const base3 = `http://127.0.0.1:${port}`;
228514
- async function postJson(path6, body) {
228515
- const resp = await fetch(`${base3}${path6}`, {
228848
+ async function postJson(path5, body) {
228849
+ const resp = await fetch(`${base3}${path5}`, {
228516
228850
  method: "POST",
228517
228851
  headers: { "content-type": "application/json" },
228518
228852
  body: JSON.stringify(body)
@@ -228614,12 +228948,12 @@ Releasing ${arg}...
228614
228948
  console.error(`\u2717 Usage: clawrouter phone ${subcommand} <+E.164-number>`);
228615
228949
  process.exit(1);
228616
228950
  }
228617
- const path6 = subcommand === "fraud" ? "/v1/phone/lookup/fraud" : "/v1/phone/lookup";
228951
+ const path5 = subcommand === "fraud" ? "/v1/phone/lookup/fraud" : "/v1/phone/lookup";
228618
228952
  const price = subcommand === "fraud" ? "$0.05" : "$0.01";
228619
228953
  console.log(`
228620
228954
  Looking up ${arg}... (${price})
228621
228955
  `);
228622
- const result = await postJson(path6, { phoneNumber: arg });
228956
+ const result = await postJson(path5, { phoneNumber: arg });
228623
228957
  console.log(JSON.stringify(result, null, 2));
228624
228958
  console.log();
228625
228959
  }