@blockrun/clawrouter 0.12.255 → 0.12.257
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +973 -614
- package/dist/index.d.ts +235 -113
- package/dist/index.js +959 -600
- package/docs/configuration.md +81 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29310,8 +29310,8 @@ var init_parseUtil = __esm({
|
|
|
29310
29310
|
init_errors4();
|
|
29311
29311
|
init_en();
|
|
29312
29312
|
makeIssue = (params) => {
|
|
29313
|
-
const { data, path:
|
|
29314
|
-
const fullPath = [...
|
|
29313
|
+
const { data, path: path5, errorMaps, issueData } = params;
|
|
29314
|
+
const fullPath = [...path5, ...issueData.path || []];
|
|
29315
29315
|
const fullIssue = {
|
|
29316
29316
|
...issueData,
|
|
29317
29317
|
path: fullPath
|
|
@@ -29622,11 +29622,11 @@ var init_types = __esm({
|
|
|
29622
29622
|
init_parseUtil();
|
|
29623
29623
|
init_util();
|
|
29624
29624
|
ParseInputLazyPath = class {
|
|
29625
|
-
constructor(parent, value,
|
|
29625
|
+
constructor(parent, value, path5, key2) {
|
|
29626
29626
|
this._cachedPath = [];
|
|
29627
29627
|
this.parent = parent;
|
|
29628
29628
|
this.data = value;
|
|
29629
|
-
this._path =
|
|
29629
|
+
this._path = path5;
|
|
29630
29630
|
this._key = key2;
|
|
29631
29631
|
}
|
|
29632
29632
|
get path() {
|
|
@@ -34035,6 +34035,613 @@ var init_max_tokens = __esm({
|
|
|
34035
34035
|
}
|
|
34036
34036
|
});
|
|
34037
34037
|
|
|
34038
|
+
// src/fs-read.ts
|
|
34039
|
+
import { open } from "fs/promises";
|
|
34040
|
+
import { openSync, readSync, closeSync, fstatSync } from "fs";
|
|
34041
|
+
async function readTextFile(filePath) {
|
|
34042
|
+
const fh = await open(filePath, "r");
|
|
34043
|
+
try {
|
|
34044
|
+
const size5 = (await fh.stat()).size;
|
|
34045
|
+
const buf = Buffer.alloc(size5);
|
|
34046
|
+
let offset = 0;
|
|
34047
|
+
while (offset < size5) {
|
|
34048
|
+
const { bytesRead } = await fh.read(buf, offset, size5 - offset, offset);
|
|
34049
|
+
if (bytesRead === 0) break;
|
|
34050
|
+
offset += bytesRead;
|
|
34051
|
+
}
|
|
34052
|
+
return buf.subarray(0, offset).toString("utf-8");
|
|
34053
|
+
} finally {
|
|
34054
|
+
await fh.close();
|
|
34055
|
+
}
|
|
34056
|
+
}
|
|
34057
|
+
function readTextFileSync(filePath) {
|
|
34058
|
+
const fd = openSync(filePath, "r");
|
|
34059
|
+
try {
|
|
34060
|
+
const size5 = fstatSync(fd).size;
|
|
34061
|
+
const buf = Buffer.alloc(size5);
|
|
34062
|
+
let offset = 0;
|
|
34063
|
+
while (offset < size5) {
|
|
34064
|
+
const bytesRead = readSync(fd, buf, offset, size5 - offset, offset);
|
|
34065
|
+
if (bytesRead === 0) break;
|
|
34066
|
+
offset += bytesRead;
|
|
34067
|
+
}
|
|
34068
|
+
return buf.subarray(0, offset).toString("utf-8");
|
|
34069
|
+
} finally {
|
|
34070
|
+
closeSync(fd);
|
|
34071
|
+
}
|
|
34072
|
+
}
|
|
34073
|
+
var init_fs_read = __esm({
|
|
34074
|
+
"src/fs-read.ts"() {
|
|
34075
|
+
"use strict";
|
|
34076
|
+
}
|
|
34077
|
+
});
|
|
34078
|
+
|
|
34079
|
+
// src/spend-control.ts
|
|
34080
|
+
import * as fs from "fs";
|
|
34081
|
+
import * as path from "path";
|
|
34082
|
+
import { homedir } from "os";
|
|
34083
|
+
function normalizePayee(value) {
|
|
34084
|
+
return EVM_ADDRESS.test(value) ? value.toLowerCase() : value;
|
|
34085
|
+
}
|
|
34086
|
+
function isAddressList(list) {
|
|
34087
|
+
return ADDRESS_LISTS.includes(list);
|
|
34088
|
+
}
|
|
34089
|
+
function normalizePolicyValues(list, values) {
|
|
34090
|
+
return isAddressList(list) ? values.map(normalizePayee) : [...values];
|
|
34091
|
+
}
|
|
34092
|
+
function isValidPolicyValues(values) {
|
|
34093
|
+
return Array.isArray(values) && values.every((v) => typeof v === "string" && v.length > 0);
|
|
34094
|
+
}
|
|
34095
|
+
function isPolicyList(value) {
|
|
34096
|
+
return POLICY_LISTS.includes(value);
|
|
34097
|
+
}
|
|
34098
|
+
function cloneLimits(limits) {
|
|
34099
|
+
const clone = { ...limits };
|
|
34100
|
+
for (const key2 of POLICY_LISTS) {
|
|
34101
|
+
const val = limits[key2];
|
|
34102
|
+
if (val !== void 0) {
|
|
34103
|
+
clone[key2] = [...val];
|
|
34104
|
+
}
|
|
34105
|
+
}
|
|
34106
|
+
return clone;
|
|
34107
|
+
}
|
|
34108
|
+
function parseQuotedAmountUsd(selected) {
|
|
34109
|
+
const raw = selected.amount ?? selected.maxAmountRequired;
|
|
34110
|
+
if (typeof raw !== "string" || !CANONICAL_AMOUNT.test(raw)) {
|
|
34111
|
+
return void 0;
|
|
34112
|
+
}
|
|
34113
|
+
const micros = Number(raw);
|
|
34114
|
+
if (!Number.isSafeInteger(micros)) {
|
|
34115
|
+
return void 0;
|
|
34116
|
+
}
|
|
34117
|
+
return micros / 1e6;
|
|
34118
|
+
}
|
|
34119
|
+
function assertSpendPolicyAllows(control, selected) {
|
|
34120
|
+
const quoted = parseQuotedAmountUsd(selected);
|
|
34121
|
+
if (quoted === void 0 && control.hasAmountLimits()) {
|
|
34122
|
+
throw new SpendPolicyError(
|
|
34123
|
+
`Payment quote carries no usable amount (${JSON.stringify(
|
|
34124
|
+
selected.amount ?? selected.maxAmountRequired
|
|
34125
|
+
)}); refusing to sign against a configured spend limit`
|
|
34126
|
+
);
|
|
34127
|
+
}
|
|
34128
|
+
const estimatedCost2 = quoted ?? 0;
|
|
34129
|
+
const result = control.check(estimatedCost2, {
|
|
34130
|
+
payTo: selected.payTo,
|
|
34131
|
+
network: selected.network,
|
|
34132
|
+
asset: selected.asset
|
|
34133
|
+
});
|
|
34134
|
+
if (!result.allowed) {
|
|
34135
|
+
throw new SpendPolicyError(result.reason ?? "blocked by spend policy", {
|
|
34136
|
+
blockedBy: result.blockedBy,
|
|
34137
|
+
blockedByPolicy: result.blockedByPolicy
|
|
34138
|
+
});
|
|
34139
|
+
}
|
|
34140
|
+
if (!control.hasAggregateLimits()) {
|
|
34141
|
+
return void 0;
|
|
34142
|
+
}
|
|
34143
|
+
return control.reserve(estimatedCost2);
|
|
34144
|
+
}
|
|
34145
|
+
function registerSpendPolicyHook(x402, control) {
|
|
34146
|
+
const reservations = /* @__PURE__ */ new WeakMap();
|
|
34147
|
+
x402.onBeforePaymentCreation(async (ctx) => {
|
|
34148
|
+
const selected = ctx.selectedRequirements;
|
|
34149
|
+
const reservationId = assertSpendPolicyAllows(control, selected);
|
|
34150
|
+
if (reservationId !== void 0) {
|
|
34151
|
+
reservations.set(ctx.selectedRequirements, reservationId);
|
|
34152
|
+
}
|
|
34153
|
+
});
|
|
34154
|
+
x402.onAfterPaymentCreation(async (ctx) => {
|
|
34155
|
+
const key2 = ctx.selectedRequirements;
|
|
34156
|
+
const id2 = reservations.get(key2);
|
|
34157
|
+
if (id2 !== void 0) {
|
|
34158
|
+
reservations.delete(key2);
|
|
34159
|
+
control.settleReservation(id2, { action: "x402 payment" });
|
|
34160
|
+
}
|
|
34161
|
+
});
|
|
34162
|
+
x402.onPaymentCreationFailure(async (ctx) => {
|
|
34163
|
+
const key2 = ctx.selectedRequirements;
|
|
34164
|
+
const id2 = reservations.get(key2);
|
|
34165
|
+
if (id2 !== void 0) {
|
|
34166
|
+
reservations.delete(key2);
|
|
34167
|
+
control.releaseReservation(id2);
|
|
34168
|
+
}
|
|
34169
|
+
});
|
|
34170
|
+
}
|
|
34171
|
+
function formatDuration(seconds) {
|
|
34172
|
+
if (seconds < 60) {
|
|
34173
|
+
return `${seconds}s`;
|
|
34174
|
+
} else if (seconds < 3600) {
|
|
34175
|
+
const mins = Math.ceil(seconds / 60);
|
|
34176
|
+
return `${mins} min`;
|
|
34177
|
+
} else {
|
|
34178
|
+
const hours = Math.floor(seconds / 3600);
|
|
34179
|
+
const mins = Math.ceil(seconds % 3600 / 60);
|
|
34180
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
34181
|
+
}
|
|
34182
|
+
}
|
|
34183
|
+
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;
|
|
34184
|
+
var init_spend_control = __esm({
|
|
34185
|
+
"src/spend-control.ts"() {
|
|
34186
|
+
"use strict";
|
|
34187
|
+
init_fs_read();
|
|
34188
|
+
WALLET_DIR = path.join(homedir(), ".openclaw", "blockrun");
|
|
34189
|
+
HOUR_MS = 60 * 60 * 1e3;
|
|
34190
|
+
DAY_MS = 24 * HOUR_MS;
|
|
34191
|
+
CAIP2_BASE = "eip155:8453";
|
|
34192
|
+
CAIP2_SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
34193
|
+
POLICY_LISTS = [
|
|
34194
|
+
"allowedPayees",
|
|
34195
|
+
"blockedPayees",
|
|
34196
|
+
"allowedNetworks",
|
|
34197
|
+
"allowedAssets"
|
|
34198
|
+
];
|
|
34199
|
+
ADDRESS_LISTS = ["allowedPayees", "blockedPayees", "allowedAssets"];
|
|
34200
|
+
EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
34201
|
+
MalformedSpendPolicyError = class extends Error {
|
|
34202
|
+
constructor(key2) {
|
|
34203
|
+
super(
|
|
34204
|
+
`[ClawRouter] refusing to load spending.json: ${key2} is malformed; a corrupted policy file must not widen what the agent may pay`
|
|
34205
|
+
);
|
|
34206
|
+
this.name = "MalformedSpendPolicyError";
|
|
34207
|
+
}
|
|
34208
|
+
};
|
|
34209
|
+
FileSpendControlStorage = class {
|
|
34210
|
+
spendingFile;
|
|
34211
|
+
constructor() {
|
|
34212
|
+
this.spendingFile = path.join(WALLET_DIR, "spending.json");
|
|
34213
|
+
}
|
|
34214
|
+
load() {
|
|
34215
|
+
try {
|
|
34216
|
+
if (fs.existsSync(this.spendingFile)) {
|
|
34217
|
+
const data = JSON.parse(readTextFileSync(this.spendingFile));
|
|
34218
|
+
const rawLimits = data.limits ?? {};
|
|
34219
|
+
const rawHistory = data.history ?? [];
|
|
34220
|
+
const limits = {};
|
|
34221
|
+
for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
|
|
34222
|
+
const val = rawLimits[key2];
|
|
34223
|
+
if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
|
|
34224
|
+
limits[key2] = val;
|
|
34225
|
+
}
|
|
34226
|
+
}
|
|
34227
|
+
for (const key2 of POLICY_LISTS) {
|
|
34228
|
+
if (!Object.prototype.hasOwnProperty.call(rawLimits, key2)) continue;
|
|
34229
|
+
const val = rawLimits[key2];
|
|
34230
|
+
if (!isValidPolicyValues(val)) {
|
|
34231
|
+
throw new MalformedSpendPolicyError(key2);
|
|
34232
|
+
}
|
|
34233
|
+
if (val.length === 0) continue;
|
|
34234
|
+
limits[key2] = normalizePolicyValues(key2, val);
|
|
34235
|
+
}
|
|
34236
|
+
const history = [];
|
|
34237
|
+
if (Array.isArray(rawHistory)) {
|
|
34238
|
+
for (const r2 of rawHistory) {
|
|
34239
|
+
if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
|
|
34240
|
+
history.push({
|
|
34241
|
+
timestamp: r2.timestamp,
|
|
34242
|
+
amount: r2.amount,
|
|
34243
|
+
model: typeof r2.model === "string" ? r2.model : void 0,
|
|
34244
|
+
action: typeof r2.action === "string" ? r2.action : void 0
|
|
34245
|
+
});
|
|
34246
|
+
}
|
|
34247
|
+
}
|
|
34248
|
+
}
|
|
34249
|
+
return { limits, history };
|
|
34250
|
+
}
|
|
34251
|
+
} catch (err) {
|
|
34252
|
+
if (err instanceof MalformedSpendPolicyError) {
|
|
34253
|
+
throw err;
|
|
34254
|
+
}
|
|
34255
|
+
console.error(
|
|
34256
|
+
`[ClawRouter] Failed to load spending data, starting fresh (any configured spend policy is NOT in effect until this file is repaired): ${err}`
|
|
34257
|
+
);
|
|
34258
|
+
}
|
|
34259
|
+
return null;
|
|
34260
|
+
}
|
|
34261
|
+
save(data) {
|
|
34262
|
+
try {
|
|
34263
|
+
if (!fs.existsSync(WALLET_DIR)) {
|
|
34264
|
+
fs.mkdirSync(WALLET_DIR, { recursive: true, mode: 448 });
|
|
34265
|
+
}
|
|
34266
|
+
const tmp = `${this.spendingFile}.${process.pid}.tmp`;
|
|
34267
|
+
fs.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
34268
|
+
fs.renameSync(tmp, this.spendingFile);
|
|
34269
|
+
} catch (err) {
|
|
34270
|
+
console.error(`[ClawRouter] Failed to save spending data: ${err}`);
|
|
34271
|
+
}
|
|
34272
|
+
}
|
|
34273
|
+
/**
|
|
34274
|
+
* Persist history while leaving the stored limits exactly as they are on
|
|
34275
|
+
* disk. Recording spend must not rewrite policy: the proxy reads limits once
|
|
34276
|
+
* at startup, so writing its in-memory copy back on every payment would
|
|
34277
|
+
* erase an operator's hand-edit to spending.json seconds after they made it.
|
|
34278
|
+
*/
|
|
34279
|
+
saveHistory(history) {
|
|
34280
|
+
let storedLimits = {};
|
|
34281
|
+
try {
|
|
34282
|
+
const current = this.load();
|
|
34283
|
+
if (current) storedLimits = current.limits;
|
|
34284
|
+
} catch {
|
|
34285
|
+
return;
|
|
34286
|
+
}
|
|
34287
|
+
this.save({ limits: storedLimits, history });
|
|
34288
|
+
}
|
|
34289
|
+
};
|
|
34290
|
+
InMemorySpendControlStorage = class {
|
|
34291
|
+
data = null;
|
|
34292
|
+
load() {
|
|
34293
|
+
return this.data ? {
|
|
34294
|
+
limits: cloneLimits(this.data.limits),
|
|
34295
|
+
history: this.data.history.map((r2) => ({ ...r2 }))
|
|
34296
|
+
} : null;
|
|
34297
|
+
}
|
|
34298
|
+
save(data) {
|
|
34299
|
+
this.data = {
|
|
34300
|
+
limits: cloneLimits(data.limits),
|
|
34301
|
+
history: data.history.map((r2) => ({ ...r2 }))
|
|
34302
|
+
};
|
|
34303
|
+
}
|
|
34304
|
+
};
|
|
34305
|
+
RESERVATION_TTL_MS = 2 * 60 * 1e3;
|
|
34306
|
+
SpendControl = class {
|
|
34307
|
+
limits = {};
|
|
34308
|
+
history = [];
|
|
34309
|
+
sessionSpent = 0;
|
|
34310
|
+
sessionCalls = 0;
|
|
34311
|
+
pending = /* @__PURE__ */ new Map();
|
|
34312
|
+
reservationSeq = 0;
|
|
34313
|
+
/** Limits we loaded and have not changed; history-only saves must not clobber operator edits. */
|
|
34314
|
+
limitsDirty = false;
|
|
34315
|
+
/** Set when spending.json held an unusable policy list: refuse every payment. */
|
|
34316
|
+
policyFileBroken;
|
|
34317
|
+
storage;
|
|
34318
|
+
now;
|
|
34319
|
+
constructor(options) {
|
|
34320
|
+
this.storage = options?.storage ?? new FileSpendControlStorage();
|
|
34321
|
+
this.now = options?.now ?? (() => Date.now());
|
|
34322
|
+
this.load();
|
|
34323
|
+
}
|
|
34324
|
+
setLimit(window2, amount) {
|
|
34325
|
+
if (!Number.isFinite(amount) || amount <= 0) {
|
|
34326
|
+
throw new Error("Limit must be a finite positive number");
|
|
34327
|
+
}
|
|
34328
|
+
this.limits[window2] = amount;
|
|
34329
|
+
this.limitsDirty = true;
|
|
34330
|
+
this.save();
|
|
34331
|
+
}
|
|
34332
|
+
clearLimit(window2) {
|
|
34333
|
+
delete this.limits[window2];
|
|
34334
|
+
this.limitsDirty = true;
|
|
34335
|
+
this.save();
|
|
34336
|
+
}
|
|
34337
|
+
setPolicy(list, values) {
|
|
34338
|
+
if (!isPolicyList(list)) {
|
|
34339
|
+
throw new Error(`Unknown policy list: ${String(list)}`);
|
|
34340
|
+
}
|
|
34341
|
+
if (!isValidPolicyValues(values) || values.length === 0) {
|
|
34342
|
+
throw new Error("Policy list must be a non-empty array of non-empty strings");
|
|
34343
|
+
}
|
|
34344
|
+
this.limits[list] = normalizePolicyValues(list, values);
|
|
34345
|
+
this.limitsDirty = true;
|
|
34346
|
+
this.save();
|
|
34347
|
+
}
|
|
34348
|
+
clearPolicy(list) {
|
|
34349
|
+
if (!isPolicyList(list)) {
|
|
34350
|
+
throw new Error(`Unknown policy list: ${String(list)}`);
|
|
34351
|
+
}
|
|
34352
|
+
delete this.limits[list];
|
|
34353
|
+
this.limitsDirty = true;
|
|
34354
|
+
this.save();
|
|
34355
|
+
}
|
|
34356
|
+
getLimits() {
|
|
34357
|
+
return cloneLimits(this.limits);
|
|
34358
|
+
}
|
|
34359
|
+
check(estimatedCost2, counterparty) {
|
|
34360
|
+
if (this.policyFileBroken !== void 0) {
|
|
34361
|
+
return {
|
|
34362
|
+
allowed: false,
|
|
34363
|
+
reason: `Spend policy is unreadable, refusing all payments: ${this.policyFileBroken}`
|
|
34364
|
+
};
|
|
34365
|
+
}
|
|
34366
|
+
const payeePolicySet = this.limits.blockedPayees && this.limits.blockedPayees.length > 0 || this.limits.allowedPayees && this.limits.allowedPayees.length > 0;
|
|
34367
|
+
if (payeePolicySet) {
|
|
34368
|
+
if (counterparty?.payTo === void 0) {
|
|
34369
|
+
return {
|
|
34370
|
+
allowed: false,
|
|
34371
|
+
blockedByPolicy: this.limits.blockedPayees?.length ? "blockedPayees" : "allowedPayees",
|
|
34372
|
+
reason: "Payee policy is configured but no payTo was provided to check()"
|
|
34373
|
+
};
|
|
34374
|
+
}
|
|
34375
|
+
const payTo = normalizePayee(counterparty.payTo);
|
|
34376
|
+
if (this.limits.blockedPayees?.includes(payTo)) {
|
|
34377
|
+
return {
|
|
34378
|
+
allowed: false,
|
|
34379
|
+
blockedByPolicy: "blockedPayees",
|
|
34380
|
+
reason: `Payee is blocked by policy: ${counterparty.payTo}`
|
|
34381
|
+
};
|
|
34382
|
+
}
|
|
34383
|
+
if (this.limits.allowedPayees && this.limits.allowedPayees.length > 0 && !this.limits.allowedPayees.includes(payTo)) {
|
|
34384
|
+
return {
|
|
34385
|
+
allowed: false,
|
|
34386
|
+
blockedByPolicy: "allowedPayees",
|
|
34387
|
+
reason: `Payee is not in the configured allowlist: ${counterparty.payTo}`
|
|
34388
|
+
};
|
|
34389
|
+
}
|
|
34390
|
+
}
|
|
34391
|
+
if (this.limits.allowedNetworks && this.limits.allowedNetworks.length > 0) {
|
|
34392
|
+
if (counterparty?.network === void 0) {
|
|
34393
|
+
return {
|
|
34394
|
+
allowed: false,
|
|
34395
|
+
blockedByPolicy: "allowedNetworks",
|
|
34396
|
+
reason: "Network policy is configured but no network was provided to check()"
|
|
34397
|
+
};
|
|
34398
|
+
}
|
|
34399
|
+
if (!this.limits.allowedNetworks.includes(counterparty.network)) {
|
|
34400
|
+
return {
|
|
34401
|
+
allowed: false,
|
|
34402
|
+
blockedByPolicy: "allowedNetworks",
|
|
34403
|
+
reason: `Network is not in the configured allowlist: ${counterparty.network}`
|
|
34404
|
+
};
|
|
34405
|
+
}
|
|
34406
|
+
}
|
|
34407
|
+
if (this.limits.allowedAssets && this.limits.allowedAssets.length > 0) {
|
|
34408
|
+
if (counterparty?.asset === void 0) {
|
|
34409
|
+
return {
|
|
34410
|
+
allowed: false,
|
|
34411
|
+
blockedByPolicy: "allowedAssets",
|
|
34412
|
+
reason: "Asset policy is configured but no asset was provided to check()"
|
|
34413
|
+
};
|
|
34414
|
+
}
|
|
34415
|
+
if (!this.limits.allowedAssets.includes(normalizePayee(counterparty.asset))) {
|
|
34416
|
+
return {
|
|
34417
|
+
allowed: false,
|
|
34418
|
+
blockedByPolicy: "allowedAssets",
|
|
34419
|
+
reason: `Asset is not in the configured allowlist: ${counterparty.asset}`
|
|
34420
|
+
};
|
|
34421
|
+
}
|
|
34422
|
+
}
|
|
34423
|
+
const now2 = this.now();
|
|
34424
|
+
if (this.limits.perRequest !== void 0) {
|
|
34425
|
+
if (estimatedCost2 > this.limits.perRequest) {
|
|
34426
|
+
return {
|
|
34427
|
+
allowed: false,
|
|
34428
|
+
blockedBy: "perRequest",
|
|
34429
|
+
remaining: this.limits.perRequest,
|
|
34430
|
+
reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
|
|
34431
|
+
};
|
|
34432
|
+
}
|
|
34433
|
+
}
|
|
34434
|
+
if (this.limits.hourly !== void 0) {
|
|
34435
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
34436
|
+
const remaining = this.limits.hourly - hourlySpent;
|
|
34437
|
+
if (estimatedCost2 > remaining) {
|
|
34438
|
+
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
34439
|
+
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
|
|
34440
|
+
return {
|
|
34441
|
+
allowed: false,
|
|
34442
|
+
blockedBy: "hourly",
|
|
34443
|
+
remaining,
|
|
34444
|
+
reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
|
|
34445
|
+
resetIn
|
|
34446
|
+
};
|
|
34447
|
+
}
|
|
34448
|
+
}
|
|
34449
|
+
if (this.limits.daily !== void 0) {
|
|
34450
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
34451
|
+
const remaining = this.limits.daily - dailySpent;
|
|
34452
|
+
if (estimatedCost2 > remaining) {
|
|
34453
|
+
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
34454
|
+
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
|
|
34455
|
+
return {
|
|
34456
|
+
allowed: false,
|
|
34457
|
+
blockedBy: "daily",
|
|
34458
|
+
remaining,
|
|
34459
|
+
reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
|
|
34460
|
+
resetIn
|
|
34461
|
+
};
|
|
34462
|
+
}
|
|
34463
|
+
}
|
|
34464
|
+
if (this.limits.session !== void 0) {
|
|
34465
|
+
const sessionSpent = this.sessionSpent + this.pendingTotal();
|
|
34466
|
+
const remaining = this.limits.session - sessionSpent;
|
|
34467
|
+
if (estimatedCost2 > remaining) {
|
|
34468
|
+
return {
|
|
34469
|
+
allowed: false,
|
|
34470
|
+
blockedBy: "session",
|
|
34471
|
+
remaining,
|
|
34472
|
+
reason: `Session limit exceeded: $${(sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
|
|
34473
|
+
};
|
|
34474
|
+
}
|
|
34475
|
+
}
|
|
34476
|
+
return { allowed: true };
|
|
34477
|
+
}
|
|
34478
|
+
record(amount, metadata) {
|
|
34479
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
34480
|
+
throw new Error("Record amount must be a non-negative finite number");
|
|
34481
|
+
}
|
|
34482
|
+
const record = {
|
|
34483
|
+
timestamp: this.now(),
|
|
34484
|
+
amount,
|
|
34485
|
+
model: metadata?.model,
|
|
34486
|
+
action: metadata?.action
|
|
34487
|
+
};
|
|
34488
|
+
this.history.push(record);
|
|
34489
|
+
this.sessionSpent += amount;
|
|
34490
|
+
this.sessionCalls += 1;
|
|
34491
|
+
this.cleanup();
|
|
34492
|
+
this.save();
|
|
34493
|
+
}
|
|
34494
|
+
/** True when any window that this module can compare an amount against is set. */
|
|
34495
|
+
hasAmountLimits() {
|
|
34496
|
+
return this.limits.perRequest !== void 0 || this.limits.hourly !== void 0 || this.limits.daily !== void 0 || this.limits.session !== void 0;
|
|
34497
|
+
}
|
|
34498
|
+
/** True when a window spans more than one request, so reservations matter. */
|
|
34499
|
+
hasAggregateLimits() {
|
|
34500
|
+
return this.limits.hourly !== void 0 || this.limits.daily !== void 0 || this.limits.session !== void 0;
|
|
34501
|
+
}
|
|
34502
|
+
/**
|
|
34503
|
+
* Hold `amount` against the aggregate windows before a payment is signed.
|
|
34504
|
+
*
|
|
34505
|
+
* Reservations live in memory only and are never persisted: an unsettled
|
|
34506
|
+
* reservation is not spend, and writing it to disk is what made a failed
|
|
34507
|
+
* signer permanently consume budget. They expire on their own so a caller
|
|
34508
|
+
* that never settles or releases (process killed mid-payment, a transport
|
|
34509
|
+
* that hangs past the payment timeout) cannot wedge the window shut.
|
|
34510
|
+
*/
|
|
34511
|
+
reserve(amount) {
|
|
34512
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
34513
|
+
throw new Error("Reservation amount must be a non-negative finite number");
|
|
34514
|
+
}
|
|
34515
|
+
const id2 = `${this.now()}-${this.reservationSeq += 1}`;
|
|
34516
|
+
this.pending.set(id2, { amount, expiresAt: this.now() + RESERVATION_TTL_MS });
|
|
34517
|
+
return id2;
|
|
34518
|
+
}
|
|
34519
|
+
/** Convert a reservation into recorded spend (the payment was signed). */
|
|
34520
|
+
settleReservation(id2, metadata) {
|
|
34521
|
+
const held = this.pending.get(id2);
|
|
34522
|
+
if (!held) return;
|
|
34523
|
+
this.pending.delete(id2);
|
|
34524
|
+
this.record(held.amount, metadata);
|
|
34525
|
+
}
|
|
34526
|
+
/** Drop a reservation without recording spend (the payment was never signed). */
|
|
34527
|
+
releaseReservation(id2) {
|
|
34528
|
+
this.pending.delete(id2);
|
|
34529
|
+
}
|
|
34530
|
+
/** Total currently held but not yet settled. */
|
|
34531
|
+
pendingTotal() {
|
|
34532
|
+
this.expireReservations();
|
|
34533
|
+
let total = 0;
|
|
34534
|
+
for (const held of this.pending.values()) {
|
|
34535
|
+
total += held.amount;
|
|
34536
|
+
}
|
|
34537
|
+
return total;
|
|
34538
|
+
}
|
|
34539
|
+
expireReservations() {
|
|
34540
|
+
const now2 = this.now();
|
|
34541
|
+
for (const [id2, held] of this.pending) {
|
|
34542
|
+
if (held.expiresAt <= now2) {
|
|
34543
|
+
this.pending.delete(id2);
|
|
34544
|
+
}
|
|
34545
|
+
}
|
|
34546
|
+
}
|
|
34547
|
+
getSpendingInWindow(from15, to) {
|
|
34548
|
+
const recorded = this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
34549
|
+
return recorded + (to >= this.now() ? this.pendingTotal() : 0);
|
|
34550
|
+
}
|
|
34551
|
+
getSpending(window2) {
|
|
34552
|
+
const now2 = this.now();
|
|
34553
|
+
switch (window2) {
|
|
34554
|
+
case "hourly":
|
|
34555
|
+
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
34556
|
+
case "daily":
|
|
34557
|
+
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
34558
|
+
case "session":
|
|
34559
|
+
return this.sessionSpent + this.pendingTotal();
|
|
34560
|
+
}
|
|
34561
|
+
}
|
|
34562
|
+
getRemaining(window2) {
|
|
34563
|
+
const limit = this.limits[window2];
|
|
34564
|
+
if (limit === void 0) return null;
|
|
34565
|
+
return Math.max(0, limit - this.getSpending(window2));
|
|
34566
|
+
}
|
|
34567
|
+
getStatus() {
|
|
34568
|
+
const now2 = this.now();
|
|
34569
|
+
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
34570
|
+
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
34571
|
+
return {
|
|
34572
|
+
limits: cloneLimits(this.limits),
|
|
34573
|
+
spending: {
|
|
34574
|
+
hourly: hourlySpent,
|
|
34575
|
+
daily: dailySpent,
|
|
34576
|
+
session: this.sessionSpent
|
|
34577
|
+
},
|
|
34578
|
+
remaining: {
|
|
34579
|
+
hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
|
|
34580
|
+
daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
|
|
34581
|
+
session: this.limits.session !== void 0 ? this.limits.session - (this.sessionSpent + this.pendingTotal()) : null
|
|
34582
|
+
},
|
|
34583
|
+
calls: this.sessionCalls
|
|
34584
|
+
};
|
|
34585
|
+
}
|
|
34586
|
+
getHistory(limit) {
|
|
34587
|
+
const records = [...this.history].reverse();
|
|
34588
|
+
return limit ? records.slice(0, limit) : records;
|
|
34589
|
+
}
|
|
34590
|
+
resetSession() {
|
|
34591
|
+
this.sessionSpent = 0;
|
|
34592
|
+
this.sessionCalls = 0;
|
|
34593
|
+
}
|
|
34594
|
+
cleanup() {
|
|
34595
|
+
const cutoff = this.now() - DAY_MS;
|
|
34596
|
+
this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
|
|
34597
|
+
}
|
|
34598
|
+
save() {
|
|
34599
|
+
if (this.policyFileBroken !== void 0) {
|
|
34600
|
+
return;
|
|
34601
|
+
}
|
|
34602
|
+
if (!this.limitsDirty && this.storage.saveHistory) {
|
|
34603
|
+
this.storage.saveHistory([...this.history]);
|
|
34604
|
+
return;
|
|
34605
|
+
}
|
|
34606
|
+
this.storage.save({
|
|
34607
|
+
limits: cloneLimits(this.limits),
|
|
34608
|
+
history: [...this.history]
|
|
34609
|
+
});
|
|
34610
|
+
}
|
|
34611
|
+
load() {
|
|
34612
|
+
let data;
|
|
34613
|
+
try {
|
|
34614
|
+
data = this.storage.load();
|
|
34615
|
+
} catch (err) {
|
|
34616
|
+
if (!(err instanceof MalformedSpendPolicyError)) throw err;
|
|
34617
|
+
this.policyFileBroken = err.message;
|
|
34618
|
+
console.error(`[ClawRouter] ${err.message}`);
|
|
34619
|
+
console.error(
|
|
34620
|
+
"[ClawRouter] All paid requests will be refused until spending.json is repaired. Free models are unaffected."
|
|
34621
|
+
);
|
|
34622
|
+
return;
|
|
34623
|
+
}
|
|
34624
|
+
if (data) {
|
|
34625
|
+
this.limits = cloneLimits(data.limits);
|
|
34626
|
+
this.history = data.history;
|
|
34627
|
+
this.cleanup();
|
|
34628
|
+
}
|
|
34629
|
+
}
|
|
34630
|
+
};
|
|
34631
|
+
SpendPolicyError = class extends Error {
|
|
34632
|
+
blockedBy;
|
|
34633
|
+
blockedByPolicy;
|
|
34634
|
+
constructor(reason, blocked) {
|
|
34635
|
+
super(`Payment creation aborted: ${reason}`);
|
|
34636
|
+
this.name = "SpendPolicyError";
|
|
34637
|
+
this.blockedBy = blocked?.blockedBy;
|
|
34638
|
+
this.blockedByPolicy = blocked?.blockedByPolicy;
|
|
34639
|
+
}
|
|
34640
|
+
};
|
|
34641
|
+
CANONICAL_AMOUNT = /^\d+$/;
|
|
34642
|
+
}
|
|
34643
|
+
});
|
|
34644
|
+
|
|
34038
34645
|
// src/payment-preauth.ts
|
|
34039
34646
|
function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, options) {
|
|
34040
34647
|
const httpClient = new x402HTTPClient(client);
|
|
@@ -34079,8 +34686,11 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
|
|
|
34079
34686
|
return response2;
|
|
34080
34687
|
}
|
|
34081
34688
|
cache2.delete(cacheKey2);
|
|
34082
|
-
} catch {
|
|
34689
|
+
} catch (err) {
|
|
34083
34690
|
cache2.delete(cacheKey2);
|
|
34691
|
+
if (err instanceof SpendPolicyError) {
|
|
34692
|
+
throw err;
|
|
34693
|
+
}
|
|
34084
34694
|
}
|
|
34085
34695
|
}
|
|
34086
34696
|
const clonedRequest = request2.clone();
|
|
@@ -34124,6 +34734,7 @@ var init_payment_preauth = __esm({
|
|
|
34124
34734
|
"use strict";
|
|
34125
34735
|
init_esm4();
|
|
34126
34736
|
init_max_tokens();
|
|
34737
|
+
init_spend_control();
|
|
34127
34738
|
DEFAULT_TTL_MS = 36e5;
|
|
34128
34739
|
}
|
|
34129
34740
|
});
|
|
@@ -38823,8 +39434,8 @@ var init_router = __esm({
|
|
|
38823
39434
|
|
|
38824
39435
|
// src/logger.ts
|
|
38825
39436
|
import { appendFile, mkdir } from "fs/promises";
|
|
38826
|
-
import { join as
|
|
38827
|
-
import { homedir } from "os";
|
|
39437
|
+
import { join as join3 } from "path";
|
|
39438
|
+
import { homedir as homedir2 } from "os";
|
|
38828
39439
|
async function ensureDir() {
|
|
38829
39440
|
if (dirReady) return;
|
|
38830
39441
|
await mkdir(LOG_DIR, { recursive: true });
|
|
@@ -38834,7 +39445,7 @@ async function logUsage(entry) {
|
|
|
38834
39445
|
try {
|
|
38835
39446
|
await ensureDir();
|
|
38836
39447
|
const date = entry.timestamp.slice(0, 10);
|
|
38837
|
-
const file =
|
|
39448
|
+
const file = join3(LOG_DIR, `usage-${date}.jsonl`);
|
|
38838
39449
|
await appendFile(file, JSON.stringify(entry) + "\n");
|
|
38839
39450
|
} catch {
|
|
38840
39451
|
}
|
|
@@ -38843,56 +39454,15 @@ var LOG_DIR, dirReady;
|
|
|
38843
39454
|
var init_logger = __esm({
|
|
38844
39455
|
"src/logger.ts"() {
|
|
38845
39456
|
"use strict";
|
|
38846
|
-
LOG_DIR =
|
|
39457
|
+
LOG_DIR = join3(homedir2(), ".openclaw", "blockrun", "logs");
|
|
38847
39458
|
dirReady = false;
|
|
38848
39459
|
}
|
|
38849
39460
|
});
|
|
38850
39461
|
|
|
38851
|
-
// src/fs-read.ts
|
|
38852
|
-
import { open } from "fs/promises";
|
|
38853
|
-
import { openSync, readSync, closeSync, fstatSync } from "fs";
|
|
38854
|
-
async function readTextFile(filePath) {
|
|
38855
|
-
const fh = await open(filePath, "r");
|
|
38856
|
-
try {
|
|
38857
|
-
const size5 = (await fh.stat()).size;
|
|
38858
|
-
const buf = Buffer.alloc(size5);
|
|
38859
|
-
let offset = 0;
|
|
38860
|
-
while (offset < size5) {
|
|
38861
|
-
const { bytesRead } = await fh.read(buf, offset, size5 - offset, offset);
|
|
38862
|
-
if (bytesRead === 0) break;
|
|
38863
|
-
offset += bytesRead;
|
|
38864
|
-
}
|
|
38865
|
-
return buf.subarray(0, offset).toString("utf-8");
|
|
38866
|
-
} finally {
|
|
38867
|
-
await fh.close();
|
|
38868
|
-
}
|
|
38869
|
-
}
|
|
38870
|
-
function readTextFileSync(filePath) {
|
|
38871
|
-
const fd = openSync(filePath, "r");
|
|
38872
|
-
try {
|
|
38873
|
-
const size5 = fstatSync(fd).size;
|
|
38874
|
-
const buf = Buffer.alloc(size5);
|
|
38875
|
-
let offset = 0;
|
|
38876
|
-
while (offset < size5) {
|
|
38877
|
-
const bytesRead = readSync(fd, buf, offset, size5 - offset, offset);
|
|
38878
|
-
if (bytesRead === 0) break;
|
|
38879
|
-
offset += bytesRead;
|
|
38880
|
-
}
|
|
38881
|
-
return buf.subarray(0, offset).toString("utf-8");
|
|
38882
|
-
} finally {
|
|
38883
|
-
closeSync(fd);
|
|
38884
|
-
}
|
|
38885
|
-
}
|
|
38886
|
-
var init_fs_read = __esm({
|
|
38887
|
-
"src/fs-read.ts"() {
|
|
38888
|
-
"use strict";
|
|
38889
|
-
}
|
|
38890
|
-
});
|
|
38891
|
-
|
|
38892
39462
|
// src/version.ts
|
|
38893
39463
|
import { createRequire } from "module";
|
|
38894
39464
|
import { fileURLToPath } from "url";
|
|
38895
|
-
import { dirname, join as
|
|
39465
|
+
import { dirname, join as join4 } from "path";
|
|
38896
39466
|
function clientTag() {
|
|
38897
39467
|
const raw = (process.env.CLAWROUTER_CLIENT ?? "").trim();
|
|
38898
39468
|
if (!raw) return "";
|
|
@@ -38906,7 +39476,7 @@ var init_version4 = __esm({
|
|
|
38906
39476
|
__filename2 = fileURLToPath(import.meta.url);
|
|
38907
39477
|
__dirname = dirname(__filename2);
|
|
38908
39478
|
require2 = createRequire(import.meta.url);
|
|
38909
|
-
pkg = require2(
|
|
39479
|
+
pkg = require2(join4(__dirname, "..", "package.json"));
|
|
38910
39480
|
VERSION = pkg.version;
|
|
38911
39481
|
USER_AGENT = `clawrouter/${VERSION}${clientTag()}`;
|
|
38912
39482
|
}
|
|
@@ -38914,8 +39484,8 @@ var init_version4 = __esm({
|
|
|
38914
39484
|
|
|
38915
39485
|
// src/stats.ts
|
|
38916
39486
|
import { readdir, unlink } from "fs/promises";
|
|
38917
|
-
import { join as
|
|
38918
|
-
import { homedir as
|
|
39487
|
+
import { join as join5 } from "path";
|
|
39488
|
+
import { homedir as homedir3 } from "os";
|
|
38919
39489
|
async function parseLogFile(filePath) {
|
|
38920
39490
|
try {
|
|
38921
39491
|
const content = await readTextFile(filePath);
|
|
@@ -38987,7 +39557,7 @@ async function getStats(days = 7) {
|
|
|
38987
39557
|
let totalLatency = 0;
|
|
38988
39558
|
for (const file of filesToRead) {
|
|
38989
39559
|
const date = file.replace("usage-", "").replace(".jsonl", "");
|
|
38990
|
-
const filePath =
|
|
39560
|
+
const filePath = join5(LOG_DIR2, file);
|
|
38991
39561
|
const entries = await parseLogFile(filePath);
|
|
38992
39562
|
if (entries.length === 0) continue;
|
|
38993
39563
|
const dayStats = aggregateDay(date, entries);
|
|
@@ -39105,7 +39675,7 @@ async function clearStats() {
|
|
|
39105
39675
|
try {
|
|
39106
39676
|
const files = await readdir(LOG_DIR2);
|
|
39107
39677
|
const logFiles = files.filter((f) => f.startsWith("usage-") && f.endsWith(".jsonl"));
|
|
39108
|
-
await Promise.all(logFiles.map((f) => unlink(
|
|
39678
|
+
await Promise.all(logFiles.map((f) => unlink(join5(LOG_DIR2, f))));
|
|
39109
39679
|
return { deletedFiles: logFiles.length };
|
|
39110
39680
|
} catch {
|
|
39111
39681
|
return { deletedFiles: 0 };
|
|
@@ -39117,7 +39687,27 @@ var init_stats = __esm({
|
|
|
39117
39687
|
"use strict";
|
|
39118
39688
|
init_fs_read();
|
|
39119
39689
|
init_version4();
|
|
39120
|
-
LOG_DIR2 =
|
|
39690
|
+
LOG_DIR2 = join5(homedir3(), ".openclaw", "blockrun", "logs");
|
|
39691
|
+
}
|
|
39692
|
+
});
|
|
39693
|
+
|
|
39694
|
+
// src/timestamp-strip.ts
|
|
39695
|
+
function stripLeadingTextBlockTimestamp(blocks) {
|
|
39696
|
+
let stripped = false;
|
|
39697
|
+
return blocks.map((block) => {
|
|
39698
|
+
if (!stripped && block !== null && typeof block === "object" && block.type === "text" && typeof block.text === "string") {
|
|
39699
|
+
stripped = true;
|
|
39700
|
+
const b = block;
|
|
39701
|
+
return { ...b, text: b.text.replace(TIMESTAMP_PATTERN, "") };
|
|
39702
|
+
}
|
|
39703
|
+
return block;
|
|
39704
|
+
});
|
|
39705
|
+
}
|
|
39706
|
+
var TIMESTAMP_PATTERN;
|
|
39707
|
+
var init_timestamp_strip = __esm({
|
|
39708
|
+
"src/timestamp-strip.ts"() {
|
|
39709
|
+
"use strict";
|
|
39710
|
+
TIMESTAMP_PATTERN = /^\[\w{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+\w+\]\s*/;
|
|
39121
39711
|
}
|
|
39122
39712
|
});
|
|
39123
39713
|
|
|
@@ -39147,19 +39737,21 @@ function stripTimestamps(obj) {
|
|
|
39147
39737
|
for (const [key2, value] of Object.entries(obj)) {
|
|
39148
39738
|
if (key2 === "content" && typeof value === "string") {
|
|
39149
39739
|
result[key2] = value.replace(TIMESTAMP_PATTERN, "");
|
|
39740
|
+
} else if (key2 === "content" && Array.isArray(value)) {
|
|
39741
|
+
result[key2] = stripLeadingTextBlockTimestamp(value.map(stripTimestamps));
|
|
39150
39742
|
} else {
|
|
39151
39743
|
result[key2] = stripTimestamps(value);
|
|
39152
39744
|
}
|
|
39153
39745
|
}
|
|
39154
39746
|
return result;
|
|
39155
39747
|
}
|
|
39156
|
-
var DEFAULT_TTL_MS2, MAX_BODY_SIZE,
|
|
39748
|
+
var DEFAULT_TTL_MS2, MAX_BODY_SIZE, RequestDeduplicator;
|
|
39157
39749
|
var init_dedup = __esm({
|
|
39158
39750
|
"src/dedup.ts"() {
|
|
39159
39751
|
"use strict";
|
|
39752
|
+
init_timestamp_strip();
|
|
39160
39753
|
DEFAULT_TTL_MS2 = 3e4;
|
|
39161
39754
|
MAX_BODY_SIZE = 1048576;
|
|
39162
|
-
TIMESTAMP_PATTERN = /^\[\w{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+\w+\]\s*/;
|
|
39163
39755
|
RequestDeduplicator = class {
|
|
39164
39756
|
inflight = /* @__PURE__ */ new Map();
|
|
39165
39757
|
completed = /* @__PURE__ */ new Map();
|
|
@@ -39277,7 +39869,10 @@ function normalizeForCache(obj) {
|
|
|
39277
39869
|
if (typeof msg === "object" && msg !== null) {
|
|
39278
39870
|
const m = msg;
|
|
39279
39871
|
if (typeof m.content === "string") {
|
|
39280
|
-
return { ...m, content: m.content.replace(
|
|
39872
|
+
return { ...m, content: m.content.replace(TIMESTAMP_PATTERN, "") };
|
|
39873
|
+
}
|
|
39874
|
+
if (Array.isArray(m.content)) {
|
|
39875
|
+
return { ...m, content: stripLeadingTextBlockTimestamp(m.content) };
|
|
39281
39876
|
}
|
|
39282
39877
|
}
|
|
39283
39878
|
return msg;
|
|
@@ -39288,10 +39883,11 @@ function normalizeForCache(obj) {
|
|
|
39288
39883
|
}
|
|
39289
39884
|
return result;
|
|
39290
39885
|
}
|
|
39291
|
-
var DEFAULT_CONFIG,
|
|
39886
|
+
var DEFAULT_CONFIG, ResponseCache;
|
|
39292
39887
|
var init_response_cache = __esm({
|
|
39293
39888
|
"src/response-cache.ts"() {
|
|
39294
39889
|
"use strict";
|
|
39890
|
+
init_timestamp_strip();
|
|
39295
39891
|
DEFAULT_CONFIG = {
|
|
39296
39892
|
maxSize: 200,
|
|
39297
39893
|
defaultTTL: 600,
|
|
@@ -39299,7 +39895,6 @@ var init_response_cache = __esm({
|
|
|
39299
39895
|
// 1MB
|
|
39300
39896
|
enabled: true
|
|
39301
39897
|
};
|
|
39302
|
-
TIMESTAMP_PATTERN2 = /^\[\w{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}\s+\w+\]\s*/;
|
|
39303
39898
|
ResponseCache = class {
|
|
39304
39899
|
cache = /* @__PURE__ */ new Map();
|
|
39305
39900
|
expirationHeap = [];
|
|
@@ -42911,7 +43506,7 @@ function alphabet2(letters) {
|
|
|
42911
43506
|
};
|
|
42912
43507
|
}
|
|
42913
43508
|
// @__NO_SIDE_EFFECTS__
|
|
42914
|
-
function
|
|
43509
|
+
function join6(separator = "") {
|
|
42915
43510
|
astr2("join", separator);
|
|
42916
43511
|
return {
|
|
42917
43512
|
encode: (from15) => {
|
|
@@ -43021,7 +43616,7 @@ var genBase58, base58, createBase58check;
|
|
|
43021
43616
|
var init_base3 = __esm({
|
|
43022
43617
|
"node_modules/@scure/base/index.js"() {
|
|
43023
43618
|
"use strict";
|
|
43024
|
-
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */
|
|
43619
|
+
genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join6(""));
|
|
43025
43620
|
base58 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"));
|
|
43026
43621
|
createBase58check = (sha25610) => {
|
|
43027
43622
|
afn2(sha25610);
|
|
@@ -43170,14 +43765,14 @@ var init_bip32 = __esm({
|
|
|
43170
43765
|
}
|
|
43171
43766
|
this.pubHash = hash160(this._publicKey);
|
|
43172
43767
|
}
|
|
43173
|
-
derive(
|
|
43174
|
-
if (!/^[mM]'?/.test(
|
|
43768
|
+
derive(path5) {
|
|
43769
|
+
if (!/^[mM]'?/.test(path5)) {
|
|
43175
43770
|
throw new Error('Path must start with "m" or "M"');
|
|
43176
43771
|
}
|
|
43177
|
-
if (/^[mM]'?$/.test(
|
|
43772
|
+
if (/^[mM]'?$/.test(path5)) {
|
|
43178
43773
|
return this;
|
|
43179
43774
|
}
|
|
43180
|
-
const parts =
|
|
43775
|
+
const parts = path5.replace(/^[mM]'?\//, "").split("/");
|
|
43181
43776
|
let child = this;
|
|
43182
43777
|
for (const c of parts) {
|
|
43183
43778
|
const m = /^(\d+)('?)$/.exec(c);
|
|
@@ -51467,14 +52062,14 @@ function createSolanaJsonRpcIntegerOverflowError(methodName, keyPath, value) {
|
|
|
51467
52062
|
} else {
|
|
51468
52063
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
51469
52064
|
}
|
|
51470
|
-
const
|
|
52065
|
+
const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
51471
52066
|
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
51472
52067
|
argumentLabel,
|
|
51473
52068
|
keyPath,
|
|
51474
52069
|
methodName,
|
|
51475
|
-
optionalPathLabel:
|
|
52070
|
+
optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
|
|
51476
52071
|
value,
|
|
51477
|
-
...
|
|
52072
|
+
...path5 !== void 0 ? { path: path5 } : void 0
|
|
51478
52073
|
});
|
|
51479
52074
|
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);
|
|
51480
52075
|
return error;
|
|
@@ -56138,14 +56733,14 @@ function createSolanaJsonRpcIntegerOverflowError2(methodName, keyPath, value) {
|
|
|
56138
56733
|
} else {
|
|
56139
56734
|
argumentLabel = `\`${keyPath[0].toString()}\``;
|
|
56140
56735
|
}
|
|
56141
|
-
const
|
|
56736
|
+
const path5 = keyPath.length > 1 ? keyPath.slice(1).map((pathPart) => typeof pathPart === "number" ? `[${pathPart}]` : pathPart).join(".") : void 0;
|
|
56142
56737
|
const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {
|
|
56143
56738
|
argumentLabel,
|
|
56144
56739
|
keyPath,
|
|
56145
56740
|
methodName,
|
|
56146
|
-
optionalPathLabel:
|
|
56741
|
+
optionalPathLabel: path5 ? ` at path \`${path5}\`` : "",
|
|
56147
56742
|
value,
|
|
56148
|
-
...
|
|
56743
|
+
...path5 !== void 0 ? { path: path5 } : void 0
|
|
56149
56744
|
});
|
|
56150
56745
|
safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError2);
|
|
56151
56746
|
return error;
|
|
@@ -58213,8 +58808,8 @@ var init_wallet2 = __esm({
|
|
|
58213
58808
|
|
|
58214
58809
|
// src/auth.ts
|
|
58215
58810
|
import { writeFile, mkdir as mkdir2 } from "fs/promises";
|
|
58216
|
-
import { join as
|
|
58217
|
-
import { homedir as
|
|
58811
|
+
import { join as join7 } from "path";
|
|
58812
|
+
import { homedir as homedir4 } from "os";
|
|
58218
58813
|
async function loadSavedWallet() {
|
|
58219
58814
|
try {
|
|
58220
58815
|
const key2 = (await readTextFile(WALLET_FILE)).trim();
|
|
@@ -58263,7 +58858,7 @@ async function loadMnemonic() {
|
|
|
58263
58858
|
return void 0;
|
|
58264
58859
|
}
|
|
58265
58860
|
async function saveMnemonic(mnemonic) {
|
|
58266
|
-
await mkdir2(
|
|
58861
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58267
58862
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
58268
58863
|
}
|
|
58269
58864
|
async function generateAndSaveWallet() {
|
|
@@ -58282,7 +58877,7 @@ Then run: npx @blockrun/clawrouter`
|
|
|
58282
58877
|
}
|
|
58283
58878
|
const mnemonic = generateWalletMnemonic();
|
|
58284
58879
|
const derived = deriveAllKeys(mnemonic);
|
|
58285
|
-
await mkdir2(
|
|
58880
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58286
58881
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
58287
58882
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
58288
58883
|
try {
|
|
@@ -58404,7 +58999,7 @@ async function setupSolana() {
|
|
|
58404
58999
|
return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
|
|
58405
59000
|
}
|
|
58406
59001
|
async function savePaymentChain(chain3) {
|
|
58407
|
-
await mkdir2(
|
|
59002
|
+
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
58408
59003
|
await writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
|
|
58409
59004
|
}
|
|
58410
59005
|
async function loadPaymentChain() {
|
|
@@ -58421,17 +59016,17 @@ async function resolvePaymentChain() {
|
|
|
58421
59016
|
if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
|
|
58422
59017
|
return loadPaymentChain();
|
|
58423
59018
|
}
|
|
58424
|
-
var
|
|
59019
|
+
var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
|
|
58425
59020
|
var init_auth = __esm({
|
|
58426
59021
|
"src/auth.ts"() {
|
|
58427
59022
|
"use strict";
|
|
58428
59023
|
init_fs_read();
|
|
58429
59024
|
init_accounts();
|
|
58430
59025
|
init_wallet2();
|
|
58431
|
-
|
|
58432
|
-
WALLET_FILE =
|
|
58433
|
-
MNEMONIC_FILE =
|
|
58434
|
-
CHAIN_FILE =
|
|
59026
|
+
WALLET_DIR2 = join7(homedir4(), ".openclaw", "blockrun");
|
|
59027
|
+
WALLET_FILE = join7(WALLET_DIR2, "wallet.key");
|
|
59028
|
+
MNEMONIC_FILE = join7(WALLET_DIR2, "mnemonic");
|
|
59029
|
+
CHAIN_FILE = join7(WALLET_DIR2, "payment-chain");
|
|
58435
59030
|
}
|
|
58436
59031
|
});
|
|
58437
59032
|
|
|
@@ -58590,7 +59185,7 @@ function generateCodebookHeader(usedCodes, pathMap = {}) {
|
|
|
58590
59185
|
parts.push(`[Dict: ${codeEntries}]`);
|
|
58591
59186
|
}
|
|
58592
59187
|
if (Object.keys(pathMap).length > 0) {
|
|
58593
|
-
const pathEntries = Object.entries(pathMap).map(([code,
|
|
59188
|
+
const pathEntries = Object.entries(pathMap).map(([code, path5]) => `${code}=${path5}`).join(", ");
|
|
58594
59189
|
parts.push(`[Paths: ${pathEntries}]`);
|
|
58595
59190
|
}
|
|
58596
59191
|
return parts.join("\n");
|
|
@@ -58738,8 +59333,8 @@ function extractPaths(messages) {
|
|
|
58738
59333
|
}
|
|
58739
59334
|
function findFrequentPrefixes(paths) {
|
|
58740
59335
|
const prefixCounts = /* @__PURE__ */ new Map();
|
|
58741
|
-
for (const
|
|
58742
|
-
const parts =
|
|
59336
|
+
for (const path5 of paths) {
|
|
59337
|
+
const parts = path5.split("/").filter(Boolean);
|
|
58743
59338
|
for (let i = 2; i < parts.length; i++) {
|
|
58744
59339
|
const prefix = "/" + parts.slice(0, i).join("/") + "/";
|
|
58745
59340
|
prefixCounts.set(prefix, (prefixCounts.get(prefix) || 0) + 1);
|
|
@@ -59523,9 +60118,9 @@ var init_updater = __esm({
|
|
|
59523
60118
|
});
|
|
59524
60119
|
|
|
59525
60120
|
// src/exclude-models.ts
|
|
59526
|
-
import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
|
|
59527
|
-
import { join as
|
|
59528
|
-
import { homedir as
|
|
60121
|
+
import { readFileSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
60122
|
+
import { join as join8, dirname as dirname2 } from "path";
|
|
60123
|
+
import { homedir as homedir5 } from "os";
|
|
59529
60124
|
function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
59530
60125
|
try {
|
|
59531
60126
|
const mtimeMs = statSync(filePath).mtimeMs;
|
|
@@ -59546,8 +60141,8 @@ function loadExcludeList(filePath = DEFAULT_FILE_PATH) {
|
|
|
59546
60141
|
function saveExcludeList(set, filePath) {
|
|
59547
60142
|
const sorted = [...set].sort();
|
|
59548
60143
|
const dir = dirname2(filePath);
|
|
59549
|
-
|
|
59550
|
-
|
|
60144
|
+
mkdirSync2(dir, { recursive: true });
|
|
60145
|
+
writeFileSync2(filePath, JSON.stringify(sorted, null, 2) + "\n", "utf-8");
|
|
59551
60146
|
loadCache.delete(filePath);
|
|
59552
60147
|
}
|
|
59553
60148
|
function addExclusion(model, filePath = DEFAULT_FILE_PATH) {
|
|
@@ -59574,7 +60169,7 @@ var init_exclude_models = __esm({
|
|
|
59574
60169
|
"src/exclude-models.ts"() {
|
|
59575
60170
|
"use strict";
|
|
59576
60171
|
init_models();
|
|
59577
|
-
DEFAULT_FILE_PATH =
|
|
60172
|
+
DEFAULT_FILE_PATH = join8(homedir5(), ".openclaw", "blockrun", "exclude-models.json");
|
|
59578
60173
|
loadCache = /* @__PURE__ */ new Map();
|
|
59579
60174
|
}
|
|
59580
60175
|
});
|
|
@@ -60879,14 +61474,14 @@ var require_util = __commonJS({
|
|
|
60879
61474
|
}
|
|
60880
61475
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
60881
61476
|
let origin2 = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
60882
|
-
let
|
|
61477
|
+
let path5 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
60883
61478
|
if (origin2[origin2.length - 1] === "/") {
|
|
60884
61479
|
origin2 = origin2.slice(0, origin2.length - 1);
|
|
60885
61480
|
}
|
|
60886
|
-
if (
|
|
60887
|
-
|
|
61481
|
+
if (path5 && path5[0] !== "/") {
|
|
61482
|
+
path5 = `/${path5}`;
|
|
60888
61483
|
}
|
|
60889
|
-
return new URL(`${origin2}${
|
|
61484
|
+
return new URL(`${origin2}${path5}`);
|
|
60890
61485
|
}
|
|
60891
61486
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
60892
61487
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -61757,9 +62352,9 @@ var require_diagnostics = __commonJS({
|
|
|
61757
62352
|
"undici:client:sendHeaders",
|
|
61758
62353
|
(evt) => {
|
|
61759
62354
|
const {
|
|
61760
|
-
request: { method, path:
|
|
62355
|
+
request: { method, path: path5, origin: origin2 }
|
|
61761
62356
|
} = evt;
|
|
61762
|
-
debugLog("sending request to %s %s%s", method, origin2,
|
|
62357
|
+
debugLog("sending request to %s %s%s", method, origin2, path5);
|
|
61763
62358
|
}
|
|
61764
62359
|
);
|
|
61765
62360
|
}
|
|
@@ -61777,14 +62372,14 @@ var require_diagnostics = __commonJS({
|
|
|
61777
62372
|
"undici:request:headers",
|
|
61778
62373
|
(evt) => {
|
|
61779
62374
|
const {
|
|
61780
|
-
request: { method, path:
|
|
62375
|
+
request: { method, path: path5, origin: origin2 },
|
|
61781
62376
|
response: { statusCode }
|
|
61782
62377
|
} = evt;
|
|
61783
62378
|
debugLog(
|
|
61784
62379
|
"received response to %s %s%s - HTTP %d",
|
|
61785
62380
|
method,
|
|
61786
62381
|
origin2,
|
|
61787
|
-
|
|
62382
|
+
path5,
|
|
61788
62383
|
statusCode
|
|
61789
62384
|
);
|
|
61790
62385
|
}
|
|
@@ -61793,23 +62388,23 @@ var require_diagnostics = __commonJS({
|
|
|
61793
62388
|
"undici:request:trailers",
|
|
61794
62389
|
(evt) => {
|
|
61795
62390
|
const {
|
|
61796
|
-
request: { method, path:
|
|
62391
|
+
request: { method, path: path5, origin: origin2 }
|
|
61797
62392
|
} = evt;
|
|
61798
|
-
debugLog("trailers received from %s %s%s", method, origin2,
|
|
62393
|
+
debugLog("trailers received from %s %s%s", method, origin2, path5);
|
|
61799
62394
|
}
|
|
61800
62395
|
);
|
|
61801
62396
|
diagnosticsChannel.subscribe(
|
|
61802
62397
|
"undici:request:error",
|
|
61803
62398
|
(evt) => {
|
|
61804
62399
|
const {
|
|
61805
|
-
request: { method, path:
|
|
62400
|
+
request: { method, path: path5, origin: origin2 },
|
|
61806
62401
|
error
|
|
61807
62402
|
} = evt;
|
|
61808
62403
|
debugLog(
|
|
61809
62404
|
"request to %s %s%s errored - %s",
|
|
61810
62405
|
method,
|
|
61811
62406
|
origin2,
|
|
61812
|
-
|
|
62407
|
+
path5,
|
|
61813
62408
|
error.message
|
|
61814
62409
|
);
|
|
61815
62410
|
}
|
|
@@ -61964,7 +62559,7 @@ var require_request = __commonJS({
|
|
|
61964
62559
|
};
|
|
61965
62560
|
var Request2 = class {
|
|
61966
62561
|
constructor(origin2, {
|
|
61967
|
-
path:
|
|
62562
|
+
path: path5,
|
|
61968
62563
|
method,
|
|
61969
62564
|
body,
|
|
61970
62565
|
headers,
|
|
@@ -61981,11 +62576,11 @@ var require_request = __commonJS({
|
|
|
61981
62576
|
maxRedirections,
|
|
61982
62577
|
typeOfService
|
|
61983
62578
|
}, handler) {
|
|
61984
|
-
if (typeof
|
|
62579
|
+
if (typeof path5 !== "string") {
|
|
61985
62580
|
throw new InvalidArgumentError("path must be a string");
|
|
61986
|
-
} else if (
|
|
62581
|
+
} else if (path5[0] !== "/" && !(path5.startsWith("http://") || path5.startsWith("https://")) && method !== "CONNECT") {
|
|
61987
62582
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
61988
|
-
} else if (invalidPathRegex.test(
|
|
62583
|
+
} else if (invalidPathRegex.test(path5)) {
|
|
61989
62584
|
throw new InvalidArgumentError("invalid request path");
|
|
61990
62585
|
}
|
|
61991
62586
|
if (typeof method !== "string") {
|
|
@@ -62060,7 +62655,7 @@ var require_request = __commonJS({
|
|
|
62060
62655
|
this.completed = false;
|
|
62061
62656
|
this.aborted = false;
|
|
62062
62657
|
this.upgrade = upgrade || null;
|
|
62063
|
-
this.path = query ? serializePathWithQuery(
|
|
62658
|
+
this.path = query ? serializePathWithQuery(path5, query) : path5;
|
|
62064
62659
|
this.origin = origin2;
|
|
62065
62660
|
this.protocol = getProtocolFromUrlString(origin2);
|
|
62066
62661
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" || method === "QUERY" : idempotent;
|
|
@@ -67146,7 +67741,7 @@ var require_client_h1 = __commonJS({
|
|
|
67146
67741
|
}
|
|
67147
67742
|
}
|
|
67148
67743
|
function writeH1(client, request2) {
|
|
67149
|
-
const { method, path:
|
|
67744
|
+
const { method, path: path5, host, upgrade, blocking, reset } = request2;
|
|
67150
67745
|
let { body, headers, contentLength } = request2;
|
|
67151
67746
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
67152
67747
|
if (util5.isFormDataLike(body)) {
|
|
@@ -67222,7 +67817,7 @@ var require_client_h1 = __commonJS({
|
|
|
67222
67817
|
socket[kBlocking] = true;
|
|
67223
67818
|
}
|
|
67224
67819
|
setTypeOfService(socket, request2);
|
|
67225
|
-
let header = `${method} ${
|
|
67820
|
+
let header = `${method} ${path5} HTTP/1.1\r
|
|
67226
67821
|
`;
|
|
67227
67822
|
if (typeof host === "string") {
|
|
67228
67823
|
header += `host: ${host}\r
|
|
@@ -68303,7 +68898,7 @@ var require_client_h2 = __commonJS({
|
|
|
68303
68898
|
const headersTimeout = request2.headersTimeout ?? client[kHeadersTimeout];
|
|
68304
68899
|
const bodyTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
|
|
68305
68900
|
const session = client[kHTTP2Session];
|
|
68306
|
-
const { method, path:
|
|
68901
|
+
const { method, path: path5, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
|
|
68307
68902
|
if (upgrade != null && upgrade !== "websocket") {
|
|
68308
68903
|
util5.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
68309
68904
|
return false;
|
|
@@ -68366,7 +68961,7 @@ var require_client_h2 = __commonJS({
|
|
|
68366
68961
|
}
|
|
68367
68962
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
68368
68963
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
68369
|
-
headers[HTTP2_HEADER_PATH] =
|
|
68964
|
+
headers[HTTP2_HEADER_PATH] = path5;
|
|
68370
68965
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
68371
68966
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
68372
68967
|
} else {
|
|
@@ -68388,7 +68983,7 @@ var require_client_h2 = __commonJS({
|
|
|
68388
68983
|
setupUpgradeStream(stream4, state);
|
|
68389
68984
|
return true;
|
|
68390
68985
|
}
|
|
68391
|
-
headers[HTTP2_HEADER_PATH] =
|
|
68986
|
+
headers[HTTP2_HEADER_PATH] = path5;
|
|
68392
68987
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
68393
68988
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
68394
68989
|
let body = state.body;
|
|
@@ -71058,10 +71653,10 @@ var require_proxy_agent = __commonJS({
|
|
|
71058
71653
|
};
|
|
71059
71654
|
const {
|
|
71060
71655
|
origin: origin2,
|
|
71061
|
-
path:
|
|
71656
|
+
path: path5 = "/",
|
|
71062
71657
|
headers = {}
|
|
71063
71658
|
} = opts;
|
|
71064
|
-
opts.path = origin2 +
|
|
71659
|
+
opts.path = origin2 + path5;
|
|
71065
71660
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
71066
71661
|
const { host } = new URL(origin2);
|
|
71067
71662
|
headers.host = host;
|
|
@@ -73326,20 +73921,20 @@ var require_mock_utils = __commonJS({
|
|
|
73326
73921
|
}
|
|
73327
73922
|
return normalizedQp;
|
|
73328
73923
|
}
|
|
73329
|
-
function safeUrl(
|
|
73330
|
-
if (typeof
|
|
73331
|
-
return
|
|
73924
|
+
function safeUrl(path5) {
|
|
73925
|
+
if (typeof path5 !== "string") {
|
|
73926
|
+
return path5;
|
|
73332
73927
|
}
|
|
73333
|
-
const pathSegments =
|
|
73928
|
+
const pathSegments = path5.split("?", 3);
|
|
73334
73929
|
if (pathSegments.length !== 2) {
|
|
73335
|
-
return
|
|
73930
|
+
return path5;
|
|
73336
73931
|
}
|
|
73337
73932
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
73338
73933
|
qp.sort();
|
|
73339
73934
|
return [...pathSegments, qp.toString()].join("?");
|
|
73340
73935
|
}
|
|
73341
|
-
function matchKey(mockDispatch2, { path:
|
|
73342
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
73936
|
+
function matchKey(mockDispatch2, { path: path5, method, body, headers }) {
|
|
73937
|
+
const pathMatch = matchValue(mockDispatch2.path, path5);
|
|
73343
73938
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
73344
73939
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
73345
73940
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -73366,8 +73961,8 @@ var require_mock_utils = __commonJS({
|
|
|
73366
73961
|
const basePath = key2.query ? serializePathWithQuery(key2.path, key2.query) : key2.path;
|
|
73367
73962
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
73368
73963
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
73369
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
73370
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
73964
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path5, ignoreTrailingSlash }) => {
|
|
73965
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path5)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path5), resolvedPath);
|
|
73371
73966
|
});
|
|
73372
73967
|
if (matchedMockDispatches.length === 0) {
|
|
73373
73968
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -73406,22 +74001,22 @@ var require_mock_utils = __commonJS({
|
|
|
73406
74001
|
mockDispatches.splice(index2, 1);
|
|
73407
74002
|
}
|
|
73408
74003
|
}
|
|
73409
|
-
function removeTrailingSlash(
|
|
73410
|
-
if (typeof
|
|
73411
|
-
return
|
|
74004
|
+
function removeTrailingSlash(path5) {
|
|
74005
|
+
if (typeof path5 !== "string") {
|
|
74006
|
+
return path5;
|
|
73412
74007
|
}
|
|
73413
|
-
while (
|
|
73414
|
-
|
|
74008
|
+
while (path5.endsWith("/")) {
|
|
74009
|
+
path5 = path5.slice(0, -1);
|
|
73415
74010
|
}
|
|
73416
|
-
if (
|
|
73417
|
-
|
|
74011
|
+
if (path5.length === 0) {
|
|
74012
|
+
path5 = "/";
|
|
73418
74013
|
}
|
|
73419
|
-
return
|
|
74014
|
+
return path5;
|
|
73420
74015
|
}
|
|
73421
74016
|
function buildKey(opts) {
|
|
73422
|
-
const { path:
|
|
74017
|
+
const { path: path5, method, body, headers, query } = opts;
|
|
73423
74018
|
return {
|
|
73424
|
-
path:
|
|
74019
|
+
path: path5,
|
|
73425
74020
|
method,
|
|
73426
74021
|
body,
|
|
73427
74022
|
headers,
|
|
@@ -74292,10 +74887,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
74292
74887
|
}
|
|
74293
74888
|
format(pendingInterceptors) {
|
|
74294
74889
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
74295
|
-
({ method, path:
|
|
74890
|
+
({ method, path: path5, data: { statusCode }, persist, times, timesInvoked, origin: origin2 }) => ({
|
|
74296
74891
|
Method: method,
|
|
74297
74892
|
Origin: origin2,
|
|
74298
|
-
Path:
|
|
74893
|
+
Path: path5,
|
|
74299
74894
|
"Status code": statusCode,
|
|
74300
74895
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
74301
74896
|
Invocations: timesInvoked,
|
|
@@ -74377,9 +74972,9 @@ var require_mock_agent = __commonJS({
|
|
|
74377
74972
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
74378
74973
|
const dispatchOpts = { ...opts };
|
|
74379
74974
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
74380
|
-
const [
|
|
74975
|
+
const [path5, searchParams] = dispatchOpts.path.split("?");
|
|
74381
74976
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
74382
|
-
dispatchOpts.path = `${
|
|
74977
|
+
dispatchOpts.path = `${path5}?${normalizedSearchParams}`;
|
|
74383
74978
|
}
|
|
74384
74979
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
74385
74980
|
}
|
|
@@ -74795,12 +75390,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
74795
75390
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
74796
75391
|
*/
|
|
74797
75392
|
async loadSnapshots(filePath) {
|
|
74798
|
-
const
|
|
74799
|
-
if (!
|
|
75393
|
+
const path5 = filePath || this.#snapshotPath;
|
|
75394
|
+
if (!path5) {
|
|
74800
75395
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
74801
75396
|
}
|
|
74802
75397
|
try {
|
|
74803
|
-
const data = await readFile3(resolve(
|
|
75398
|
+
const data = await readFile3(resolve(path5), "utf8");
|
|
74804
75399
|
const parsed = JSON.parse(data);
|
|
74805
75400
|
if (Array.isArray(parsed)) {
|
|
74806
75401
|
this.#snapshots.clear();
|
|
@@ -74814,7 +75409,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
74814
75409
|
if (error.code === "ENOENT") {
|
|
74815
75410
|
this.#snapshots.clear();
|
|
74816
75411
|
} else {
|
|
74817
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
75412
|
+
throw new UndiciError(`Failed to load snapshots from ${path5}`, { cause: error });
|
|
74818
75413
|
}
|
|
74819
75414
|
}
|
|
74820
75415
|
}
|
|
@@ -74825,11 +75420,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
74825
75420
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
74826
75421
|
*/
|
|
74827
75422
|
async saveSnapshots(filePath) {
|
|
74828
|
-
const
|
|
74829
|
-
if (!
|
|
75423
|
+
const path5 = filePath || this.#snapshotPath;
|
|
75424
|
+
if (!path5) {
|
|
74830
75425
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
74831
75426
|
}
|
|
74832
|
-
const resolvedPath = resolve(
|
|
75427
|
+
const resolvedPath = resolve(path5);
|
|
74833
75428
|
await mkdir5(dirname5(resolvedPath), { recursive: true });
|
|
74834
75429
|
const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
|
|
74835
75430
|
hash: hash5,
|
|
@@ -75466,15 +76061,15 @@ var require_redirect_handler = __commonJS({
|
|
|
75466
76061
|
return;
|
|
75467
76062
|
}
|
|
75468
76063
|
const { origin: origin2, pathname, search } = util5.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
75469
|
-
const
|
|
75470
|
-
const redirectUrlString = `${origin2}${
|
|
76064
|
+
const path5 = search ? `${pathname}${search}` : pathname;
|
|
76065
|
+
const redirectUrlString = `${origin2}${path5}`;
|
|
75471
76066
|
for (const historyUrl of this.history) {
|
|
75472
76067
|
if (historyUrl.toString() === redirectUrlString) {
|
|
75473
76068
|
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.`);
|
|
75474
76069
|
}
|
|
75475
76070
|
}
|
|
75476
76071
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, removeContentHeaders, this.opts.origin !== origin2, this.stripHeadersOnRedirect, this.stripHeadersOnCrossOriginRedirect);
|
|
75477
|
-
this.opts.path =
|
|
76072
|
+
this.opts.path = path5;
|
|
75478
76073
|
this.opts.origin = origin2;
|
|
75479
76074
|
this.opts.query = null;
|
|
75480
76075
|
}
|
|
@@ -77302,10 +77897,10 @@ var require_cache_handler = __commonJS({
|
|
|
77302
77897
|
}
|
|
77303
77898
|
return locationUrl.pathname + locationUrl.search;
|
|
77304
77899
|
}
|
|
77305
|
-
function deleteCachedUri(store, cacheKey2,
|
|
77900
|
+
function deleteCachedUri(store, cacheKey2, path5) {
|
|
77306
77901
|
deleteCachedValue(store, {
|
|
77307
77902
|
...cacheKey2,
|
|
77308
|
-
path:
|
|
77903
|
+
path: path5
|
|
77309
77904
|
});
|
|
77310
77905
|
for (let i = 0; i < util5.safeHTTPMethods.length; i++) {
|
|
77311
77906
|
const method = util5.safeHTTPMethods[i];
|
|
@@ -77313,7 +77908,7 @@ var require_cache_handler = __commonJS({
|
|
|
77313
77908
|
deleteCachedValue(store, {
|
|
77314
77909
|
...cacheKey2,
|
|
77315
77910
|
method,
|
|
77316
|
-
path:
|
|
77911
|
+
path: path5
|
|
77317
77912
|
});
|
|
77318
77913
|
}
|
|
77319
77914
|
}
|
|
@@ -77324,9 +77919,9 @@ var require_cache_handler = __commonJS({
|
|
|
77324
77919
|
}
|
|
77325
77920
|
const values = Array.isArray(headerValue) ? headerValue : [headerValue];
|
|
77326
77921
|
for (let i = 0; i < values.length; i++) {
|
|
77327
|
-
const
|
|
77328
|
-
if (
|
|
77329
|
-
deleteCachedUri(store, cacheKey2,
|
|
77922
|
+
const path5 = getSameOriginPath(cacheKey2, values[i]);
|
|
77923
|
+
if (path5 !== void 0) {
|
|
77924
|
+
deleteCachedUri(store, cacheKey2, path5);
|
|
77330
77925
|
}
|
|
77331
77926
|
}
|
|
77332
77927
|
}
|
|
@@ -82323,13 +82918,13 @@ var require_fetch = __commonJS({
|
|
|
82323
82918
|
function dispatch({ body }) {
|
|
82324
82919
|
const url2 = requestCurrentURL(request2);
|
|
82325
82920
|
const agent = fetchParams.controller.dispatcher;
|
|
82326
|
-
const
|
|
82921
|
+
const path5 = url2.pathname + url2.search;
|
|
82327
82922
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
82328
82923
|
return dispatchWithProtocolPreference(body);
|
|
82329
82924
|
function dispatchWithProtocolPreference(body2, allowH2) {
|
|
82330
82925
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
82331
82926
|
{
|
|
82332
|
-
path: hasTrailingQuestionMark ? `${
|
|
82927
|
+
path: hasTrailingQuestionMark ? `${path5}?` : path5,
|
|
82333
82928
|
origin: url2.origin,
|
|
82334
82929
|
method: request2.method,
|
|
82335
82930
|
body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body2,
|
|
@@ -83241,9 +83836,9 @@ var require_util4 = __commonJS({
|
|
|
83241
83836
|
}
|
|
83242
83837
|
}
|
|
83243
83838
|
}
|
|
83244
|
-
function validateCookiePath(
|
|
83245
|
-
for (let i = 0; i <
|
|
83246
|
-
const code =
|
|
83839
|
+
function validateCookiePath(path5) {
|
|
83840
|
+
for (let i = 0; i < path5.length; ++i) {
|
|
83841
|
+
const code = path5.charCodeAt(i);
|
|
83247
83842
|
if (code < 32 || // exclude CTLs (0-31)
|
|
83248
83843
|
code > 126 || // exclude non-ascii and DEL
|
|
83249
83844
|
code === 59) {
|
|
@@ -86615,11 +87210,11 @@ var require_undici = __commonJS({
|
|
|
86615
87210
|
if (typeof opts.path !== "string") {
|
|
86616
87211
|
throw new InvalidArgumentError("invalid opts.path");
|
|
86617
87212
|
}
|
|
86618
|
-
let
|
|
87213
|
+
let path5 = opts.path;
|
|
86619
87214
|
if (!opts.path.startsWith("/")) {
|
|
86620
|
-
|
|
87215
|
+
path5 = `/${path5}`;
|
|
86621
87216
|
}
|
|
86622
|
-
url2 = new URL(util5.parseOrigin(url2).origin +
|
|
87217
|
+
url2 = new URL(util5.parseOrigin(url2).origin + path5);
|
|
86623
87218
|
} else {
|
|
86624
87219
|
if (!opts) {
|
|
86625
87220
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -87165,8 +87760,8 @@ var init_textual_tool_calls = __esm({
|
|
|
87165
87760
|
|
|
87166
87761
|
// src/response-store.ts
|
|
87167
87762
|
import { appendFile as appendFile2, mkdir as mkdir3, readFile, readdir as readdir2 } from "fs/promises";
|
|
87168
|
-
import { homedir as
|
|
87169
|
-
import { join as
|
|
87763
|
+
import { homedir as homedir6 } from "os";
|
|
87764
|
+
import { join as join9 } from "path";
|
|
87170
87765
|
import { randomBytes as randomBytes7 } from "crypto";
|
|
87171
87766
|
function isEnabled() {
|
|
87172
87767
|
const v = process.env.BLOCKRUN_RESPONSE_STORE;
|
|
@@ -87179,7 +87774,7 @@ async function ensureDir2() {
|
|
|
87179
87774
|
}
|
|
87180
87775
|
function dailyFile(date = /* @__PURE__ */ new Date()) {
|
|
87181
87776
|
const iso = date.toISOString().slice(0, 10);
|
|
87182
|
-
return
|
|
87777
|
+
return join9(STORE_DIR, `responses-${iso}.jsonl`);
|
|
87183
87778
|
}
|
|
87184
87779
|
function genId() {
|
|
87185
87780
|
return `resp_${Date.now()}_${randomBytes7(3).toString("hex")}`;
|
|
@@ -87229,7 +87824,7 @@ async function listRecent(limit = 20, daysBack = 7) {
|
|
|
87229
87824
|
d.setUTCDate(d.getUTCDate() - i);
|
|
87230
87825
|
const iso = d.toISOString().slice(0, 10);
|
|
87231
87826
|
const name = `responses-${iso}.jsonl`;
|
|
87232
|
-
if (files.includes(name)) candidateFiles.push(
|
|
87827
|
+
if (files.includes(name)) candidateFiles.push(join9(STORE_DIR, name));
|
|
87233
87828
|
}
|
|
87234
87829
|
const all3 = [];
|
|
87235
87830
|
for (const f of candidateFiles) {
|
|
@@ -87258,7 +87853,7 @@ var STORE_DIR, dirReady2;
|
|
|
87258
87853
|
var init_response_store = __esm({
|
|
87259
87854
|
"src/response-store.ts"() {
|
|
87260
87855
|
"use strict";
|
|
87261
|
-
STORE_DIR =
|
|
87856
|
+
STORE_DIR = join9(homedir6(), ".openclaw", "blockrun", "responses");
|
|
87262
87857
|
dirReady2 = false;
|
|
87263
87858
|
}
|
|
87264
87859
|
});
|
|
@@ -88908,10 +89503,10 @@ var init_client3 = __esm({
|
|
|
88908
89503
|
import { AsyncLocalStorage } from "async_hooks";
|
|
88909
89504
|
import { createServer } from "http";
|
|
88910
89505
|
import { finished } from "stream";
|
|
88911
|
-
import { homedir as
|
|
88912
|
-
import { join as
|
|
89506
|
+
import { homedir as homedir7 } from "os";
|
|
89507
|
+
import { join as join10 } from "path";
|
|
88913
89508
|
import { mkdir as mkdir4, writeFile as writeFile2, readFile as readFile2, stat as fsStat } from "fs/promises";
|
|
88914
|
-
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
89509
|
+
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
88915
89510
|
function pickFreeModel(excludeList) {
|
|
88916
89511
|
for (const m of FREE_MODELS) {
|
|
88917
89512
|
if (!excludeList?.has(m)) return m;
|
|
@@ -89677,8 +90272,8 @@ async function proxyPaidApiRequest(req, res, apiBase, payFetch, getActualPayment
|
|
|
89677
90272
|
});
|
|
89678
90273
|
}
|
|
89679
90274
|
function readImageFileAsDataUri(filePath) {
|
|
89680
|
-
const resolved = filePath.startsWith("~/") ?
|
|
89681
|
-
if (!
|
|
90275
|
+
const resolved = filePath.startsWith("~/") ? join10(homedir7(), filePath.slice(2)) : filePath;
|
|
90276
|
+
if (!existsSync2(resolved)) {
|
|
89682
90277
|
throw new Error(`Image file not found: ${resolved}`);
|
|
89683
90278
|
}
|
|
89684
90279
|
const ext = resolved.split(".").pop()?.toLowerCase() ?? "png";
|
|
@@ -89792,6 +90387,8 @@ async function startProxy(options) {
|
|
|
89792
90387
|
const evmPublicClient = createPublicClient({ chain: base, transport: http() });
|
|
89793
90388
|
const evmSigner = toClientEvmSigner(account, evmPublicClient);
|
|
89794
90389
|
const x402 = new x402Client();
|
|
90390
|
+
const spendControl = options.spendControl ?? new SpendControl();
|
|
90391
|
+
registerSpendPolicyHook(x402, spendControl);
|
|
89795
90392
|
registerExactEvmScheme(x402, { signer: evmSigner });
|
|
89796
90393
|
let solanaAddress;
|
|
89797
90394
|
if (solanaPrivateKeyBytes) {
|
|
@@ -89960,8 +90557,8 @@ async function startProxy(options) {
|
|
|
89960
90557
|
if (req.url?.startsWith("/share") && req.method === "GET") {
|
|
89961
90558
|
try {
|
|
89962
90559
|
const url2 = new URL(req.url, "http://localhost");
|
|
89963
|
-
const
|
|
89964
|
-
if (
|
|
90560
|
+
const path5 = url2.pathname;
|
|
90561
|
+
if (path5 === "/share/list") {
|
|
89965
90562
|
const limit = Math.min(parseInt(url2.searchParams.get("limit") || "20", 10), 100);
|
|
89966
90563
|
const entries = await listRecent(limit);
|
|
89967
90564
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -89979,7 +90576,7 @@ async function startProxy(options) {
|
|
|
89979
90576
|
);
|
|
89980
90577
|
return;
|
|
89981
90578
|
}
|
|
89982
|
-
if (
|
|
90579
|
+
if (path5 === "/share/last") {
|
|
89983
90580
|
const sessionId = url2.searchParams.get("sessionId") || void 0;
|
|
89984
90581
|
const entry = await getLast(sessionId);
|
|
89985
90582
|
if (!entry) {
|
|
@@ -90008,7 +90605,7 @@ async function startProxy(options) {
|
|
|
90008
90605
|
res.end(JSON.stringify(entry));
|
|
90009
90606
|
return;
|
|
90010
90607
|
}
|
|
90011
|
-
const idMatch =
|
|
90608
|
+
const idMatch = path5.match(/^\/share\/(resp_[A-Za-z0-9_]+)(?:\/render)?$/);
|
|
90012
90609
|
if (idMatch) {
|
|
90013
90610
|
const id2 = idMatch[1];
|
|
90014
90611
|
const entry = await getById(id2);
|
|
@@ -90054,7 +90651,7 @@ async function startProxy(options) {
|
|
|
90054
90651
|
res.end("Bad request");
|
|
90055
90652
|
return;
|
|
90056
90653
|
}
|
|
90057
|
-
const filePath =
|
|
90654
|
+
const filePath = join10(IMAGE_DIR, filename);
|
|
90058
90655
|
try {
|
|
90059
90656
|
const s3 = await fsStat(filePath);
|
|
90060
90657
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90085,7 +90682,7 @@ async function startProxy(options) {
|
|
|
90085
90682
|
res.end("Bad request");
|
|
90086
90683
|
return;
|
|
90087
90684
|
}
|
|
90088
|
-
const filePath =
|
|
90685
|
+
const filePath = join10(AUDIO_DIR, filename);
|
|
90089
90686
|
try {
|
|
90090
90687
|
const s3 = await fsStat(filePath);
|
|
90091
90688
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90115,7 +90712,7 @@ async function startProxy(options) {
|
|
|
90115
90712
|
res.end("Bad request");
|
|
90116
90713
|
return;
|
|
90117
90714
|
}
|
|
90118
|
-
const filePath =
|
|
90715
|
+
const filePath = join10(VIDEO_DIR, filename);
|
|
90119
90716
|
try {
|
|
90120
90717
|
const s3 = await fsStat(filePath);
|
|
90121
90718
|
if (!s3.isFile()) throw new Error("not a file");
|
|
@@ -90256,7 +90853,7 @@ async function startProxy(options) {
|
|
|
90256
90853
|
const [, mimeType, b64] = dataUriMatch;
|
|
90257
90854
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
90258
90855
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90259
|
-
await writeFile2(
|
|
90856
|
+
await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
90260
90857
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90261
90858
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90262
90859
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
@@ -90267,7 +90864,7 @@ async function startProxy(options) {
|
|
|
90267
90864
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
90268
90865
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90269
90866
|
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
90270
|
-
await writeFile2(
|
|
90867
|
+
await writeFile2(join10(IMAGE_DIR, filename), buf);
|
|
90271
90868
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90272
90869
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
90273
90870
|
}
|
|
@@ -90379,7 +90976,7 @@ async function startProxy(options) {
|
|
|
90379
90976
|
const [, mimeType, b64] = dataUriMatch;
|
|
90380
90977
|
const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
|
|
90381
90978
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90382
|
-
await writeFile2(
|
|
90979
|
+
await writeFile2(join10(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
|
|
90383
90980
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90384
90981
|
console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
|
|
90385
90982
|
} else if (img.url?.startsWith("https://") || img.url?.startsWith("http://")) {
|
|
@@ -90390,7 +90987,7 @@ async function startProxy(options) {
|
|
|
90390
90987
|
const ext = contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("webp") ? "webp" : "png";
|
|
90391
90988
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90392
90989
|
const buf = Buffer.from(await imgResp.arrayBuffer());
|
|
90393
|
-
await writeFile2(
|
|
90990
|
+
await writeFile2(join10(IMAGE_DIR, filename), buf);
|
|
90394
90991
|
img.url = `http://localhost:${port2}/images/${filename}`;
|
|
90395
90992
|
console.log(`[ClawRouter] Image downloaded & saved \u2192 ${img.url}`);
|
|
90396
90993
|
}
|
|
@@ -90476,7 +91073,7 @@ async function startProxy(options) {
|
|
|
90476
91073
|
const ext = contentType.includes("wav") ? "wav" : "mp3";
|
|
90477
91074
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90478
91075
|
const buf = Buffer.from(await audioResp.arrayBuffer());
|
|
90479
|
-
await writeFile2(
|
|
91076
|
+
await writeFile2(join10(AUDIO_DIR, filename), buf);
|
|
90480
91077
|
track.url = `http://localhost:${port2}/audio/${filename}`;
|
|
90481
91078
|
console.log(`[ClawRouter] Audio saved \u2192 ${track.url}`);
|
|
90482
91079
|
}
|
|
@@ -90636,7 +91233,7 @@ async function startProxy(options) {
|
|
|
90636
91233
|
const ext = contentType.includes("webm") ? "webm" : contentType.includes("quicktime") ? "mov" : "mp4";
|
|
90637
91234
|
const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
|
|
90638
91235
|
const buf = Buffer.from(await videoResp.arrayBuffer());
|
|
90639
|
-
await writeFile2(
|
|
91236
|
+
await writeFile2(join10(VIDEO_DIR, filename), buf);
|
|
90640
91237
|
clip.url = `http://localhost:${port2}/videos/${filename}`;
|
|
90641
91238
|
console.log(`[ClawRouter] Video saved \u2192 ${clip.url}`);
|
|
90642
91239
|
}
|
|
@@ -90976,6 +91573,17 @@ async function tryModelRequest(upstreamUrl, method, headers, body, modelId, maxT
|
|
|
90976
91573
|
return { success: true, response };
|
|
90977
91574
|
} catch (err) {
|
|
90978
91575
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
91576
|
+
if (err instanceof SpendPolicyError) {
|
|
91577
|
+
return {
|
|
91578
|
+
success: false,
|
|
91579
|
+
errorBody: JSON.stringify({
|
|
91580
|
+
error: { message: errorMsg, type: "spend_policy_denied", status: 403 }
|
|
91581
|
+
}),
|
|
91582
|
+
errorStatus: 403,
|
|
91583
|
+
isProviderError: false,
|
|
91584
|
+
errorCategory: "payment_error"
|
|
91585
|
+
};
|
|
91586
|
+
}
|
|
90979
91587
|
return {
|
|
90980
91588
|
success: false,
|
|
90981
91589
|
errorBody: errorMsg,
|
|
@@ -93162,6 +93770,7 @@ var init_proxy = __esm({
|
|
|
93162
93770
|
init_response_cache();
|
|
93163
93771
|
init_balance();
|
|
93164
93772
|
init_auth();
|
|
93773
|
+
init_spend_control();
|
|
93165
93774
|
init_compression();
|
|
93166
93775
|
init_version4();
|
|
93167
93776
|
init_session();
|
|
@@ -93177,9 +93786,9 @@ var init_proxy = __esm({
|
|
|
93177
93786
|
paymentStore = new AsyncLocalStorage();
|
|
93178
93787
|
BLOCKRUN_API = "https://blockrun.ai/api";
|
|
93179
93788
|
BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
|
|
93180
|
-
IMAGE_DIR =
|
|
93181
|
-
AUDIO_DIR =
|
|
93182
|
-
VIDEO_DIR =
|
|
93789
|
+
IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
|
|
93790
|
+
AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
|
|
93791
|
+
VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
|
|
93183
93792
|
AUTO_MODEL = "blockrun/auto";
|
|
93184
93793
|
ROUTING_PROFILES = /* @__PURE__ */ new Set([
|
|
93185
93794
|
"blockrun/eco",
|
|
@@ -94515,7 +95124,7 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94515
95124
|
required
|
|
94516
95125
|
},
|
|
94517
95126
|
execute: async (_toolCallId, params) => {
|
|
94518
|
-
let
|
|
95127
|
+
let path5;
|
|
94519
95128
|
const leftoverParams = {};
|
|
94520
95129
|
let dynamicMethod = "GET";
|
|
94521
95130
|
let dynamicBody = void 0;
|
|
@@ -94527,7 +95136,7 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94527
95136
|
`predexon_endpoint_call: invalid path '${rawPath}' \u2014 must begin with '/pm/' and contain no '..'`
|
|
94528
95137
|
);
|
|
94529
95138
|
}
|
|
94530
|
-
|
|
95139
|
+
path5 = `/v1${normalized}`;
|
|
94531
95140
|
if (typeof params.method === "string") {
|
|
94532
95141
|
const upper = params.method.toUpperCase();
|
|
94533
95142
|
if (upper !== "GET" && upper !== "POST") {
|
|
@@ -94576,19 +95185,19 @@ function buildTool(service, proxyBaseUrl) {
|
|
|
94576
95185
|
}
|
|
94577
95186
|
}
|
|
94578
95187
|
} else {
|
|
94579
|
-
|
|
95188
|
+
path5 = `/v1${service.proxyPath}`;
|
|
94580
95189
|
for (const [key2, value] of Object.entries(params)) {
|
|
94581
95190
|
if (value === void 0 || value === null) continue;
|
|
94582
95191
|
const placeholder = `:${key2}`;
|
|
94583
|
-
if (
|
|
94584
|
-
|
|
95192
|
+
if (path5.includes(placeholder)) {
|
|
95193
|
+
path5 = path5.replace(placeholder, encodeURIComponent(String(value)));
|
|
94585
95194
|
} else {
|
|
94586
95195
|
leftoverParams[key2] = value;
|
|
94587
95196
|
}
|
|
94588
95197
|
}
|
|
94589
95198
|
}
|
|
94590
95199
|
const effectiveMethod = service.proxyPath === "/pm/__dynamic__" ? dynamicMethod : service.method;
|
|
94591
|
-
let url2 = `${proxyBaseUrl}${
|
|
95200
|
+
let url2 = `${proxyBaseUrl}${path5}`;
|
|
94592
95201
|
if (effectiveMethod === "GET" && Object.keys(leftoverParams).length > 0) {
|
|
94593
95202
|
const qs = new URLSearchParams();
|
|
94594
95203
|
for (const [key2, value] of Object.entries(leftoverParams)) {
|
|
@@ -105996,11 +106605,11 @@ var require_mime_types = __commonJS({
|
|
|
105996
106605
|
}
|
|
105997
106606
|
return exts[0];
|
|
105998
106607
|
}
|
|
105999
|
-
function lookup(
|
|
106000
|
-
if (!
|
|
106608
|
+
function lookup(path5) {
|
|
106609
|
+
if (!path5 || typeof path5 !== "string") {
|
|
106001
106610
|
return false;
|
|
106002
106611
|
}
|
|
106003
|
-
var extension3 = extname("x." +
|
|
106612
|
+
var extension3 = extname("x." + path5).toLowerCase().substr(1);
|
|
106004
106613
|
if (!extension3) {
|
|
106005
106614
|
return false;
|
|
106006
106615
|
}
|
|
@@ -107115,7 +107724,7 @@ var require_form_data = __commonJS({
|
|
|
107115
107724
|
"use strict";
|
|
107116
107725
|
var CombinedStream = require_combined_stream();
|
|
107117
107726
|
var util5 = __require("util");
|
|
107118
|
-
var
|
|
107727
|
+
var path5 = __require("path");
|
|
107119
107728
|
var http5 = __require("http");
|
|
107120
107729
|
var https2 = __require("https");
|
|
107121
107730
|
var parseUrl3 = __require("url").parse;
|
|
@@ -107246,11 +107855,11 @@ var require_form_data = __commonJS({
|
|
|
107246
107855
|
FormData3.prototype._getContentDisposition = function(value, options) {
|
|
107247
107856
|
var filename;
|
|
107248
107857
|
if (typeof options.filepath === "string") {
|
|
107249
|
-
filename =
|
|
107858
|
+
filename = path5.normalize(options.filepath).replace(/\\/g, "/");
|
|
107250
107859
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
107251
|
-
filename =
|
|
107860
|
+
filename = path5.basename(options.filename || value && (value.name || value.path));
|
|
107252
107861
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
107253
|
-
filename =
|
|
107862
|
+
filename = path5.basename(value.client._httpMessage.path || "");
|
|
107254
107863
|
}
|
|
107255
107864
|
if (filename) {
|
|
107256
107865
|
return 'filename="' + escapeHeaderParam(filename) + '"';
|
|
@@ -107464,9 +108073,9 @@ function isVisitable(thing) {
|
|
|
107464
108073
|
function removeBrackets(key2) {
|
|
107465
108074
|
return utils_default.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
|
|
107466
108075
|
}
|
|
107467
|
-
function renderKey(
|
|
107468
|
-
if (!
|
|
107469
|
-
return
|
|
108076
|
+
function renderKey(path5, key2, dots) {
|
|
108077
|
+
if (!path5) return key2;
|
|
108078
|
+
return path5.concat(key2).map(function each(token, i) {
|
|
107470
108079
|
token = removeBrackets(token);
|
|
107471
108080
|
return !dots && i ? "[" + token + "]" : token;
|
|
107472
108081
|
}).join(dots ? "." : "");
|
|
@@ -107549,13 +108158,13 @@ function toFormData(obj, formData, options) {
|
|
|
107549
108158
|
return currentValue;
|
|
107550
108159
|
});
|
|
107551
108160
|
}
|
|
107552
|
-
function defaultVisitor(value, key2,
|
|
108161
|
+
function defaultVisitor(value, key2, path5) {
|
|
107553
108162
|
let arr = value;
|
|
107554
108163
|
if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
|
|
107555
|
-
formData.append(renderKey(
|
|
108164
|
+
formData.append(renderKey(path5, key2, dots), convertValue(value));
|
|
107556
108165
|
return false;
|
|
107557
108166
|
}
|
|
107558
|
-
if (value && !
|
|
108167
|
+
if (value && !path5 && typeof value === "object") {
|
|
107559
108168
|
if (utils_default.endsWith(key2, "{}")) {
|
|
107560
108169
|
key2 = metaTokens ? key2 : key2.slice(0, -2);
|
|
107561
108170
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -107574,7 +108183,7 @@ function toFormData(obj, formData, options) {
|
|
|
107574
108183
|
if (isVisitable(value)) {
|
|
107575
108184
|
return true;
|
|
107576
108185
|
}
|
|
107577
|
-
formData.append(renderKey(
|
|
108186
|
+
formData.append(renderKey(path5, key2, dots), convertValue(value));
|
|
107578
108187
|
return false;
|
|
107579
108188
|
}
|
|
107580
108189
|
const exposedHelpers = Object.assign(predicates, {
|
|
@@ -107582,17 +108191,17 @@ function toFormData(obj, formData, options) {
|
|
|
107582
108191
|
convertValue,
|
|
107583
108192
|
isVisitable
|
|
107584
108193
|
});
|
|
107585
|
-
function build(value,
|
|
108194
|
+
function build(value, path5, depth = 0) {
|
|
107586
108195
|
if (utils_default.isUndefined(value)) return;
|
|
107587
108196
|
throwIfMaxDepthExceeded(depth);
|
|
107588
108197
|
if (stack.indexOf(value) !== -1) {
|
|
107589
|
-
throw new Error("Circular reference detected in " +
|
|
108198
|
+
throw new Error("Circular reference detected in " + path5.join("."));
|
|
107590
108199
|
}
|
|
107591
108200
|
stack.push(value);
|
|
107592
108201
|
utils_default.forEach(value, function each(el, key2) {
|
|
107593
|
-
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2,
|
|
108202
|
+
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key2) ? key2.trim() : key2, path5, exposedHelpers);
|
|
107594
108203
|
if (result === true) {
|
|
107595
|
-
build(el,
|
|
108204
|
+
build(el, path5 ? path5.concat(key2) : [key2], depth + 1);
|
|
107596
108205
|
}
|
|
107597
108206
|
});
|
|
107598
108207
|
stack.pop();
|
|
@@ -107871,7 +108480,7 @@ var init_platform = __esm({
|
|
|
107871
108480
|
// node_modules/axios/lib/helpers/toURLEncodedForm.js
|
|
107872
108481
|
function toURLEncodedForm(data, options) {
|
|
107873
108482
|
return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
|
|
107874
|
-
visitor: function(value, key2,
|
|
108483
|
+
visitor: function(value, key2, path5, helpers) {
|
|
107875
108484
|
if (platform_default.isNode && utils_default.isBuffer(value)) {
|
|
107876
108485
|
this.append(key2, value.toString("base64"));
|
|
107877
108486
|
return false;
|
|
@@ -107900,14 +108509,14 @@ function throwIfDepthExceeded(index2) {
|
|
|
107900
108509
|
}
|
|
107901
108510
|
}
|
|
107902
108511
|
function parsePropPath(name) {
|
|
107903
|
-
const
|
|
108512
|
+
const path5 = [];
|
|
107904
108513
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
107905
108514
|
let match;
|
|
107906
108515
|
while ((match = pattern.exec(name)) !== null) {
|
|
107907
|
-
throwIfDepthExceeded(
|
|
107908
|
-
|
|
108516
|
+
throwIfDepthExceeded(path5.length);
|
|
108517
|
+
path5.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
107909
108518
|
}
|
|
107910
|
-
return
|
|
108519
|
+
return path5;
|
|
107911
108520
|
}
|
|
107912
108521
|
function arrayToObject(arr) {
|
|
107913
108522
|
const obj = {};
|
|
@@ -107922,12 +108531,12 @@ function arrayToObject(arr) {
|
|
|
107922
108531
|
return obj;
|
|
107923
108532
|
}
|
|
107924
108533
|
function formDataToJSON(formData) {
|
|
107925
|
-
function buildPath(
|
|
108534
|
+
function buildPath(path5, value, target, index2) {
|
|
107926
108535
|
throwIfDepthExceeded(index2);
|
|
107927
|
-
let name =
|
|
108536
|
+
let name = path5[index2++];
|
|
107928
108537
|
if (name === "__proto__") return true;
|
|
107929
108538
|
const isNumericKey = Number.isFinite(+name);
|
|
107930
|
-
const isLast = index2 >=
|
|
108539
|
+
const isLast = index2 >= path5.length;
|
|
107931
108540
|
name = !name && utils_default.isArray(target) ? target.length : name;
|
|
107932
108541
|
if (isLast) {
|
|
107933
108542
|
if (utils_default.hasOwnProp(target, name)) {
|
|
@@ -107940,7 +108549,7 @@ function formDataToJSON(formData) {
|
|
|
107940
108549
|
if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
|
|
107941
108550
|
target[name] = [];
|
|
107942
108551
|
}
|
|
107943
|
-
const result = buildPath(
|
|
108552
|
+
const result = buildPath(path5, value, target[name], index2);
|
|
107944
108553
|
if (result && utils_default.isArray(target[name])) {
|
|
107945
108554
|
target[name] = arrayToObject(target[name]);
|
|
107946
108555
|
}
|
|
@@ -111487,9 +112096,9 @@ var init_http4 = __esm({
|
|
|
111487
112096
|
auth = urlUsername + ":" + urlPassword;
|
|
111488
112097
|
}
|
|
111489
112098
|
auth && headers.delete("authorization");
|
|
111490
|
-
let
|
|
112099
|
+
let path5;
|
|
111491
112100
|
try {
|
|
111492
|
-
|
|
112101
|
+
path5 = buildURL(
|
|
111493
112102
|
parsed.pathname + parsed.search,
|
|
111494
112103
|
own2("params"),
|
|
111495
112104
|
own2("paramsSerializer")
|
|
@@ -111508,7 +112117,7 @@ var init_http4 = __esm({
|
|
|
111508
112117
|
false
|
|
111509
112118
|
);
|
|
111510
112119
|
const options = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
111511
|
-
path:
|
|
112120
|
+
path: path5,
|
|
111512
112121
|
method,
|
|
111513
112122
|
headers: toByteStringHeaderObject(headers),
|
|
111514
112123
|
agents: { http: httpAgent, https: httpsAgent },
|
|
@@ -111925,14 +112534,14 @@ var init_cookies = __esm({
|
|
|
111925
112534
|
cookies_default = platform_default.hasStandardBrowserEnv ? (
|
|
111926
112535
|
// Standard browser envs support document.cookie
|
|
111927
112536
|
{
|
|
111928
|
-
write(name, value, expires,
|
|
112537
|
+
write(name, value, expires, path5, domain, secure, sameSite) {
|
|
111929
112538
|
if (typeof document === "undefined") return;
|
|
111930
112539
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
111931
112540
|
if (utils_default.isNumber(expires)) {
|
|
111932
112541
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
111933
112542
|
}
|
|
111934
|
-
if (utils_default.isString(
|
|
111935
|
-
cookie.push(`path=${
|
|
112543
|
+
if (utils_default.isString(path5)) {
|
|
112544
|
+
cookie.push(`path=${path5}`);
|
|
111936
112545
|
}
|
|
111937
112546
|
if (utils_default.isString(domain)) {
|
|
111938
112547
|
cookie.push(`domain=${domain}`);
|
|
@@ -115361,15 +115970,15 @@ var init_constants3 = __esm({
|
|
|
115361
115970
|
});
|
|
115362
115971
|
|
|
115363
115972
|
// src/polymarket/wallet-adapter.ts
|
|
115364
|
-
import
|
|
115365
|
-
import { homedir as
|
|
115366
|
-
import { join as
|
|
115973
|
+
import fs2 from "fs";
|
|
115974
|
+
import { homedir as homedir8 } from "os";
|
|
115975
|
+
import { join as join11 } from "path";
|
|
115367
115976
|
function getOrCreateWalletKey() {
|
|
115368
115977
|
const envKey = process.env.BLOCKRUN_WALLET_KEY?.trim();
|
|
115369
115978
|
if (envKey && /^0x[0-9a-fA-F]{64}$/.test(envKey)) return envKey;
|
|
115370
115979
|
let key2;
|
|
115371
115980
|
try {
|
|
115372
|
-
key2 =
|
|
115981
|
+
key2 = fs2.readFileSync(WALLET_FILE2, "utf-8").trim();
|
|
115373
115982
|
} catch (err) {
|
|
115374
115983
|
if (err.code === "ENOENT") {
|
|
115375
115984
|
throw new Error(
|
|
@@ -115411,7 +116020,7 @@ var init_wallet_adapter = __esm({
|
|
|
115411
116020
|
init_esm();
|
|
115412
116021
|
init_chains();
|
|
115413
116022
|
init_constants3();
|
|
115414
|
-
WALLET_FILE2 =
|
|
116023
|
+
WALLET_FILE2 = join11(homedir8(), ".openclaw", "blockrun", "wallet.key");
|
|
115415
116024
|
BASE_RPC_URLS = [
|
|
115416
116025
|
"https://mainnet.base.org",
|
|
115417
116026
|
"https://base.llamarpc.com",
|
|
@@ -115422,21 +116031,21 @@ var init_wallet_adapter = __esm({
|
|
|
115422
116031
|
});
|
|
115423
116032
|
|
|
115424
116033
|
// src/polymarket/creds.ts
|
|
115425
|
-
import
|
|
115426
|
-
import
|
|
116034
|
+
import fs3 from "fs";
|
|
116035
|
+
import path2 from "path";
|
|
115427
116036
|
import os from "os";
|
|
115428
116037
|
function readJsonFile(file) {
|
|
115429
116038
|
try {
|
|
115430
|
-
if (!
|
|
115431
|
-
const raw =
|
|
116039
|
+
if (!fs3.existsSync(file)) return null;
|
|
116040
|
+
const raw = fs3.readFileSync(file, "utf-8").trim();
|
|
115432
116041
|
return raw ? JSON.parse(raw) : null;
|
|
115433
116042
|
} catch {
|
|
115434
116043
|
return null;
|
|
115435
116044
|
}
|
|
115436
116045
|
}
|
|
115437
116046
|
function writeJsonFile(file, value) {
|
|
115438
|
-
|
|
115439
|
-
|
|
116047
|
+
fs3.mkdirSync(BLOCKRUN_DIR, { recursive: true });
|
|
116048
|
+
fs3.writeFileSync(file, JSON.stringify(value, null, 2), { mode: 384 });
|
|
115440
116049
|
}
|
|
115441
116050
|
function credsKey(address2, sigType) {
|
|
115442
116051
|
return `${address2.toLowerCase()}:${sigType}`;
|
|
@@ -115488,10 +116097,10 @@ var BLOCKRUN_DIR, CREDS_FILE, BUILDER_CREDS_FILE, STATE_FILE;
|
|
|
115488
116097
|
var init_creds = __esm({
|
|
115489
116098
|
"src/polymarket/creds.ts"() {
|
|
115490
116099
|
"use strict";
|
|
115491
|
-
BLOCKRUN_DIR =
|
|
115492
|
-
CREDS_FILE =
|
|
115493
|
-
BUILDER_CREDS_FILE =
|
|
115494
|
-
STATE_FILE =
|
|
116100
|
+
BLOCKRUN_DIR = path2.join(os.homedir(), ".openclaw", "blockrun");
|
|
116101
|
+
CREDS_FILE = path2.join(BLOCKRUN_DIR, ".polymarket-creds");
|
|
116102
|
+
BUILDER_CREDS_FILE = path2.join(BLOCKRUN_DIR, ".polymarket-builder-creds");
|
|
116103
|
+
STATE_FILE = path2.join(BLOCKRUN_DIR, ".polymarket.json");
|
|
115495
116104
|
}
|
|
115496
116105
|
});
|
|
115497
116106
|
|
|
@@ -116673,13 +117282,13 @@ function __disposeResources(env) {
|
|
|
116673
117282
|
}
|
|
116674
117283
|
return next();
|
|
116675
117284
|
}
|
|
116676
|
-
function __rewriteRelativeImportExtension(
|
|
116677
|
-
if (typeof
|
|
116678
|
-
return
|
|
117285
|
+
function __rewriteRelativeImportExtension(path5, preserveJsx) {
|
|
117286
|
+
if (typeof path5 === "string" && /^\.\.?\//.test(path5)) {
|
|
117287
|
+
return path5.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
|
|
116679
117288
|
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
|
|
116680
117289
|
});
|
|
116681
117290
|
}
|
|
116682
|
-
return
|
|
117291
|
+
return path5;
|
|
116683
117292
|
}
|
|
116684
117293
|
var extendStatics, __assign, __createBinding, __setModuleDefault, ownKeys, _SuppressedError, tslib_es6_default;
|
|
116685
117294
|
var init_tslib_es6 = __esm({
|
|
@@ -148976,9 +149585,9 @@ var require_setupKzg = __commonJS({
|
|
|
148976
149585
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
148977
149586
|
exports.setupKzg = setupKzg;
|
|
148978
149587
|
var defineKzg_js_1 = require_defineKzg();
|
|
148979
|
-
function setupKzg(parameters,
|
|
149588
|
+
function setupKzg(parameters, path5) {
|
|
148980
149589
|
try {
|
|
148981
|
-
parameters.loadTrustedSetup(
|
|
149590
|
+
parameters.loadTrustedSetup(path5);
|
|
148982
149591
|
} catch (e7) {
|
|
148983
149592
|
const error = e7;
|
|
148984
149593
|
if (!error.message.includes("trusted setup is already loaded"))
|
|
@@ -197063,12 +197672,12 @@ var init_fragments = __esm({
|
|
|
197063
197672
|
// node_modules/@ethersproject/abi/lib.esm/coders/abstract-coder.js
|
|
197064
197673
|
function checkResultErrors(result) {
|
|
197065
197674
|
const errors = [];
|
|
197066
|
-
const checkErrors = function(
|
|
197675
|
+
const checkErrors = function(path5, object) {
|
|
197067
197676
|
if (!Array.isArray(object)) {
|
|
197068
197677
|
return;
|
|
197069
197678
|
}
|
|
197070
197679
|
for (let key2 in object) {
|
|
197071
|
-
const childPath =
|
|
197680
|
+
const childPath = path5.slice();
|
|
197072
197681
|
childPath.push(key2);
|
|
197073
197682
|
try {
|
|
197074
197683
|
checkErrors(childPath, object[key2]);
|
|
@@ -202886,8 +203495,8 @@ function createCommonjsModule(fn, basedir, module) {
|
|
|
202886
203495
|
return module = {
|
|
202887
203496
|
path: basedir,
|
|
202888
203497
|
exports: {},
|
|
202889
|
-
require: function(
|
|
202890
|
-
return commonjsRequire(
|
|
203498
|
+
require: function(path5, base3) {
|
|
203499
|
+
return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
|
|
202891
203500
|
}
|
|
202892
203501
|
}, fn(module, module.exports), module.exports;
|
|
202893
203502
|
}
|
|
@@ -206737,9 +207346,9 @@ var init_lib23 = __esm({
|
|
|
206737
207346
|
if (index2 > 4294967295) {
|
|
206738
207347
|
throw new Error("invalid index - " + String(index2));
|
|
206739
207348
|
}
|
|
206740
|
-
let
|
|
206741
|
-
if (
|
|
206742
|
-
|
|
207349
|
+
let path5 = this.path;
|
|
207350
|
+
if (path5) {
|
|
207351
|
+
path5 += "/" + (index2 & ~HardenedBit);
|
|
206743
207352
|
}
|
|
206744
207353
|
const data = new Uint8Array(37);
|
|
206745
207354
|
if (index2 & HardenedBit) {
|
|
@@ -206747,8 +207356,8 @@ var init_lib23 = __esm({
|
|
|
206747
207356
|
throw new Error("cannot derive child of neutered node");
|
|
206748
207357
|
}
|
|
206749
207358
|
data.set(arrayify(this.privateKey), 1);
|
|
206750
|
-
if (
|
|
206751
|
-
|
|
207359
|
+
if (path5) {
|
|
207360
|
+
path5 += "'";
|
|
206752
207361
|
}
|
|
206753
207362
|
} else {
|
|
206754
207363
|
data.set(arrayify(this.publicKey));
|
|
@@ -206767,21 +207376,21 @@ var init_lib23 = __esm({
|
|
|
206767
207376
|
const ek = new SigningKey(hexlify(IL));
|
|
206768
207377
|
Ki = ek._addPoint(this.publicKey);
|
|
206769
207378
|
}
|
|
206770
|
-
let mnemonicOrPath =
|
|
207379
|
+
let mnemonicOrPath = path5;
|
|
206771
207380
|
const srcMnemonic = this.mnemonic;
|
|
206772
207381
|
if (srcMnemonic) {
|
|
206773
207382
|
mnemonicOrPath = Object.freeze({
|
|
206774
207383
|
phrase: srcMnemonic.phrase,
|
|
206775
|
-
path:
|
|
207384
|
+
path: path5,
|
|
206776
207385
|
locale: srcMnemonic.locale || "en"
|
|
206777
207386
|
});
|
|
206778
207387
|
}
|
|
206779
207388
|
return new _HDNode(_constructorGuard4, ki, Ki, this.fingerprint, bytes32(IR), index2, this.depth + 1, mnemonicOrPath);
|
|
206780
207389
|
}
|
|
206781
|
-
derivePath(
|
|
206782
|
-
const components =
|
|
207390
|
+
derivePath(path5) {
|
|
207391
|
+
const components = path5.split("/");
|
|
206783
207392
|
if (components.length === 0 || components[0] === "m" && this.depth !== 0) {
|
|
206784
|
-
throw new Error("invalid path - " +
|
|
207393
|
+
throw new Error("invalid path - " + path5);
|
|
206785
207394
|
}
|
|
206786
207395
|
if (components[0] === "m") {
|
|
206787
207396
|
components.shift();
|
|
@@ -207516,9 +208125,9 @@ function getPassword(password) {
|
|
|
207516
208125
|
}
|
|
207517
208126
|
return arrayify(password);
|
|
207518
208127
|
}
|
|
207519
|
-
function searchPath(object,
|
|
208128
|
+
function searchPath(object, path5) {
|
|
207520
208129
|
let currentChild = object;
|
|
207521
|
-
const comps =
|
|
208130
|
+
const comps = path5.toLowerCase().split("/");
|
|
207522
208131
|
for (let i = 0; i < comps.length; i++) {
|
|
207523
208132
|
let matchingChild = null;
|
|
207524
208133
|
for (const key2 in currentChild) {
|
|
@@ -208167,12 +208776,12 @@ function _getAccount(data, key2) {
|
|
|
208167
208776
|
const mnemonicIv = looseArrayify(searchPath(data, "x-ethers/mnemonicCounter"));
|
|
208168
208777
|
const mnemonicCounter = new import_aes_js2.default.Counter(mnemonicIv);
|
|
208169
208778
|
const mnemonicAesCtr = new import_aes_js2.default.ModeOfOperation.ctr(mnemonicKey, mnemonicCounter);
|
|
208170
|
-
const
|
|
208779
|
+
const path5 = searchPath(data, "x-ethers/path") || defaultPath;
|
|
208171
208780
|
const locale = searchPath(data, "x-ethers/locale") || "en";
|
|
208172
208781
|
const entropy = arrayify(mnemonicAesCtr.decrypt(mnemonicCiphertext));
|
|
208173
208782
|
try {
|
|
208174
208783
|
const mnemonic = entropyToMnemonic2(entropy, locale);
|
|
208175
|
-
const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(
|
|
208784
|
+
const node = HDNode.fromMnemonic(mnemonic, null, locale).derivePath(path5);
|
|
208176
208785
|
if (node.privateKey != account.privateKey) {
|
|
208177
208786
|
throw new Error("mnemonic mismatch");
|
|
208178
208787
|
}
|
|
@@ -208272,12 +208881,12 @@ function encrypt(account, password, options, progressCallback) {
|
|
|
208272
208881
|
const privateKey = arrayify(account.privateKey);
|
|
208273
208882
|
const passwordBytes = getPassword(password);
|
|
208274
208883
|
let entropy = null;
|
|
208275
|
-
let
|
|
208884
|
+
let path5 = null;
|
|
208276
208885
|
let locale = null;
|
|
208277
208886
|
if (hasMnemonic(account)) {
|
|
208278
208887
|
const srcMnemonic = account.mnemonic;
|
|
208279
208888
|
entropy = arrayify(mnemonicToEntropy2(srcMnemonic.phrase, srcMnemonic.locale || "en"));
|
|
208280
|
-
|
|
208889
|
+
path5 = srcMnemonic.path || defaultPath;
|
|
208281
208890
|
locale = srcMnemonic.locale || "en";
|
|
208282
208891
|
}
|
|
208283
208892
|
let client = options.client;
|
|
@@ -208363,7 +208972,7 @@ function encrypt(account, password, options, progressCallback) {
|
|
|
208363
208972
|
gethFilename: "UTC--" + timestamp + "--" + data.address,
|
|
208364
208973
|
mnemonicCounter: hexlify(mnemonicIv).substring(2),
|
|
208365
208974
|
mnemonicCiphertext: hexlify(mnemonicCiphertext).substring(2),
|
|
208366
|
-
path:
|
|
208975
|
+
path: path5,
|
|
208367
208976
|
locale,
|
|
208368
208977
|
version: "0.1"
|
|
208369
208978
|
};
|
|
@@ -208657,11 +209266,11 @@ var init_lib26 = __esm({
|
|
|
208657
209266
|
static fromEncryptedJsonSync(json, password) {
|
|
208658
209267
|
return new _Wallet(decryptJsonWalletSync(json, password));
|
|
208659
209268
|
}
|
|
208660
|
-
static fromMnemonic(mnemonic,
|
|
208661
|
-
if (!
|
|
208662
|
-
|
|
209269
|
+
static fromMnemonic(mnemonic, path5, wordlist3) {
|
|
209270
|
+
if (!path5) {
|
|
209271
|
+
path5 = defaultPath;
|
|
208663
209272
|
}
|
|
208664
|
-
return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(
|
|
209273
|
+
return new _Wallet(HDNode.fromMnemonic(mnemonic, null, wordlist3).derivePath(path5));
|
|
208665
209274
|
}
|
|
208666
209275
|
};
|
|
208667
209276
|
}
|
|
@@ -214657,21 +215266,21 @@ var init_web3_provider = __esm({
|
|
|
214657
215266
|
if (provider == null) {
|
|
214658
215267
|
logger43.throwArgumentError("missing provider", "provider", provider);
|
|
214659
215268
|
}
|
|
214660
|
-
let
|
|
215269
|
+
let path5 = null;
|
|
214661
215270
|
let jsonRpcFetchFunc = null;
|
|
214662
215271
|
let subprovider = null;
|
|
214663
215272
|
if (typeof provider === "function") {
|
|
214664
|
-
|
|
215273
|
+
path5 = "unknown:";
|
|
214665
215274
|
jsonRpcFetchFunc = provider;
|
|
214666
215275
|
} else {
|
|
214667
|
-
|
|
214668
|
-
if (!
|
|
214669
|
-
|
|
215276
|
+
path5 = provider.host || provider.path || "";
|
|
215277
|
+
if (!path5 && provider.isMetaMask) {
|
|
215278
|
+
path5 = "metamask";
|
|
214670
215279
|
}
|
|
214671
215280
|
subprovider = provider;
|
|
214672
215281
|
if (provider.request) {
|
|
214673
|
-
if (
|
|
214674
|
-
|
|
215282
|
+
if (path5 === "") {
|
|
215283
|
+
path5 = "eip-1193:";
|
|
214675
215284
|
}
|
|
214676
215285
|
jsonRpcFetchFunc = buildEip1193Fetcher(provider);
|
|
214677
215286
|
} else if (provider.sendAsync) {
|
|
@@ -214681,11 +215290,11 @@ var init_web3_provider = __esm({
|
|
|
214681
215290
|
} else {
|
|
214682
215291
|
logger43.throwArgumentError("unsupported provider", "provider", provider);
|
|
214683
215292
|
}
|
|
214684
|
-
if (!
|
|
214685
|
-
|
|
215293
|
+
if (!path5) {
|
|
215294
|
+
path5 = "unknown:";
|
|
214686
215295
|
}
|
|
214687
215296
|
}
|
|
214688
|
-
super(
|
|
215297
|
+
super(path5, network);
|
|
214689
215298
|
defineReadOnly(this, "jsonRpcFetchFunc", jsonRpcFetchFunc);
|
|
214690
215299
|
defineReadOnly(this, "provider", subprovider);
|
|
214691
215300
|
}
|
|
@@ -215523,7 +216132,7 @@ var require_axios = __commonJS({
|
|
|
215523
216132
|
var https2 = __require("https");
|
|
215524
216133
|
var http23 = __require("http2");
|
|
215525
216134
|
var util5 = __require("util");
|
|
215526
|
-
var
|
|
216135
|
+
var path5 = __require("path");
|
|
215527
216136
|
var followRedirects2 = require_follow_redirects();
|
|
215528
216137
|
var zlib2 = __require("zlib");
|
|
215529
216138
|
var stream4 = __require("stream");
|
|
@@ -216591,9 +217200,9 @@ var require_axios = __commonJS({
|
|
|
216591
217200
|
function removeBrackets2(key2) {
|
|
216592
217201
|
return utils$1.endsWith(key2, "[]") ? key2.slice(0, -2) : key2;
|
|
216593
217202
|
}
|
|
216594
|
-
function renderKey2(
|
|
216595
|
-
if (!
|
|
216596
|
-
return
|
|
217203
|
+
function renderKey2(path6, key2, dots) {
|
|
217204
|
+
if (!path6) return key2;
|
|
217205
|
+
return path6.concat(key2).map(function each(token, i) {
|
|
216597
217206
|
token = removeBrackets2(token);
|
|
216598
217207
|
return !dots && i ? "[" + token + "]" : token;
|
|
216599
217208
|
}).join(dots ? "." : "");
|
|
@@ -216671,13 +217280,13 @@ var require_axios = __commonJS({
|
|
|
216671
217280
|
return currentValue;
|
|
216672
217281
|
});
|
|
216673
217282
|
}
|
|
216674
|
-
function defaultVisitor(value, key2,
|
|
217283
|
+
function defaultVisitor(value, key2, path6) {
|
|
216675
217284
|
let arr = value;
|
|
216676
217285
|
if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
|
|
216677
|
-
formData.append(renderKey2(
|
|
217286
|
+
formData.append(renderKey2(path6, key2, dots), convertValue(value));
|
|
216678
217287
|
return false;
|
|
216679
217288
|
}
|
|
216680
|
-
if (value && !
|
|
217289
|
+
if (value && !path6 && typeof value === "object") {
|
|
216681
217290
|
if (utils$1.endsWith(key2, "{}")) {
|
|
216682
217291
|
key2 = metaTokens ? key2 : key2.slice(0, -2);
|
|
216683
217292
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -216696,7 +217305,7 @@ var require_axios = __commonJS({
|
|
|
216696
217305
|
if (isVisitable2(value)) {
|
|
216697
217306
|
return true;
|
|
216698
217307
|
}
|
|
216699
|
-
formData.append(renderKey2(
|
|
217308
|
+
formData.append(renderKey2(path6, key2, dots), convertValue(value));
|
|
216700
217309
|
return false;
|
|
216701
217310
|
}
|
|
216702
217311
|
const exposedHelpers = Object.assign(predicates2, {
|
|
@@ -216704,17 +217313,17 @@ var require_axios = __commonJS({
|
|
|
216704
217313
|
convertValue,
|
|
216705
217314
|
isVisitable: isVisitable2
|
|
216706
217315
|
});
|
|
216707
|
-
function build(value,
|
|
217316
|
+
function build(value, path6, depth = 0) {
|
|
216708
217317
|
if (utils$1.isUndefined(value)) return;
|
|
216709
217318
|
throwIfMaxDepthExceeded(depth);
|
|
216710
217319
|
if (stack.indexOf(value) !== -1) {
|
|
216711
|
-
throw new Error("Circular reference detected in " +
|
|
217320
|
+
throw new Error("Circular reference detected in " + path6.join("."));
|
|
216712
217321
|
}
|
|
216713
217322
|
stack.push(value);
|
|
216714
217323
|
utils$1.forEach(value, function each(el, key2) {
|
|
216715
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2,
|
|
217324
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key2) ? key2.trim() : key2, path6, exposedHelpers);
|
|
216716
217325
|
if (result === true) {
|
|
216717
|
-
build(el,
|
|
217326
|
+
build(el, path6 ? path6.concat(key2) : [key2], depth + 1);
|
|
216718
217327
|
}
|
|
216719
217328
|
});
|
|
216720
217329
|
stack.pop();
|
|
@@ -216903,7 +217512,7 @@ var require_axios = __commonJS({
|
|
|
216903
217512
|
};
|
|
216904
217513
|
function toURLEncodedForm2(data, options) {
|
|
216905
217514
|
return toFormData3(data, new platform.classes.URLSearchParams(), {
|
|
216906
|
-
visitor: function(value, key2,
|
|
217515
|
+
visitor: function(value, key2, path6, helpers) {
|
|
216907
217516
|
if (platform.isNode && utils$1.isBuffer(value)) {
|
|
216908
217517
|
this.append(key2, value.toString("base64"));
|
|
216909
217518
|
return false;
|
|
@@ -216920,14 +217529,14 @@ var require_axios = __commonJS({
|
|
|
216920
217529
|
}
|
|
216921
217530
|
}
|
|
216922
217531
|
function parsePropPath2(name) {
|
|
216923
|
-
const
|
|
217532
|
+
const path6 = [];
|
|
216924
217533
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
216925
217534
|
let match;
|
|
216926
217535
|
while ((match = pattern.exec(name)) !== null) {
|
|
216927
|
-
throwIfDepthExceeded2(
|
|
216928
|
-
|
|
217536
|
+
throwIfDepthExceeded2(path6.length);
|
|
217537
|
+
path6.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
216929
217538
|
}
|
|
216930
|
-
return
|
|
217539
|
+
return path6;
|
|
216931
217540
|
}
|
|
216932
217541
|
function arrayToObject2(arr) {
|
|
216933
217542
|
const obj = {};
|
|
@@ -216942,12 +217551,12 @@ var require_axios = __commonJS({
|
|
|
216942
217551
|
return obj;
|
|
216943
217552
|
}
|
|
216944
217553
|
function formDataToJSON2(formData) {
|
|
216945
|
-
function buildPath(
|
|
217554
|
+
function buildPath(path6, value, target, index2) {
|
|
216946
217555
|
throwIfDepthExceeded2(index2);
|
|
216947
|
-
let name =
|
|
217556
|
+
let name = path6[index2++];
|
|
216948
217557
|
if (name === "__proto__") return true;
|
|
216949
217558
|
const isNumericKey = Number.isFinite(+name);
|
|
216950
|
-
const isLast = index2 >=
|
|
217559
|
+
const isLast = index2 >= path6.length;
|
|
216951
217560
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
216952
217561
|
if (isLast) {
|
|
216953
217562
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -216960,7 +217569,7 @@ var require_axios = __commonJS({
|
|
|
216960
217569
|
if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
|
|
216961
217570
|
target[name] = [];
|
|
216962
217571
|
}
|
|
216963
|
-
const result = buildPath(
|
|
217572
|
+
const result = buildPath(path6, value, target[name], index2);
|
|
216964
217573
|
if (result && utils$1.isArray(target[name])) {
|
|
216965
217574
|
target[name] = arrayToObject2(target[name]);
|
|
216966
217575
|
}
|
|
@@ -218571,8 +219180,8 @@ var require_axios = __commonJS({
|
|
|
218571
219180
|
const allowedSocketPaths = own3("allowedSocketPaths");
|
|
218572
219181
|
if (allowedSocketPaths != null) {
|
|
218573
219182
|
const allowed = Array.isArray(allowedSocketPaths) ? allowedSocketPaths : [allowedSocketPaths];
|
|
218574
|
-
const resolvedSocket =
|
|
218575
|
-
const isAllowed = allowed.some((entry) => typeof entry === "string" &&
|
|
219183
|
+
const resolvedSocket = path5.resolve(socketPath);
|
|
219184
|
+
const isAllowed = allowed.some((entry) => typeof entry === "string" && path5.resolve(entry) === resolvedSocket);
|
|
218576
219185
|
if (!isAllowed) {
|
|
218577
219186
|
return reject(new AxiosError3(`socketPath "${socketPath}" is not permitted by allowedSocketPaths`, AxiosError3.ERR_BAD_OPTION_VALUE, config));
|
|
218578
219187
|
}
|
|
@@ -218871,14 +219480,14 @@ var require_axios = __commonJS({
|
|
|
218871
219480
|
var cookies = platform.hasStandardBrowserEnv ? (
|
|
218872
219481
|
// Standard browser envs support document.cookie
|
|
218873
219482
|
{
|
|
218874
|
-
write(name, value, expires,
|
|
219483
|
+
write(name, value, expires, path6, domain, secure, sameSite) {
|
|
218875
219484
|
if (typeof document === "undefined") return;
|
|
218876
219485
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
218877
219486
|
if (utils$1.isNumber(expires)) {
|
|
218878
219487
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
218879
219488
|
}
|
|
218880
|
-
if (utils$1.isString(
|
|
218881
|
-
cookie.push(`path=${
|
|
219489
|
+
if (utils$1.isString(path6)) {
|
|
219490
|
+
cookie.push(`path=${path6}`);
|
|
218882
219491
|
}
|
|
218883
219492
|
if (utils$1.isString(domain)) {
|
|
218884
219493
|
cookie.push(`domain=${domain}`);
|
|
@@ -223367,18 +223976,18 @@ var require_client2 = __commonJS({
|
|
|
223367
223976
|
}
|
|
223368
223977
|
console.log(`Transaction not found or not in given states, timing out!`);
|
|
223369
223978
|
}
|
|
223370
|
-
async sendAuthedRequest(method,
|
|
223979
|
+
async sendAuthedRequest(method, path5, body) {
|
|
223371
223980
|
if (this.canBuilderAuth()) {
|
|
223372
|
-
const builderHeaders = await this._generateBuilderHeaders(method,
|
|
223981
|
+
const builderHeaders = await this._generateBuilderHeaders(method, path5, body);
|
|
223373
223982
|
if (builderHeaders !== void 0) {
|
|
223374
|
-
return this.send(
|
|
223983
|
+
return this.send(path5, method, { headers: builderHeaders, data: body });
|
|
223375
223984
|
}
|
|
223376
223985
|
}
|
|
223377
|
-
return this.send(
|
|
223986
|
+
return this.send(path5, method, { data: body });
|
|
223378
223987
|
}
|
|
223379
|
-
async _generateBuilderHeaders(method,
|
|
223988
|
+
async _generateBuilderHeaders(method, path5, body) {
|
|
223380
223989
|
if (this.builderConfig !== void 0) {
|
|
223381
|
-
const builderHeaders = await this.builderConfig.generateBuilderHeaders(method,
|
|
223990
|
+
const builderHeaders = await this.builderConfig.generateBuilderHeaders(method, path5, body);
|
|
223382
223991
|
if (builderHeaders == void 0) {
|
|
223383
223992
|
return void 0;
|
|
223384
223993
|
}
|
|
@@ -223469,12 +224078,12 @@ var require_signer = __commonJS({
|
|
|
223469
224078
|
constructor(creds) {
|
|
223470
224079
|
this.creds = creds;
|
|
223471
224080
|
}
|
|
223472
|
-
createBuilderHeaderPayload(method,
|
|
224081
|
+
createBuilderHeaderPayload(method, path5, body, timestamp) {
|
|
223473
224082
|
let ts = Math.floor(Date.now() / 1e3);
|
|
223474
224083
|
if (timestamp !== void 0) {
|
|
223475
224084
|
ts = timestamp;
|
|
223476
224085
|
}
|
|
223477
|
-
const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method,
|
|
224086
|
+
const builderSig = (0, signing_1.buildHmacSignature)(this.creds.secret, ts, method, path5, body);
|
|
223478
224087
|
return {
|
|
223479
224088
|
POLY_BUILDER_API_KEY: this.creds.key,
|
|
223480
224089
|
POLY_BUILDER_PASSPHRASE: this.creds.passphrase,
|
|
@@ -223563,17 +224172,17 @@ var require_config2 = __commonJS({
|
|
|
223563
224172
|
* @param path
|
|
223564
224173
|
* @param body
|
|
223565
224174
|
*/
|
|
223566
|
-
async generateBuilderHeaders(method,
|
|
224175
|
+
async generateBuilderHeaders(method, path5, body, timestamp) {
|
|
223567
224176
|
this.ensureValid();
|
|
223568
224177
|
const builderType = this.getBuilderType();
|
|
223569
224178
|
if (builderType == types_1.BuilderType.LOCAL) {
|
|
223570
|
-
return Promise.resolve(this.signer?.createBuilderHeaderPayload(method,
|
|
224179
|
+
return Promise.resolve(this.signer?.createBuilderHeaderPayload(method, path5, body, timestamp));
|
|
223571
224180
|
}
|
|
223572
224181
|
if (builderType == types_1.BuilderType.REMOTE) {
|
|
223573
224182
|
const url2 = this.remoteBuilderConfig.url;
|
|
223574
224183
|
const payload = {
|
|
223575
224184
|
method,
|
|
223576
|
-
path:
|
|
224185
|
+
path: path5,
|
|
223577
224186
|
body,
|
|
223578
224187
|
timestamp
|
|
223579
224188
|
};
|
|
@@ -224355,11 +224964,11 @@ var init_withdraw = __esm({
|
|
|
224355
224964
|
});
|
|
224356
224965
|
|
|
224357
224966
|
// node_modules/@blockrun/llm/dist/index.js
|
|
224358
|
-
import * as
|
|
224967
|
+
import * as path3 from "path";
|
|
224359
224968
|
import * as os2 from "os";
|
|
224360
224969
|
import * as path22 from "path";
|
|
224361
224970
|
import * as os22 from "os";
|
|
224362
|
-
import * as
|
|
224971
|
+
import * as path32 from "path";
|
|
224363
224972
|
import * as os3 from "os";
|
|
224364
224973
|
import * as path4 from "path";
|
|
224365
224974
|
import * as os4 from "os";
|
|
@@ -224533,7 +225142,7 @@ function resolveDefaultTimeout() {
|
|
|
224533
225142
|
function sleep2(ms) {
|
|
224534
225143
|
return new Promise((r2) => setTimeout(r2, ms));
|
|
224535
225144
|
}
|
|
224536
|
-
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,
|
|
225145
|
+
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;
|
|
224537
225146
|
var init_dist7 = __esm({
|
|
224538
225147
|
"node_modules/@blockrun/llm/dist/index.js"() {
|
|
224539
225148
|
"use strict";
|
|
@@ -224581,8 +225190,8 @@ var init_dist7 = __esm({
|
|
|
224581
225190
|
};
|
|
224582
225191
|
BLOCKRUN_SERVICE_CODE2 = "blockrun";
|
|
224583
225192
|
LOCALHOST_DOMAINS = ["localhost", "127.0.0.1"];
|
|
224584
|
-
BLOCKRUN_DIR2 =
|
|
224585
|
-
COST_LOG_FILE =
|
|
225193
|
+
BLOCKRUN_DIR2 = path3.join(os2.homedir(), ".blockrun");
|
|
225194
|
+
COST_LOG_FILE = path3.join(BLOCKRUN_DIR2, "cost_log.jsonl");
|
|
224586
225195
|
SDK_VERSION = "3.10.0";
|
|
224587
225196
|
USER_AGENT2 = `blockrun-ts/${SDK_VERSION}`;
|
|
224588
225197
|
DEFAULT_TIMEOUT = resolveDefaultTimeout();
|
|
@@ -224627,15 +225236,15 @@ var init_dist7 = __esm({
|
|
|
224627
225236
|
* `/api` is tolerated and stripped). Query params are URL-encoded; arrays
|
|
224628
225237
|
* become repeated keys (`?a=1&a=2`); undefined/null are dropped.
|
|
224629
225238
|
*/
|
|
224630
|
-
async get(
|
|
224631
|
-
const url2 = this.buildUrl(
|
|
225239
|
+
async get(path5, params) {
|
|
225240
|
+
const url2 = this.buildUrl(path5, params);
|
|
224632
225241
|
return this.requestWithPayment(url2, "GET");
|
|
224633
225242
|
}
|
|
224634
225243
|
/**
|
|
224635
225244
|
* POST a BlockRun endpoint with a JSON body.
|
|
224636
225245
|
*/
|
|
224637
|
-
async post(
|
|
224638
|
-
const url2 = this.buildUrl(
|
|
225246
|
+
async post(path5, body) {
|
|
225247
|
+
const url2 = this.buildUrl(path5);
|
|
224639
225248
|
return this.requestWithPayment(url2, "POST", body);
|
|
224640
225249
|
}
|
|
224641
225250
|
/**
|
|
@@ -224650,8 +225259,8 @@ var init_dist7 = __esm({
|
|
|
224650
225259
|
* short-circuits and returns the body. Most long-running endpoints (image,
|
|
224651
225260
|
* video, music, voice) return 202 with a poll_url.
|
|
224652
225261
|
*/
|
|
224653
|
-
async poll(
|
|
224654
|
-
const submitUrl = this.buildUrl(
|
|
225262
|
+
async poll(path5, body, options) {
|
|
225263
|
+
const submitUrl = this.buildUrl(path5);
|
|
224655
225264
|
const budgetMs = options?.budgetMs ?? DEFAULT_POLL_BUDGET_MS;
|
|
224656
225265
|
const intervalMs = options?.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
224657
225266
|
const resp402 = await this.fetchWithTimeout(submitUrl, {
|
|
@@ -224750,8 +225359,8 @@ var init_dist7 = __esm({
|
|
|
224750
225359
|
* process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
|
|
224751
225360
|
* }
|
|
224752
225361
|
*/
|
|
224753
|
-
async *stream(
|
|
224754
|
-
const url2 = this.buildUrl(
|
|
225362
|
+
async *stream(path5, body) {
|
|
225363
|
+
const url2 = this.buildUrl(path5);
|
|
224755
225364
|
const requestBody = JSON.stringify(body ?? {});
|
|
224756
225365
|
const resp402 = await this.fetchWithTimeout(url2, {
|
|
224757
225366
|
method: "POST",
|
|
@@ -224817,8 +225426,8 @@ var init_dist7 = __esm({
|
|
|
224817
225426
|
// --------------------------------------------------------------------
|
|
224818
225427
|
// Internal: shared infrastructure
|
|
224819
225428
|
// --------------------------------------------------------------------
|
|
224820
|
-
buildUrl(
|
|
224821
|
-
let normalized =
|
|
225429
|
+
buildUrl(path5, params) {
|
|
225430
|
+
let normalized = path5.startsWith("/") ? path5 : `/${path5}`;
|
|
224822
225431
|
if (normalized.startsWith("/api/")) {
|
|
224823
225432
|
normalized = normalized.slice(4);
|
|
224824
225433
|
}
|
|
@@ -224966,10 +225575,10 @@ var init_dist7 = __esm({
|
|
|
224966
225575
|
return { totalUsd: this.sessionTotalUsd, calls: this.sessionCalls };
|
|
224967
225576
|
}
|
|
224968
225577
|
};
|
|
224969
|
-
|
|
224970
|
-
WALLET_FILE3 = path22.join(
|
|
224971
|
-
WALLET_DIR22 =
|
|
224972
|
-
SOLANA_WALLET_FILE =
|
|
225578
|
+
WALLET_DIR3 = path22.join(os22.homedir(), ".blockrun");
|
|
225579
|
+
WALLET_FILE3 = path22.join(WALLET_DIR3, ".session");
|
|
225580
|
+
WALLET_DIR22 = path32.join(os3.homedir(), ".blockrun");
|
|
225581
|
+
SOLANA_WALLET_FILE = path32.join(WALLET_DIR22, ".solana-session");
|
|
224973
225582
|
CACHE_DIR = path4.join(os4.homedir(), ".blockrun", "cache");
|
|
224974
225583
|
DATA_DIR = path4.join(os4.homedir(), ".blockrun", "data");
|
|
224975
225584
|
COST_LOG_FILE2 = path4.join(os4.homedir(), ".blockrun", "cost_log.jsonl");
|
|
@@ -225465,261 +226074,6 @@ var init_mcp_config = __esm({
|
|
|
225465
226074
|
}
|
|
225466
226075
|
});
|
|
225467
226076
|
|
|
225468
|
-
// src/spend-control.ts
|
|
225469
|
-
import * as fs3 from "fs";
|
|
225470
|
-
import * as path5 from "path";
|
|
225471
|
-
import { homedir as homedir12 } from "os";
|
|
225472
|
-
function formatDuration(seconds) {
|
|
225473
|
-
if (seconds < 60) {
|
|
225474
|
-
return `${seconds}s`;
|
|
225475
|
-
} else if (seconds < 3600) {
|
|
225476
|
-
const mins = Math.ceil(seconds / 60);
|
|
225477
|
-
return `${mins} min`;
|
|
225478
|
-
} else {
|
|
225479
|
-
const hours = Math.floor(seconds / 3600);
|
|
225480
|
-
const mins = Math.ceil(seconds % 3600 / 60);
|
|
225481
|
-
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
225482
|
-
}
|
|
225483
|
-
}
|
|
225484
|
-
var WALLET_DIR3, HOUR_MS, DAY_MS, FileSpendControlStorage, InMemorySpendControlStorage, SpendControl;
|
|
225485
|
-
var init_spend_control = __esm({
|
|
225486
|
-
"src/spend-control.ts"() {
|
|
225487
|
-
"use strict";
|
|
225488
|
-
init_fs_read();
|
|
225489
|
-
WALLET_DIR3 = path5.join(homedir12(), ".openclaw", "blockrun");
|
|
225490
|
-
HOUR_MS = 60 * 60 * 1e3;
|
|
225491
|
-
DAY_MS = 24 * HOUR_MS;
|
|
225492
|
-
FileSpendControlStorage = class {
|
|
225493
|
-
spendingFile;
|
|
225494
|
-
constructor() {
|
|
225495
|
-
this.spendingFile = path5.join(WALLET_DIR3, "spending.json");
|
|
225496
|
-
}
|
|
225497
|
-
load() {
|
|
225498
|
-
try {
|
|
225499
|
-
if (fs3.existsSync(this.spendingFile)) {
|
|
225500
|
-
const data = JSON.parse(readTextFileSync(this.spendingFile));
|
|
225501
|
-
const rawLimits = data.limits ?? {};
|
|
225502
|
-
const rawHistory = data.history ?? [];
|
|
225503
|
-
const limits = {};
|
|
225504
|
-
for (const key2 of ["perRequest", "hourly", "daily", "session"]) {
|
|
225505
|
-
const val = rawLimits[key2];
|
|
225506
|
-
if (typeof val === "number" && val > 0 && Number.isFinite(val)) {
|
|
225507
|
-
limits[key2] = val;
|
|
225508
|
-
}
|
|
225509
|
-
}
|
|
225510
|
-
const history = [];
|
|
225511
|
-
if (Array.isArray(rawHistory)) {
|
|
225512
|
-
for (const r2 of rawHistory) {
|
|
225513
|
-
if (typeof r2?.timestamp === "number" && typeof r2?.amount === "number" && Number.isFinite(r2.timestamp) && Number.isFinite(r2.amount) && r2.amount >= 0) {
|
|
225514
|
-
history.push({
|
|
225515
|
-
timestamp: r2.timestamp,
|
|
225516
|
-
amount: r2.amount,
|
|
225517
|
-
model: typeof r2.model === "string" ? r2.model : void 0,
|
|
225518
|
-
action: typeof r2.action === "string" ? r2.action : void 0
|
|
225519
|
-
});
|
|
225520
|
-
}
|
|
225521
|
-
}
|
|
225522
|
-
}
|
|
225523
|
-
return { limits, history };
|
|
225524
|
-
}
|
|
225525
|
-
} catch (err) {
|
|
225526
|
-
console.error(`[ClawRouter] Failed to load spending data, starting fresh: ${err}`);
|
|
225527
|
-
}
|
|
225528
|
-
return null;
|
|
225529
|
-
}
|
|
225530
|
-
save(data) {
|
|
225531
|
-
try {
|
|
225532
|
-
if (!fs3.existsSync(WALLET_DIR3)) {
|
|
225533
|
-
fs3.mkdirSync(WALLET_DIR3, { recursive: true, mode: 448 });
|
|
225534
|
-
}
|
|
225535
|
-
fs3.writeFileSync(this.spendingFile, JSON.stringify(data, null, 2), {
|
|
225536
|
-
mode: 384
|
|
225537
|
-
});
|
|
225538
|
-
} catch (err) {
|
|
225539
|
-
console.error(`[ClawRouter] Failed to save spending data: ${err}`);
|
|
225540
|
-
}
|
|
225541
|
-
}
|
|
225542
|
-
};
|
|
225543
|
-
InMemorySpendControlStorage = class {
|
|
225544
|
-
data = null;
|
|
225545
|
-
load() {
|
|
225546
|
-
return this.data ? {
|
|
225547
|
-
limits: { ...this.data.limits },
|
|
225548
|
-
history: this.data.history.map((r2) => ({ ...r2 }))
|
|
225549
|
-
} : null;
|
|
225550
|
-
}
|
|
225551
|
-
save(data) {
|
|
225552
|
-
this.data = {
|
|
225553
|
-
limits: { ...data.limits },
|
|
225554
|
-
history: data.history.map((r2) => ({ ...r2 }))
|
|
225555
|
-
};
|
|
225556
|
-
}
|
|
225557
|
-
};
|
|
225558
|
-
SpendControl = class {
|
|
225559
|
-
limits = {};
|
|
225560
|
-
history = [];
|
|
225561
|
-
sessionSpent = 0;
|
|
225562
|
-
sessionCalls = 0;
|
|
225563
|
-
storage;
|
|
225564
|
-
now;
|
|
225565
|
-
constructor(options) {
|
|
225566
|
-
this.storage = options?.storage ?? new FileSpendControlStorage();
|
|
225567
|
-
this.now = options?.now ?? (() => Date.now());
|
|
225568
|
-
this.load();
|
|
225569
|
-
}
|
|
225570
|
-
setLimit(window2, amount) {
|
|
225571
|
-
if (!Number.isFinite(amount) || amount <= 0) {
|
|
225572
|
-
throw new Error("Limit must be a finite positive number");
|
|
225573
|
-
}
|
|
225574
|
-
this.limits[window2] = amount;
|
|
225575
|
-
this.save();
|
|
225576
|
-
}
|
|
225577
|
-
clearLimit(window2) {
|
|
225578
|
-
delete this.limits[window2];
|
|
225579
|
-
this.save();
|
|
225580
|
-
}
|
|
225581
|
-
getLimits() {
|
|
225582
|
-
return { ...this.limits };
|
|
225583
|
-
}
|
|
225584
|
-
check(estimatedCost2) {
|
|
225585
|
-
const now2 = this.now();
|
|
225586
|
-
if (this.limits.perRequest !== void 0) {
|
|
225587
|
-
if (estimatedCost2 > this.limits.perRequest) {
|
|
225588
|
-
return {
|
|
225589
|
-
allowed: false,
|
|
225590
|
-
blockedBy: "perRequest",
|
|
225591
|
-
remaining: this.limits.perRequest,
|
|
225592
|
-
reason: `Per-request limit exceeded: $${estimatedCost2.toFixed(4)} > $${this.limits.perRequest.toFixed(2)} max`
|
|
225593
|
-
};
|
|
225594
|
-
}
|
|
225595
|
-
}
|
|
225596
|
-
if (this.limits.hourly !== void 0) {
|
|
225597
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225598
|
-
const remaining = this.limits.hourly - hourlySpent;
|
|
225599
|
-
if (estimatedCost2 > remaining) {
|
|
225600
|
-
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - HOUR_MS);
|
|
225601
|
-
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + HOUR_MS - now2) / 1e3) : 0;
|
|
225602
|
-
return {
|
|
225603
|
-
allowed: false,
|
|
225604
|
-
blockedBy: "hourly",
|
|
225605
|
-
remaining,
|
|
225606
|
-
reason: `Hourly limit exceeded: $${(hourlySpent + estimatedCost2).toFixed(2)} > $${this.limits.hourly.toFixed(2)} max`,
|
|
225607
|
-
resetIn
|
|
225608
|
-
};
|
|
225609
|
-
}
|
|
225610
|
-
}
|
|
225611
|
-
if (this.limits.daily !== void 0) {
|
|
225612
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225613
|
-
const remaining = this.limits.daily - dailySpent;
|
|
225614
|
-
if (estimatedCost2 > remaining) {
|
|
225615
|
-
const oldestInWindow = this.history.find((r2) => r2.timestamp >= now2 - DAY_MS);
|
|
225616
|
-
const resetIn = oldestInWindow ? Math.ceil((oldestInWindow.timestamp + DAY_MS - now2) / 1e3) : 0;
|
|
225617
|
-
return {
|
|
225618
|
-
allowed: false,
|
|
225619
|
-
blockedBy: "daily",
|
|
225620
|
-
remaining,
|
|
225621
|
-
reason: `Daily limit exceeded: $${(dailySpent + estimatedCost2).toFixed(2)} > $${this.limits.daily.toFixed(2)} max`,
|
|
225622
|
-
resetIn
|
|
225623
|
-
};
|
|
225624
|
-
}
|
|
225625
|
-
}
|
|
225626
|
-
if (this.limits.session !== void 0) {
|
|
225627
|
-
const remaining = this.limits.session - this.sessionSpent;
|
|
225628
|
-
if (estimatedCost2 > remaining) {
|
|
225629
|
-
return {
|
|
225630
|
-
allowed: false,
|
|
225631
|
-
blockedBy: "session",
|
|
225632
|
-
remaining,
|
|
225633
|
-
reason: `Session limit exceeded: $${(this.sessionSpent + estimatedCost2).toFixed(2)} > $${this.limits.session.toFixed(2)} max`
|
|
225634
|
-
};
|
|
225635
|
-
}
|
|
225636
|
-
}
|
|
225637
|
-
return { allowed: true };
|
|
225638
|
-
}
|
|
225639
|
-
record(amount, metadata) {
|
|
225640
|
-
if (!Number.isFinite(amount) || amount < 0) {
|
|
225641
|
-
throw new Error("Record amount must be a non-negative finite number");
|
|
225642
|
-
}
|
|
225643
|
-
const record = {
|
|
225644
|
-
timestamp: this.now(),
|
|
225645
|
-
amount,
|
|
225646
|
-
model: metadata?.model,
|
|
225647
|
-
action: metadata?.action
|
|
225648
|
-
};
|
|
225649
|
-
this.history.push(record);
|
|
225650
|
-
this.sessionSpent += amount;
|
|
225651
|
-
this.sessionCalls += 1;
|
|
225652
|
-
this.cleanup();
|
|
225653
|
-
this.save();
|
|
225654
|
-
}
|
|
225655
|
-
getSpendingInWindow(from15, to) {
|
|
225656
|
-
return this.history.filter((r2) => r2.timestamp >= from15 && r2.timestamp <= to).reduce((sum, r2) => sum + r2.amount, 0);
|
|
225657
|
-
}
|
|
225658
|
-
getSpending(window2) {
|
|
225659
|
-
const now2 = this.now();
|
|
225660
|
-
switch (window2) {
|
|
225661
|
-
case "hourly":
|
|
225662
|
-
return this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225663
|
-
case "daily":
|
|
225664
|
-
return this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225665
|
-
case "session":
|
|
225666
|
-
return this.sessionSpent;
|
|
225667
|
-
}
|
|
225668
|
-
}
|
|
225669
|
-
getRemaining(window2) {
|
|
225670
|
-
const limit = this.limits[window2];
|
|
225671
|
-
if (limit === void 0) return null;
|
|
225672
|
-
return Math.max(0, limit - this.getSpending(window2));
|
|
225673
|
-
}
|
|
225674
|
-
getStatus() {
|
|
225675
|
-
const now2 = this.now();
|
|
225676
|
-
const hourlySpent = this.getSpendingInWindow(now2 - HOUR_MS, now2);
|
|
225677
|
-
const dailySpent = this.getSpendingInWindow(now2 - DAY_MS, now2);
|
|
225678
|
-
return {
|
|
225679
|
-
limits: { ...this.limits },
|
|
225680
|
-
spending: {
|
|
225681
|
-
hourly: hourlySpent,
|
|
225682
|
-
daily: dailySpent,
|
|
225683
|
-
session: this.sessionSpent
|
|
225684
|
-
},
|
|
225685
|
-
remaining: {
|
|
225686
|
-
hourly: this.limits.hourly !== void 0 ? this.limits.hourly - hourlySpent : null,
|
|
225687
|
-
daily: this.limits.daily !== void 0 ? this.limits.daily - dailySpent : null,
|
|
225688
|
-
session: this.limits.session !== void 0 ? this.limits.session - this.sessionSpent : null
|
|
225689
|
-
},
|
|
225690
|
-
calls: this.sessionCalls
|
|
225691
|
-
};
|
|
225692
|
-
}
|
|
225693
|
-
getHistory(limit) {
|
|
225694
|
-
const records = [...this.history].reverse();
|
|
225695
|
-
return limit ? records.slice(0, limit) : records;
|
|
225696
|
-
}
|
|
225697
|
-
resetSession() {
|
|
225698
|
-
this.sessionSpent = 0;
|
|
225699
|
-
this.sessionCalls = 0;
|
|
225700
|
-
}
|
|
225701
|
-
cleanup() {
|
|
225702
|
-
const cutoff = this.now() - DAY_MS;
|
|
225703
|
-
this.history = this.history.filter((r2) => r2.timestamp >= cutoff);
|
|
225704
|
-
}
|
|
225705
|
-
save() {
|
|
225706
|
-
this.storage.save({
|
|
225707
|
-
limits: { ...this.limits },
|
|
225708
|
-
history: [...this.history]
|
|
225709
|
-
});
|
|
225710
|
-
}
|
|
225711
|
-
load() {
|
|
225712
|
-
const data = this.storage.load();
|
|
225713
|
-
if (data) {
|
|
225714
|
-
this.limits = data.limits;
|
|
225715
|
-
this.history = data.history;
|
|
225716
|
-
this.cleanup();
|
|
225717
|
-
}
|
|
225718
|
-
}
|
|
225719
|
-
};
|
|
225720
|
-
}
|
|
225721
|
-
});
|
|
225722
|
-
|
|
225723
226077
|
// src/retry.ts
|
|
225724
226078
|
function sleep3(ms) {
|
|
225725
226079
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -225789,7 +226143,7 @@ import {
|
|
|
225789
226143
|
readdirSync,
|
|
225790
226144
|
mkdirSync as mkdirSync3,
|
|
225791
226145
|
copyFileSync,
|
|
225792
|
-
renameSync
|
|
226146
|
+
renameSync as renameSync2
|
|
225793
226147
|
} from "fs";
|
|
225794
226148
|
import { readFile as readFileAsync } from "fs/promises";
|
|
225795
226149
|
import { homedir as homedir13 } from "os";
|
|
@@ -226067,7 +226421,7 @@ function injectModelsConfig(logger48, options = {}) {
|
|
|
226067
226421
|
try {
|
|
226068
226422
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
226069
226423
|
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
226070
|
-
|
|
226424
|
+
renameSync2(tmpPath, configPath);
|
|
226071
226425
|
logger48.info("Smart routing enabled (blockrun/auto)");
|
|
226072
226426
|
} catch (err) {
|
|
226073
226427
|
logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -226103,7 +226457,7 @@ function syncAgentModelCache(logger48, options = {}) {
|
|
|
226103
226457
|
entry.models = VISIBLE_OPENCLAW_MODELS;
|
|
226104
226458
|
const tmpPath = `${cachePath}.tmp.${process.pid}`;
|
|
226105
226459
|
writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
|
|
226106
|
-
|
|
226460
|
+
renameSync2(tmpPath, cachePath);
|
|
226107
226461
|
logger48.info(
|
|
226108
226462
|
`Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
|
|
226109
226463
|
);
|
|
@@ -227466,7 +227820,7 @@ ${errText}`
|
|
|
227466
227820
|
}
|
|
227467
227821
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
227468
227822
|
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
227469
|
-
|
|
227823
|
+
renameSync2(tmpPath, configPath);
|
|
227470
227824
|
api.logger.info("ClawRouter config cleaned up");
|
|
227471
227825
|
}
|
|
227472
227826
|
} catch (err) {
|
|
@@ -227502,6 +227856,8 @@ export {
|
|
|
227502
227856
|
BALANCE_THRESHOLDS,
|
|
227503
227857
|
BLOCKRUN_MODELS,
|
|
227504
227858
|
BalanceMonitor,
|
|
227859
|
+
CAIP2_BASE,
|
|
227860
|
+
CAIP2_SOLANA_MAINNET,
|
|
227505
227861
|
DEFAULT_RETRY_CONFIG,
|
|
227506
227862
|
DEFAULT_ROUTING_CONFIG,
|
|
227507
227863
|
DEFAULT_SESSION_CONFIG,
|
|
@@ -227510,6 +227866,7 @@ export {
|
|
|
227510
227866
|
InMemorySpendControlStorage,
|
|
227511
227867
|
InsufficientFundsError2 as InsufficientFundsError,
|
|
227512
227868
|
MODEL_ALIASES,
|
|
227869
|
+
MalformedSpendPolicyError,
|
|
227513
227870
|
OPENCLAW_MODELS,
|
|
227514
227871
|
PARTNER_SERVICES,
|
|
227515
227872
|
RequestDeduplicator,
|
|
@@ -227518,6 +227875,7 @@ export {
|
|
|
227518
227875
|
SessionStore,
|
|
227519
227876
|
SolanaBalanceMonitor,
|
|
227520
227877
|
SpendControl,
|
|
227878
|
+
SpendPolicyError,
|
|
227521
227879
|
VISIBLE_OPENCLAW_MODELS,
|
|
227522
227880
|
blockrunProvider,
|
|
227523
227881
|
buildImageGenerationProvider,
|
|
@@ -227557,6 +227915,7 @@ export {
|
|
|
227557
227915
|
loadPaymentChain,
|
|
227558
227916
|
logUsage,
|
|
227559
227917
|
parseCallArgs,
|
|
227918
|
+
registerSpendPolicyHook,
|
|
227560
227919
|
resolveModelAlias,
|
|
227561
227920
|
resolvePaymentChain,
|
|
227562
227921
|
route,
|