@blockrun/clawrouter 0.12.265 → 0.12.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/dist/cli.js +1383 -417
- package/dist/index.d.ts +52 -23
- package/dist/index.js +1101 -388
- package/docs/clawrouter-cuts-llm-api-costs-500x.md +1 -1
- package/docs/configuration.md +26 -24
- package/docs/troubleshooting.md +6 -2
- package/openclaw.plugin.json +2 -1
- package/package.json +3 -2
- package/scripts/reinstall.sh +181 -77
- package/scripts/uninstall.sh +53 -8
- package/scripts/update.ps1 +215 -33
- package/scripts/update.sh +223 -86
package/dist/cli.js
CHANGED
|
@@ -5786,15 +5786,15 @@ function wNAF(c, bits) {
|
|
|
5786
5786
|
const { windows, windowSize } = calcWOpts(W, bits);
|
|
5787
5787
|
const points = [];
|
|
5788
5788
|
let p = elm;
|
|
5789
|
-
let
|
|
5789
|
+
let base4 = p;
|
|
5790
5790
|
for (let window2 = 0; window2 < windows; window2++) {
|
|
5791
|
-
|
|
5792
|
-
points.push(
|
|
5791
|
+
base4 = p;
|
|
5792
|
+
points.push(base4);
|
|
5793
5793
|
for (let i = 1; i < windowSize; i++) {
|
|
5794
|
-
|
|
5795
|
-
points.push(
|
|
5794
|
+
base4 = base4.add(p);
|
|
5795
|
+
points.push(base4);
|
|
5796
5796
|
}
|
|
5797
|
-
p =
|
|
5797
|
+
p = base4.double();
|
|
5798
5798
|
}
|
|
5799
5799
|
return points;
|
|
5800
5800
|
},
|
|
@@ -8432,7 +8432,7 @@ async function internal_estimateFeesPerGas(client, args) {
|
|
|
8432
8432
|
throw new BaseFeeScalarError();
|
|
8433
8433
|
const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
|
|
8434
8434
|
const denominator = 10 ** decimals;
|
|
8435
|
-
const multiply = (
|
|
8435
|
+
const multiply = (base4) => base4 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
|
|
8436
8436
|
const block = block_ ? block_ : await getAction(client, getBlock, "getBlock")({});
|
|
8437
8437
|
if (typeof chain3?.fees?.estimateFeesPerGas === "function") {
|
|
8438
8438
|
const fees = await chain3.fees.estimateFeesPerGas({
|
|
@@ -8903,7 +8903,7 @@ async function fillTransaction(client, parameters) {
|
|
|
8903
8903
|
throw new BaseFeeScalarError();
|
|
8904
8904
|
const decimals = feeMultiplier.toString().split(".")[1]?.length ?? 0;
|
|
8905
8905
|
const denominator = 10 ** decimals;
|
|
8906
|
-
const multiplyFee = (
|
|
8906
|
+
const multiplyFee = (base4) => base4 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
|
|
8907
8907
|
if (!transaction.feePayerSignature) {
|
|
8908
8908
|
if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
|
|
8909
8909
|
transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas);
|
|
@@ -11861,17 +11861,17 @@ async function call(client, args) {
|
|
|
11861
11861
|
}
|
|
11862
11862
|
}
|
|
11863
11863
|
const params = (() => {
|
|
11864
|
-
const
|
|
11864
|
+
const base4 = [
|
|
11865
11865
|
request2,
|
|
11866
11866
|
block
|
|
11867
11867
|
];
|
|
11868
11868
|
if (rpcStateOverride && rpcBlockOverrides)
|
|
11869
|
-
return [...
|
|
11869
|
+
return [...base4, rpcStateOverride, rpcBlockOverrides];
|
|
11870
11870
|
if (rpcStateOverride)
|
|
11871
|
-
return [...
|
|
11871
|
+
return [...base4, rpcStateOverride];
|
|
11872
11872
|
if (rpcBlockOverrides)
|
|
11873
|
-
return [...
|
|
11874
|
-
return
|
|
11873
|
+
return [...base4, {}, rpcBlockOverrides];
|
|
11874
|
+
return base4;
|
|
11875
11875
|
})();
|
|
11876
11876
|
const response = await client.request({
|
|
11877
11877
|
method: "eth_call",
|
|
@@ -13277,14 +13277,14 @@ function createClient(parameters) {
|
|
|
13277
13277
|
uid: uid(),
|
|
13278
13278
|
...experimental_blockTag ? { experimental_blockTag } : {}
|
|
13279
13279
|
};
|
|
13280
|
-
function extend2(
|
|
13280
|
+
function extend2(base4) {
|
|
13281
13281
|
return (extendFn) => {
|
|
13282
|
-
const extended = extendFn(
|
|
13282
|
+
const extended = extendFn(base4);
|
|
13283
13283
|
for (const key3 in client)
|
|
13284
13284
|
delete extended[key3];
|
|
13285
|
-
const combined = { ...
|
|
13285
|
+
const combined = { ...base4, ...extended };
|
|
13286
13286
|
for (const key3 in extended) {
|
|
13287
|
-
const a =
|
|
13287
|
+
const a = base4[key3];
|
|
13288
13288
|
const b = extended[key3];
|
|
13289
13289
|
if (isPlainObject(a) && isPlainObject(b))
|
|
13290
13290
|
combined[key3] = { ...a, ...b };
|
|
@@ -15037,10 +15037,10 @@ function defineChain(chain3) {
|
|
|
15037
15037
|
serializers: void 0,
|
|
15038
15038
|
...chain3
|
|
15039
15039
|
};
|
|
15040
|
-
function extend2(
|
|
15040
|
+
function extend2(base4) {
|
|
15041
15041
|
return (fnOrExtended) => {
|
|
15042
|
-
const properties = typeof fnOrExtended === "function" ? fnOrExtended(
|
|
15043
|
-
const combined = { ...
|
|
15042
|
+
const properties = typeof fnOrExtended === "function" ? fnOrExtended(base4) : fnOrExtended;
|
|
15043
|
+
const combined = { ...base4, ...properties };
|
|
15044
15044
|
return Object.assign(combined, { extend: extend2(combined) });
|
|
15045
15045
|
};
|
|
15046
15046
|
}
|
|
@@ -15404,9 +15404,9 @@ function validateTypedData(parameters) {
|
|
|
15404
15404
|
throw new InvalidTypedDataTypeError({ type });
|
|
15405
15405
|
const integerMatch = type.match(integerRegex2);
|
|
15406
15406
|
if (integerMatch && (typeof value === "number" || typeof value === "bigint")) {
|
|
15407
|
-
const [_type,
|
|
15407
|
+
const [_type, base4, size_] = integerMatch;
|
|
15408
15408
|
numberToHex(value, {
|
|
15409
|
-
signed:
|
|
15409
|
+
signed: base4 === "int",
|
|
15410
15410
|
size: Number.parseInt(size_, 10) / 8
|
|
15411
15411
|
});
|
|
15412
15412
|
}
|
|
@@ -18035,15 +18035,15 @@ function wNAF2(c, bits) {
|
|
|
18035
18035
|
const { windows, windowSize } = calcWOpts2(W, bits);
|
|
18036
18036
|
const points = [];
|
|
18037
18037
|
let p = elm;
|
|
18038
|
-
let
|
|
18038
|
+
let base4 = p;
|
|
18039
18039
|
for (let window2 = 0; window2 < windows; window2++) {
|
|
18040
|
-
|
|
18041
|
-
points.push(
|
|
18040
|
+
base4 = p;
|
|
18041
|
+
points.push(base4);
|
|
18042
18042
|
for (let i = 1; i < windowSize; i++) {
|
|
18043
|
-
|
|
18044
|
-
points.push(
|
|
18043
|
+
base4 = base4.add(p);
|
|
18044
|
+
points.push(base4);
|
|
18045
18045
|
}
|
|
18046
|
-
p =
|
|
18046
|
+
p = base4.double();
|
|
18047
18047
|
}
|
|
18048
18048
|
return points;
|
|
18049
18049
|
},
|
|
@@ -30627,23 +30627,23 @@ var init_types = __esm({
|
|
|
30627
30627
|
}
|
|
30628
30628
|
if (effect.type === "transform") {
|
|
30629
30629
|
if (ctx.common.async === false) {
|
|
30630
|
-
const
|
|
30630
|
+
const base4 = this._def.schema._parseSync({
|
|
30631
30631
|
data: ctx.data,
|
|
30632
30632
|
path: ctx.path,
|
|
30633
30633
|
parent: ctx
|
|
30634
30634
|
});
|
|
30635
|
-
if (!isValid(
|
|
30635
|
+
if (!isValid(base4))
|
|
30636
30636
|
return INVALID;
|
|
30637
|
-
const result = effect.transform(
|
|
30637
|
+
const result = effect.transform(base4.value, checkCtx);
|
|
30638
30638
|
if (result instanceof Promise) {
|
|
30639
30639
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
30640
30640
|
}
|
|
30641
30641
|
return { status: status.value, value: result };
|
|
30642
30642
|
} else {
|
|
30643
|
-
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((
|
|
30644
|
-
if (!isValid(
|
|
30643
|
+
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base4) => {
|
|
30644
|
+
if (!isValid(base4))
|
|
30645
30645
|
return INVALID;
|
|
30646
|
-
return Promise.resolve(effect.transform(
|
|
30646
|
+
return Promise.resolve(effect.transform(base4.value, checkCtx)).then((result) => ({
|
|
30647
30647
|
status: status.value,
|
|
30648
30648
|
value: result
|
|
30649
30649
|
}));
|
|
@@ -32305,6 +32305,11 @@ function cloneLimits(limits) {
|
|
|
32305
32305
|
}
|
|
32306
32306
|
return clone;
|
|
32307
32307
|
}
|
|
32308
|
+
function canonicalLimits(limits) {
|
|
32309
|
+
return JSON.stringify(
|
|
32310
|
+
Object.fromEntries(Object.entries(limits).sort(([a], [b]) => a < b ? -1 : 1))
|
|
32311
|
+
);
|
|
32312
|
+
}
|
|
32308
32313
|
function parseQuotedAmountUsd(selected) {
|
|
32309
32314
|
const raw = selected.amount ?? selected.maxAmountRequired;
|
|
32310
32315
|
if (typeof raw !== "string" || !CANONICAL_AMOUNT.test(raw)) {
|
|
@@ -32380,7 +32385,7 @@ function formatDuration(seconds) {
|
|
|
32380
32385
|
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
32381
32386
|
}
|
|
32382
32387
|
}
|
|
32383
|
-
var WALLET_DIR, HOUR_MS, DAY_MS, CAIP2_BASE, CAIP2_SOLANA_MAINNET, POLICY_LISTS, ADDRESS_LISTS, EVM_ADDRESS, MalformedSpendPolicyError, FileSpendControlStorage, InMemorySpendControlStorage, RESERVATION_TTL_MS, SpendControl, SpendPolicyError, CANONICAL_AMOUNT;
|
|
32388
|
+
var WALLET_DIR, HOUR_MS, DAY_MS, CAIP2_BASE, CAIP2_SOLANA_MAINNET, PAYABLE_NETWORKS, POLICY_LISTS, ADDRESS_LISTS, EVM_ADDRESS, MalformedSpendPolicyError, SpendPolicyConflictError, FileSpendControlStorage, InMemorySpendControlStorage, RESERVATION_TTL_MS, SpendControl, SpendPolicyError, CANONICAL_AMOUNT;
|
|
32384
32389
|
var init_spend_control = __esm({
|
|
32385
32390
|
"src/spend-control.ts"() {
|
|
32386
32391
|
"use strict";
|
|
@@ -32390,6 +32395,7 @@ var init_spend_control = __esm({
|
|
|
32390
32395
|
DAY_MS = 24 * HOUR_MS;
|
|
32391
32396
|
CAIP2_BASE = "eip155:8453";
|
|
32392
32397
|
CAIP2_SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
|
|
32398
|
+
PAYABLE_NETWORKS = [CAIP2_BASE, CAIP2_SOLANA_MAINNET];
|
|
32393
32399
|
POLICY_LISTS = [
|
|
32394
32400
|
"allowedPayees",
|
|
32395
32401
|
"blockedPayees",
|
|
@@ -32406,6 +32412,12 @@ var init_spend_control = __esm({
|
|
|
32406
32412
|
this.name = "MalformedSpendPolicyError";
|
|
32407
32413
|
}
|
|
32408
32414
|
};
|
|
32415
|
+
SpendPolicyConflictError = class extends Error {
|
|
32416
|
+
constructor() {
|
|
32417
|
+
super("spending.json limits changed underneath this write; nothing was written");
|
|
32418
|
+
this.name = "SpendPolicyConflictError";
|
|
32419
|
+
}
|
|
32420
|
+
};
|
|
32409
32421
|
FileSpendControlStorage = class {
|
|
32410
32422
|
spendingFile;
|
|
32411
32423
|
constructor() {
|
|
@@ -32486,6 +32498,25 @@ var init_spend_control = __esm({
|
|
|
32486
32498
|
}
|
|
32487
32499
|
this.save({ limits: storedLimits, history });
|
|
32488
32500
|
}
|
|
32501
|
+
/**
|
|
32502
|
+
* Persist limits while leaving the stored history exactly as it is on disk.
|
|
32503
|
+
* With `expect`, refuse when the stored limits are no longer the ones the
|
|
32504
|
+
* writer read — a stale instance must not replace another writer's edit.
|
|
32505
|
+
* The re-read happens immediately before the atomic rename, so the race
|
|
32506
|
+
* window is the write itself, not the whole command.
|
|
32507
|
+
*/
|
|
32508
|
+
saveLimits(limits, expect) {
|
|
32509
|
+
let current;
|
|
32510
|
+
try {
|
|
32511
|
+
current = this.load();
|
|
32512
|
+
} catch {
|
|
32513
|
+
return;
|
|
32514
|
+
}
|
|
32515
|
+
if (expect !== void 0 && canonicalLimits(current?.limits ?? {}) !== canonicalLimits(expect)) {
|
|
32516
|
+
throw new SpendPolicyConflictError();
|
|
32517
|
+
}
|
|
32518
|
+
this.save({ limits, history: current?.history ?? [] });
|
|
32519
|
+
}
|
|
32489
32520
|
};
|
|
32490
32521
|
InMemorySpendControlStorage = class {
|
|
32491
32522
|
data = null;
|
|
@@ -32501,6 +32532,15 @@ var init_spend_control = __esm({
|
|
|
32501
32532
|
history: data.history.map((r2) => ({ ...r2 }))
|
|
32502
32533
|
};
|
|
32503
32534
|
}
|
|
32535
|
+
saveLimits(limits, expect) {
|
|
32536
|
+
if (expect !== void 0 && canonicalLimits(this.data?.limits ?? {}) !== canonicalLimits(expect)) {
|
|
32537
|
+
throw new SpendPolicyConflictError();
|
|
32538
|
+
}
|
|
32539
|
+
this.data = {
|
|
32540
|
+
limits: cloneLimits(limits),
|
|
32541
|
+
history: this.data?.history.map((r2) => ({ ...r2 })) ?? []
|
|
32542
|
+
};
|
|
32543
|
+
}
|
|
32504
32544
|
};
|
|
32505
32545
|
RESERVATION_TTL_MS = 2 * 60 * 1e3;
|
|
32506
32546
|
SpendControl = class {
|
|
@@ -32512,6 +32552,8 @@ var init_spend_control = __esm({
|
|
|
32512
32552
|
reservationSeq = 0;
|
|
32513
32553
|
/** Limits we loaded and have not changed; history-only saves must not clobber operator edits. */
|
|
32514
32554
|
limitsDirty = false;
|
|
32555
|
+
/** The limits this instance last read from or wrote to storage — the compare-and-swap baseline. */
|
|
32556
|
+
diskLimits = {};
|
|
32515
32557
|
/** Set when spending.json held an unusable policy list: refuse every payment. */
|
|
32516
32558
|
policyFileBroken;
|
|
32517
32559
|
storage;
|
|
@@ -32556,6 +32598,15 @@ var init_spend_control = __esm({
|
|
|
32556
32598
|
getLimits() {
|
|
32557
32599
|
return cloneLimits(this.limits);
|
|
32558
32600
|
}
|
|
32601
|
+
/**
|
|
32602
|
+
* Why spending.json could not be loaded, or undefined when it is usable.
|
|
32603
|
+
* While set, every setter mutates memory only: save() refuses to rewrite a
|
|
32604
|
+
* file it could not fully parse, so callers must check this before
|
|
32605
|
+
* reporting a change as applied.
|
|
32606
|
+
*/
|
|
32607
|
+
getPolicyFileError() {
|
|
32608
|
+
return this.policyFileBroken;
|
|
32609
|
+
}
|
|
32559
32610
|
check(estimatedCost2, counterparty) {
|
|
32560
32611
|
if (this.policyFileBroken !== void 0) {
|
|
32561
32612
|
return {
|
|
@@ -32816,6 +32867,22 @@ var init_spend_control = __esm({
|
|
|
32816
32867
|
this.storage.saveHistory([...this.history]);
|
|
32817
32868
|
return;
|
|
32818
32869
|
}
|
|
32870
|
+
if (this.limitsDirty && this.storage.saveLimits) {
|
|
32871
|
+
try {
|
|
32872
|
+
this.storage.saveLimits(cloneLimits(this.limits), cloneLimits(this.diskLimits));
|
|
32873
|
+
} catch (err) {
|
|
32874
|
+
if (err instanceof SpendPolicyConflictError) {
|
|
32875
|
+
const current = this.storage.load();
|
|
32876
|
+
this.limits = cloneLimits(current?.limits ?? {});
|
|
32877
|
+
this.diskLimits = cloneLimits(this.limits);
|
|
32878
|
+
this.limitsDirty = false;
|
|
32879
|
+
}
|
|
32880
|
+
throw err;
|
|
32881
|
+
}
|
|
32882
|
+
this.diskLimits = cloneLimits(this.limits);
|
|
32883
|
+
this.limitsDirty = false;
|
|
32884
|
+
return;
|
|
32885
|
+
}
|
|
32819
32886
|
this.storage.save({
|
|
32820
32887
|
limits: cloneLimits(this.limits),
|
|
32821
32888
|
history: [...this.history]
|
|
@@ -32836,6 +32903,7 @@ var init_spend_control = __esm({
|
|
|
32836
32903
|
}
|
|
32837
32904
|
if (data) {
|
|
32838
32905
|
this.limits = cloneLimits(data.limits);
|
|
32906
|
+
this.diskLimits = cloneLimits(data.limits);
|
|
32839
32907
|
this.history = data.history;
|
|
32840
32908
|
this.cleanup();
|
|
32841
32909
|
}
|
|
@@ -34488,12 +34556,12 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34488
34556
|
const id2 = modelId.toLowerCase();
|
|
34489
34557
|
const modelName = id2.slice(id2.indexOf("/") + 1);
|
|
34490
34558
|
const match = (values, score) => values.some((value) => modelName === value) ? score : 0;
|
|
34491
|
-
const
|
|
34559
|
+
const base4 = 0.68;
|
|
34492
34560
|
switch (task) {
|
|
34493
34561
|
case "code_agent":
|
|
34494
34562
|
if (terminalToolSignal && agentRisk === "complex_high") {
|
|
34495
34563
|
return Math.max(
|
|
34496
|
-
|
|
34564
|
+
base4,
|
|
34497
34565
|
match(["claude-sonnet-5"], 1),
|
|
34498
34566
|
match(["gpt-5.3-codex"], 0.87),
|
|
34499
34567
|
match(["gpt-5-mini"], 0.78),
|
|
@@ -34501,7 +34569,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34501
34569
|
);
|
|
34502
34570
|
}
|
|
34503
34571
|
return Math.max(
|
|
34504
|
-
|
|
34572
|
+
base4,
|
|
34505
34573
|
match(["gpt-5.3-codex"], 1),
|
|
34506
34574
|
match(["claude-sonnet-5"], 0.98),
|
|
34507
34575
|
match(["gpt-5-mini"], 0.96),
|
|
@@ -34512,7 +34580,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34512
34580
|
case "tool_agent":
|
|
34513
34581
|
if (terminalToolSignal && agentRisk === "complex_high") {
|
|
34514
34582
|
return Math.max(
|
|
34515
|
-
|
|
34583
|
+
base4,
|
|
34516
34584
|
match(["claude-sonnet-5"], 1),
|
|
34517
34585
|
match(["gpt-5.3-codex"], 0.87),
|
|
34518
34586
|
match(["gpt-5-mini"], 0.78),
|
|
@@ -34521,7 +34589,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34521
34589
|
}
|
|
34522
34590
|
if (terminalToolSignal && !terminalSafetySensitive) {
|
|
34523
34591
|
return Math.max(
|
|
34524
|
-
|
|
34592
|
+
base4,
|
|
34525
34593
|
match(["gpt-5-mini"], 1),
|
|
34526
34594
|
match(["gpt-5.3-codex"], 0.98),
|
|
34527
34595
|
match(["claude-sonnet-5"], 0.9),
|
|
@@ -34530,7 +34598,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34530
34598
|
}
|
|
34531
34599
|
if (terminalToolSignal && terminalSafetySensitive) {
|
|
34532
34600
|
return Math.max(
|
|
34533
|
-
|
|
34601
|
+
base4,
|
|
34534
34602
|
match(["claude-sonnet-5"], 1),
|
|
34535
34603
|
match(["claude-opus-4.8"], 0.9),
|
|
34536
34604
|
match(["gpt-5.3-codex"], 0.84)
|
|
@@ -34538,14 +34606,14 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34538
34606
|
}
|
|
34539
34607
|
if (agentDomain === "web_research") {
|
|
34540
34608
|
return deepWebResearch ? Math.max(
|
|
34541
|
-
|
|
34609
|
+
base4,
|
|
34542
34610
|
match(["claude-sonnet-5"], 1),
|
|
34543
34611
|
match(["gpt-5-mini"], 0.88),
|
|
34544
34612
|
match(["gemini-3.5-flash"], 0.84),
|
|
34545
34613
|
match(["claude-opus-5"], 0.8),
|
|
34546
34614
|
match(["claude-opus-4.8"], 0.78)
|
|
34547
34615
|
) : Math.max(
|
|
34548
|
-
|
|
34616
|
+
base4,
|
|
34549
34617
|
match(["claude-sonnet-5"], 1),
|
|
34550
34618
|
match(["gpt-5-mini"], 0.88),
|
|
34551
34619
|
match(["gemini-3.5-flash"], 0.86),
|
|
@@ -34556,7 +34624,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34556
34624
|
if (agentDomain === "retail") {
|
|
34557
34625
|
if (agentRisk === "standard") {
|
|
34558
34626
|
return Math.max(
|
|
34559
|
-
|
|
34627
|
+
base4,
|
|
34560
34628
|
match(["gpt-5-mini"], 1),
|
|
34561
34629
|
match(["claude-sonnet-5"], 0.88),
|
|
34562
34630
|
match(["gemini-3.5-flash"], 0.82),
|
|
@@ -34567,7 +34635,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34567
34635
|
}
|
|
34568
34636
|
if (agentRisk === "policy_exception") {
|
|
34569
34637
|
return Math.max(
|
|
34570
|
-
|
|
34638
|
+
base4,
|
|
34571
34639
|
match(["gpt-4.1"], 1),
|
|
34572
34640
|
match(["claude-sonnet-5"], 0.9),
|
|
34573
34641
|
match(["deepseek-v4-pro"], 0.82),
|
|
@@ -34577,7 +34645,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34577
34645
|
}
|
|
34578
34646
|
if (agentRisk === "policy_exception_simple") {
|
|
34579
34647
|
return Math.max(
|
|
34580
|
-
|
|
34648
|
+
base4,
|
|
34581
34649
|
match(["gpt-5-mini"], 1),
|
|
34582
34650
|
match(["gpt-4.1"], 0.86),
|
|
34583
34651
|
match(["deepseek-v4-pro"], 0.82),
|
|
@@ -34585,7 +34653,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34585
34653
|
);
|
|
34586
34654
|
}
|
|
34587
34655
|
return Math.max(
|
|
34588
|
-
|
|
34656
|
+
base4,
|
|
34589
34657
|
match(["deepseek-v4-pro"], 1),
|
|
34590
34658
|
match(["claude-sonnet-5"], 0.88),
|
|
34591
34659
|
match(["gemini-3.5-flash"], 0.82),
|
|
@@ -34597,7 +34665,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34597
34665
|
if (agentDomain === "airline") {
|
|
34598
34666
|
if (agentRisk === "complex_high") {
|
|
34599
34667
|
return Math.max(
|
|
34600
|
-
|
|
34668
|
+
base4,
|
|
34601
34669
|
match(["claude-sonnet-5"], 1),
|
|
34602
34670
|
match(["gpt-5-mini"], 0.78),
|
|
34603
34671
|
match(["gemini-3.5-flash"], 0.76),
|
|
@@ -34605,7 +34673,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34605
34673
|
);
|
|
34606
34674
|
}
|
|
34607
34675
|
return Math.max(
|
|
34608
|
-
|
|
34676
|
+
base4,
|
|
34609
34677
|
match(["gpt-5-mini"], 1),
|
|
34610
34678
|
match(["claude-sonnet-5"], 0.9),
|
|
34611
34679
|
match(["gemini-3.5-flash"], 0.8),
|
|
@@ -34613,7 +34681,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34613
34681
|
);
|
|
34614
34682
|
}
|
|
34615
34683
|
return Math.max(
|
|
34616
|
-
|
|
34684
|
+
base4,
|
|
34617
34685
|
match(["claude-sonnet-5"], 1),
|
|
34618
34686
|
match(["gemini-3.5-flash"], 0.88),
|
|
34619
34687
|
match(["gpt-5.3-codex"], 0.87),
|
|
@@ -34624,12 +34692,12 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34624
34692
|
case "tool_agent_parallel":
|
|
34625
34693
|
if (terminalToolSignal) {
|
|
34626
34694
|
return terminalSafetySensitive ? Math.max(
|
|
34627
|
-
|
|
34695
|
+
base4,
|
|
34628
34696
|
match(["claude-sonnet-5"], 1),
|
|
34629
34697
|
match(["claude-opus-4.8"], 0.9),
|
|
34630
34698
|
match(["gpt-5.3-codex"], 0.86)
|
|
34631
34699
|
) : Math.max(
|
|
34632
|
-
|
|
34700
|
+
base4,
|
|
34633
34701
|
match(["gpt-5-mini"], 1),
|
|
34634
34702
|
match(["gpt-5.3-codex"], 0.98),
|
|
34635
34703
|
match(["claude-sonnet-5"], 0.92),
|
|
@@ -34638,14 +34706,14 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34638
34706
|
}
|
|
34639
34707
|
if (agentDomain === "web_research") {
|
|
34640
34708
|
return deepWebResearch ? Math.max(
|
|
34641
|
-
|
|
34709
|
+
base4,
|
|
34642
34710
|
match(["claude-sonnet-5"], 1),
|
|
34643
34711
|
match(["gpt-5-mini"], 0.88),
|
|
34644
34712
|
match(["gemini-3.5-flash"], 0.84),
|
|
34645
34713
|
match(["claude-opus-5"], 0.8),
|
|
34646
34714
|
match(["claude-opus-4.8"], 0.78)
|
|
34647
34715
|
) : Math.max(
|
|
34648
|
-
|
|
34716
|
+
base4,
|
|
34649
34717
|
match(["claude-sonnet-5"], 1),
|
|
34650
34718
|
match(["gpt-5-mini"], 0.88),
|
|
34651
34719
|
match(["gemini-3.5-flash"], 0.86),
|
|
@@ -34656,7 +34724,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34656
34724
|
if (agentDomain === "retail") {
|
|
34657
34725
|
if (agentRisk === "policy_exception") {
|
|
34658
34726
|
return Math.max(
|
|
34659
|
-
|
|
34727
|
+
base4,
|
|
34660
34728
|
match(["gpt-4.1"], 1),
|
|
34661
34729
|
match(["claude-sonnet-5"], 0.9),
|
|
34662
34730
|
match(["deepseek-v4-pro"], 0.82),
|
|
@@ -34666,7 +34734,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34666
34734
|
}
|
|
34667
34735
|
if (agentRisk === "policy_exception_simple") {
|
|
34668
34736
|
return Math.max(
|
|
34669
|
-
|
|
34737
|
+
base4,
|
|
34670
34738
|
match(["gpt-5-mini"], 1),
|
|
34671
34739
|
match(["gpt-4.1"], 0.86),
|
|
34672
34740
|
match(["deepseek-v4-pro"], 0.82),
|
|
@@ -34674,7 +34742,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34674
34742
|
);
|
|
34675
34743
|
}
|
|
34676
34744
|
return Math.max(
|
|
34677
|
-
|
|
34745
|
+
base4,
|
|
34678
34746
|
match(["deepseek-v4-pro"], 1),
|
|
34679
34747
|
match(["claude-sonnet-5"], 0.88),
|
|
34680
34748
|
match(["claude-opus-4.8"], 0.84),
|
|
@@ -34684,20 +34752,20 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34684
34752
|
}
|
|
34685
34753
|
if (agentDomain === "airline") {
|
|
34686
34754
|
return agentRisk === "complex_high" ? Math.max(
|
|
34687
|
-
|
|
34755
|
+
base4,
|
|
34688
34756
|
match(["claude-sonnet-5"], 1),
|
|
34689
34757
|
match(["gpt-5-mini"], 0.78),
|
|
34690
34758
|
match(["claude-opus-4.8"], 0.76),
|
|
34691
34759
|
match(["gemini-3.5-flash"], 0.74)
|
|
34692
34760
|
) : Math.max(
|
|
34693
|
-
|
|
34761
|
+
base4,
|
|
34694
34762
|
match(["gpt-5-mini"], 1),
|
|
34695
34763
|
match(["claude-sonnet-5"], 0.9),
|
|
34696
34764
|
match(["gemini-3.5-flash"], 0.8)
|
|
34697
34765
|
);
|
|
34698
34766
|
}
|
|
34699
34767
|
return Math.max(
|
|
34700
|
-
|
|
34768
|
+
base4,
|
|
34701
34769
|
match(["claude-opus-4.8"], 1),
|
|
34702
34770
|
match(["claude-sonnet-5"], 0.84),
|
|
34703
34771
|
match(["grok-4.5"], 0.82),
|
|
@@ -34707,7 +34775,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34707
34775
|
case "code_edit":
|
|
34708
34776
|
case "debug":
|
|
34709
34777
|
return Math.max(
|
|
34710
|
-
|
|
34778
|
+
base4,
|
|
34711
34779
|
match(["gpt-5.3-codex"], 1),
|
|
34712
34780
|
match(["claude-sonnet-4.6"], 0.94),
|
|
34713
34781
|
match(["glm-5.2"], 0.9),
|
|
@@ -34715,7 +34783,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34715
34783
|
);
|
|
34716
34784
|
case "reasoning":
|
|
34717
34785
|
return Math.max(
|
|
34718
|
-
|
|
34786
|
+
base4,
|
|
34719
34787
|
match(["claude-sonnet-5", "claude-sonnet-4.6"], 0.98),
|
|
34720
34788
|
match(["deepseek-v4-pro"], 0.95),
|
|
34721
34789
|
match(["grok-4.5"], 0.94),
|
|
@@ -34723,7 +34791,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34723
34791
|
);
|
|
34724
34792
|
case "reasoning_mcq":
|
|
34725
34793
|
return Math.max(
|
|
34726
|
-
|
|
34794
|
+
base4,
|
|
34727
34795
|
match(["gemini-3-flash-preview"], 1),
|
|
34728
34796
|
match(["gemini-3.5-flash"], 0.91),
|
|
34729
34797
|
match(["grok-4.5"], 0.9),
|
|
@@ -34732,20 +34800,20 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34732
34800
|
);
|
|
34733
34801
|
case "reasoning_math":
|
|
34734
34802
|
return Math.max(
|
|
34735
|
-
|
|
34803
|
+
base4,
|
|
34736
34804
|
match(["gemini-3.5-flash"], 1),
|
|
34737
34805
|
match(["grok-4.5"], 0.93),
|
|
34738
34806
|
match(["claude-sonnet-5", "deepseek-v4-pro", "kimi-k3"], 0.9)
|
|
34739
34807
|
);
|
|
34740
34808
|
case "vision":
|
|
34741
34809
|
return Math.max(
|
|
34742
|
-
|
|
34810
|
+
base4,
|
|
34743
34811
|
match(["gemini-3.1-pro"], 0.96),
|
|
34744
34812
|
match(["qwen3.7-max", "claude-sonnet-4.6", "kimi-k3", "grok-4.3"], 0.9)
|
|
34745
34813
|
);
|
|
34746
34814
|
case "long_context":
|
|
34747
34815
|
return Math.max(
|
|
34748
|
-
|
|
34816
|
+
base4,
|
|
34749
34817
|
match(["gemini-3.1-pro"], 1),
|
|
34750
34818
|
match(["qwen3.7-max", "glm-5.2"], 0.89),
|
|
34751
34819
|
match(["gemini-3.5-flash"], 0.88),
|
|
@@ -34755,7 +34823,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34755
34823
|
const kimiExtractionAffinity = language === "zh" ? 1 : 0.9;
|
|
34756
34824
|
const otherExtractionAffinity = language === "zh" ? 0.88 : 0.9;
|
|
34757
34825
|
return Math.max(
|
|
34758
|
-
|
|
34826
|
+
base4,
|
|
34759
34827
|
match(["gemini-3.5-flash", "gemini-2.5-flash", "gpt-4o-mini"], otherExtractionAffinity),
|
|
34760
34828
|
match(["claude-sonnet-5", "claude-sonnet-4.6"], otherExtractionAffinity),
|
|
34761
34829
|
match(["kimi-k3"], kimiExtractionAffinity)
|
|
@@ -34763,7 +34831,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
|
|
|
34763
34831
|
}
|
|
34764
34832
|
default:
|
|
34765
34833
|
return Math.max(
|
|
34766
|
-
|
|
34834
|
+
base4,
|
|
34767
34835
|
match(["gemini-3.5-flash", "gemini-2.5-flash", "kimi-k3"], 0.86)
|
|
34768
34836
|
);
|
|
34769
34837
|
}
|
|
@@ -36038,13 +36106,13 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36038
36106
|
name = "portfolio";
|
|
36039
36107
|
route(prompt, systemPrompt, maxOutputTokens, options) {
|
|
36040
36108
|
const features = classifyTask(prompt, systemPrompt, options);
|
|
36041
|
-
const
|
|
36109
|
+
const base4 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
|
|
36042
36110
|
...options,
|
|
36043
36111
|
requiresTools: features.needsTools
|
|
36044
36112
|
});
|
|
36045
|
-
const tierConfigs =
|
|
36046
|
-
if (!tierConfigs) return
|
|
36047
|
-
const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (
|
|
36113
|
+
const tierConfigs = base4.tierConfigs;
|
|
36114
|
+
if (!tierConfigs) return base4;
|
|
36115
|
+
const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (base4.tier === "SIMPLE" || base4.tier === "MEDIUM") ? "REASONING" : base4.tier;
|
|
36048
36116
|
const tierConfig = tierConfigs[targetTier];
|
|
36049
36117
|
const configuredCandidates = tierConfig ? getFallbackChain(targetTier, tierConfigs) : [];
|
|
36050
36118
|
const unavailable = new Set(options.unavailableModels ?? []);
|
|
@@ -36057,7 +36125,7 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36057
36125
|
(model2) => isEligible(model2, features, maxOutputTokens, options)
|
|
36058
36126
|
);
|
|
36059
36127
|
const eligibleCandidates = eligible.length > 0 ? eligible : chain3;
|
|
36060
|
-
if (eligibleCandidates.length === 0) return
|
|
36128
|
+
if (eligibleCandidates.length === 0) return base4;
|
|
36061
36129
|
const profileName = options.routingProfile === "eco" ? "eco" : options.routingProfile === "premium" ? "premium" : "auto";
|
|
36062
36130
|
const portfolio = options.config.portfolio ?? DEFAULT_PORTFOLIO_WEIGHTS;
|
|
36063
36131
|
const getAffinity = (model2) => affinity(
|
|
@@ -36130,27 +36198,27 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
36130
36198
|
(model2) => !scoredModels.includes(model2) && !webResearchFallbackOrder.includes(model2)
|
|
36131
36199
|
)
|
|
36132
36200
|
] : [...scoredModels, ...eligibleCandidates.filter((model2) => !scoredModels.includes(model2))];
|
|
36133
|
-
const model = ranked[0] ??
|
|
36201
|
+
const model = ranked[0] ?? base4.model;
|
|
36134
36202
|
const selectedTierConfigs = {
|
|
36135
36203
|
...tierConfigs,
|
|
36136
36204
|
[targetTier]: { primary: model, fallback: ranked.slice(1) }
|
|
36137
36205
|
};
|
|
36138
36206
|
const decision = selectModel(
|
|
36139
36207
|
targetTier,
|
|
36140
|
-
|
|
36208
|
+
base4.confidence,
|
|
36141
36209
|
"portfolio",
|
|
36142
|
-
`${
|
|
36210
|
+
`${base4.reasoning} | v3 task=${features.taskType} agentRisk=${features.agentRisk} deepWebResearch=${features.deepWebResearch} terminalCode=${features.implicitTerminalCode} terminalSafety=${features.terminalSafetySensitive} candidates=${ranked.length}`,
|
|
36143
36211
|
selectedTierConfigs,
|
|
36144
36212
|
options.modelPricing,
|
|
36145
36213
|
features.estimatedInputTokens,
|
|
36146
36214
|
maxOutputTokens,
|
|
36147
36215
|
options.routingProfile,
|
|
36148
|
-
|
|
36216
|
+
base4.agenticScore
|
|
36149
36217
|
);
|
|
36150
36218
|
return {
|
|
36151
36219
|
...decision,
|
|
36152
36220
|
tierConfigs: selectedTierConfigs,
|
|
36153
|
-
profile:
|
|
36221
|
+
profile: base4.profile,
|
|
36154
36222
|
candidates: ranked,
|
|
36155
36223
|
candidateScores: rankedEntries.map(({ model: model2, score, quality, cost, speed, reliability }) => ({
|
|
36156
36224
|
model: model2,
|
|
@@ -40597,7 +40665,7 @@ var init_errors5 = __esm({
|
|
|
40597
40665
|
`Options:`,
|
|
40598
40666
|
` 1. Fund wallet: ${walletAddress}`,
|
|
40599
40667
|
` 2. Use free model: /model free`,
|
|
40600
|
-
` 3. Uninstall: bash ~/.openclaw/extensions/clawrouter/scripts/uninstall.sh`
|
|
40668
|
+
` 3. Uninstall: bash ~/.openclaw/extensions/blockrun-clawrouter/scripts/uninstall.sh`
|
|
40601
40669
|
].join("\n");
|
|
40602
40670
|
super(msg);
|
|
40603
40671
|
this.name = "EmptyWalletError";
|
|
@@ -40749,6 +40817,154 @@ var init_balance = __esm({
|
|
|
40749
40817
|
}
|
|
40750
40818
|
});
|
|
40751
40819
|
|
|
40820
|
+
// node_modules/base-x/src/esm/index.js
|
|
40821
|
+
function base2(ALPHABET3) {
|
|
40822
|
+
if (ALPHABET3.length >= 255) {
|
|
40823
|
+
throw new TypeError("Alphabet too long");
|
|
40824
|
+
}
|
|
40825
|
+
const BASE_MAP = new Uint8Array(256);
|
|
40826
|
+
for (let j = 0; j < BASE_MAP.length; j++) {
|
|
40827
|
+
BASE_MAP[j] = 255;
|
|
40828
|
+
}
|
|
40829
|
+
for (let i = 0; i < ALPHABET3.length; i++) {
|
|
40830
|
+
const x = ALPHABET3.charAt(i);
|
|
40831
|
+
const xc = x.charCodeAt(0);
|
|
40832
|
+
if (BASE_MAP[xc] !== 255) {
|
|
40833
|
+
throw new TypeError(x + " is ambiguous");
|
|
40834
|
+
}
|
|
40835
|
+
BASE_MAP[xc] = i;
|
|
40836
|
+
}
|
|
40837
|
+
const BASE = ALPHABET3.length;
|
|
40838
|
+
const LEADER = ALPHABET3.charAt(0);
|
|
40839
|
+
const FACTOR = Math.log(BASE) / Math.log(256);
|
|
40840
|
+
const iFACTOR = Math.log(256) / Math.log(BASE);
|
|
40841
|
+
function encode9(source) {
|
|
40842
|
+
if (source instanceof Uint8Array) {
|
|
40843
|
+
} else if (ArrayBuffer.isView(source)) {
|
|
40844
|
+
source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
40845
|
+
} else if (Array.isArray(source)) {
|
|
40846
|
+
source = Uint8Array.from(source);
|
|
40847
|
+
}
|
|
40848
|
+
if (!(source instanceof Uint8Array)) {
|
|
40849
|
+
throw new TypeError("Expected Uint8Array");
|
|
40850
|
+
}
|
|
40851
|
+
if (source.length === 0) {
|
|
40852
|
+
return "";
|
|
40853
|
+
}
|
|
40854
|
+
let zeroes = 0;
|
|
40855
|
+
let length = 0;
|
|
40856
|
+
let pbegin = 0;
|
|
40857
|
+
const pend = source.length;
|
|
40858
|
+
while (pbegin !== pend && source[pbegin] === 0) {
|
|
40859
|
+
pbegin++;
|
|
40860
|
+
zeroes++;
|
|
40861
|
+
}
|
|
40862
|
+
const size5 = (pend - pbegin) * iFACTOR + 1 >>> 0;
|
|
40863
|
+
const b58 = new Uint8Array(size5);
|
|
40864
|
+
while (pbegin !== pend) {
|
|
40865
|
+
let carry2 = source[pbegin];
|
|
40866
|
+
let i = 0;
|
|
40867
|
+
for (let it1 = size5 - 1; (carry2 !== 0 || i < length) && it1 !== -1; it1--, i++) {
|
|
40868
|
+
carry2 += 256 * b58[it1] >>> 0;
|
|
40869
|
+
b58[it1] = carry2 % BASE >>> 0;
|
|
40870
|
+
carry2 = carry2 / BASE >>> 0;
|
|
40871
|
+
}
|
|
40872
|
+
if (carry2 !== 0) {
|
|
40873
|
+
throw new Error("Non-zero carry");
|
|
40874
|
+
}
|
|
40875
|
+
length = i;
|
|
40876
|
+
pbegin++;
|
|
40877
|
+
}
|
|
40878
|
+
let it2 = size5 - length;
|
|
40879
|
+
while (it2 !== size5 && b58[it2] === 0) {
|
|
40880
|
+
it2++;
|
|
40881
|
+
}
|
|
40882
|
+
let str = LEADER.repeat(zeroes);
|
|
40883
|
+
for (; it2 < size5; ++it2) {
|
|
40884
|
+
str += ALPHABET3.charAt(b58[it2]);
|
|
40885
|
+
}
|
|
40886
|
+
return str;
|
|
40887
|
+
}
|
|
40888
|
+
function decodeUnsafe(source) {
|
|
40889
|
+
if (typeof source !== "string") {
|
|
40890
|
+
throw new TypeError("Expected String");
|
|
40891
|
+
}
|
|
40892
|
+
if (source.length === 0) {
|
|
40893
|
+
return new Uint8Array();
|
|
40894
|
+
}
|
|
40895
|
+
let psz = 0;
|
|
40896
|
+
let zeroes = 0;
|
|
40897
|
+
let length = 0;
|
|
40898
|
+
while (source[psz] === LEADER) {
|
|
40899
|
+
zeroes++;
|
|
40900
|
+
psz++;
|
|
40901
|
+
}
|
|
40902
|
+
const size5 = (source.length - psz) * FACTOR + 1 >>> 0;
|
|
40903
|
+
const b256 = new Uint8Array(size5);
|
|
40904
|
+
while (psz < source.length) {
|
|
40905
|
+
const charCode = source.charCodeAt(psz);
|
|
40906
|
+
if (charCode > 255) {
|
|
40907
|
+
return;
|
|
40908
|
+
}
|
|
40909
|
+
let carry2 = BASE_MAP[charCode];
|
|
40910
|
+
if (carry2 === 255) {
|
|
40911
|
+
return;
|
|
40912
|
+
}
|
|
40913
|
+
let i = 0;
|
|
40914
|
+
for (let it3 = size5 - 1; (carry2 !== 0 || i < length) && it3 !== -1; it3--, i++) {
|
|
40915
|
+
carry2 += BASE * b256[it3] >>> 0;
|
|
40916
|
+
b256[it3] = carry2 % 256 >>> 0;
|
|
40917
|
+
carry2 = carry2 / 256 >>> 0;
|
|
40918
|
+
}
|
|
40919
|
+
if (carry2 !== 0) {
|
|
40920
|
+
throw new Error("Non-zero carry");
|
|
40921
|
+
}
|
|
40922
|
+
length = i;
|
|
40923
|
+
psz++;
|
|
40924
|
+
}
|
|
40925
|
+
let it4 = size5 - length;
|
|
40926
|
+
while (it4 !== size5 && b256[it4] === 0) {
|
|
40927
|
+
it4++;
|
|
40928
|
+
}
|
|
40929
|
+
const vch = new Uint8Array(zeroes + (size5 - it4));
|
|
40930
|
+
let j = zeroes;
|
|
40931
|
+
while (it4 !== size5) {
|
|
40932
|
+
vch[j++] = b256[it4++];
|
|
40933
|
+
}
|
|
40934
|
+
return vch;
|
|
40935
|
+
}
|
|
40936
|
+
function decode4(string) {
|
|
40937
|
+
const buffer2 = decodeUnsafe(string);
|
|
40938
|
+
if (buffer2) {
|
|
40939
|
+
return buffer2;
|
|
40940
|
+
}
|
|
40941
|
+
throw new Error("Non-base" + BASE + " character");
|
|
40942
|
+
}
|
|
40943
|
+
return {
|
|
40944
|
+
encode: encode9,
|
|
40945
|
+
decodeUnsafe,
|
|
40946
|
+
decode: decode4
|
|
40947
|
+
};
|
|
40948
|
+
}
|
|
40949
|
+
var esm_default;
|
|
40950
|
+
var init_esm6 = __esm({
|
|
40951
|
+
"node_modules/base-x/src/esm/index.js"() {
|
|
40952
|
+
"use strict";
|
|
40953
|
+
esm_default = base2;
|
|
40954
|
+
}
|
|
40955
|
+
});
|
|
40956
|
+
|
|
40957
|
+
// node_modules/bs58/src/esm/index.js
|
|
40958
|
+
var ALPHABET, esm_default2;
|
|
40959
|
+
var init_esm7 = __esm({
|
|
40960
|
+
"node_modules/bs58/src/esm/index.js"() {
|
|
40961
|
+
"use strict";
|
|
40962
|
+
init_esm6();
|
|
40963
|
+
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
40964
|
+
esm_default2 = esm_default(ALPHABET);
|
|
40965
|
+
}
|
|
40966
|
+
});
|
|
40967
|
+
|
|
40752
40968
|
// node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
|
|
40753
40969
|
function isBytes7(a) {
|
|
40754
40970
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
@@ -41917,15 +42133,15 @@ var init_curve3 = __esm({
|
|
|
41917
42133
|
const { windows, windowSize } = calcWOpts3(W, this.bits);
|
|
41918
42134
|
const points = [];
|
|
41919
42135
|
let p = point3;
|
|
41920
|
-
let
|
|
42136
|
+
let base4 = p;
|
|
41921
42137
|
for (let window2 = 0; window2 < windows; window2++) {
|
|
41922
|
-
|
|
41923
|
-
points.push(
|
|
42138
|
+
base4 = p;
|
|
42139
|
+
points.push(base4);
|
|
41924
42140
|
for (let i = 1; i < windowSize; i++) {
|
|
41925
|
-
|
|
41926
|
-
points.push(
|
|
42141
|
+
base4 = base4.add(p);
|
|
42142
|
+
points.push(base4);
|
|
41927
42143
|
}
|
|
41928
|
-
p =
|
|
42144
|
+
p = base4.double();
|
|
41929
42145
|
}
|
|
41930
42146
|
return points;
|
|
41931
42147
|
}
|
|
@@ -44973,6 +45189,37 @@ var init_sha26 = __esm({
|
|
|
44973
45189
|
}
|
|
44974
45190
|
});
|
|
44975
45191
|
|
|
45192
|
+
// src/solana-key.ts
|
|
45193
|
+
function deriveSolanaKeyBytes(mnemonic) {
|
|
45194
|
+
const seed = mnemonicToSeedSync(mnemonic);
|
|
45195
|
+
let digest = hmac6(sha5123, new TextEncoder().encode("ed25519 seed"), seed);
|
|
45196
|
+
let key2 = digest.slice(0, 32);
|
|
45197
|
+
let chainCode = digest.slice(32);
|
|
45198
|
+
for (const index2 of SOLANA_HARDENED_INDICES) {
|
|
45199
|
+
const data = new Uint8Array(37);
|
|
45200
|
+
data[0] = 0;
|
|
45201
|
+
data.set(key2, 1);
|
|
45202
|
+
data[33] = index2 >>> 24 & 255;
|
|
45203
|
+
data[34] = index2 >>> 16 & 255;
|
|
45204
|
+
data[35] = index2 >>> 8 & 255;
|
|
45205
|
+
data[36] = index2 & 255;
|
|
45206
|
+
digest = hmac6(sha5123, chainCode, data);
|
|
45207
|
+
key2 = digest.slice(0, 32);
|
|
45208
|
+
chainCode = digest.slice(32);
|
|
45209
|
+
}
|
|
45210
|
+
return new Uint8Array(key2);
|
|
45211
|
+
}
|
|
45212
|
+
var SOLANA_HARDENED_INDICES;
|
|
45213
|
+
var init_solana_key = __esm({
|
|
45214
|
+
"src/solana-key.ts"() {
|
|
45215
|
+
"use strict";
|
|
45216
|
+
init_hmac6();
|
|
45217
|
+
init_sha26();
|
|
45218
|
+
init_esm3();
|
|
45219
|
+
SOLANA_HARDENED_INDICES = [44 + 2147483648, 501 + 2147483648, 0 + 2147483648, 0 + 2147483648];
|
|
45220
|
+
}
|
|
45221
|
+
});
|
|
45222
|
+
|
|
44976
45223
|
// node_modules/@solana/errors/dist/index.node.mjs
|
|
44977
45224
|
function encodeValue(value) {
|
|
44978
45225
|
if (Array.isArray(value)) {
|
|
@@ -46414,20 +46661,20 @@ function partitionLeadingZeroes(value, zeroCharacter) {
|
|
|
46414
46661
|
return [leadingZeros, tailChars];
|
|
46415
46662
|
}
|
|
46416
46663
|
function getBigIntFromBaseX(value, alphabet4) {
|
|
46417
|
-
const
|
|
46664
|
+
const base4 = BigInt(alphabet4.length);
|
|
46418
46665
|
let sum = 0n;
|
|
46419
46666
|
for (const char of value) {
|
|
46420
|
-
sum *=
|
|
46667
|
+
sum *= base4;
|
|
46421
46668
|
sum += BigInt(alphabet4.indexOf(char));
|
|
46422
46669
|
}
|
|
46423
46670
|
return sum;
|
|
46424
46671
|
}
|
|
46425
46672
|
function getBaseXFromBigInt(value, alphabet4) {
|
|
46426
|
-
const
|
|
46673
|
+
const base4 = BigInt(alphabet4.length);
|
|
46427
46674
|
const tailChars = [];
|
|
46428
46675
|
while (value > 0n) {
|
|
46429
|
-
tailChars.unshift(alphabet4[Number(value %
|
|
46430
|
-
value /=
|
|
46676
|
+
tailChars.unshift(alphabet4[Number(value % base4)]);
|
|
46677
|
+
value /= base4;
|
|
46431
46678
|
}
|
|
46432
46679
|
return tailChars.join("");
|
|
46433
46680
|
}
|
|
@@ -48474,20 +48721,20 @@ function partitionLeadingZeroes2(value, zeroCharacter) {
|
|
|
48474
48721
|
return [leadingZeros, tailChars];
|
|
48475
48722
|
}
|
|
48476
48723
|
function getBigIntFromBaseX2(value, alphabet4) {
|
|
48477
|
-
const
|
|
48724
|
+
const base4 = BigInt(alphabet4.length);
|
|
48478
48725
|
let sum = 0n;
|
|
48479
48726
|
for (const char of value) {
|
|
48480
|
-
sum *=
|
|
48727
|
+
sum *= base4;
|
|
48481
48728
|
sum += BigInt(alphabet4.indexOf(char));
|
|
48482
48729
|
}
|
|
48483
48730
|
return sum;
|
|
48484
48731
|
}
|
|
48485
48732
|
function getBaseXFromBigInt2(value, alphabet4) {
|
|
48486
|
-
const
|
|
48733
|
+
const base4 = BigInt(alphabet4.length);
|
|
48487
48734
|
const tailChars = [];
|
|
48488
48735
|
while (value > 0n) {
|
|
48489
|
-
tailChars.unshift(alphabet4[Number(value %
|
|
48490
|
-
value /=
|
|
48736
|
+
tailChars.unshift(alphabet4[Number(value % base4)]);
|
|
48737
|
+
value /= base4;
|
|
48491
48738
|
}
|
|
48492
48739
|
return tailChars.join("");
|
|
48493
48740
|
}
|
|
@@ -59265,25 +59512,6 @@ function deriveEvmKey(mnemonic) {
|
|
|
59265
59512
|
const account = privateKeyToAccount(hex);
|
|
59266
59513
|
return { privateKey: hex, address: account.address };
|
|
59267
59514
|
}
|
|
59268
|
-
function deriveSolanaKeyBytes(mnemonic) {
|
|
59269
|
-
const seed = mnemonicToSeedSync(mnemonic);
|
|
59270
|
-
let I = hmac6(sha5123, new TextEncoder().encode("ed25519 seed"), seed);
|
|
59271
|
-
let key2 = I.slice(0, 32);
|
|
59272
|
-
let chainCode = I.slice(32);
|
|
59273
|
-
for (const index2 of SOLANA_HARDENED_INDICES) {
|
|
59274
|
-
const data = new Uint8Array(37);
|
|
59275
|
-
data[0] = 0;
|
|
59276
|
-
data.set(key2, 1);
|
|
59277
|
-
data[33] = index2 >>> 24 & 255;
|
|
59278
|
-
data[34] = index2 >>> 16 & 255;
|
|
59279
|
-
data[35] = index2 >>> 8 & 255;
|
|
59280
|
-
data[36] = index2 & 255;
|
|
59281
|
-
I = hmac6(sha5123, chainCode, data);
|
|
59282
|
-
key2 = I.slice(0, 32);
|
|
59283
|
-
chainCode = I.slice(32);
|
|
59284
|
-
}
|
|
59285
|
-
return new Uint8Array(key2);
|
|
59286
|
-
}
|
|
59287
59515
|
function deriveAllKeys(mnemonic) {
|
|
59288
59516
|
const { privateKey: evmPrivateKey, address: evmAddress } = deriveEvmKey(mnemonic);
|
|
59289
59517
|
const solanaPrivateKeyBytes = deriveSolanaKeyBytes(mnemonic);
|
|
@@ -59294,18 +59522,17 @@ async function getSolanaAddress(privateKeyBytes) {
|
|
|
59294
59522
|
const signer = await createKeyPairSignerFromPrivateKeyBytes2(privateKeyBytes);
|
|
59295
59523
|
return signer.address;
|
|
59296
59524
|
}
|
|
59297
|
-
var ETH_DERIVATION_PATH
|
|
59525
|
+
var ETH_DERIVATION_PATH;
|
|
59298
59526
|
var init_wallet2 = __esm({
|
|
59299
59527
|
"src/wallet.ts"() {
|
|
59300
59528
|
"use strict";
|
|
59301
59529
|
init_bip32();
|
|
59302
59530
|
init_esm3();
|
|
59303
59531
|
init_english();
|
|
59304
|
-
init_hmac6();
|
|
59305
|
-
init_sha26();
|
|
59306
59532
|
init_accounts();
|
|
59533
|
+
init_solana_key();
|
|
59534
|
+
init_solana_key();
|
|
59307
59535
|
ETH_DERIVATION_PATH = "m/44'/60'/0'/0/0";
|
|
59308
|
-
SOLANA_HARDENED_INDICES = [44 + 2147483648, 501 + 2147483648, 0 + 2147483648, 0 + 2147483648];
|
|
59309
59536
|
}
|
|
59310
59537
|
});
|
|
59311
59538
|
|
|
@@ -59313,15 +59540,21 @@ var init_wallet2 = __esm({
|
|
|
59313
59540
|
var auth_exports = {};
|
|
59314
59541
|
__export(auth_exports, {
|
|
59315
59542
|
CHAIN_FILE: () => CHAIN_FILE,
|
|
59543
|
+
CORE_CHAIN_FILE: () => CORE_CHAIN_FILE,
|
|
59544
|
+
CORE_SOLANA_WALLET_FILE: () => CORE_SOLANA_WALLET_FILE,
|
|
59545
|
+
CORE_WALLET_FILE: () => CORE_WALLET_FILE,
|
|
59316
59546
|
MNEMONIC_FILE: () => MNEMONIC_FILE,
|
|
59317
59547
|
WALLET_FILE: () => WALLET_FILE,
|
|
59318
59548
|
loadPaymentChain: () => loadPaymentChain,
|
|
59549
|
+
migrateLegacyWalletToCore: () => migrateLegacyWalletToCore,
|
|
59319
59550
|
recoverWalletFromMnemonic: () => recoverWalletFromMnemonic,
|
|
59551
|
+
resolveExistingWalletKey: () => resolveExistingWalletKey,
|
|
59320
59552
|
resolveOrGenerateWalletKey: () => resolveOrGenerateWalletKey,
|
|
59321
59553
|
resolvePaymentChain: () => resolvePaymentChain,
|
|
59322
59554
|
savePaymentChain: () => savePaymentChain,
|
|
59323
59555
|
setupSolana: () => setupSolana
|
|
59324
59556
|
});
|
|
59557
|
+
import { createPrivateKey, createPublicKey } from "crypto";
|
|
59325
59558
|
import { writeFile, mkdir as mkdir2 } from "fs/promises";
|
|
59326
59559
|
import { join as join7 } from "path";
|
|
59327
59560
|
import { homedir as homedir4 } from "os";
|
|
@@ -59376,7 +59609,67 @@ async function saveMnemonic(mnemonic) {
|
|
|
59376
59609
|
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
59377
59610
|
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
59378
59611
|
}
|
|
59379
|
-
async function
|
|
59612
|
+
async function migrateLegacyWalletToCore() {
|
|
59613
|
+
const migrated = { base: false, solana: false, chain: false };
|
|
59614
|
+
const [coreBase, coreSolana, coreChain] = await Promise.all([
|
|
59615
|
+
readExisting(CORE_WALLET_FILE),
|
|
59616
|
+
readExisting(CORE_SOLANA_WALLET_FILE),
|
|
59617
|
+
readExisting(CORE_CHAIN_FILE)
|
|
59618
|
+
]);
|
|
59619
|
+
if (coreBase === void 0) {
|
|
59620
|
+
const legacyBase = await loadSavedWallet();
|
|
59621
|
+
if (legacyBase) {
|
|
59622
|
+
migrated.base = await writeCoreFileIfMissing(CORE_WALLET_FILE, legacyBase + "\n");
|
|
59623
|
+
}
|
|
59624
|
+
}
|
|
59625
|
+
if (coreSolana === void 0) {
|
|
59626
|
+
const mnemonic = await loadMnemonic();
|
|
59627
|
+
if (mnemonic) {
|
|
59628
|
+
const secret = solanaSecretKeyFromSeed(deriveSolanaKeyBytes(mnemonic));
|
|
59629
|
+
migrated.solana = await writeCoreFileIfMissing(
|
|
59630
|
+
CORE_SOLANA_WALLET_FILE,
|
|
59631
|
+
JSON.stringify([...secret]) + "\n"
|
|
59632
|
+
);
|
|
59633
|
+
}
|
|
59634
|
+
}
|
|
59635
|
+
if (coreChain === void 0) {
|
|
59636
|
+
const legacyChain = await readOptional(CHAIN_FILE);
|
|
59637
|
+
if (legacyChain === "base" || legacyChain === "solana") {
|
|
59638
|
+
migrated.chain = await writeCoreFileIfMissing(CORE_CHAIN_FILE, legacyChain + "\n");
|
|
59639
|
+
}
|
|
59640
|
+
}
|
|
59641
|
+
if (migrated.base || migrated.solana || migrated.chain) {
|
|
59642
|
+
const parts = Object.entries(migrated).filter(([, changed]) => changed).map(([name]) => name).join(", ");
|
|
59643
|
+
console.log(`[ClawRouter] Migrated legacy ${parts} data to ${CORE_WALLET_DIR}`);
|
|
59644
|
+
}
|
|
59645
|
+
return migrated;
|
|
59646
|
+
}
|
|
59647
|
+
async function writeCoreFileIfMissing(path5, value) {
|
|
59648
|
+
await mkdir2(CORE_WALLET_DIR, { recursive: true });
|
|
59649
|
+
try {
|
|
59650
|
+
await writeFile(path5, value, { mode: 384, flag: "wx" });
|
|
59651
|
+
return true;
|
|
59652
|
+
} catch (error) {
|
|
59653
|
+
if (error.code === "EEXIST") return false;
|
|
59654
|
+
throw error;
|
|
59655
|
+
}
|
|
59656
|
+
}
|
|
59657
|
+
async function readExisting(path5) {
|
|
59658
|
+
try {
|
|
59659
|
+
return await readTextFile(path5);
|
|
59660
|
+
} catch (error) {
|
|
59661
|
+
if (error.code === "ENOENT") return void 0;
|
|
59662
|
+
throw error;
|
|
59663
|
+
}
|
|
59664
|
+
}
|
|
59665
|
+
function solanaSecretKeyFromSeed(seed) {
|
|
59666
|
+
const privateDer = Buffer.concat([Buffer.from("302e020100300506032b657004220420", "hex"), seed]);
|
|
59667
|
+
const publicDer = createPublicKey(
|
|
59668
|
+
createPrivateKey({ key: privateDer, format: "der", type: "pkcs8" })
|
|
59669
|
+
).export({ format: "der", type: "spki" });
|
|
59670
|
+
return Uint8Array.from([...seed, ...Buffer.from(publicDer).subarray(-32)]);
|
|
59671
|
+
}
|
|
59672
|
+
async function generateAndSaveWallet(existingCoreSolanaKey) {
|
|
59380
59673
|
const existingMnemonic = await loadMnemonic();
|
|
59381
59674
|
if (existingMnemonic) {
|
|
59382
59675
|
throw new Error(
|
|
@@ -59394,7 +59687,17 @@ Then run: npx @blockrun/clawrouter`
|
|
|
59394
59687
|
const derived = deriveAllKeys(mnemonic);
|
|
59395
59688
|
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
59396
59689
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
59397
|
-
|
|
59690
|
+
if (!existingCoreSolanaKey) {
|
|
59691
|
+
await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
|
|
59692
|
+
}
|
|
59693
|
+
await writeCoreFileIfMissing(CORE_WALLET_FILE, derived.evmPrivateKey + "\n");
|
|
59694
|
+
if (!existingCoreSolanaKey) {
|
|
59695
|
+
await writeCoreFileIfMissing(
|
|
59696
|
+
CORE_SOLANA_WALLET_FILE,
|
|
59697
|
+
JSON.stringify([...solanaSecretKeyFromSeed(derived.solanaPrivateKeyBytes)]) + "\n"
|
|
59698
|
+
);
|
|
59699
|
+
}
|
|
59700
|
+
const solanaPrivateKeyBytes = existingCoreSolanaKey ?? derived.solanaPrivateKeyBytes;
|
|
59398
59701
|
try {
|
|
59399
59702
|
const verification = (await readTextFile(WALLET_FILE)).trim();
|
|
59400
59703
|
if (verification !== derived.evmPrivateKey) {
|
|
@@ -59409,7 +59712,7 @@ Then run: npx @blockrun/clawrouter`
|
|
|
59409
59712
|
}
|
|
59410
59713
|
let solanaAddress;
|
|
59411
59714
|
try {
|
|
59412
|
-
solanaAddress = await getSolanaAddress(
|
|
59715
|
+
solanaAddress = await getSolanaAddress(solanaPrivateKeyBytes);
|
|
59413
59716
|
} catch {
|
|
59414
59717
|
}
|
|
59415
59718
|
let solanaDefaultSaved = false;
|
|
@@ -59428,8 +59731,11 @@ Then run: npx @blockrun/clawrouter`
|
|
|
59428
59731
|
if (solanaAddress) {
|
|
59429
59732
|
console.log(`[ClawRouter] Solana Address : ${solanaAddress}`);
|
|
59430
59733
|
}
|
|
59431
|
-
console.log(`[ClawRouter]
|
|
59432
|
-
console.log(`[ClawRouter]
|
|
59734
|
+
console.log(`[ClawRouter] Base key : ${CORE_WALLET_FILE}`);
|
|
59735
|
+
console.log(`[ClawRouter] Solana key : ${CORE_SOLANA_WALLET_FILE}`);
|
|
59736
|
+
if (!existingCoreSolanaKey) {
|
|
59737
|
+
console.log(`[ClawRouter] Recovery words : ${MNEMONIC_FILE}`);
|
|
59738
|
+
}
|
|
59433
59739
|
console.log(`[ClawRouter]`);
|
|
59434
59740
|
console.log(`[ClawRouter] Both EVM (Base) and Solana wallets are ready.`);
|
|
59435
59741
|
if (solanaDefaultSaved) {
|
|
@@ -59448,44 +59754,50 @@ Then run: npx @blockrun/clawrouter`
|
|
|
59448
59754
|
return {
|
|
59449
59755
|
key: derived.evmPrivateKey,
|
|
59450
59756
|
address: derived.evmAddress,
|
|
59451
|
-
mnemonic,
|
|
59452
|
-
solanaPrivateKeyBytes
|
|
59757
|
+
...existingCoreSolanaKey ? {} : { mnemonic },
|
|
59758
|
+
solanaPrivateKeyBytes
|
|
59453
59759
|
};
|
|
59454
59760
|
}
|
|
59455
|
-
async function
|
|
59761
|
+
async function resolveExistingWalletKey() {
|
|
59762
|
+
const coreSolanaKey = await loadCoreSolanaKeyForSelectedChain();
|
|
59763
|
+
const envKey = process["env"].BLOCKRUN_WALLET_KEY;
|
|
59764
|
+
if (typeof envKey === "string" && /^0x[0-9a-f]{64}$/i.test(envKey)) {
|
|
59765
|
+
const account = privateKeyToAccount(envKey);
|
|
59766
|
+
return {
|
|
59767
|
+
key: envKey,
|
|
59768
|
+
address: account.address,
|
|
59769
|
+
source: "env",
|
|
59770
|
+
...await resolvedSolanaMaterial(coreSolanaKey)
|
|
59771
|
+
};
|
|
59772
|
+
}
|
|
59773
|
+
const core = await loadCoreWallet();
|
|
59774
|
+
if (core) {
|
|
59775
|
+
const account = privateKeyToAccount(core);
|
|
59776
|
+
return {
|
|
59777
|
+
key: core,
|
|
59778
|
+
address: account.address,
|
|
59779
|
+
source: "core",
|
|
59780
|
+
...await resolvedSolanaMaterial(coreSolanaKey)
|
|
59781
|
+
};
|
|
59782
|
+
}
|
|
59456
59783
|
const saved = await loadSavedWallet();
|
|
59457
59784
|
if (saved) {
|
|
59458
59785
|
const account = privateKeyToAccount(saved);
|
|
59459
|
-
|
|
59460
|
-
|
|
59461
|
-
|
|
59462
|
-
|
|
59463
|
-
|
|
59464
|
-
|
|
59465
|
-
source: "saved",
|
|
59466
|
-
mnemonic,
|
|
59467
|
-
solanaPrivateKeyBytes: solanaKeyBytes
|
|
59468
|
-
};
|
|
59469
|
-
}
|
|
59470
|
-
return { key: saved, address: account.address, source: "saved" };
|
|
59471
|
-
}
|
|
59472
|
-
const envKey = process["env"].BLOCKRUN_WALLET_KEY;
|
|
59473
|
-
if (typeof envKey === "string" && envKey.startsWith("0x") && envKey.length === 66) {
|
|
59474
|
-
const account = privateKeyToAccount(envKey);
|
|
59475
|
-
const mnemonic = await loadMnemonic();
|
|
59476
|
-
if (mnemonic) {
|
|
59477
|
-
const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
|
|
59478
|
-
return {
|
|
59479
|
-
key: envKey,
|
|
59480
|
-
address: account.address,
|
|
59481
|
-
source: "env",
|
|
59482
|
-
mnemonic,
|
|
59483
|
-
solanaPrivateKeyBytes: solanaKeyBytes
|
|
59484
|
-
};
|
|
59485
|
-
}
|
|
59486
|
-
return { key: envKey, address: account.address, source: "env" };
|
|
59786
|
+
return {
|
|
59787
|
+
key: saved,
|
|
59788
|
+
address: account.address,
|
|
59789
|
+
source: "saved",
|
|
59790
|
+
...await resolvedSolanaMaterial(coreSolanaKey)
|
|
59791
|
+
};
|
|
59487
59792
|
}
|
|
59488
|
-
|
|
59793
|
+
return void 0;
|
|
59794
|
+
}
|
|
59795
|
+
async function resolveOrGenerateWalletKey() {
|
|
59796
|
+
await migrateLegacyWalletToCore();
|
|
59797
|
+
const existing = await resolveExistingWalletKey();
|
|
59798
|
+
if (existing) return existing;
|
|
59799
|
+
const existingCoreSolanaKey = await loadCoreSolanaKey();
|
|
59800
|
+
const result = await generateAndSaveWallet(existingCoreSolanaKey);
|
|
59489
59801
|
return {
|
|
59490
59802
|
key: result.key,
|
|
59491
59803
|
address: result.address,
|
|
@@ -59494,6 +59806,62 @@ async function resolveOrGenerateWalletKey() {
|
|
|
59494
59806
|
solanaPrivateKeyBytes: result.solanaPrivateKeyBytes
|
|
59495
59807
|
};
|
|
59496
59808
|
}
|
|
59809
|
+
async function loadCoreSolanaKeyForSelectedChain() {
|
|
59810
|
+
try {
|
|
59811
|
+
return await loadCoreSolanaKey();
|
|
59812
|
+
} catch (error) {
|
|
59813
|
+
if (await resolvePaymentChain() === "solana") throw error;
|
|
59814
|
+
return void 0;
|
|
59815
|
+
}
|
|
59816
|
+
}
|
|
59817
|
+
async function loadCoreWallet() {
|
|
59818
|
+
const key2 = (await readExisting(CORE_WALLET_FILE))?.trim();
|
|
59819
|
+
if (key2 === void 0) return void 0;
|
|
59820
|
+
if (/^0x[0-9a-f]{64}$/i.test(key2)) return key2;
|
|
59821
|
+
throw new Error(
|
|
59822
|
+
`BlockRun Core wallet at ${CORE_WALLET_FILE} has an invalid format. Refusing to use another wallet implicitly.`
|
|
59823
|
+
);
|
|
59824
|
+
}
|
|
59825
|
+
async function loadCoreSolanaKey() {
|
|
59826
|
+
const environmentKey = process["env"].SOLANA_WALLET_KEY?.trim();
|
|
59827
|
+
const raw = environmentKey || (await readExisting(CORE_SOLANA_WALLET_FILE))?.trim();
|
|
59828
|
+
if (!raw) return void 0;
|
|
59829
|
+
try {
|
|
59830
|
+
let bytes;
|
|
59831
|
+
if (raw.startsWith("[")) {
|
|
59832
|
+
const parsed = JSON.parse(raw);
|
|
59833
|
+
if (!Array.isArray(parsed) || !parsed.every((item) => Number.isInteger(item) && item >= 0 && item <= 255))
|
|
59834
|
+
throw new Error("expected an array of byte values");
|
|
59835
|
+
bytes = Uint8Array.from(parsed);
|
|
59836
|
+
} else {
|
|
59837
|
+
const hex = raw.replace(/^0x/i, "");
|
|
59838
|
+
bytes = /^[0-9a-f]{128}$/i.test(hex) ? Buffer.from(hex, "hex") : esm_default2.decode(raw);
|
|
59839
|
+
}
|
|
59840
|
+
if (bytes.length !== 64) throw new Error(`expected 64 bytes, received ${bytes.length}`);
|
|
59841
|
+
const expected = solanaSecretKeyFromSeed(bytes.slice(0, 32));
|
|
59842
|
+
if (!Buffer.from(expected).equals(Buffer.from(bytes))) {
|
|
59843
|
+
throw new Error("public key does not match the private seed");
|
|
59844
|
+
}
|
|
59845
|
+
return bytes.slice(0, 32);
|
|
59846
|
+
} catch (error) {
|
|
59847
|
+
throw new Error(
|
|
59848
|
+
`BlockRun Core Solana wallet has an invalid format: ${error instanceof Error ? error.message : String(error)}`,
|
|
59849
|
+
{ cause: error }
|
|
59850
|
+
);
|
|
59851
|
+
}
|
|
59852
|
+
}
|
|
59853
|
+
async function readOptional(path5) {
|
|
59854
|
+
try {
|
|
59855
|
+
return (await readTextFile(path5)).trim() || void 0;
|
|
59856
|
+
} catch {
|
|
59857
|
+
return void 0;
|
|
59858
|
+
}
|
|
59859
|
+
}
|
|
59860
|
+
async function resolvedSolanaMaterial(coreSolanaKey) {
|
|
59861
|
+
if (coreSolanaKey) return { solanaPrivateKeyBytes: coreSolanaKey };
|
|
59862
|
+
const mnemonic = await loadMnemonic();
|
|
59863
|
+
return mnemonic ? { mnemonic, solanaPrivateKeyBytes: deriveSolanaKeyBytes(mnemonic) } : {};
|
|
59864
|
+
}
|
|
59497
59865
|
async function recoverWalletFromMnemonic() {
|
|
59498
59866
|
const mnemonic = await loadMnemonic();
|
|
59499
59867
|
if (!mnemonic) {
|
|
@@ -59501,6 +59869,12 @@ async function recoverWalletFromMnemonic() {
|
|
|
59501
59869
|
console.error(`[ClawRouter] Cannot recover \u2014 no mnemonic to derive from.`);
|
|
59502
59870
|
process.exit(1);
|
|
59503
59871
|
}
|
|
59872
|
+
const existingCore = await loadCoreWallet();
|
|
59873
|
+
if (existingCore) {
|
|
59874
|
+
console.error(`[ClawRouter] BlockRun Core wallet already exists at ${CORE_WALLET_FILE}`);
|
|
59875
|
+
console.error(`[ClawRouter] Recovery not needed.`);
|
|
59876
|
+
process.exit(1);
|
|
59877
|
+
}
|
|
59504
59878
|
const existing = await loadSavedWallet().catch(() => void 0);
|
|
59505
59879
|
if (existing) {
|
|
59506
59880
|
console.error(`[ClawRouter] wallet.key already exists at ${WALLET_FILE}`);
|
|
@@ -59527,7 +59901,8 @@ async function recoverWalletFromMnemonic() {
|
|
|
59527
59901
|
console.log(`[ClawRouter]`);
|
|
59528
59902
|
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
59529
59903
|
await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
|
|
59530
|
-
|
|
59904
|
+
await migrateLegacyWalletToCore();
|
|
59905
|
+
console.log(`[ClawRouter] \u2713 Wallet restored into BlockRun Core at ${CORE_WALLET_DIR}`);
|
|
59531
59906
|
console.log(`[ClawRouter] Run: npx @blockrun/clawrouter`);
|
|
59532
59907
|
console.log(`[ClawRouter]`);
|
|
59533
59908
|
}
|
|
@@ -59536,8 +59911,8 @@ async function setupSolana() {
|
|
|
59536
59911
|
if (existing) {
|
|
59537
59912
|
throw new Error("Solana wallet already set up. Mnemonic file exists at " + MNEMONIC_FILE);
|
|
59538
59913
|
}
|
|
59539
|
-
const
|
|
59540
|
-
if (!
|
|
59914
|
+
const evmKey = await loadCoreWallet() ?? await loadSavedWallet();
|
|
59915
|
+
if (!evmKey) {
|
|
59541
59916
|
throw new Error(
|
|
59542
59917
|
"No EVM wallet found. Run ClawRouter first to generate a wallet before setting up Solana."
|
|
59543
59918
|
);
|
|
@@ -59545,16 +59920,28 @@ async function setupSolana() {
|
|
|
59545
59920
|
const mnemonic = generateWalletMnemonic();
|
|
59546
59921
|
const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
|
|
59547
59922
|
await saveMnemonic(mnemonic);
|
|
59923
|
+
await writeCoreFileIfMissing(
|
|
59924
|
+
CORE_SOLANA_WALLET_FILE,
|
|
59925
|
+
JSON.stringify([...solanaSecretKeyFromSeed(solanaKeyBytes)]) + "\n"
|
|
59926
|
+
);
|
|
59548
59927
|
console.log(`[ClawRouter] Solana wallet set up successfully.`);
|
|
59549
|
-
console.log(`[ClawRouter]
|
|
59928
|
+
console.log(`[ClawRouter] Solana key saved to ${CORE_SOLANA_WALLET_FILE}`);
|
|
59929
|
+
console.log(`[ClawRouter] Recovery mnemonic saved to ${MNEMONIC_FILE}`);
|
|
59550
59930
|
console.log(`[ClawRouter] Existing EVM wallet unchanged.`);
|
|
59551
59931
|
return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
|
|
59552
59932
|
}
|
|
59553
59933
|
async function savePaymentChain(chain3) {
|
|
59554
59934
|
await mkdir2(WALLET_DIR2, { recursive: true });
|
|
59555
|
-
await
|
|
59935
|
+
await mkdir2(CORE_WALLET_DIR, { recursive: true });
|
|
59936
|
+
await Promise.all([
|
|
59937
|
+
writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 }),
|
|
59938
|
+
writeFile(CORE_CHAIN_FILE, chain3 + "\n", { mode: 384 })
|
|
59939
|
+
]);
|
|
59556
59940
|
}
|
|
59557
59941
|
async function loadPaymentChain() {
|
|
59942
|
+
const core = await readOptional(CORE_CHAIN_FILE);
|
|
59943
|
+
if (core === "solana") return "solana";
|
|
59944
|
+
if (core === "base") return "base";
|
|
59558
59945
|
try {
|
|
59559
59946
|
const content = (await readTextFile(CHAIN_FILE)).trim();
|
|
59560
59947
|
if (content === "solana") return "solana";
|
|
@@ -59568,17 +59955,22 @@ async function resolvePaymentChain() {
|
|
|
59568
59955
|
if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
|
|
59569
59956
|
return loadPaymentChain();
|
|
59570
59957
|
}
|
|
59571
|
-
var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
|
|
59958
|
+
var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE, CORE_WALLET_DIR, CORE_WALLET_FILE, CORE_SOLANA_WALLET_FILE, CORE_CHAIN_FILE;
|
|
59572
59959
|
var init_auth = __esm({
|
|
59573
59960
|
"src/auth.ts"() {
|
|
59574
59961
|
"use strict";
|
|
59575
59962
|
init_fs_read();
|
|
59963
|
+
init_esm7();
|
|
59576
59964
|
init_accounts();
|
|
59577
59965
|
init_wallet2();
|
|
59578
59966
|
WALLET_DIR2 = join7(homedir4(), ".openclaw", "blockrun");
|
|
59579
59967
|
WALLET_FILE = join7(WALLET_DIR2, "wallet.key");
|
|
59580
59968
|
MNEMONIC_FILE = join7(WALLET_DIR2, "mnemonic");
|
|
59581
59969
|
CHAIN_FILE = join7(WALLET_DIR2, "payment-chain");
|
|
59970
|
+
CORE_WALLET_DIR = join7(homedir4(), ".blockrun");
|
|
59971
|
+
CORE_WALLET_FILE = join7(CORE_WALLET_DIR, ".session");
|
|
59972
|
+
CORE_SOLANA_WALLET_FILE = join7(CORE_WALLET_DIR, ".solana-session");
|
|
59973
|
+
CORE_CHAIN_FILE = join7(CORE_WALLET_DIR, ".chain");
|
|
59582
59974
|
}
|
|
59583
59975
|
});
|
|
59584
59976
|
|
|
@@ -75731,7 +76123,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
75731
76123
|
"node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
75732
76124
|
"use strict";
|
|
75733
76125
|
var { writeFile: writeFile3, readFile: readFile3, mkdir: mkdir5 } = __require("fs/promises");
|
|
75734
|
-
var { dirname:
|
|
76126
|
+
var { dirname: dirname4, resolve } = __require("path");
|
|
75735
76127
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
|
|
75736
76128
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
75737
76129
|
var { hashId, isUrlExcludedFactory, normalizeHeaders: normalizeHeaders3, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -75977,7 +76369,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
75977
76369
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
75978
76370
|
}
|
|
75979
76371
|
const resolvedPath = resolve(path5);
|
|
75980
|
-
await mkdir5(
|
|
76372
|
+
await mkdir5(dirname4(resolvedPath), { recursive: true });
|
|
75981
76373
|
const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
|
|
75982
76374
|
hash: hash5,
|
|
75983
76375
|
snapshot
|
|
@@ -90053,6 +90445,7 @@ var init_client3 = __esm({
|
|
|
90053
90445
|
|
|
90054
90446
|
// src/proxy.ts
|
|
90055
90447
|
import { AsyncLocalStorage } from "async_hooks";
|
|
90448
|
+
import { createHmac } from "crypto";
|
|
90056
90449
|
import { createServer } from "http";
|
|
90057
90450
|
import { finished } from "stream";
|
|
90058
90451
|
import { homedir as homedir7 } from "os";
|
|
@@ -90678,12 +91071,25 @@ function buildProxyModelList(createdAt = Math.floor(Date.now() / 1e3)) {
|
|
|
90678
91071
|
if (seen.has(model.id)) return false;
|
|
90679
91072
|
seen.add(model.id);
|
|
90680
91073
|
return true;
|
|
90681
|
-
}).map((model) =>
|
|
90682
|
-
id
|
|
90683
|
-
|
|
90684
|
-
|
|
90685
|
-
|
|
90686
|
-
|
|
91074
|
+
}).map((model) => {
|
|
91075
|
+
const targetId = MODEL_ALIASES[model.id] ?? model.id;
|
|
91076
|
+
const canonical = BLOCKRUN_MODELS.find((entry) => entry.id === targetId);
|
|
91077
|
+
return {
|
|
91078
|
+
id: model.id,
|
|
91079
|
+
object: "model",
|
|
91080
|
+
created: createdAt,
|
|
91081
|
+
owned_by: targetId.includes("/") ? targetId.split("/")[0] ?? "blockrun" : "blockrun",
|
|
91082
|
+
name: model.name,
|
|
91083
|
+
context_window: model.contextWindow,
|
|
91084
|
+
max_output: model.maxTokens,
|
|
91085
|
+
input_price: model.cost.input,
|
|
91086
|
+
output_price: model.cost.output,
|
|
91087
|
+
reasoning: model.reasoning,
|
|
91088
|
+
vision: model.input.includes("image"),
|
|
91089
|
+
agentic: canonical?.agentic ?? false,
|
|
91090
|
+
tool_calling: canonical?.toolCalling ?? false
|
|
91091
|
+
};
|
|
91092
|
+
});
|
|
90687
91093
|
}
|
|
90688
91094
|
function mergeRoutingConfig(overrides) {
|
|
90689
91095
|
if (!overrides) return DEFAULT_ROUTING_CONFIG;
|
|
@@ -90923,7 +91329,7 @@ async function startProxy(options) {
|
|
|
90923
91329
|
}
|
|
90924
91330
|
void loadGatewayCatalog(apiBase);
|
|
90925
91331
|
const listenPort = options.port ?? getProxyPort();
|
|
90926
|
-
const existingProxy = await checkExistingProxy(listenPort);
|
|
91332
|
+
const existingProxy = options.allowExistingProxy === false ? void 0 : await checkExistingProxy(listenPort);
|
|
90927
91333
|
if (existingProxy) {
|
|
90928
91334
|
const account2 = privateKeyToAccount(walletKey);
|
|
90929
91335
|
const baseUrl2 = `http://127.0.0.1:${listenPort}`;
|
|
@@ -91078,7 +91484,22 @@ async function startProxy(options) {
|
|
|
91078
91484
|
response.balanceError = "Could not fetch balance";
|
|
91079
91485
|
}
|
|
91080
91486
|
}
|
|
91081
|
-
|
|
91487
|
+
const headers = {
|
|
91488
|
+
"Content-Type": "application/json",
|
|
91489
|
+
"Cache-Control": "no-store"
|
|
91490
|
+
};
|
|
91491
|
+
const challengeValue = req.headers["x-clawrouter-challenge"];
|
|
91492
|
+
const challenge2 = Array.isArray(challengeValue) ? challengeValue[0] : challengeValue;
|
|
91493
|
+
if (challenge2 && /^[a-f0-9]{64}$/i.test(challenge2)) {
|
|
91494
|
+
try {
|
|
91495
|
+
const token = readFileSync2(DESKTOP_SERVICE_TOKEN_FILE, "utf8").trim();
|
|
91496
|
+
if (/^[a-f0-9]{64}$/i.test(token)) {
|
|
91497
|
+
headers["X-ClawRouter-Proof"] = createHmac("sha256", token).update(challenge2).digest("hex");
|
|
91498
|
+
}
|
|
91499
|
+
} catch {
|
|
91500
|
+
}
|
|
91501
|
+
}
|
|
91502
|
+
res.writeHead(200, headers);
|
|
91082
91503
|
res.end(JSON.stringify(response));
|
|
91083
91504
|
return;
|
|
91084
91505
|
}
|
|
@@ -91947,6 +92368,10 @@ async function startProxy(options) {
|
|
|
91947
92368
|
const onError = async (err) => {
|
|
91948
92369
|
server.removeListener("error", onError);
|
|
91949
92370
|
if (err.code === "EADDRINUSE") {
|
|
92371
|
+
if (options.allowExistingProxy === false) {
|
|
92372
|
+
rejectAttempt(err);
|
|
92373
|
+
return;
|
|
92374
|
+
}
|
|
91950
92375
|
const existingProxy2 = await checkExistingProxy(listenPort);
|
|
91951
92376
|
if (existingProxy2) {
|
|
91952
92377
|
console.log(`[ClawRouter] Existing proxy detected on port ${listenPort}, reusing`);
|
|
@@ -94351,7 +94776,7 @@ data: [DONE]
|
|
|
94351
94776
|
});
|
|
94352
94777
|
}
|
|
94353
94778
|
}
|
|
94354
|
-
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, gatewayModelIds, FREE_MODEL, FREE_UPSTREAM_OVERRIDES, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, GATEWAY_CATALOG_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
94779
|
+
var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, DESKTOP_SERVICE_TOKEN_FILE, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, gatewayModelIds, FREE_MODEL, FREE_UPSTREAM_OVERRIDES, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, GATEWAY_CATALOG_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
|
|
94355
94780
|
var init_proxy = __esm({
|
|
94356
94781
|
"src/proxy.ts"() {
|
|
94357
94782
|
"use strict";
|
|
@@ -94389,6 +94814,7 @@ var init_proxy = __esm({
|
|
|
94389
94814
|
paymentStore = new AsyncLocalStorage();
|
|
94390
94815
|
BLOCKRUN_API = "https://blockrun.ai/api";
|
|
94391
94816
|
BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
|
|
94817
|
+
DESKTOP_SERVICE_TOKEN_FILE = process.env.CLAWROUTER_DESKTOP_TOKEN_FILE ?? join10(homedir7(), ".clawrouter-desktop", "service-token");
|
|
94392
94818
|
IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
|
|
94393
94819
|
AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
|
|
94394
94820
|
VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
|
|
@@ -95597,6 +96023,210 @@ var init_partners = __esm({
|
|
|
95597
96023
|
}
|
|
95598
96024
|
});
|
|
95599
96025
|
|
|
96026
|
+
// src/commands/policy.ts
|
|
96027
|
+
function unsetMeaning(key2) {
|
|
96028
|
+
switch (key2) {
|
|
96029
|
+
case "allowedPayees":
|
|
96030
|
+
return "every payee is permitted";
|
|
96031
|
+
case "allowedNetworks":
|
|
96032
|
+
return "every network is permitted";
|
|
96033
|
+
case "allowedAssets":
|
|
96034
|
+
return "every asset is permitted";
|
|
96035
|
+
case "blockedPayees":
|
|
96036
|
+
return "no payee is blocked";
|
|
96037
|
+
default:
|
|
96038
|
+
return `spend in the ${key2} window is uncapped`;
|
|
96039
|
+
}
|
|
96040
|
+
}
|
|
96041
|
+
function fail(text) {
|
|
96042
|
+
return { text, isError: true };
|
|
96043
|
+
}
|
|
96044
|
+
function isPolicyList2(v) {
|
|
96045
|
+
return POLICY_LISTS.includes(v);
|
|
96046
|
+
}
|
|
96047
|
+
function isSpendWindow(v) {
|
|
96048
|
+
return SPEND_WINDOWS.includes(v);
|
|
96049
|
+
}
|
|
96050
|
+
function isListAction(v) {
|
|
96051
|
+
return LIST_ACTIONS.includes(v);
|
|
96052
|
+
}
|
|
96053
|
+
function rejectValue(list, value) {
|
|
96054
|
+
if (list === "allowedNetworks") {
|
|
96055
|
+
return PAYABLE_NETWORKS.includes(value) ? void 0 : `"${value}" is not a network the proxy can pay on \u2014 allowedNetworks accepts only ${CAIP2_BASE} (Base) or ${CAIP2_SOLANA_MAINNET} (Solana mainnet), not a nickname. Other CAIP-2 ids are well formed but cannot appear in a payment quote, so allowlisting one would only block payments`;
|
|
96056
|
+
}
|
|
96057
|
+
if (/^0x/i.test(value)) {
|
|
96058
|
+
return EVM_ADDRESS2.test(value) ? void 0 : `"${value}" starts with 0x but is not 0x followed by exactly 40 hex characters`;
|
|
96059
|
+
}
|
|
96060
|
+
return BASE58_ADDRESS.test(value) ? void 0 : `"${value}" is not an address \u2014 expected 0x plus 40 hex characters (Base) or a 32\u201344 character base58 id (Solana)`;
|
|
96061
|
+
}
|
|
96062
|
+
function parsePolicyArgs(argv) {
|
|
96063
|
+
const [sub = "", target = "", ...values] = argv;
|
|
96064
|
+
const action = sub.toLowerCase();
|
|
96065
|
+
if (action === "") return { kind: "show" };
|
|
96066
|
+
if (action === "limit") {
|
|
96067
|
+
if (!isSpendWindow(target)) {
|
|
96068
|
+
return fail(
|
|
96069
|
+
`Unknown window "${target}"; expected one of: ${SPEND_WINDOWS.join(", ")}
|
|
96070
|
+
${USAGE}`
|
|
96071
|
+
);
|
|
96072
|
+
}
|
|
96073
|
+
const raw = values[0];
|
|
96074
|
+
if (raw === void 0 || values.length !== 1) {
|
|
96075
|
+
return fail(`policy limit takes exactly one amount (or "clear")
|
|
96076
|
+
${USAGE}`);
|
|
96077
|
+
}
|
|
96078
|
+
if (raw === "clear") return { kind: "limit", window: target, usd: void 0 };
|
|
96079
|
+
const usd = Number(raw);
|
|
96080
|
+
if (!USD.test(raw) || !Number.isFinite(usd) || usd <= 0) {
|
|
96081
|
+
return fail(
|
|
96082
|
+
`Rejected amount "${raw}": must be a positive decimal USD value such as 0.10 or 5`
|
|
96083
|
+
);
|
|
96084
|
+
}
|
|
96085
|
+
return { kind: "limit", window: target, usd };
|
|
96086
|
+
}
|
|
96087
|
+
if (!isListAction(action)) return fail(`Unknown subcommand "${sub}"
|
|
96088
|
+
${USAGE}`);
|
|
96089
|
+
if (!isPolicyList2(target)) {
|
|
96090
|
+
return fail(`Unknown list "${target}"; expected one of: ${POLICY_LISTS.join(", ")}
|
|
96091
|
+
${USAGE}`);
|
|
96092
|
+
}
|
|
96093
|
+
if (action === "clear" ? values.length !== 0 : values.length === 0) {
|
|
96094
|
+
return fail(
|
|
96095
|
+
`policy ${action} <list> ${action === "clear" ? "takes no values" : "needs at least one value"}
|
|
96096
|
+
${USAGE}`
|
|
96097
|
+
);
|
|
96098
|
+
}
|
|
96099
|
+
for (const v of values) {
|
|
96100
|
+
const why = rejectValue(target, v);
|
|
96101
|
+
if (why !== void 0) return fail(`Rejected ${target} entry: ${why}`);
|
|
96102
|
+
}
|
|
96103
|
+
return { kind: "list", action, list: target, values };
|
|
96104
|
+
}
|
|
96105
|
+
function nextListValue(current, plan) {
|
|
96106
|
+
const have = current ?? [];
|
|
96107
|
+
const wanted = [...new Set(plan.values.map(normalizePayee))];
|
|
96108
|
+
switch (plan.action) {
|
|
96109
|
+
case "set":
|
|
96110
|
+
return { next: wanted };
|
|
96111
|
+
case "clear":
|
|
96112
|
+
return { next: void 0 };
|
|
96113
|
+
case "add":
|
|
96114
|
+
return { next: [.../* @__PURE__ */ new Set([...have, ...wanted])] };
|
|
96115
|
+
case "remove": {
|
|
96116
|
+
if (have.length === 0) return { reject: `${plan.list} is not configured; nothing to remove` };
|
|
96117
|
+
const missing = wanted.filter((v) => !have.includes(v));
|
|
96118
|
+
if (missing.length > 0) return { reject: `not in ${plan.list}: ${missing.join(", ")}` };
|
|
96119
|
+
const next = have.filter((v) => !wanted.includes(v));
|
|
96120
|
+
if (next.length === 0 && ALLOW_LISTS.includes(plan.list)) {
|
|
96121
|
+
return {
|
|
96122
|
+
reject: `removing the last ${plan.list} entry would unset the list, and then ${unsetMeaning(plan.list)}. Use "policy clear ${plan.list}" if that is what you want`
|
|
96123
|
+
};
|
|
96124
|
+
}
|
|
96125
|
+
return { next: next.length > 0 ? next : void 0 };
|
|
96126
|
+
}
|
|
96127
|
+
}
|
|
96128
|
+
}
|
|
96129
|
+
function formatPolicy(limits) {
|
|
96130
|
+
const lines = ["Spend limits (USD):"];
|
|
96131
|
+
for (const w of SPEND_WINDOWS) {
|
|
96132
|
+
const v = limits[w];
|
|
96133
|
+
lines.push(` ${w}: ${v === void 0 ? `(unset \u2014 ${unsetMeaning(w)})` : `$${v}`}`);
|
|
96134
|
+
}
|
|
96135
|
+
lines.push("Policy lists:");
|
|
96136
|
+
for (const l2 of POLICY_LISTS) {
|
|
96137
|
+
const v = limits[l2];
|
|
96138
|
+
lines.push(` ${l2}: ${v && v.length > 0 ? v.join(", ") : `(unset \u2014 ${unsetMeaning(l2)})`}`);
|
|
96139
|
+
}
|
|
96140
|
+
return lines.join("\n");
|
|
96141
|
+
}
|
|
96142
|
+
function runPolicyCommand(argv, options) {
|
|
96143
|
+
const plan = parsePolicyArgs(argv);
|
|
96144
|
+
if (!("kind" in plan)) return plan;
|
|
96145
|
+
const openControl = options?.openControl ?? (() => new SpendControl());
|
|
96146
|
+
const live = options?.liveControl?.();
|
|
96147
|
+
const control = live ?? openControl();
|
|
96148
|
+
const broken = control.getPolicyFileError();
|
|
96149
|
+
if (broken !== void 0) {
|
|
96150
|
+
return fail(`${broken}
|
|
96151
|
+
Nothing was written; repair or delete spending.json, then retry.`);
|
|
96152
|
+
}
|
|
96153
|
+
if (plan.kind === "show") return { text: formatPolicy(control.getLimits()) };
|
|
96154
|
+
const before = openControl().getLimits();
|
|
96155
|
+
const key2 = plan.kind === "limit" ? plan.window : plan.list;
|
|
96156
|
+
let expected;
|
|
96157
|
+
try {
|
|
96158
|
+
if (plan.kind === "limit") {
|
|
96159
|
+
expected = plan.usd;
|
|
96160
|
+
if (plan.usd === void 0) control.clearLimit(plan.window);
|
|
96161
|
+
else control.setLimit(plan.window, plan.usd);
|
|
96162
|
+
} else {
|
|
96163
|
+
const outcome = nextListValue(control.getLimits()[plan.list], plan);
|
|
96164
|
+
if ("reject" in outcome) return fail(`${outcome.reject}; nothing written`);
|
|
96165
|
+
expected = outcome.next;
|
|
96166
|
+
if (outcome.next === void 0) control.clearPolicy(plan.list);
|
|
96167
|
+
else control.setPolicy(plan.list, outcome.next);
|
|
96168
|
+
}
|
|
96169
|
+
} catch (err) {
|
|
96170
|
+
if (err instanceof SpendPolicyConflictError) {
|
|
96171
|
+
return fail(
|
|
96172
|
+
`${key2} was not written: another writer changed spending.json while this command ran, and replacing it would have dropped their change. Run "policy" to see what disk holds now, then retry`
|
|
96173
|
+
);
|
|
96174
|
+
}
|
|
96175
|
+
return fail(`Nothing was written: ${err instanceof Error ? err.message : String(err)}`);
|
|
96176
|
+
}
|
|
96177
|
+
const expectedAll = { ...before };
|
|
96178
|
+
if (expected === void 0) delete expectedAll[key2];
|
|
96179
|
+
else expectedAll[key2] = expected;
|
|
96180
|
+
const after = openControl().getLimits();
|
|
96181
|
+
const keys = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after), key2])];
|
|
96182
|
+
const drift = keys.filter((k) => JSON.stringify(after[k]) !== JSON.stringify(expectedAll[k]));
|
|
96183
|
+
if (drift.length > 0) {
|
|
96184
|
+
const show = (v) => v === void 0 ? "(unset)" : JSON.stringify(v);
|
|
96185
|
+
const detail = drift.map((k) => `${k} ${show(after[k])} vs ${show(expectedAll[k])}`).join("; ");
|
|
96186
|
+
return fail(
|
|
96187
|
+
`Write did not land cleanly \u2014 on disk vs expected: ${detail}. Another write may have raced this one; run "policy" to see what disk holds now`
|
|
96188
|
+
);
|
|
96189
|
+
}
|
|
96190
|
+
const headline = expected === void 0 ? `${key2} is now unset \u2014 ${unsetMeaning(key2)}.` : `${key2}: ${JSON.stringify(expected)}`;
|
|
96191
|
+
return {
|
|
96192
|
+
text: live ? `${headline}
|
|
96193
|
+
${APPLIED_LIVE}` : `${RESTART_REQUIRED}
|
|
96194
|
+
${headline}`
|
|
96195
|
+
};
|
|
96196
|
+
}
|
|
96197
|
+
function createPolicyCommand(options) {
|
|
96198
|
+
return {
|
|
96199
|
+
name: "policy",
|
|
96200
|
+
description: "Spend limits and counterparty policy \u2014 /policy [set|add|remove|clear <list> ...] [limit <window> <usd>|clear]",
|
|
96201
|
+
acceptsArgs: true,
|
|
96202
|
+
requireAuth: true,
|
|
96203
|
+
handler: async (ctx) => runPolicyCommand((ctx.args ?? "").trim().split(/\s+/).filter(Boolean), options)
|
|
96204
|
+
};
|
|
96205
|
+
}
|
|
96206
|
+
var SPEND_WINDOWS, USD, EVM_ADDRESS2, BASE58_ADDRESS, LIST_ACTIONS, ALLOW_LISTS, USAGE, RESTART_REQUIRED, APPLIED_LIVE;
|
|
96207
|
+
var init_policy = __esm({
|
|
96208
|
+
"src/commands/policy.ts"() {
|
|
96209
|
+
"use strict";
|
|
96210
|
+
init_spend_control();
|
|
96211
|
+
SPEND_WINDOWS = ["perRequest", "hourly", "daily", "session"];
|
|
96212
|
+
USD = /^\d+(\.\d+)?$/;
|
|
96213
|
+
EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/;
|
|
96214
|
+
BASE58_ADDRESS = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
96215
|
+
LIST_ACTIONS = ["set", "add", "remove", "clear"];
|
|
96216
|
+
ALLOW_LISTS = ["allowedPayees", "allowedNetworks", "allowedAssets"];
|
|
96217
|
+
USAGE = [
|
|
96218
|
+
"Usage:",
|
|
96219
|
+
" policy show limits and lists on disk",
|
|
96220
|
+
` policy set|add|remove <list> <v>... <list>: ${POLICY_LISTS.join(" | ")}`,
|
|
96221
|
+
" policy clear <list>",
|
|
96222
|
+
` policy limit <window> <usd>|clear <window>: ${SPEND_WINDOWS.join(" | ")}`,
|
|
96223
|
+
`Networks are CAIP-2 ids: ${CAIP2_BASE} (Base) or ${CAIP2_SOLANA_MAINNET} (Solana mainnet).`
|
|
96224
|
+
].join("\n");
|
|
96225
|
+
RESTART_REQUIRED = "NOT applied to a running proxy \u2014 it reads spending.json once at startup. Restart the proxy (or the OpenClaw gateway) for this to take effect.";
|
|
96226
|
+
APPLIED_LIVE = "Applied to the running proxy and saved to spending.json.";
|
|
96227
|
+
}
|
|
96228
|
+
});
|
|
96229
|
+
|
|
95600
96230
|
// src/provider.ts
|
|
95601
96231
|
function setActiveProxy(proxy) {
|
|
95602
96232
|
activeProxy = proxy;
|
|
@@ -95628,8 +96258,8 @@ var init_provider = __esm({
|
|
|
95628
96258
|
return buildProviderModels(`http://127.0.0.1:${port}/v1`);
|
|
95629
96259
|
},
|
|
95630
96260
|
// No auth required — the x402 proxy handles wallet-based payments internally.
|
|
95631
|
-
// The proxy
|
|
95632
|
-
//
|
|
96261
|
+
// The proxy uses the shared BlockRun Core wallet under ~/.blockrun, with
|
|
96262
|
+
// automatic non-destructive migration from older ClawRouter wallet files.
|
|
95633
96263
|
auth: []
|
|
95634
96264
|
};
|
|
95635
96265
|
}
|
|
@@ -109014,7 +109644,7 @@ var init_URLSearchParams = __esm({
|
|
|
109014
109644
|
|
|
109015
109645
|
// node_modules/axios/lib/platform/node/index.js
|
|
109016
109646
|
import crypto6 from "crypto";
|
|
109017
|
-
var ALPHA, DIGIT,
|
|
109647
|
+
var ALPHA, DIGIT, ALPHABET2, generateString, node_default;
|
|
109018
109648
|
var init_node2 = __esm({
|
|
109019
109649
|
"node_modules/axios/lib/platform/node/index.js"() {
|
|
109020
109650
|
"use strict";
|
|
@@ -109022,12 +109652,12 @@ var init_node2 = __esm({
|
|
|
109022
109652
|
init_FormData();
|
|
109023
109653
|
ALPHA = "abcdefghijklmnopqrstuvwxyz";
|
|
109024
109654
|
DIGIT = "0123456789";
|
|
109025
|
-
|
|
109655
|
+
ALPHABET2 = {
|
|
109026
109656
|
DIGIT,
|
|
109027
109657
|
ALPHA,
|
|
109028
109658
|
ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT
|
|
109029
109659
|
};
|
|
109030
|
-
generateString = (size5 = 16, alphabet4 =
|
|
109660
|
+
generateString = (size5 = 16, alphabet4 = ALPHABET2.ALPHA_DIGIT) => {
|
|
109031
109661
|
let str = "";
|
|
109032
109662
|
const { length } = alphabet4;
|
|
109033
109663
|
const randomValues = new Uint32Array(size5);
|
|
@@ -109044,7 +109674,7 @@ var init_node2 = __esm({
|
|
|
109044
109674
|
FormData: FormData_default,
|
|
109045
109675
|
Blob: typeof Blob !== "undefined" && Blob || null
|
|
109046
109676
|
},
|
|
109047
|
-
ALPHABET,
|
|
109677
|
+
ALPHABET: ALPHABET2,
|
|
109048
109678
|
generateString,
|
|
109049
109679
|
protocols: ["http", "https", "file", "data"]
|
|
109050
109680
|
};
|
|
@@ -111108,8 +111738,8 @@ var require_follow_redirects = __commonJS({
|
|
|
111108
111738
|
}
|
|
111109
111739
|
return parsed;
|
|
111110
111740
|
}
|
|
111111
|
-
function resolveUrl(relative,
|
|
111112
|
-
return useNativeURL ? new URL3(relative,
|
|
111741
|
+
function resolveUrl(relative, base4) {
|
|
111742
|
+
return useNativeURL ? new URL3(relative, base4) : parseUrl3(url2.resolve(base4, relative));
|
|
111113
111743
|
}
|
|
111114
111744
|
function validateUrl(input) {
|
|
111115
111745
|
if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
|
|
@@ -117920,7 +118550,7 @@ function __addDisposableResource(env, value, async) {
|
|
|
117920
118550
|
return value;
|
|
117921
118551
|
}
|
|
117922
118552
|
function __disposeResources(env) {
|
|
117923
|
-
function
|
|
118553
|
+
function fail2(e7) {
|
|
117924
118554
|
env.error = env.hasError ? new _SuppressedError(e7, env.error, "An error was suppressed during disposal.") : e7;
|
|
117925
118555
|
env.hasError = true;
|
|
117926
118556
|
}
|
|
@@ -117932,12 +118562,12 @@ function __disposeResources(env) {
|
|
|
117932
118562
|
if (r2.dispose) {
|
|
117933
118563
|
var result = r2.dispose.call(r2.value);
|
|
117934
118564
|
if (r2.async) return s3 |= 2, Promise.resolve(result).then(next, function(e7) {
|
|
117935
|
-
|
|
118565
|
+
fail2(e7);
|
|
117936
118566
|
return next();
|
|
117937
118567
|
});
|
|
117938
118568
|
} else s3 |= 1;
|
|
117939
118569
|
} catch (e7) {
|
|
117940
|
-
|
|
118570
|
+
fail2(e7);
|
|
117941
118571
|
}
|
|
117942
118572
|
}
|
|
117943
118573
|
if (s3 === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
@@ -125107,15 +125737,15 @@ var require_curve = __commonJS({
|
|
|
125107
125737
|
const { windows, windowSize } = calcWOpts4(W, bits);
|
|
125108
125738
|
const points = [];
|
|
125109
125739
|
let p = elm;
|
|
125110
|
-
let
|
|
125740
|
+
let base4 = p;
|
|
125111
125741
|
for (let window2 = 0; window2 < windows; window2++) {
|
|
125112
|
-
|
|
125113
|
-
points.push(
|
|
125742
|
+
base4 = p;
|
|
125743
|
+
points.push(base4);
|
|
125114
125744
|
for (let i = 1; i < windowSize; i++) {
|
|
125115
|
-
|
|
125116
|
-
points.push(
|
|
125745
|
+
base4 = base4.add(p);
|
|
125746
|
+
points.push(base4);
|
|
125117
125747
|
}
|
|
125118
|
-
p =
|
|
125748
|
+
p = base4.double();
|
|
125119
125749
|
}
|
|
125120
125750
|
return points;
|
|
125121
125751
|
},
|
|
@@ -127873,7 +128503,7 @@ var require_estimateFeesPerGas = __commonJS({
|
|
|
127873
128503
|
throw new fee_js_1.BaseFeeScalarError();
|
|
127874
128504
|
const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
|
|
127875
128505
|
const denominator = 10 ** decimals;
|
|
127876
|
-
const multiply = (
|
|
128506
|
+
const multiply = (base4) => base4 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
|
|
127877
128507
|
const block = block_ ? block_ : await (0, getAction_js_1.getAction)(client, getBlock_js_1.getBlock, "getBlock")({});
|
|
127878
128508
|
if (typeof chain3?.fees?.estimateFeesPerGas === "function") {
|
|
127879
128509
|
const fees = await chain3.fees.estimateFeesPerGas({
|
|
@@ -128383,7 +129013,7 @@ var require_fillTransaction = __commonJS({
|
|
|
128383
129013
|
throw new fee_js_1.BaseFeeScalarError();
|
|
128384
129014
|
const decimals = feeMultiplier.toString().split(".")[1]?.length ?? 0;
|
|
128385
129015
|
const denominator = 10 ** decimals;
|
|
128386
|
-
const multiplyFee = (
|
|
129016
|
+
const multiplyFee = (base4) => base4 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
|
|
128387
129017
|
if (!transaction.feePayerSignature) {
|
|
128388
129018
|
if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
|
|
128389
129019
|
transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas);
|
|
@@ -133141,17 +133771,17 @@ var require_call = __commonJS({
|
|
|
133141
133771
|
}
|
|
133142
133772
|
}
|
|
133143
133773
|
const params = (() => {
|
|
133144
|
-
const
|
|
133774
|
+
const base4 = [
|
|
133145
133775
|
request2,
|
|
133146
133776
|
block
|
|
133147
133777
|
];
|
|
133148
133778
|
if (rpcStateOverride && rpcBlockOverrides)
|
|
133149
|
-
return [...
|
|
133779
|
+
return [...base4, rpcStateOverride, rpcBlockOverrides];
|
|
133150
133780
|
if (rpcStateOverride)
|
|
133151
|
-
return [...
|
|
133781
|
+
return [...base4, rpcStateOverride];
|
|
133152
133782
|
if (rpcBlockOverrides)
|
|
133153
|
-
return [...
|
|
133154
|
-
return
|
|
133783
|
+
return [...base4, {}, rpcBlockOverrides];
|
|
133784
|
+
return base4;
|
|
133155
133785
|
})();
|
|
133156
133786
|
const response = await client.request({
|
|
133157
133787
|
method: "eth_call",
|
|
@@ -134763,14 +135393,14 @@ var require_createClient = __commonJS({
|
|
|
134763
135393
|
uid: (0, uid_js_1.uid)(),
|
|
134764
135394
|
...experimental_blockTag ? { experimental_blockTag } : {}
|
|
134765
135395
|
};
|
|
134766
|
-
function extend2(
|
|
135396
|
+
function extend2(base4) {
|
|
134767
135397
|
return (extendFn) => {
|
|
134768
|
-
const extended = extendFn(
|
|
135398
|
+
const extended = extendFn(base4);
|
|
134769
135399
|
for (const key3 in client)
|
|
134770
135400
|
delete extended[key3];
|
|
134771
|
-
const combined = { ...
|
|
135401
|
+
const combined = { ...base4, ...extended };
|
|
134772
135402
|
for (const key3 in extended) {
|
|
134773
|
-
const a =
|
|
135403
|
+
const a = base4[key3];
|
|
134774
135404
|
const b = extended[key3];
|
|
134775
135405
|
if (isPlainObject4(a) && isPlainObject4(b))
|
|
134776
135406
|
combined[key3] = { ...a, ...b };
|
|
@@ -136788,10 +137418,10 @@ var require_defineChain = __commonJS({
|
|
|
136788
137418
|
serializers: void 0,
|
|
136789
137419
|
...chain3
|
|
136790
137420
|
};
|
|
136791
|
-
function extend2(
|
|
137421
|
+
function extend2(base4) {
|
|
136792
137422
|
return (fnOrExtended) => {
|
|
136793
|
-
const properties = typeof fnOrExtended === "function" ? fnOrExtended(
|
|
136794
|
-
const combined = { ...
|
|
137423
|
+
const properties = typeof fnOrExtended === "function" ? fnOrExtended(base4) : fnOrExtended;
|
|
137424
|
+
const combined = { ...base4, ...properties };
|
|
136795
137425
|
return Object.assign(combined, { extend: extend2(combined) });
|
|
136796
137426
|
};
|
|
136797
137427
|
}
|
|
@@ -138126,9 +138756,9 @@ var require_typedData2 = __commonJS({
|
|
|
138126
138756
|
throw new typedData_js_1.InvalidTypedDataTypeError({ type });
|
|
138127
138757
|
const integerMatch = type.match(regex_js_1.integerRegex);
|
|
138128
138758
|
if (integerMatch && (typeof value === "number" || typeof value === "bigint")) {
|
|
138129
|
-
const [_type,
|
|
138759
|
+
const [_type, base4, size_] = integerMatch;
|
|
138130
138760
|
(0, toHex_js_1.numberToHex)(value, {
|
|
138131
|
-
signed:
|
|
138761
|
+
signed: base4 === "int",
|
|
138132
138762
|
size: Number.parseInt(size_, 10) / 8
|
|
138133
138763
|
});
|
|
138134
138764
|
}
|
|
@@ -141920,15 +142550,15 @@ var require_curve2 = __commonJS({
|
|
|
141920
142550
|
const { windows, windowSize } = calcWOpts4(W, bits);
|
|
141921
142551
|
const points = [];
|
|
141922
142552
|
let p = elm;
|
|
141923
|
-
let
|
|
142553
|
+
let base4 = p;
|
|
141924
142554
|
for (let window2 = 0; window2 < windows; window2++) {
|
|
141925
|
-
|
|
141926
|
-
points.push(
|
|
142555
|
+
base4 = p;
|
|
142556
|
+
points.push(base4);
|
|
141927
142557
|
for (let i = 1; i < windowSize; i++) {
|
|
141928
|
-
|
|
141929
|
-
points.push(
|
|
142558
|
+
base4 = base4.add(p);
|
|
142559
|
+
points.push(base4);
|
|
141930
142560
|
}
|
|
141931
|
-
p =
|
|
142561
|
+
p = base4.double();
|
|
141932
142562
|
}
|
|
141933
142563
|
return points;
|
|
141934
142564
|
},
|
|
@@ -175441,14 +176071,14 @@ var require_Authenticator = __commonJS({
|
|
|
175441
176071
|
const rpIdHash = Hash4.sha256(Hex.fromString(rpId));
|
|
175442
176072
|
const flag_bytes = Hex.fromNumber(flag, { size: 1 });
|
|
175443
176073
|
const signCount_bytes = Hex.fromNumber(signCount, { size: 4 });
|
|
175444
|
-
const
|
|
176074
|
+
const base4 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
|
|
175445
176075
|
if (!credential)
|
|
175446
|
-
return
|
|
176076
|
+
return base4;
|
|
175447
176077
|
const aaguid = Hex.fromBytes(new Uint8Array(16));
|
|
175448
176078
|
const credentialId = Hex.fromBytes(credential.id);
|
|
175449
176079
|
const credIdLen = Hex.fromNumber(credential.id.length, { size: 2 });
|
|
175450
176080
|
const coseKey = CoseKey.fromPublicKey(credential.publicKey);
|
|
175451
|
-
return Hex.concat(
|
|
176081
|
+
return Hex.concat(base4, aaguid, credIdLen, credentialId, coseKey);
|
|
175452
176082
|
}
|
|
175453
176083
|
function getSignCount(authenticatorData) {
|
|
175454
176084
|
const bytes = Bytes.fromHex(authenticatorData);
|
|
@@ -179356,7 +179986,7 @@ var require_VirtualMaster = __commonJS({
|
|
|
179356
179986
|
terminateAll();
|
|
179357
179987
|
resolve(result);
|
|
179358
179988
|
};
|
|
179359
|
-
const
|
|
179989
|
+
const fail2 = (error) => {
|
|
179360
179990
|
if (settled)
|
|
179361
179991
|
return;
|
|
179362
179992
|
settled = true;
|
|
@@ -179381,14 +180011,14 @@ var require_VirtualMaster = __commonJS({
|
|
|
179381
180011
|
succeed(void 0);
|
|
179382
180012
|
return;
|
|
179383
180013
|
case "error":
|
|
179384
|
-
|
|
180014
|
+
fail2(new Errors.BaseError(msg.message));
|
|
179385
180015
|
return;
|
|
179386
180016
|
}
|
|
179387
180017
|
};
|
|
179388
|
-
const onAbort = () =>
|
|
180018
|
+
const onAbort = () => fail2(getAbortError2(value.signal));
|
|
179389
180019
|
value.signal?.addEventListener("abort", onAbort, { once: true });
|
|
179390
180020
|
for (let i = 0; i < value.workerCount; i++) {
|
|
179391
|
-
const handle = value.pool.spawn(i, onMessage,
|
|
180021
|
+
const handle = value.pool.spawn(i, onMessage, fail2);
|
|
179392
180022
|
handles.push(handle);
|
|
179393
180023
|
handle.postMessage({
|
|
179394
180024
|
type: "start",
|
|
@@ -179532,8 +180162,8 @@ var require_ZoneId = __commonJS({
|
|
|
179532
180162
|
return chainId - getChainIdConfig(sourceId2).base;
|
|
179533
180163
|
}
|
|
179534
180164
|
function toChainId(zoneId, sourceId2 = defaultSourceId) {
|
|
179535
|
-
const { base:
|
|
179536
|
-
return
|
|
180165
|
+
const { base: base4, range } = getChainIdConfig(sourceId2);
|
|
180166
|
+
return base4 + zoneId % range;
|
|
179537
180167
|
}
|
|
179538
180168
|
var UnsupportedSourceIdError = class extends Errors.BaseError {
|
|
179539
180169
|
constructor({ sourceId: sourceId2 }) {
|
|
@@ -193139,7 +193769,7 @@ var require_bn = __commonJS({
|
|
|
193139
193769
|
ctor.prototype = new TempCtor();
|
|
193140
193770
|
ctor.prototype.constructor = ctor;
|
|
193141
193771
|
}
|
|
193142
|
-
function BN3(number,
|
|
193772
|
+
function BN3(number, base4, endian) {
|
|
193143
193773
|
if (BN3.isBN(number)) {
|
|
193144
193774
|
return number;
|
|
193145
193775
|
}
|
|
@@ -193148,11 +193778,11 @@ var require_bn = __commonJS({
|
|
|
193148
193778
|
this.length = 0;
|
|
193149
193779
|
this.red = null;
|
|
193150
193780
|
if (number !== null) {
|
|
193151
|
-
if (
|
|
193152
|
-
endian =
|
|
193153
|
-
|
|
193781
|
+
if (base4 === "le" || base4 === "be") {
|
|
193782
|
+
endian = base4;
|
|
193783
|
+
base4 = 10;
|
|
193154
193784
|
}
|
|
193155
|
-
this._init(number || 0,
|
|
193785
|
+
this._init(number || 0, base4 || 10, endian || "be");
|
|
193156
193786
|
}
|
|
193157
193787
|
}
|
|
193158
193788
|
if (typeof module2 === "object") {
|
|
@@ -193185,17 +193815,17 @@ var require_bn = __commonJS({
|
|
|
193185
193815
|
if (left.cmp(right) < 0) return left;
|
|
193186
193816
|
return right;
|
|
193187
193817
|
};
|
|
193188
|
-
BN3.prototype._init = function init2(number,
|
|
193818
|
+
BN3.prototype._init = function init2(number, base4, endian) {
|
|
193189
193819
|
if (typeof number === "number") {
|
|
193190
|
-
return this._initNumber(number,
|
|
193820
|
+
return this._initNumber(number, base4, endian);
|
|
193191
193821
|
}
|
|
193192
193822
|
if (typeof number === "object") {
|
|
193193
|
-
return this._initArray(number,
|
|
193823
|
+
return this._initArray(number, base4, endian);
|
|
193194
193824
|
}
|
|
193195
|
-
if (
|
|
193196
|
-
|
|
193825
|
+
if (base4 === "hex") {
|
|
193826
|
+
base4 = 16;
|
|
193197
193827
|
}
|
|
193198
|
-
assert10(
|
|
193828
|
+
assert10(base4 === (base4 | 0) && base4 >= 2 && base4 <= 36);
|
|
193199
193829
|
number = number.toString().replace(/\s+/g, "");
|
|
193200
193830
|
var start = 0;
|
|
193201
193831
|
if (number[0] === "-") {
|
|
@@ -193203,17 +193833,17 @@ var require_bn = __commonJS({
|
|
|
193203
193833
|
this.negative = 1;
|
|
193204
193834
|
}
|
|
193205
193835
|
if (start < number.length) {
|
|
193206
|
-
if (
|
|
193836
|
+
if (base4 === 16) {
|
|
193207
193837
|
this._parseHex(number, start, endian);
|
|
193208
193838
|
} else {
|
|
193209
|
-
this._parseBase(number,
|
|
193839
|
+
this._parseBase(number, base4, start);
|
|
193210
193840
|
if (endian === "le") {
|
|
193211
|
-
this._initArray(this.toArray(),
|
|
193841
|
+
this._initArray(this.toArray(), base4, endian);
|
|
193212
193842
|
}
|
|
193213
193843
|
}
|
|
193214
193844
|
}
|
|
193215
193845
|
};
|
|
193216
|
-
BN3.prototype._initNumber = function _initNumber(number,
|
|
193846
|
+
BN3.prototype._initNumber = function _initNumber(number, base4, endian) {
|
|
193217
193847
|
if (number < 0) {
|
|
193218
193848
|
this.negative = 1;
|
|
193219
193849
|
number = -number;
|
|
@@ -193237,9 +193867,9 @@ var require_bn = __commonJS({
|
|
|
193237
193867
|
this.length = 3;
|
|
193238
193868
|
}
|
|
193239
193869
|
if (endian !== "le") return;
|
|
193240
|
-
this._initArray(this.toArray(),
|
|
193870
|
+
this._initArray(this.toArray(), base4, endian);
|
|
193241
193871
|
};
|
|
193242
|
-
BN3.prototype._initArray = function _initArray(number,
|
|
193872
|
+
BN3.prototype._initArray = function _initArray(number, base4, endian) {
|
|
193243
193873
|
assert10(typeof number.length === "number");
|
|
193244
193874
|
if (number.length <= 0) {
|
|
193245
193875
|
this.words = [0];
|
|
@@ -193353,20 +193983,20 @@ var require_bn = __commonJS({
|
|
|
193353
193983
|
}
|
|
193354
193984
|
return r2;
|
|
193355
193985
|
}
|
|
193356
|
-
BN3.prototype._parseBase = function _parseBase(number,
|
|
193986
|
+
BN3.prototype._parseBase = function _parseBase(number, base4, start) {
|
|
193357
193987
|
this.words = [0];
|
|
193358
193988
|
this.length = 1;
|
|
193359
|
-
for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *=
|
|
193989
|
+
for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *= base4) {
|
|
193360
193990
|
limbLen++;
|
|
193361
193991
|
}
|
|
193362
193992
|
limbLen--;
|
|
193363
|
-
limbPow = limbPow /
|
|
193993
|
+
limbPow = limbPow / base4 | 0;
|
|
193364
193994
|
var total = number.length - start;
|
|
193365
193995
|
var mod5 = total % limbLen;
|
|
193366
193996
|
var end = Math.min(total, total - mod5) + start;
|
|
193367
193997
|
var word = 0;
|
|
193368
193998
|
for (var i = start; i < end; i += limbLen) {
|
|
193369
|
-
word = parseBase(number, i, i + limbLen,
|
|
193999
|
+
word = parseBase(number, i, i + limbLen, base4);
|
|
193370
194000
|
this.imuln(limbPow);
|
|
193371
194001
|
if (this.words[0] + word < 67108864) {
|
|
193372
194002
|
this.words[0] += word;
|
|
@@ -193376,9 +194006,9 @@ var require_bn = __commonJS({
|
|
|
193376
194006
|
}
|
|
193377
194007
|
if (mod5 !== 0) {
|
|
193378
194008
|
var pow = 1;
|
|
193379
|
-
word = parseBase(number, i, number.length,
|
|
194009
|
+
word = parseBase(number, i, number.length, base4);
|
|
193380
194010
|
for (i = 0; i < mod5; i++) {
|
|
193381
|
-
pow *=
|
|
194011
|
+
pow *= base4;
|
|
193382
194012
|
}
|
|
193383
194013
|
this.imuln(pow);
|
|
193384
194014
|
if (this.words[0] + word < 67108864) {
|
|
@@ -193548,11 +194178,11 @@ var require_bn = __commonJS({
|
|
|
193548
194178
|
52521875,
|
|
193549
194179
|
60466176
|
|
193550
194180
|
];
|
|
193551
|
-
BN3.prototype.toString = function toString4(
|
|
193552
|
-
|
|
194181
|
+
BN3.prototype.toString = function toString4(base4, padding3) {
|
|
194182
|
+
base4 = base4 || 10;
|
|
193553
194183
|
padding3 = padding3 | 0 || 1;
|
|
193554
194184
|
var out;
|
|
193555
|
-
if (
|
|
194185
|
+
if (base4 === 16 || base4 === "hex") {
|
|
193556
194186
|
out = "";
|
|
193557
194187
|
var off = 0;
|
|
193558
194188
|
var carry2 = 0;
|
|
@@ -193582,14 +194212,14 @@ var require_bn = __commonJS({
|
|
|
193582
194212
|
}
|
|
193583
194213
|
return out;
|
|
193584
194214
|
}
|
|
193585
|
-
if (
|
|
193586
|
-
var groupSize = groupSizes[
|
|
193587
|
-
var groupBase = groupBases[
|
|
194215
|
+
if (base4 === (base4 | 0) && base4 >= 2 && base4 <= 36) {
|
|
194216
|
+
var groupSize = groupSizes[base4];
|
|
194217
|
+
var groupBase = groupBases[base4];
|
|
193588
194218
|
out = "";
|
|
193589
194219
|
var c = this.clone();
|
|
193590
194220
|
c.negative = 0;
|
|
193591
194221
|
while (!c.isZero()) {
|
|
193592
|
-
var r2 = c.modrn(groupBase).toString(
|
|
194222
|
+
var r2 = c.modrn(groupBase).toString(base4);
|
|
193593
194223
|
c = c.idivn(groupBase);
|
|
193594
194224
|
if (!c.isZero()) {
|
|
193595
194225
|
out = zeros2[groupSize - r2.length] + r2 + out;
|
|
@@ -204158,8 +204788,8 @@ function createCommonjsModule(fn, basedir, module) {
|
|
|
204158
204788
|
return module = {
|
|
204159
204789
|
path: basedir,
|
|
204160
204790
|
exports: {},
|
|
204161
|
-
require: function(path5,
|
|
204162
|
-
return commonjsRequire(path5,
|
|
204791
|
+
require: function(path5, base4) {
|
|
204792
|
+
return commonjsRequire(path5, base4 === void 0 || base4 === null ? module.path : base4);
|
|
204163
204793
|
}
|
|
204164
204794
|
}, fn(module, module.exports), module.exports;
|
|
204165
204795
|
}
|
|
@@ -204198,7 +204828,7 @@ function BasePoint(curve, type) {
|
|
|
204198
204828
|
this.precomputed = null;
|
|
204199
204829
|
}
|
|
204200
204830
|
function ShortCurve(conf) {
|
|
204201
|
-
|
|
204831
|
+
base3.call(this, "short", conf);
|
|
204202
204832
|
this.a = new import_bn2.default(conf.a, 16).toRed(this.red);
|
|
204203
204833
|
this.b = new import_bn2.default(conf.b, 16).toRed(this.red);
|
|
204204
204834
|
this.tinv = this.two.redInvm();
|
|
@@ -204209,7 +204839,7 @@ function ShortCurve(conf) {
|
|
|
204209
204839
|
this._endoWnafT2 = new Array(4);
|
|
204210
204840
|
}
|
|
204211
204841
|
function Point3(curve, x, y, isRed) {
|
|
204212
|
-
|
|
204842
|
+
base3.BasePoint.call(this, curve, "affine");
|
|
204213
204843
|
if (x === null && y === null) {
|
|
204214
204844
|
this.x = null;
|
|
204215
204845
|
this.y = null;
|
|
@@ -204229,7 +204859,7 @@ function Point3(curve, x, y, isRed) {
|
|
|
204229
204859
|
}
|
|
204230
204860
|
}
|
|
204231
204861
|
function JPoint(curve, x, y, z) {
|
|
204232
|
-
|
|
204862
|
+
base3.BasePoint.call(this, curve, "jacobian");
|
|
204233
204863
|
if (x === null && y === null && z === null) {
|
|
204234
204864
|
this.x = this.curve.one;
|
|
204235
204865
|
this.y = this.curve.one;
|
|
@@ -204359,7 +204989,7 @@ function EC(options) {
|
|
|
204359
204989
|
this.g.precompute(options.curve.n.bitLength() + 1);
|
|
204360
204990
|
this.hash = options.hash || options.curve.hash;
|
|
204361
204991
|
}
|
|
204362
|
-
var import_bn2, import_hash2, minimalisticAssert, utils_1, utils_1$1, getNAF, getJSF, assert$1,
|
|
204992
|
+
var import_bn2, import_hash2, minimalisticAssert, utils_1, utils_1$1, getNAF, getJSF, assert$1, base3, inherits_browser, assert$2, short_1, curve_1, curves_1, hmacDrbg, assert$3, key, assert$4, signature2, rand, assert$5, ec, elliptic_1, EC$1;
|
|
204363
204993
|
var init_elliptic = __esm({
|
|
204364
204994
|
"node_modules/@ethersproject/signing-key/lib.esm/elliptic.js"() {
|
|
204365
204995
|
"use strict";
|
|
@@ -204527,7 +205157,7 @@ var init_elliptic = __esm({
|
|
|
204527
205157
|
getNAF = utils_1$1.getNAF;
|
|
204528
205158
|
getJSF = utils_1$1.getJSF;
|
|
204529
205159
|
assert$1 = utils_1$1.assert;
|
|
204530
|
-
|
|
205160
|
+
base3 = BaseCurve;
|
|
204531
205161
|
BaseCurve.prototype.point = function point() {
|
|
204532
205162
|
throw new Error("Not implemented");
|
|
204533
205163
|
};
|
|
@@ -204839,7 +205469,7 @@ var init_elliptic = __esm({
|
|
|
204839
205469
|
}
|
|
204840
205470
|
});
|
|
204841
205471
|
assert$2 = utils_1$1.assert;
|
|
204842
|
-
inherits_browser(ShortCurve,
|
|
205472
|
+
inherits_browser(ShortCurve, base3);
|
|
204843
205473
|
short_1 = ShortCurve;
|
|
204844
205474
|
ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
|
|
204845
205475
|
if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
|
|
@@ -205013,7 +205643,7 @@ var init_elliptic = __esm({
|
|
|
205013
205643
|
}
|
|
205014
205644
|
return res;
|
|
205015
205645
|
};
|
|
205016
|
-
inherits_browser(Point3,
|
|
205646
|
+
inherits_browser(Point3, base3.BasePoint);
|
|
205017
205647
|
ShortCurve.prototype.point = function point2(x, y, isRed) {
|
|
205018
205648
|
return new Point3(this, x, y, isRed);
|
|
205019
205649
|
};
|
|
@@ -205188,7 +205818,7 @@ var init_elliptic = __esm({
|
|
|
205188
205818
|
var res = this.curve.jpoint(this.x, this.y, this.curve.one);
|
|
205189
205819
|
return res;
|
|
205190
205820
|
};
|
|
205191
|
-
inherits_browser(JPoint,
|
|
205821
|
+
inherits_browser(JPoint, base3.BasePoint);
|
|
205192
205822
|
ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
|
|
205193
205823
|
return new JPoint(this, x, y, z);
|
|
205194
205824
|
};
|
|
@@ -205478,7 +206108,7 @@ var init_elliptic = __esm({
|
|
|
205478
206108
|
curve_1 = createCommonjsModule(function(module, exports) {
|
|
205479
206109
|
"use strict";
|
|
205480
206110
|
var curve = exports;
|
|
205481
|
-
curve.base =
|
|
206111
|
+
curve.base = base3;
|
|
205482
206112
|
curve.short = short_1;
|
|
205483
206113
|
curve.mont = /*RicMoo:ethers:require(./mont)*/
|
|
205484
206114
|
null;
|
|
@@ -210699,10 +211329,10 @@ var init_lib28 = __esm({
|
|
|
210699
211329
|
var require_bech32 = __commonJS({
|
|
210700
211330
|
"node_modules/bech32/index.js"(exports, module) {
|
|
210701
211331
|
"use strict";
|
|
210702
|
-
var
|
|
211332
|
+
var ALPHABET3 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
210703
211333
|
var ALPHABET_MAP = {};
|
|
210704
|
-
for (z = 0; z <
|
|
210705
|
-
x =
|
|
211334
|
+
for (z = 0; z < ALPHABET3.length; z++) {
|
|
211335
|
+
x = ALPHABET3.charAt(z);
|
|
210706
211336
|
if (ALPHABET_MAP[x] !== void 0) throw new TypeError(x + " is ambiguous");
|
|
210707
211337
|
ALPHABET_MAP[x] = z;
|
|
210708
211338
|
}
|
|
@@ -210737,7 +211367,7 @@ var require_bech32 = __commonJS({
|
|
|
210737
211367
|
var x2 = words2[i];
|
|
210738
211368
|
if (x2 >> 5 !== 0) throw new Error("Non 5-bit word");
|
|
210739
211369
|
chk = polymodStep(chk) ^ x2;
|
|
210740
|
-
result +=
|
|
211370
|
+
result += ALPHABET3.charAt(x2);
|
|
210741
211371
|
}
|
|
210742
211372
|
for (i = 0; i < 6; ++i) {
|
|
210743
211373
|
chk = polymodStep(chk);
|
|
@@ -210745,7 +211375,7 @@ var require_bech32 = __commonJS({
|
|
|
210745
211375
|
chk ^= 1;
|
|
210746
211376
|
for (i = 0; i < 6; ++i) {
|
|
210747
211377
|
var v = chk >> (5 - i) * 5 & 31;
|
|
210748
|
-
result +=
|
|
211378
|
+
result += ALPHABET3.charAt(v);
|
|
210749
211379
|
}
|
|
210750
211380
|
return result;
|
|
210751
211381
|
}
|
|
@@ -218125,12 +218755,12 @@ var require_axios = __commonJS({
|
|
|
218125
218755
|
var URLSearchParams2 = url2.URLSearchParams;
|
|
218126
218756
|
var ALPHA2 = "abcdefghijklmnopqrstuvwxyz";
|
|
218127
218757
|
var DIGIT2 = "0123456789";
|
|
218128
|
-
var
|
|
218758
|
+
var ALPHABET3 = {
|
|
218129
218759
|
DIGIT: DIGIT2,
|
|
218130
218760
|
ALPHA: ALPHA2,
|
|
218131
218761
|
ALPHA_DIGIT: ALPHA2 + ALPHA2.toUpperCase() + DIGIT2
|
|
218132
218762
|
};
|
|
218133
|
-
var generateString2 = (size5 = 16, alphabet4 =
|
|
218763
|
+
var generateString2 = (size5 = 16, alphabet4 = ALPHABET3.ALPHA_DIGIT) => {
|
|
218134
218764
|
let str = "";
|
|
218135
218765
|
const {
|
|
218136
218766
|
length
|
|
@@ -218149,7 +218779,7 @@ var require_axios = __commonJS({
|
|
|
218149
218779
|
FormData: FormData$1,
|
|
218150
218780
|
Blob: typeof Blob !== "undefined" && Blob || null
|
|
218151
218781
|
},
|
|
218152
|
-
ALPHABET:
|
|
218782
|
+
ALPHABET: ALPHABET3,
|
|
218153
218783
|
generateString: generateString2,
|
|
218154
218784
|
protocols: ["http", "https", "file", "data"]
|
|
218155
218785
|
};
|
|
@@ -225475,10 +226105,10 @@ async function redeemPosition(input, deps) {
|
|
|
225475
226105
|
structured: { conditionId, negRisk, transactionHash: txHash, pusdBalance: balanceAfter }
|
|
225476
226106
|
};
|
|
225477
226107
|
} catch (err) {
|
|
225478
|
-
const
|
|
226108
|
+
const base4 = await mapClobError(err);
|
|
225479
226109
|
const legacyHint = ` If this market predates the 2026-04-28 V2 cutover it may settle in legacy USDC.e collateral, which this tool does not auto-detect yet \u2014 redeem it once via the Polymarket UI.`;
|
|
225480
226110
|
return {
|
|
225481
|
-
text: `${
|
|
226111
|
+
text: `${base4}${/revert|execution reverted|failed/i.test(base4) ? legacyHint : ""}`,
|
|
225482
226112
|
isError: true
|
|
225483
226113
|
};
|
|
225484
226114
|
}
|
|
@@ -226124,8 +226754,8 @@ var init_dist7 = __esm({
|
|
|
226124
226754
|
if (normalized.startsWith("/api/")) {
|
|
226125
226755
|
normalized = normalized.slice(4);
|
|
226126
226756
|
}
|
|
226127
|
-
const
|
|
226128
|
-
if (!params) return
|
|
226757
|
+
const base4 = `${this.apiUrl}${normalized}`;
|
|
226758
|
+
if (!params) return base4;
|
|
226129
226759
|
const qs = new URLSearchParams();
|
|
226130
226760
|
for (const [key2, value] of Object.entries(params)) {
|
|
226131
226761
|
if (value === void 0 || value === null) continue;
|
|
@@ -226139,12 +226769,12 @@ var init_dist7 = __esm({
|
|
|
226139
226769
|
}
|
|
226140
226770
|
}
|
|
226141
226771
|
const query = qs.toString();
|
|
226142
|
-
return query ? `${
|
|
226772
|
+
return query ? `${base4}?${query}` : base4;
|
|
226143
226773
|
}
|
|
226144
226774
|
absolute(url2) {
|
|
226145
226775
|
if (url2.startsWith("http://") || url2.startsWith("https://")) return url2;
|
|
226146
|
-
const
|
|
226147
|
-
return `${
|
|
226776
|
+
const base4 = this.apiUrl.endsWith("/api") ? this.apiUrl.slice(0, -"/api".length) : this.apiUrl;
|
|
226777
|
+
return `${base4}${url2}`;
|
|
226148
226778
|
}
|
|
226149
226779
|
async requestWithPayment(url2, method, body) {
|
|
226150
226780
|
const init2 = { method };
|
|
@@ -226768,6 +227398,113 @@ var init_mcp_config = __esm({
|
|
|
226768
227398
|
}
|
|
226769
227399
|
});
|
|
226770
227400
|
|
|
227401
|
+
// src/openclaw-plugin-config.ts
|
|
227402
|
+
var openclaw_plugin_config_exports = {};
|
|
227403
|
+
__export(openclaw_plugin_config_exports, {
|
|
227404
|
+
BLOCKRUN_PLUGIN_ID: () => BLOCKRUN_PLUGIN_ID,
|
|
227405
|
+
prepareBlockRunPluginConfig: () => prepareBlockRunPluginConfig
|
|
227406
|
+
});
|
|
227407
|
+
function asObject2(value) {
|
|
227408
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
227409
|
+
}
|
|
227410
|
+
function prepareBlockRunPluginConfig(config, options = {}) {
|
|
227411
|
+
if (!options.explicitSetup && !options.legacyBlockRunInstall && !options.stripUnsupportedInstalls) {
|
|
227412
|
+
return false;
|
|
227413
|
+
}
|
|
227414
|
+
let changed = false;
|
|
227415
|
+
let plugins = asObject2(config.plugins);
|
|
227416
|
+
if (!plugins) {
|
|
227417
|
+
plugins = {};
|
|
227418
|
+
config.plugins = plugins;
|
|
227419
|
+
changed = true;
|
|
227420
|
+
}
|
|
227421
|
+
let entries = asObject2(plugins.entries);
|
|
227422
|
+
if (!entries) {
|
|
227423
|
+
entries = {};
|
|
227424
|
+
plugins.entries = entries;
|
|
227425
|
+
changed = true;
|
|
227426
|
+
}
|
|
227427
|
+
const legacyEntry = asObject2(entries.clawrouter);
|
|
227428
|
+
const currentEntry = asObject2(entries[BLOCKRUN_PLUGIN_ID]);
|
|
227429
|
+
if (options.legacyBlockRunInstall && legacyEntry) {
|
|
227430
|
+
const migratedEntry = currentEntry ?? {};
|
|
227431
|
+
if (!currentEntry && typeof legacyEntry.enabled === "boolean") {
|
|
227432
|
+
migratedEntry.enabled = legacyEntry.enabled;
|
|
227433
|
+
}
|
|
227434
|
+
for (const key2 of ["walletKey", "routing"]) {
|
|
227435
|
+
if (!(key2 in migratedEntry) && key2 in legacyEntry) {
|
|
227436
|
+
migratedEntry[key2] = legacyEntry[key2];
|
|
227437
|
+
}
|
|
227438
|
+
if (key2 in legacyEntry) {
|
|
227439
|
+
delete legacyEntry[key2];
|
|
227440
|
+
changed = true;
|
|
227441
|
+
}
|
|
227442
|
+
}
|
|
227443
|
+
const legacyConfig = asObject2(legacyEntry.config);
|
|
227444
|
+
if (legacyConfig) {
|
|
227445
|
+
const currentConfig = asObject2(migratedEntry.config) ?? {};
|
|
227446
|
+
for (const key2 of ["walletKey", "routing"]) {
|
|
227447
|
+
if (!(key2 in currentConfig) && key2 in legacyConfig) {
|
|
227448
|
+
currentConfig[key2] = legacyConfig[key2];
|
|
227449
|
+
}
|
|
227450
|
+
if (key2 in legacyConfig) {
|
|
227451
|
+
delete legacyConfig[key2];
|
|
227452
|
+
changed = true;
|
|
227453
|
+
}
|
|
227454
|
+
}
|
|
227455
|
+
if (Object.keys(currentConfig).length > 0) migratedEntry.config = currentConfig;
|
|
227456
|
+
if (Object.keys(legacyConfig).length === 0) {
|
|
227457
|
+
delete legacyEntry.config;
|
|
227458
|
+
changed = true;
|
|
227459
|
+
}
|
|
227460
|
+
}
|
|
227461
|
+
if (!currentEntry || entries[BLOCKRUN_PLUGIN_ID] !== migratedEntry) {
|
|
227462
|
+
entries[BLOCKRUN_PLUGIN_ID] = migratedEntry;
|
|
227463
|
+
changed = true;
|
|
227464
|
+
}
|
|
227465
|
+
}
|
|
227466
|
+
if (options.explicitSetup) {
|
|
227467
|
+
const next = asObject2(entries[BLOCKRUN_PLUGIN_ID]) ?? {};
|
|
227468
|
+
if (next.enabled !== true) {
|
|
227469
|
+
entries[BLOCKRUN_PLUGIN_ID] = { ...next, enabled: true };
|
|
227470
|
+
changed = true;
|
|
227471
|
+
}
|
|
227472
|
+
}
|
|
227473
|
+
const allow = plugins.allow;
|
|
227474
|
+
if (Array.isArray(allow)) {
|
|
227475
|
+
const shouldAllow = options.explicitSetup || options.legacyBlockRunInstall && allow.includes("clawrouter");
|
|
227476
|
+
if (shouldAllow && !allow.includes(BLOCKRUN_PLUGIN_ID)) {
|
|
227477
|
+
allow.push(BLOCKRUN_PLUGIN_ID);
|
|
227478
|
+
changed = true;
|
|
227479
|
+
}
|
|
227480
|
+
}
|
|
227481
|
+
const deny = plugins.deny;
|
|
227482
|
+
if (Array.isArray(deny)) {
|
|
227483
|
+
if (options.explicitSetup) {
|
|
227484
|
+
const next = deny.filter((id2) => id2 !== BLOCKRUN_PLUGIN_ID);
|
|
227485
|
+
if (next.length !== deny.length) {
|
|
227486
|
+
plugins.deny = next;
|
|
227487
|
+
changed = true;
|
|
227488
|
+
}
|
|
227489
|
+
} else if (options.legacyBlockRunInstall && deny.includes("clawrouter") && !deny.includes(BLOCKRUN_PLUGIN_ID)) {
|
|
227490
|
+
deny.push(BLOCKRUN_PLUGIN_ID);
|
|
227491
|
+
changed = true;
|
|
227492
|
+
}
|
|
227493
|
+
}
|
|
227494
|
+
if (options.stripUnsupportedInstalls && "installs" in plugins) {
|
|
227495
|
+
delete plugins.installs;
|
|
227496
|
+
changed = true;
|
|
227497
|
+
}
|
|
227498
|
+
return changed;
|
|
227499
|
+
}
|
|
227500
|
+
var BLOCKRUN_PLUGIN_ID;
|
|
227501
|
+
var init_openclaw_plugin_config = __esm({
|
|
227502
|
+
"src/openclaw-plugin-config.ts"() {
|
|
227503
|
+
"use strict";
|
|
227504
|
+
BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
|
|
227505
|
+
}
|
|
227506
|
+
});
|
|
227507
|
+
|
|
226771
227508
|
// src/retry.ts
|
|
226772
227509
|
function sleep3(ms) {
|
|
226773
227510
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -226850,6 +227587,7 @@ __export(index_exports, {
|
|
|
226850
227587
|
MalformedSpendPolicyError: () => MalformedSpendPolicyError,
|
|
226851
227588
|
OPENCLAW_MODELS: () => OPENCLAW_MODELS,
|
|
226852
227589
|
PARTNER_SERVICES: () => PARTNER_SERVICES,
|
|
227590
|
+
PAYABLE_NETWORKS: () => PAYABLE_NETWORKS,
|
|
226853
227591
|
RequestDeduplicator: () => RequestDeduplicator,
|
|
226854
227592
|
ResponseCache: () => ResponseCache,
|
|
226855
227593
|
RpcError: () => RpcError2,
|
|
@@ -226911,13 +227649,14 @@ import {
|
|
|
226911
227649
|
readdirSync,
|
|
226912
227650
|
mkdirSync as mkdirSync3,
|
|
226913
227651
|
copyFileSync,
|
|
227652
|
+
chmodSync,
|
|
226914
227653
|
renameSync as renameSync2,
|
|
226915
227654
|
unlinkSync
|
|
226916
227655
|
} from "fs";
|
|
226917
227656
|
import { readFile as readFileAsync } from "fs/promises";
|
|
226918
227657
|
import { homedir as homedir13 } from "os";
|
|
226919
|
-
import {
|
|
226920
|
-
import {
|
|
227658
|
+
import { randomUUID } from "crypto";
|
|
227659
|
+
import { join as join16 } from "path";
|
|
226921
227660
|
async function waitForProxyHealth(port, timeoutMs = 3e3) {
|
|
226922
227661
|
const start = Date.now();
|
|
226923
227662
|
while (Date.now() - start < timeoutMs) {
|
|
@@ -226930,53 +227669,21 @@ async function waitForProxyHealth(port, timeoutMs = 3e3) {
|
|
|
226930
227669
|
}
|
|
226931
227670
|
return false;
|
|
226932
227671
|
}
|
|
226933
|
-
function
|
|
226934
|
-
|
|
226935
|
-
}
|
|
226936
|
-
function installSkillsToWorkspace(logger48) {
|
|
227672
|
+
function writePrivateJsonSync(path5, value) {
|
|
227673
|
+
const temporary = `${path5}.tmp.${randomUUID()}`;
|
|
226937
227674
|
try {
|
|
226938
|
-
|
|
226939
|
-
|
|
226940
|
-
|
|
226941
|
-
|
|
226942
|
-
|
|
226943
|
-
const profile = (process["env"].OPENCLAW_PROFILE ?? "").trim().toLowerCase();
|
|
226944
|
-
const workspaceDirName = profile && profile !== "default" ? `workspace-${profile}` : "workspace";
|
|
226945
|
-
const workspaceSkillsDir = join16(homedir13(), ".openclaw", workspaceDirName, "skills");
|
|
226946
|
-
mkdirSync3(workspaceSkillsDir, { recursive: true });
|
|
226947
|
-
const INTERNAL_SKILLS = /* @__PURE__ */ new Set(["release"]);
|
|
226948
|
-
const entries = readdirSync(bundledSkillsDir, { withFileTypes: true });
|
|
226949
|
-
let installed = 0;
|
|
226950
|
-
for (const entry of entries) {
|
|
226951
|
-
if (!entry.isDirectory()) continue;
|
|
226952
|
-
const skillName = entry.name;
|
|
226953
|
-
if (INTERNAL_SKILLS.has(skillName)) continue;
|
|
226954
|
-
const srcSkillFile = join16(bundledSkillsDir, skillName, "SKILL.md");
|
|
226955
|
-
if (!existsSync4(srcSkillFile)) continue;
|
|
226956
|
-
const destDir = join16(workspaceSkillsDir, skillName);
|
|
226957
|
-
const destSkillFile = join16(destDir, "SKILL.md");
|
|
226958
|
-
let needsUpdate = true;
|
|
226959
|
-
if (existsSync4(destSkillFile)) {
|
|
226960
|
-
try {
|
|
226961
|
-
const srcContent = readTextFileSync(srcSkillFile);
|
|
226962
|
-
const destContent = readTextFileSync(destSkillFile);
|
|
226963
|
-
if (srcContent === destContent) needsUpdate = false;
|
|
226964
|
-
} catch {
|
|
226965
|
-
}
|
|
226966
|
-
}
|
|
226967
|
-
if (needsUpdate) {
|
|
226968
|
-
mkdirSync3(destDir, { recursive: true });
|
|
226969
|
-
copyFileSync(srcSkillFile, destSkillFile);
|
|
226970
|
-
installed++;
|
|
226971
|
-
}
|
|
226972
|
-
}
|
|
226973
|
-
if (installed > 0) {
|
|
226974
|
-
logger48.info(`Installed ${installed} skill(s) to ${workspaceSkillsDir}`);
|
|
226975
|
-
}
|
|
226976
|
-
} catch (err) {
|
|
226977
|
-
logger48.warn(`Failed to install skills: ${err instanceof Error ? err.message : String(err)}`);
|
|
227675
|
+
writeFileSync3(temporary, JSON.stringify(value, null, 2), { mode: 384 });
|
|
227676
|
+
renameSync2(temporary, path5);
|
|
227677
|
+
chmodSync(path5, 384);
|
|
227678
|
+
} finally {
|
|
227679
|
+
if (existsSync4(temporary)) unlinkSync(temporary);
|
|
226978
227680
|
}
|
|
226979
227681
|
}
|
|
227682
|
+
function hasConfiguredWallet() {
|
|
227683
|
+
return Boolean(
|
|
227684
|
+
process["env"].BLOCKRUN_WALLET_KEY || existsSync4(CORE_WALLET_FILE) || existsSync4(WALLET_FILE)
|
|
227685
|
+
);
|
|
227686
|
+
}
|
|
226980
227687
|
function isCompletionMode() {
|
|
226981
227688
|
const args = process.argv;
|
|
226982
227689
|
return args.some((arg, i) => arg === "completion" && i >= 1 && i <= 3);
|
|
@@ -227150,35 +227857,19 @@ function injectModelsConfig(logger48, options = {}) {
|
|
|
227150
227857
|
logger48.info(`Added ${addedCount} models to allowlist (${TOP_MODELS.length} total)`);
|
|
227151
227858
|
}
|
|
227152
227859
|
}
|
|
227153
|
-
const
|
|
227154
|
-
|
|
227155
|
-
|
|
227156
|
-
|
|
227860
|
+
const legacyEntry = config.plugins?.entries?.clawrouter;
|
|
227861
|
+
const legacyEntryConfig = legacyEntry?.config;
|
|
227862
|
+
const legacyBlockRunInstall = Boolean(
|
|
227863
|
+
legacyEntry && ["walletKey", "routing"].some(
|
|
227864
|
+
(key2) => key2 in legacyEntry || (legacyEntryConfig ? key2 in legacyEntryConfig : false)
|
|
227865
|
+
)
|
|
227866
|
+
);
|
|
227867
|
+
if (legacyBlockRunInstall && prepareBlockRunPluginConfig(config, { legacyBlockRunInstall })) {
|
|
227157
227868
|
needsWrite = true;
|
|
227158
227869
|
logger48.info(
|
|
227159
|
-
|
|
227870
|
+
`Migrated legacy BlockRun plugin config to ${BLOCKRUN_PLUGIN_ID} (renamed from clawrouter; see #305)`
|
|
227160
227871
|
);
|
|
227161
227872
|
}
|
|
227162
|
-
const pluginsCfg = config.plugins;
|
|
227163
|
-
const allow = pluginsCfg?.allow;
|
|
227164
|
-
if (Array.isArray(allow) && allow.includes("clawrouter") && !allow.includes(BLOCKRUN_PLUGIN_ID)) {
|
|
227165
|
-
allow.push(BLOCKRUN_PLUGIN_ID);
|
|
227166
|
-
needsWrite = true;
|
|
227167
|
-
logger48.info(`Added ${BLOCKRUN_PLUGIN_ID} to plugins.allow (renamed from clawrouter; see #305)`);
|
|
227168
|
-
}
|
|
227169
|
-
const deny = pluginsCfg?.deny;
|
|
227170
|
-
if (Array.isArray(deny) && deny.includes("clawrouter") && !deny.includes(BLOCKRUN_PLUGIN_ID)) {
|
|
227171
|
-
deny.push(BLOCKRUN_PLUGIN_ID);
|
|
227172
|
-
needsWrite = true;
|
|
227173
|
-
logger48.info(`Added ${BLOCKRUN_PLUGIN_ID} to plugins.deny (renamed from clawrouter; see #305)`);
|
|
227174
|
-
}
|
|
227175
|
-
const installs = pluginsCfg?.installs;
|
|
227176
|
-
if (installs && installs.clawrouter && !installs[BLOCKRUN_PLUGIN_ID]) {
|
|
227177
|
-
installs[BLOCKRUN_PLUGIN_ID] = installs.clawrouter;
|
|
227178
|
-
delete installs.clawrouter;
|
|
227179
|
-
needsWrite = true;
|
|
227180
|
-
logger48.info(`Migrated plugins.installs.clawrouter -> ${BLOCKRUN_PLUGIN_ID} (see #305)`);
|
|
227181
|
-
}
|
|
227182
227873
|
if (!config.tools || typeof config.tools !== "object" || Array.isArray(config.tools)) {
|
|
227183
227874
|
config.tools = {};
|
|
227184
227875
|
needsWrite = true;
|
|
@@ -227218,8 +227909,9 @@ function injectModelsConfig(logger48, options = {}) {
|
|
|
227218
227909
|
}
|
|
227219
227910
|
try {
|
|
227220
227911
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
227221
|
-
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
227912
|
+
writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
227222
227913
|
renameSync2(tmpPath, configPath);
|
|
227914
|
+
chmodSync(configPath, 384);
|
|
227223
227915
|
logger48.info("Smart routing enabled (blockrun/auto)");
|
|
227224
227916
|
} catch (err) {
|
|
227225
227917
|
logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -227254,7 +227946,7 @@ function syncAgentModelCache(logger48, options = {}) {
|
|
|
227254
227946
|
const staleCount = Array.isArray(current) ? current.length : 0;
|
|
227255
227947
|
entry.models = VISIBLE_OPENCLAW_MODELS;
|
|
227256
227948
|
const tmpPath = `${cachePath}.tmp.${process.pid}`;
|
|
227257
|
-
writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
|
|
227949
|
+
writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2), { mode: 384 });
|
|
227258
227950
|
renameSync2(tmpPath, cachePath);
|
|
227259
227951
|
logger48.info(
|
|
227260
227952
|
`Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
|
|
@@ -227325,7 +228017,7 @@ function injectAuthProfile(logger48) {
|
|
|
227325
228017
|
key: "x402-proxy-handles-auth"
|
|
227326
228018
|
};
|
|
227327
228019
|
try {
|
|
227328
|
-
|
|
228020
|
+
writePrivateJsonSync(authPath, store);
|
|
227329
228021
|
logger48.info(`Injected BlockRun auth profile for agent: ${agentId}`);
|
|
227330
228022
|
} catch (err) {
|
|
227331
228023
|
logger48.info(
|
|
@@ -227441,7 +228133,7 @@ async function startProxyInBackground(api, startupGeneration) {
|
|
|
227441
228133
|
} else {
|
|
227442
228134
|
if (configKey !== void 0) {
|
|
227443
228135
|
api.logger.warn(
|
|
227444
|
-
`pluginConfig.walletKey is set but invalid (expected 0x + 64 hex chars) \u2014 falling back to
|
|
228136
|
+
`pluginConfig.walletKey is set but invalid (expected 0x + 64 hex chars) \u2014 falling back to the BlockRun wallet`
|
|
227445
228137
|
);
|
|
227446
228138
|
}
|
|
227447
228139
|
wallet = await resolveOrGenerateWalletKey();
|
|
@@ -227453,6 +228145,8 @@ async function startProxyInBackground(api, startupGeneration) {
|
|
|
227453
228145
|
api.logger.warn(` Run /wallet export to get your private key`);
|
|
227454
228146
|
api.logger.warn(` Losing this key = losing your USDC funds`);
|
|
227455
228147
|
api.logger.warn(`\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`);
|
|
228148
|
+
} else if (wallet.source === "core") {
|
|
228149
|
+
api.logger.info(`Using BlockRun Core wallet: ${wallet.address}`);
|
|
227456
228150
|
} else if (wallet.source === "saved") {
|
|
227457
228151
|
api.logger.info(`Using saved wallet: ${wallet.address}`);
|
|
227458
228152
|
} else if (wallet.source === "config") {
|
|
@@ -227473,6 +228167,7 @@ async function startProxyInBackground(api, startupGeneration) {
|
|
|
227473
228167
|
routingConfig,
|
|
227474
228168
|
maxCostPerRunUsd,
|
|
227475
228169
|
maxCostPerRunMode,
|
|
228170
|
+
spendControl: liveSpendControl = new SpendControl(),
|
|
227476
228171
|
onReady: (port) => {
|
|
227477
228172
|
api.logger.info(`BlockRun x402 proxy listening on port ${port}`);
|
|
227478
228173
|
},
|
|
@@ -227739,7 +228434,7 @@ function buildImageGenerationProvider() {
|
|
|
227739
228434
|
]
|
|
227740
228435
|
}
|
|
227741
228436
|
},
|
|
227742
|
-
isConfigured:
|
|
228437
|
+
isConfigured: hasConfiguredWallet,
|
|
227743
228438
|
generateImage: async (req) => {
|
|
227744
228439
|
const port = getProxyPort();
|
|
227745
228440
|
const body = JSON.stringify({
|
|
@@ -227789,7 +228484,7 @@ function buildMusicGenerationProvider() {
|
|
|
227789
228484
|
supportsFormat: true,
|
|
227790
228485
|
supportedFormats: ["mp3"]
|
|
227791
228486
|
},
|
|
227792
|
-
isConfigured:
|
|
228487
|
+
isConfigured: hasConfiguredWallet,
|
|
227793
228488
|
generateMusic: async (req) => {
|
|
227794
228489
|
const port = getProxyPort();
|
|
227795
228490
|
const body = JSON.stringify({
|
|
@@ -227865,7 +228560,7 @@ function buildVideoGenerationProvider() {
|
|
|
227865
228560
|
supportedDurationSeconds: [5, 8, 10]
|
|
227866
228561
|
}
|
|
227867
228562
|
},
|
|
227868
|
-
isConfigured:
|
|
228563
|
+
isConfigured: hasConfiguredWallet,
|
|
227869
228564
|
generateVideo: async (req) => {
|
|
227870
228565
|
const port = getProxyPort();
|
|
227871
228566
|
const imageUrl = req.inputImages?.[0]?.url;
|
|
@@ -227944,26 +228639,25 @@ function createWalletCommand(api) {
|
|
|
227944
228639
|
requireAuth: true,
|
|
227945
228640
|
handler: async (ctx) => {
|
|
227946
228641
|
const subcommand = ctx.args?.trim().toLowerCase() || "status";
|
|
227947
|
-
let
|
|
227948
|
-
let address2;
|
|
228642
|
+
let wallet;
|
|
227949
228643
|
try {
|
|
227950
|
-
|
|
227951
|
-
|
|
227952
|
-
|
|
227953
|
-
|
|
227954
|
-
|
|
227955
|
-
|
|
227956
|
-
}
|
|
227957
|
-
} catch {
|
|
228644
|
+
wallet = subcommand === "status" || subcommand === "export" ? await resolveExistingWalletKey() : await resolveOrGenerateWalletKey();
|
|
228645
|
+
} catch (error) {
|
|
228646
|
+
return {
|
|
228647
|
+
text: `Could not load the BlockRun wallet: ${error instanceof Error ? error.message : String(error)}`,
|
|
228648
|
+
isError: true
|
|
228649
|
+
};
|
|
227958
228650
|
}
|
|
227959
|
-
if (!
|
|
228651
|
+
if (!wallet) {
|
|
227960
228652
|
return {
|
|
227961
|
-
text:
|
|
227962
|
-
|
|
227963
|
-
Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
228653
|
+
text: "No BlockRun wallet found. Run `clawrouter setup` or connect an agent in ClawRouter Desktop to create one.",
|
|
227964
228654
|
isError: true
|
|
227965
228655
|
};
|
|
227966
228656
|
}
|
|
228657
|
+
const walletKey = wallet.key;
|
|
228658
|
+
const address2 = wallet.address;
|
|
228659
|
+
const resolvedSolanaKey = wallet.solanaPrivateKeyBytes;
|
|
228660
|
+
const walletPath = wallet.source === "core" ? CORE_WALLET_FILE : WALLET_FILE;
|
|
227967
228661
|
if (subcommand === "export") {
|
|
227968
228662
|
const lines = [
|
|
227969
228663
|
"**ClawRouter Wallet Export**",
|
|
@@ -228000,13 +228694,26 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
228000
228694
|
}
|
|
228001
228695
|
} catch {
|
|
228002
228696
|
}
|
|
228697
|
+
if (!hasMnemonic3 && resolvedSolanaKey) {
|
|
228698
|
+
try {
|
|
228699
|
+
const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes2 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
|
|
228700
|
+
const signer = await createKeyPairSignerFromPrivateKeyBytes2(resolvedSolanaKey);
|
|
228701
|
+
lines.push(
|
|
228702
|
+
"",
|
|
228703
|
+
"**Solana:**",
|
|
228704
|
+
` Address: \`${signer.address}\``,
|
|
228705
|
+
wallet.source === "core" ? ` Private key managed by BlockRun Core: \`${CORE_SOLANA_WALLET_FILE}\`` : " Private key is managed by the configured wallet source."
|
|
228706
|
+
);
|
|
228707
|
+
} catch {
|
|
228708
|
+
}
|
|
228709
|
+
}
|
|
228003
228710
|
lines.push(
|
|
228004
228711
|
"",
|
|
228005
228712
|
"**To restore on a new machine:**",
|
|
228006
228713
|
"1. Set the environment variable before running OpenClaw:",
|
|
228007
228714
|
` \`export BLOCKRUN_WALLET_KEY=${walletKey}\``,
|
|
228008
228715
|
"2. Or save to file:",
|
|
228009
|
-
` \`mkdir -p ~/.
|
|
228716
|
+
` \`mkdir -p ~/.blockrun && echo "${walletKey}" > ~/.blockrun/.session && chmod 600 ~/.blockrun/.session\``
|
|
228010
228717
|
);
|
|
228011
228718
|
if (hasMnemonic3) {
|
|
228012
228719
|
lines.push(
|
|
@@ -228019,6 +228726,22 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
228019
228726
|
if (subcommand === "solana") {
|
|
228020
228727
|
try {
|
|
228021
228728
|
let solanaAddr;
|
|
228729
|
+
if (resolvedSolanaKey) {
|
|
228730
|
+
await savePaymentChain("solana");
|
|
228731
|
+
const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes3 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
|
|
228732
|
+
const signer2 = await createKeyPairSignerFromPrivateKeyBytes3(resolvedSolanaKey);
|
|
228733
|
+
solanaAddr = signer2.address;
|
|
228734
|
+
if (api) restartProxyForChainSwitch(api);
|
|
228735
|
+
return {
|
|
228736
|
+
text: [
|
|
228737
|
+
"\u2713 Payment chain switched to **Solana**.",
|
|
228738
|
+
api ? "Proxy restarting in background (~2s)." : "Restart the gateway to apply.",
|
|
228739
|
+
"",
|
|
228740
|
+
`**Solana Address:** \`${solanaAddr}\``,
|
|
228741
|
+
`**Fund with USDC on Solana:** https://solscan.io/account/${solanaAddr}`
|
|
228742
|
+
].join("\n")
|
|
228743
|
+
};
|
|
228744
|
+
}
|
|
228022
228745
|
if (existsSync4(MNEMONIC_FILE)) {
|
|
228023
228746
|
const existingMnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
228024
228747
|
if (existingMnemonic) {
|
|
@@ -228090,13 +228813,9 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
228090
228813
|
})();
|
|
228091
228814
|
const solanaPromise = (async () => {
|
|
228092
228815
|
try {
|
|
228093
|
-
if (!
|
|
228094
|
-
const { deriveSolanaKeyBytes: deriveSolanaKeyBytes2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
|
|
228095
|
-
const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
|
|
228096
|
-
if (!mnemonic) return "";
|
|
228097
|
-
const solKeyBytes = deriveSolanaKeyBytes2(mnemonic);
|
|
228816
|
+
if (!resolvedSolanaKey) return "";
|
|
228098
228817
|
const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes2 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
|
|
228099
|
-
const signer = await createKeyPairSignerFromPrivateKeyBytes2(
|
|
228818
|
+
const signer = await createKeyPairSignerFromPrivateKeyBytes2(resolvedSolanaKey);
|
|
228100
228819
|
const solAddr = signer.address;
|
|
228101
228820
|
let solBalanceText = "Balance: (could not check)";
|
|
228102
228821
|
try {
|
|
@@ -228157,7 +228876,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
228157
228876
|
solanaSection,
|
|
228158
228877
|
usageSection,
|
|
228159
228878
|
"",
|
|
228160
|
-
`**Key File:** \`${
|
|
228879
|
+
`**Key File:** \`${walletPath}\``,
|
|
228161
228880
|
"",
|
|
228162
228881
|
"**Commands:**",
|
|
228163
228882
|
"\u2022 `/wallet` - Show this status",
|
|
@@ -228171,7 +228890,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
|
|
|
228171
228890
|
}
|
|
228172
228891
|
};
|
|
228173
228892
|
}
|
|
228174
|
-
var activeProxyHandle, pendingConfiguredStartupApi, IMAGE_DIR2, AUDIO_DIR2, VIDEO_DIR2,
|
|
228893
|
+
var activeProxyHandle, liveSpendControl, pendingConfiguredStartupApi, IMAGE_DIR2, AUDIO_DIR2, VIDEO_DIR2, plugin, index_default2;
|
|
228175
228894
|
var init_index = __esm({
|
|
228176
228895
|
"src/index.ts"() {
|
|
228177
228896
|
"use strict";
|
|
@@ -228191,7 +228910,11 @@ var init_index = __esm({
|
|
|
228191
228910
|
init_tool();
|
|
228192
228911
|
init_stats2();
|
|
228193
228912
|
init_exclude();
|
|
228913
|
+
init_policy();
|
|
228914
|
+
init_spend_control();
|
|
228194
228915
|
init_mcp_config();
|
|
228916
|
+
init_openclaw_plugin_config();
|
|
228917
|
+
init_openclaw_plugin_config();
|
|
228195
228918
|
init_proxy();
|
|
228196
228919
|
init_provider();
|
|
228197
228920
|
init_models();
|
|
@@ -228210,11 +228933,11 @@ var init_index = __esm({
|
|
|
228210
228933
|
init_response_cache();
|
|
228211
228934
|
init_partners();
|
|
228212
228935
|
activeProxyHandle = null;
|
|
228936
|
+
liveSpendControl = null;
|
|
228213
228937
|
pendingConfiguredStartupApi = null;
|
|
228214
228938
|
IMAGE_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "images");
|
|
228215
228939
|
AUDIO_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "audio");
|
|
228216
228940
|
VIDEO_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "videos");
|
|
228217
|
-
BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
|
|
228218
228941
|
plugin = {
|
|
228219
228942
|
// NOT "clawrouter". OpenClaw bundles its own plugin under that id since the
|
|
228220
228943
|
// 2026.7.1 line (vendored at dist/extensions/clawrouter, provider `clawrouter/*`,
|
|
@@ -228232,7 +228955,6 @@ var init_index = __esm({
|
|
|
228232
228955
|
api.logger.info("ClawRouter disabled (CLAWROUTER_DISABLED=true). Using default routing.");
|
|
228233
228956
|
return;
|
|
228234
228957
|
}
|
|
228235
|
-
installSkillsToWorkspace(api.logger);
|
|
228236
228958
|
const proc = process;
|
|
228237
228959
|
const proxyAlreadyStarted = !!proc.__clawrouterProxyStarted;
|
|
228238
228960
|
if (isCompletionMode()) {
|
|
@@ -228525,9 +229247,14 @@ ${errText}`
|
|
|
228525
229247
|
}
|
|
228526
229248
|
api.registerCommand(createStatsCommand());
|
|
228527
229249
|
api.registerCommand(createExcludeCommand());
|
|
229250
|
+
api.registerCommand(
|
|
229251
|
+
createPolicyCommand({
|
|
229252
|
+
liveControl: () => activeProxyHandle ? liveSpendControl ?? void 0 : void 0
|
|
229253
|
+
})
|
|
229254
|
+
);
|
|
228528
229255
|
if (shouldLogRegistration) {
|
|
228529
229256
|
api.logger.info(
|
|
228530
|
-
"Commands registered: /wallet, /blockrun, /stats, /exclude, /partners, /cr-imagegen, /videogen, /cr-call"
|
|
229257
|
+
"Commands registered: /wallet, /blockrun, /stats, /exclude, /policy, /partners, /cr-imagegen, /videogen, /cr-call"
|
|
228531
229258
|
);
|
|
228532
229259
|
}
|
|
228533
229260
|
api.registerService({
|
|
@@ -228559,6 +229286,8 @@ ${errText}`
|
|
|
228559
229286
|
api.logger.warn(` Run /wallet export to get your private key`);
|
|
228560
229287
|
api.logger.warn(` Losing this key = losing your USDC funds`);
|
|
228561
229288
|
api.logger.warn(`\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`);
|
|
229289
|
+
} else if (source === "core") {
|
|
229290
|
+
api.logger.info(`Using BlockRun Core wallet: ${address2}`);
|
|
228562
229291
|
} else if (source === "saved") {
|
|
228563
229292
|
api.logger.info(`Using saved wallet: ${address2}`);
|
|
228564
229293
|
} else if (source === "config") {
|
|
@@ -228632,18 +229361,18 @@ ${errText}`
|
|
|
228632
229361
|
delete config.models.providers.blockrun;
|
|
228633
229362
|
}
|
|
228634
229363
|
removeManagedBlockrunMcpServerConfig(config);
|
|
228635
|
-
for (const key2 of [
|
|
228636
|
-
BLOCKRUN_PLUGIN_ID,
|
|
228637
|
-
"clawrouter",
|
|
228638
|
-
"ClawRouter",
|
|
228639
|
-
"@blockrun/clawrouter"
|
|
228640
|
-
]) {
|
|
229364
|
+
for (const key2 of [BLOCKRUN_PLUGIN_ID, "ClawRouter", "@blockrun/clawrouter"]) {
|
|
228641
229365
|
if (config.plugins?.entries?.[key2]) delete config.plugins.entries[key2];
|
|
228642
229366
|
if (config.plugins?.installs?.[key2]) delete config.plugins.installs[key2];
|
|
228643
229367
|
}
|
|
228644
229368
|
if (Array.isArray(config.plugins?.allow)) {
|
|
228645
229369
|
config.plugins.allow = config.plugins.allow.filter(
|
|
228646
|
-
(p) => p !== BLOCKRUN_PLUGIN_ID && p !== "
|
|
229370
|
+
(p) => p !== BLOCKRUN_PLUGIN_ID && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
|
|
229371
|
+
);
|
|
229372
|
+
}
|
|
229373
|
+
if (Array.isArray(config.plugins?.deny)) {
|
|
229374
|
+
config.plugins.deny = config.plugins.deny.filter(
|
|
229375
|
+
(p) => p !== BLOCKRUN_PLUGIN_ID && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
|
|
228647
229376
|
);
|
|
228648
229377
|
}
|
|
228649
229378
|
if (config.agents?.defaults?.models) {
|
|
@@ -228658,8 +229387,9 @@ ${errText}`
|
|
|
228658
229387
|
delete config.tools.web.search.provider;
|
|
228659
229388
|
}
|
|
228660
229389
|
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
228661
|
-
writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
|
|
229390
|
+
writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
228662
229391
|
renameSync2(tmpPath, configPath);
|
|
229392
|
+
chmodSync(configPath, 384);
|
|
228663
229393
|
api.logger.info("ClawRouter config cleaned up");
|
|
228664
229394
|
}
|
|
228665
229395
|
} catch (err) {
|
|
@@ -228676,7 +229406,7 @@ ${errText}`
|
|
|
228676
229406
|
const store = JSON.parse(readTextFileSync(authPath));
|
|
228677
229407
|
if (store.profiles?.["blockrun:default"]) {
|
|
228678
229408
|
delete store.profiles["blockrun:default"];
|
|
228679
|
-
|
|
229409
|
+
writePrivateJsonSync(authPath, store);
|
|
228680
229410
|
}
|
|
228681
229411
|
} catch {
|
|
228682
229412
|
}
|
|
@@ -228956,7 +229686,8 @@ function printDiagnostics(result) {
|
|
|
228956
229686
|
);
|
|
228957
229687
|
console.log("\nWallet");
|
|
228958
229688
|
if (result.wallet.exists && result.wallet.valid) {
|
|
228959
|
-
|
|
229689
|
+
const walletPath = result.wallet.source === "core" ? CORE_WALLET_FILE : WALLET_FILE;
|
|
229690
|
+
console.log(` ${green(`Key: ${walletPath} (${result.wallet.source})`)}`);
|
|
228960
229691
|
console.log(` ${green(`EVM Address: ${result.wallet.address}`)}`);
|
|
228961
229692
|
if (result.wallet.solanaAddress) {
|
|
228962
229693
|
console.log(` ${green(`Solana Address: ${result.wallet.solanaAddress}`)}`);
|
|
@@ -229151,6 +229882,7 @@ async function runDoctor(userQuestion, model = "sonnet") {
|
|
|
229151
229882
|
|
|
229152
229883
|
// src/cli.ts
|
|
229153
229884
|
init_partners();
|
|
229885
|
+
init_policy();
|
|
229154
229886
|
function printHelp() {
|
|
229155
229887
|
console.log(`
|
|
229156
229888
|
ClawRouter v${VERSION} - Smart LLM Router
|
|
@@ -229166,6 +229898,10 @@ Usage:
|
|
|
229166
229898
|
clawrouter report [daily|weekly|monthly] [--json]
|
|
229167
229899
|
clawrouter logs [--days <n>]
|
|
229168
229900
|
clawrouter setup # Finish OpenClaw integration after npm install -g
|
|
229901
|
+
clawrouter policy # Spend limits + payee/network/asset lists on disk
|
|
229902
|
+
clawrouter policy set|add|remove <list> <value>...
|
|
229903
|
+
clawrouter policy clear <list> # <list>: allowedPayees|blockedPayees|allowedNetworks|allowedAssets
|
|
229904
|
+
clawrouter policy limit <window> <usd>|clear # <window>: perRequest|hourly|daily|session
|
|
229169
229905
|
clawrouter share last [--as=<im>] # Convert most recent response for IM (default: feishu)
|
|
229170
229906
|
clawrouter share list [--limit=<n>] # Recent response ids + summaries
|
|
229171
229907
|
clawrouter share <id> [--as=<im>] # Convert a specific response by id
|
|
@@ -229182,6 +229918,7 @@ Options:
|
|
|
229182
229918
|
--version, -v Show version number
|
|
229183
229919
|
--help, -h Show this help message
|
|
229184
229920
|
--port <number> Port to listen on (default: ${getProxyPort()})
|
|
229921
|
+
--no-reuse Refuse an existing listener (used by managed Desktop startup)
|
|
229185
229922
|
|
|
229186
229923
|
Query Commands (talk to running proxy on localhost:${getProxyPort()}):
|
|
229187
229924
|
status Proxy status: wallet, balance, payment chain
|
|
@@ -229204,6 +229941,7 @@ Management Commands:
|
|
|
229204
229941
|
wallet recover Restore wallet.key from mnemonic (if generated by ClawRouter)
|
|
229205
229942
|
chain solana Switch to Solana (persists)
|
|
229206
229943
|
chain base Switch to Base EVM (persists)
|
|
229944
|
+
policy Edit spend limits and counterparty lists (fail-closed; restart proxy to apply)
|
|
229207
229945
|
|
|
229208
229946
|
Environment Variables:
|
|
229209
229947
|
BLOCKRUN_WALLET_KEY Private key for x402 payments (auto-generated if not set)
|
|
@@ -229435,9 +230173,9 @@ Usage Stats (last ${days} days)
|
|
|
229435
230173
|
}
|
|
229436
230174
|
}
|
|
229437
230175
|
async function cmdPhone(port, subcommand, numbersAction, arg, areaCode) {
|
|
229438
|
-
const
|
|
230176
|
+
const base4 = `http://127.0.0.1:${port}`;
|
|
229439
230177
|
async function postJson(path5, body) {
|
|
229440
|
-
const resp = await fetch(`${
|
|
230178
|
+
const resp = await fetch(`${base4}${path5}`, {
|
|
229441
230179
|
method: "POST",
|
|
229442
230180
|
headers: { "content-type": "application/json" },
|
|
229443
230181
|
body: JSON.stringify(body)
|
|
@@ -229571,10 +230309,22 @@ Cache Stats
|
|
|
229571
230309
|
}
|
|
229572
230310
|
async function cmdSetup() {
|
|
229573
230311
|
const { execFileSync, execSync } = await import("child_process");
|
|
229574
|
-
const {
|
|
229575
|
-
|
|
230312
|
+
const {
|
|
230313
|
+
copyFileSync: copyFileSync2,
|
|
230314
|
+
cpSync,
|
|
230315
|
+
existsSync: existsSync5,
|
|
230316
|
+
mkdirSync: mkdirSync4,
|
|
230317
|
+
readFileSync: readFileSync4,
|
|
230318
|
+
readdirSync: readdirSync2,
|
|
230319
|
+
renameSync: renameSync3,
|
|
230320
|
+
rmSync,
|
|
230321
|
+
unlinkSync: unlinkSync2,
|
|
230322
|
+
writeFileSync: writeFileSync4
|
|
230323
|
+
} = await import("fs");
|
|
230324
|
+
const { dirname: dirname4, join: join17 } = await import("path");
|
|
229576
230325
|
const { homedir: homedir14 } = await import("os");
|
|
229577
230326
|
const { injectModelsConfig: injectModelsConfig2, injectAuthProfile: injectAuthProfile2, syncAgentModelCache: syncAgentModelCache2, VISIBLE_OPENCLAW_MODELS: VISIBLE_OPENCLAW_MODELS2 } = await Promise.resolve().then(() => (init_index(), index_exports));
|
|
230327
|
+
const { BLOCKRUN_PLUGIN_ID: BLOCKRUN_PLUGIN_ID2, prepareBlockRunPluginConfig: prepareBlockRunPluginConfig2 } = await Promise.resolve().then(() => (init_openclaw_plugin_config(), openclaw_plugin_config_exports));
|
|
229578
230328
|
console.log("\u{1F99E} ClawRouter setup\n");
|
|
229579
230329
|
const openclawPath = (() => {
|
|
229580
230330
|
const candidates = [];
|
|
@@ -229594,7 +230344,7 @@ async function cmdSetup() {
|
|
|
229594
230344
|
encoding: "utf8",
|
|
229595
230345
|
stdio: ["ignore", "pipe", "ignore"]
|
|
229596
230346
|
}).trim();
|
|
229597
|
-
if (npmRoot) candidates.push(join17(
|
|
230347
|
+
if (npmRoot) candidates.push(join17(dirname4(dirname4(npmRoot)), "bin", "openclaw"));
|
|
229598
230348
|
} catch {
|
|
229599
230349
|
}
|
|
229600
230350
|
candidates.push(
|
|
@@ -229611,38 +230361,236 @@ async function cmdSetup() {
|
|
|
229611
230361
|
process.exit(1);
|
|
229612
230362
|
}
|
|
229613
230363
|
console.log(` \u2713 Found openclaw at ${openclawPath}`);
|
|
230364
|
+
const configPath = join17(homedir14(), ".openclaw", "openclaw.json");
|
|
230365
|
+
const configInitiallyExisted = existsSync5(configPath);
|
|
230366
|
+
const configRollbackBackup = configInitiallyExisted ? `${configPath}.before-${BLOCKRUN_PLUGIN_ID2}.${Date.now()}` : void 0;
|
|
230367
|
+
if (configRollbackBackup) copyFileSync2(configPath, configRollbackBackup);
|
|
230368
|
+
const ensureConfigRollbackBackup = () => {
|
|
230369
|
+
return configRollbackBackup;
|
|
230370
|
+
};
|
|
230371
|
+
let installAttempted = false;
|
|
230372
|
+
const openclawRoot = join17(homedir14(), ".openclaw");
|
|
230373
|
+
const findManagedBlockRunInstalls = () => {
|
|
230374
|
+
const candidates = [
|
|
230375
|
+
join17(openclawRoot, "extensions", BLOCKRUN_PLUGIN_ID2),
|
|
230376
|
+
join17(openclawRoot, "extensions", "clawrouter"),
|
|
230377
|
+
join17(openclawRoot, "npm", "node_modules", "@blockrun", "clawrouter")
|
|
230378
|
+
];
|
|
230379
|
+
const projectsDir = join17(openclawRoot, "npm", "projects");
|
|
230380
|
+
try {
|
|
230381
|
+
for (const project of readdirSync2(projectsDir)) {
|
|
230382
|
+
candidates.push(join17(projectsDir, project, "node_modules", "@blockrun", "clawrouter"));
|
|
230383
|
+
}
|
|
230384
|
+
} catch {
|
|
230385
|
+
}
|
|
230386
|
+
return [...new Set(candidates)].filter((candidate) => {
|
|
230387
|
+
try {
|
|
230388
|
+
const metadata = JSON.parse(readFileSync4(join17(candidate, "package.json"), "utf8"));
|
|
230389
|
+
return metadata.name === "@blockrun/clawrouter";
|
|
230390
|
+
} catch {
|
|
230391
|
+
return false;
|
|
230392
|
+
}
|
|
230393
|
+
});
|
|
230394
|
+
};
|
|
230395
|
+
const initialPluginDirs = findManagedBlockRunInstalls();
|
|
230396
|
+
const setupRollbackRoot = join17(
|
|
230397
|
+
openclawRoot,
|
|
230398
|
+
"blockrun",
|
|
230399
|
+
"setup-rollbacks",
|
|
230400
|
+
`${Date.now()}-${process.pid}`
|
|
230401
|
+
);
|
|
230402
|
+
const pluginRollbackBackups = /* @__PURE__ */ new Map();
|
|
230403
|
+
if (initialPluginDirs.length > 0) {
|
|
230404
|
+
mkdirSync4(setupRollbackRoot, { recursive: true, mode: 448 });
|
|
230405
|
+
for (const [index2, pluginDir] of initialPluginDirs.entries()) {
|
|
230406
|
+
const backup = join17(setupRollbackRoot, String(index2));
|
|
230407
|
+
cpSync(pluginDir, backup, { recursive: true });
|
|
230408
|
+
pluginRollbackBackups.set(pluginDir, backup);
|
|
230409
|
+
}
|
|
230410
|
+
}
|
|
230411
|
+
const restoreSetupConfig = () => {
|
|
230412
|
+
if (configRollbackBackup && existsSync5(configRollbackBackup)) {
|
|
230413
|
+
copyFileSync2(configRollbackBackup, configPath);
|
|
230414
|
+
console.error(` \u2713 Restored original OpenClaw config from ${configRollbackBackup}`);
|
|
230415
|
+
} else if (!configInitiallyExisted && existsSync5(configPath)) {
|
|
230416
|
+
rmSync(configPath);
|
|
230417
|
+
console.error(" \u2713 Removed the partially created OpenClaw config");
|
|
230418
|
+
}
|
|
230419
|
+
};
|
|
230420
|
+
const rollbackSetup = () => {
|
|
230421
|
+
if (installAttempted) {
|
|
230422
|
+
if (initialPluginDirs.length === 0) {
|
|
230423
|
+
try {
|
|
230424
|
+
execFileSync(openclawPath, ["plugins", "uninstall", "--force", BLOCKRUN_PLUGIN_ID2], {
|
|
230425
|
+
stdio: "ignore",
|
|
230426
|
+
timeout: 3e4
|
|
230427
|
+
});
|
|
230428
|
+
} catch {
|
|
230429
|
+
}
|
|
230430
|
+
}
|
|
230431
|
+
for (const currentDir of findManagedBlockRunInstalls()) {
|
|
230432
|
+
if (!pluginRollbackBackups.has(currentDir)) {
|
|
230433
|
+
rmSync(currentDir, { recursive: true, force: true });
|
|
230434
|
+
}
|
|
230435
|
+
}
|
|
230436
|
+
for (const [pluginDir, backup] of pluginRollbackBackups) {
|
|
230437
|
+
if (!existsSync5(backup)) continue;
|
|
230438
|
+
rmSync(pluginDir, { recursive: true, force: true });
|
|
230439
|
+
mkdirSync4(dirname4(pluginDir), { recursive: true });
|
|
230440
|
+
cpSync(backup, pluginDir, { recursive: true });
|
|
230441
|
+
}
|
|
230442
|
+
}
|
|
230443
|
+
restoreSetupConfig();
|
|
230444
|
+
rmSync(setupRollbackRoot, { recursive: true, force: true });
|
|
230445
|
+
};
|
|
230446
|
+
let legacyBlockRunInstall = false;
|
|
230447
|
+
let stagedLegacyEntry;
|
|
230448
|
+
if (existsSync5(configPath)) {
|
|
230449
|
+
try {
|
|
230450
|
+
const config = JSON.parse(readFileSync4(configPath, "utf8"));
|
|
230451
|
+
const legacyPackagePath = join17(
|
|
230452
|
+
homedir14(),
|
|
230453
|
+
".openclaw",
|
|
230454
|
+
"extensions",
|
|
230455
|
+
"clawrouter",
|
|
230456
|
+
"package.json"
|
|
230457
|
+
);
|
|
230458
|
+
if (existsSync5(legacyPackagePath)) {
|
|
230459
|
+
try {
|
|
230460
|
+
const legacyPackage = JSON.parse(readFileSync4(legacyPackagePath, "utf8"));
|
|
230461
|
+
legacyBlockRunInstall = legacyPackage.name === "@blockrun/clawrouter";
|
|
230462
|
+
} catch {
|
|
230463
|
+
}
|
|
230464
|
+
}
|
|
230465
|
+
let stripUnsupportedInstalls = false;
|
|
230466
|
+
try {
|
|
230467
|
+
execFileSync(openclawPath, ["config", "validate"], {
|
|
230468
|
+
encoding: "utf8",
|
|
230469
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
230470
|
+
timeout: 3e4
|
|
230471
|
+
});
|
|
230472
|
+
} catch (error) {
|
|
230473
|
+
const output = `${error instanceof Error ? error.message : String(error)} ${typeof error === "object" && error && "stdout" in error ? String(error.stdout) : ""} ${typeof error === "object" && error && "stderr" in error ? String(error.stderr) : ""}`;
|
|
230474
|
+
stripUnsupportedInstalls = output.includes("Unrecognized key") && output.includes("installs");
|
|
230475
|
+
}
|
|
230476
|
+
let configChanged = false;
|
|
230477
|
+
if (legacyBlockRunInstall) {
|
|
230478
|
+
const stagedConfig = structuredClone(config);
|
|
230479
|
+
prepareBlockRunPluginConfig2(stagedConfig, { legacyBlockRunInstall: true });
|
|
230480
|
+
const stagedPlugins = stagedConfig.plugins;
|
|
230481
|
+
const stagedEntries = stagedPlugins?.entries;
|
|
230482
|
+
stagedLegacyEntry = stagedEntries?.[BLOCKRUN_PLUGIN_ID2];
|
|
230483
|
+
const livePlugins = config.plugins;
|
|
230484
|
+
if (stagedEntries?.clawrouter && livePlugins?.entries?.clawrouter) {
|
|
230485
|
+
if (JSON.stringify(livePlugins.entries.clawrouter) !== JSON.stringify(stagedEntries.clawrouter)) {
|
|
230486
|
+
livePlugins.entries.clawrouter = stagedEntries.clawrouter;
|
|
230487
|
+
configChanged = true;
|
|
230488
|
+
}
|
|
230489
|
+
}
|
|
230490
|
+
}
|
|
230491
|
+
configChanged = prepareBlockRunPluginConfig2(config, { stripUnsupportedInstalls }) || configChanged;
|
|
230492
|
+
if (configChanged) {
|
|
230493
|
+
const backupPath = ensureConfigRollbackBackup();
|
|
230494
|
+
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
230495
|
+
writeFileSync4(tmpPath, `${JSON.stringify(config, null, 2)}
|
|
230496
|
+
`, { mode: 384 });
|
|
230497
|
+
renameSync3(tmpPath, configPath);
|
|
230498
|
+
console.log(` \u2713 Prepared OpenClaw 2.0 config (backup: ${backupPath})`);
|
|
230499
|
+
}
|
|
230500
|
+
} catch (err) {
|
|
230501
|
+
rollbackSetup();
|
|
230502
|
+
console.error(
|
|
230503
|
+
` \u2717 Cannot safely prepare OpenClaw config: ${err instanceof Error ? err.message : String(err)}`
|
|
230504
|
+
);
|
|
230505
|
+
process.exit(1);
|
|
230506
|
+
}
|
|
230507
|
+
}
|
|
229614
230508
|
console.log("\n\u2192 Registering ClawRouter with OpenClaw...");
|
|
229615
|
-
let installOk = false;
|
|
229616
230509
|
try {
|
|
229617
|
-
|
|
229618
|
-
|
|
230510
|
+
let acceptsCapabilities = false;
|
|
230511
|
+
try {
|
|
230512
|
+
const help = execFileSync(openclawPath, ["plugins", "install", "--help"], {
|
|
230513
|
+
encoding: "utf8",
|
|
230514
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
230515
|
+
timeout: 15e3
|
|
230516
|
+
});
|
|
230517
|
+
acceptsCapabilities = help.includes("--accept-capabilities");
|
|
230518
|
+
} catch {
|
|
230519
|
+
}
|
|
230520
|
+
const installSpec = process.env.BLOCKRUN_CLAWROUTER_INSTALL_SPEC ?? "@blockrun/clawrouter";
|
|
230521
|
+
const installArgs = ["plugins", "install", "--force"];
|
|
230522
|
+
if (acceptsCapabilities) installArgs.push("--accept-capabilities");
|
|
230523
|
+
installArgs.push(installSpec);
|
|
230524
|
+
installAttempted = true;
|
|
230525
|
+
execFileSync(openclawPath, installArgs, {
|
|
230526
|
+
stdio: "inherit",
|
|
230527
|
+
timeout: 18e4
|
|
229619
230528
|
});
|
|
229620
|
-
installOk = true;
|
|
229621
230529
|
} catch (err) {
|
|
229622
|
-
|
|
229623
|
-
|
|
230530
|
+
rollbackSetup();
|
|
230531
|
+
console.error(
|
|
230532
|
+
` \u2717 OpenClaw plugin install failed: ${err instanceof Error ? err.message : String(err)}`
|
|
229624
230533
|
);
|
|
229625
|
-
console.
|
|
229626
|
-
|
|
229627
|
-
" re-run `openclaw plugins install --force @blockrun/clawrouter` after gateway start."
|
|
230534
|
+
console.error(
|
|
230535
|
+
" Configuration was rolled back. Fix the error and run `clawrouter setup` again."
|
|
229628
230536
|
);
|
|
230537
|
+
process.exit(1);
|
|
230538
|
+
}
|
|
230539
|
+
if (existsSync5(configPath)) {
|
|
230540
|
+
try {
|
|
230541
|
+
const config = JSON.parse(readFileSync4(configPath, "utf8"));
|
|
230542
|
+
if (stagedLegacyEntry) {
|
|
230543
|
+
const plugins = config.plugins ??= {};
|
|
230544
|
+
const entries = plugins.entries ??= {};
|
|
230545
|
+
const current = entries[BLOCKRUN_PLUGIN_ID2] ?? {};
|
|
230546
|
+
const stagedConfig = stagedLegacyEntry.config;
|
|
230547
|
+
const currentConfig = current.config;
|
|
230548
|
+
entries[BLOCKRUN_PLUGIN_ID2] = {
|
|
230549
|
+
...stagedLegacyEntry,
|
|
230550
|
+
...current,
|
|
230551
|
+
...stagedConfig || currentConfig ? { config: { ...stagedConfig, ...currentConfig } } : {}
|
|
230552
|
+
};
|
|
230553
|
+
}
|
|
230554
|
+
const configChanged = prepareBlockRunPluginConfig2(config, {
|
|
230555
|
+
explicitSetup: true,
|
|
230556
|
+
legacyBlockRunInstall
|
|
230557
|
+
});
|
|
230558
|
+
if (stagedLegacyEntry || configChanged) {
|
|
230559
|
+
const backupPath = ensureConfigRollbackBackup();
|
|
230560
|
+
const tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
230561
|
+
writeFileSync4(tmpPath, `${JSON.stringify(config, null, 2)}
|
|
230562
|
+
`, { mode: 384 });
|
|
230563
|
+
renameSync3(tmpPath, configPath);
|
|
230564
|
+
console.log(
|
|
230565
|
+
` \u2713 Enabled ${BLOCKRUN_PLUGIN_ID2}${backupPath ? ` (backup: ${backupPath})` : ""}`
|
|
230566
|
+
);
|
|
230567
|
+
}
|
|
230568
|
+
} catch (err) {
|
|
230569
|
+
rollbackSetup();
|
|
230570
|
+
console.error(
|
|
230571
|
+
` \u2717 Plugin installed, but its config could not be enabled safely: ${err instanceof Error ? err.message : String(err)}`
|
|
230572
|
+
);
|
|
230573
|
+
process.exit(1);
|
|
230574
|
+
}
|
|
229629
230575
|
}
|
|
229630
230576
|
console.log("\n\u2192 Syncing models allowlist + auth profile...");
|
|
229631
230577
|
const setupLogger = {
|
|
229632
230578
|
info: (msg) => console.log(` ${msg}`)
|
|
229633
230579
|
};
|
|
229634
230580
|
try {
|
|
230581
|
+
if (existsSync5(configPath)) ensureConfigRollbackBackup();
|
|
229635
230582
|
injectModelsConfig2(setupLogger, { forceWrite: true });
|
|
229636
230583
|
syncAgentModelCache2(setupLogger, { forceWrite: true });
|
|
229637
230584
|
injectAuthProfile2(setupLogger);
|
|
229638
230585
|
} catch (err) {
|
|
230586
|
+
rollbackSetup();
|
|
229639
230587
|
console.error(` \u2717 Config sync failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
229640
230588
|
process.exit(1);
|
|
229641
230589
|
}
|
|
229642
|
-
|
|
229643
|
-
|
|
229644
|
-
|
|
229645
|
-
|
|
230590
|
+
console.log("\n\u2713 Setup complete.");
|
|
230591
|
+
rmSync(setupRollbackRoot, { recursive: true, force: true });
|
|
230592
|
+
if (configRollbackBackup && existsSync5(configRollbackBackup)) {
|
|
230593
|
+
unlinkSync2(configRollbackBackup);
|
|
229646
230594
|
}
|
|
229647
230595
|
console.log("\nNext: restart the gateway to load ClawRouter:");
|
|
229648
230596
|
console.log(" openclaw gateway restart");
|
|
@@ -229666,6 +230614,7 @@ function parseArgs(args) {
|
|
|
229666
230614
|
walletRecover: false,
|
|
229667
230615
|
chain: void 0,
|
|
229668
230616
|
port: void 0,
|
|
230617
|
+
noReuse: false,
|
|
229669
230618
|
queryStatus: false,
|
|
229670
230619
|
queryWallet: false,
|
|
229671
230620
|
queryModels: false,
|
|
@@ -229682,7 +230631,9 @@ function parseArgs(args) {
|
|
|
229682
230631
|
phoneSubcommand: void 0,
|
|
229683
230632
|
phoneNumbersAction: void 0,
|
|
229684
230633
|
phoneArg: void 0,
|
|
229685
|
-
phoneAreaCode: void 0
|
|
230634
|
+
phoneAreaCode: void 0,
|
|
230635
|
+
policy: false,
|
|
230636
|
+
policyArgs: []
|
|
229686
230637
|
};
|
|
229687
230638
|
for (let i = 0; i < args.length; i++) {
|
|
229688
230639
|
const arg = args[i];
|
|
@@ -229743,9 +230694,15 @@ function parseArgs(args) {
|
|
|
229743
230694
|
} else if ((arg === "chain" || arg === "/wallet") && (args[i + 1] === "solana" || args[i + 1] === "base")) {
|
|
229744
230695
|
result.chain = args[i + 1];
|
|
229745
230696
|
i++;
|
|
230697
|
+
} else if (arg === "policy") {
|
|
230698
|
+
result.policy = true;
|
|
230699
|
+
result.policyArgs = args.slice(i + 1);
|
|
230700
|
+
break;
|
|
229746
230701
|
} else if (arg === "--port" && args[i + 1]) {
|
|
229747
230702
|
result.port = parseInt(args[i + 1], 10);
|
|
229748
230703
|
i++;
|
|
230704
|
+
} else if (arg === "--no-reuse") {
|
|
230705
|
+
result.noReuse = true;
|
|
229749
230706
|
} else if (arg === "setup") {
|
|
229750
230707
|
result.setup = true;
|
|
229751
230708
|
} else if (arg === "phone") {
|
|
@@ -229833,6 +230790,15 @@ async function main() {
|
|
|
229833
230790
|
await cmdSetup();
|
|
229834
230791
|
process.exit(0);
|
|
229835
230792
|
}
|
|
230793
|
+
if (args.policy) {
|
|
230794
|
+
const result = runPolicyCommand(args.policyArgs);
|
|
230795
|
+
if (result.isError) {
|
|
230796
|
+
console.error(`\u2717 ${result.text}`);
|
|
230797
|
+
process.exit(1);
|
|
230798
|
+
}
|
|
230799
|
+
console.log(result.text);
|
|
230800
|
+
process.exit(0);
|
|
230801
|
+
}
|
|
229836
230802
|
const queryPort = args.port ?? getProxyPort();
|
|
229837
230803
|
if (args.queryStatus) {
|
|
229838
230804
|
await cmdStatus(queryPort);
|
|
@@ -229950,16 +230916,13 @@ ClawRouter Partner APIs (v${VERSION})
|
|
|
229950
230916
|
if (args.chain) {
|
|
229951
230917
|
const targetChain = args.chain;
|
|
229952
230918
|
if (targetChain === "solana") {
|
|
229953
|
-
const { existsSync: existsSync5 } = await import("fs");
|
|
229954
230919
|
const { MNEMONIC_FILE: MNEMONIC_FILE2, setupSolana: setupSolana2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
229955
|
-
const {
|
|
230920
|
+
const { getSolanaAddress: getSolanaAddress2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
|
|
230921
|
+
const wallet2 = await resolveOrGenerateWalletKey();
|
|
229956
230922
|
let solanaAddr;
|
|
229957
|
-
if (
|
|
229958
|
-
|
|
229959
|
-
|
|
229960
|
-
const keyBytes = deriveSolanaKeyBytes2(mnemonic);
|
|
229961
|
-
solanaAddr = await getSolanaAddress2(keyBytes);
|
|
229962
|
-
console.log(`[ClawRouter] Solana wallet already set up.`);
|
|
230923
|
+
if (wallet2.solanaPrivateKeyBytes) {
|
|
230924
|
+
solanaAddr = await getSolanaAddress2(wallet2.solanaPrivateKeyBytes);
|
|
230925
|
+
console.log(`[ClawRouter] Using BlockRun Core Solana wallet.`);
|
|
229963
230926
|
} else {
|
|
229964
230927
|
console.log(`[ClawRouter] Setting up Solana wallet...`);
|
|
229965
230928
|
const { solanaPrivateKeyBytes } = await setupSolana2();
|
|
@@ -229989,6 +230952,8 @@ ClawRouter Partner APIs (v${VERSION})
|
|
|
229989
230952
|
const wallet = await resolveOrGenerateWalletKey();
|
|
229990
230953
|
if (wallet.source === "generated") {
|
|
229991
230954
|
console.log(`[ClawRouter] Generated new wallet: ${wallet.address}`);
|
|
230955
|
+
} else if (wallet.source === "core") {
|
|
230956
|
+
console.log(`[ClawRouter] Using BlockRun Core wallet: ${wallet.address}`);
|
|
229992
230957
|
} else if (wallet.source === "saved") {
|
|
229993
230958
|
console.log(`[ClawRouter] Using saved wallet: ${wallet.address}`);
|
|
229994
230959
|
} else if (wallet.source === "config") {
|
|
@@ -230006,6 +230971,7 @@ ClawRouter Partner APIs (v${VERSION})
|
|
|
230006
230971
|
const proxy = await startProxy({
|
|
230007
230972
|
wallet,
|
|
230008
230973
|
port: args.port,
|
|
230974
|
+
allowExistingProxy: !args.noReuse,
|
|
230009
230975
|
onReady: (port) => {
|
|
230010
230976
|
console.log(`[ClawRouter] v${VERSION} | Proxy listening on http://127.0.0.1:${port}`);
|
|
230011
230977
|
console.log(`[ClawRouter] Health check: http://127.0.0.1:${port}/health`);
|