@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/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 base3 = p;
5789
+ let base4 = p;
5790
5790
  for (let window2 = 0; window2 < windows; window2++) {
5791
- base3 = p;
5792
- points.push(base3);
5791
+ base4 = p;
5792
+ points.push(base4);
5793
5793
  for (let i = 1; i < windowSize; i++) {
5794
- base3 = base3.add(p);
5795
- points.push(base3);
5794
+ base4 = base4.add(p);
5795
+ points.push(base4);
5796
5796
  }
5797
- p = base3.double();
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 = (base3) => base3 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
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 = (base3) => base3 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
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 base3 = [
11864
+ const base4 = [
11865
11865
  request2,
11866
11866
  block
11867
11867
  ];
11868
11868
  if (rpcStateOverride && rpcBlockOverrides)
11869
- return [...base3, rpcStateOverride, rpcBlockOverrides];
11869
+ return [...base4, rpcStateOverride, rpcBlockOverrides];
11870
11870
  if (rpcStateOverride)
11871
- return [...base3, rpcStateOverride];
11871
+ return [...base4, rpcStateOverride];
11872
11872
  if (rpcBlockOverrides)
11873
- return [...base3, {}, rpcBlockOverrides];
11874
- return base3;
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(base3) {
13280
+ function extend2(base4) {
13281
13281
  return (extendFn) => {
13282
- const extended = extendFn(base3);
13282
+ const extended = extendFn(base4);
13283
13283
  for (const key3 in client)
13284
13284
  delete extended[key3];
13285
- const combined = { ...base3, ...extended };
13285
+ const combined = { ...base4, ...extended };
13286
13286
  for (const key3 in extended) {
13287
- const a = base3[key3];
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(base3) {
15040
+ function extend2(base4) {
15041
15041
  return (fnOrExtended) => {
15042
- const properties = typeof fnOrExtended === "function" ? fnOrExtended(base3) : fnOrExtended;
15043
- const combined = { ...base3, ...properties };
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, base3, size_] = integerMatch;
15407
+ const [_type, base4, size_] = integerMatch;
15408
15408
  numberToHex(value, {
15409
- signed: base3 === "int",
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 base3 = p;
18038
+ let base4 = p;
18039
18039
  for (let window2 = 0; window2 < windows; window2++) {
18040
- base3 = p;
18041
- points.push(base3);
18040
+ base4 = p;
18041
+ points.push(base4);
18042
18042
  for (let i = 1; i < windowSize; i++) {
18043
- base3 = base3.add(p);
18044
- points.push(base3);
18043
+ base4 = base4.add(p);
18044
+ points.push(base4);
18045
18045
  }
18046
- p = base3.double();
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 base3 = this._def.schema._parseSync({
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(base3))
30635
+ if (!isValid(base4))
30636
30636
  return INVALID;
30637
- const result = effect.transform(base3.value, checkCtx);
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((base3) => {
30644
- if (!isValid(base3))
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(base3.value, checkCtx)).then((result) => ({
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 base3 = 0.68;
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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
- base3,
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 base3 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
36109
+ const base4 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
36042
36110
  ...options,
36043
36111
  requiresTools: features.needsTools
36044
36112
  });
36045
- const tierConfigs = base3.tierConfigs;
36046
- if (!tierConfigs) return base3;
36047
- const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (base3.tier === "SIMPLE" || base3.tier === "MEDIUM") ? "REASONING" : base3.tier;
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 base3;
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] ?? base3.model;
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
- base3.confidence,
36208
+ base4.confidence,
36141
36209
  "portfolio",
36142
- `${base3.reasoning} | v3 task=${features.taskType} agentRisk=${features.agentRisk} deepWebResearch=${features.deepWebResearch} terminalCode=${features.implicitTerminalCode} terminalSafety=${features.terminalSafetySensitive} candidates=${ranked.length}`,
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
- base3.agenticScore
36216
+ base4.agenticScore
36149
36217
  );
36150
36218
  return {
36151
36219
  ...decision,
36152
36220
  tierConfigs: selectedTierConfigs,
36153
- profile: base3.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 base3 = p;
42136
+ let base4 = p;
41921
42137
  for (let window2 = 0; window2 < windows; window2++) {
41922
- base3 = p;
41923
- points.push(base3);
42138
+ base4 = p;
42139
+ points.push(base4);
41924
42140
  for (let i = 1; i < windowSize; i++) {
41925
- base3 = base3.add(p);
41926
- points.push(base3);
42141
+ base4 = base4.add(p);
42142
+ points.push(base4);
41927
42143
  }
41928
- p = base3.double();
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 base3 = BigInt(alphabet4.length);
46664
+ const base4 = BigInt(alphabet4.length);
46418
46665
  let sum = 0n;
46419
46666
  for (const char of value) {
46420
- sum *= base3;
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 base3 = BigInt(alphabet4.length);
46673
+ const base4 = BigInt(alphabet4.length);
46427
46674
  const tailChars = [];
46428
46675
  while (value > 0n) {
46429
- tailChars.unshift(alphabet4[Number(value % base3)]);
46430
- value /= base3;
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 base3 = BigInt(alphabet4.length);
48724
+ const base4 = BigInt(alphabet4.length);
48478
48725
  let sum = 0n;
48479
48726
  for (const char of value) {
48480
- sum *= base3;
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 base3 = BigInt(alphabet4.length);
48733
+ const base4 = BigInt(alphabet4.length);
48487
48734
  const tailChars = [];
48488
48735
  while (value > 0n) {
48489
- tailChars.unshift(alphabet4[Number(value % base3)]);
48490
- value /= base3;
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, SOLANA_HARDENED_INDICES;
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 generateAndSaveWallet() {
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
- await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
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(derived.solanaPrivateKeyBytes);
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] Key file : ${WALLET_FILE}`);
59432
- console.log(`[ClawRouter] Mnemonic : ${MNEMONIC_FILE}`);
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: derived.solanaPrivateKeyBytes
59757
+ ...existingCoreSolanaKey ? {} : { mnemonic },
59758
+ solanaPrivateKeyBytes
59453
59759
  };
59454
59760
  }
59455
- async function resolveOrGenerateWalletKey() {
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
- const mnemonic = await loadMnemonic();
59460
- if (mnemonic) {
59461
- const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59462
- return {
59463
- key: saved,
59464
- address: account.address,
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
- const result = await generateAndSaveWallet();
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
- console.log(`[ClawRouter] \u2713 wallet.key restored at ${WALLET_FILE}`);
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 savedKey = await loadSavedWallet();
59540
- if (!savedKey) {
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] Mnemonic saved to ${MNEMONIC_FILE}`);
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 writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
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: dirname5, resolve } = __require("path");
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(dirname5(resolvedPath), { recursive: true });
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: model.id,
90683
- object: "model",
90684
- created: createdAt,
90685
- owned_by: model.id.includes("/") ? model.id.split("/")[0] ?? "blockrun" : "blockrun"
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
- res.writeHead(200, { "Content-Type": "application/json" });
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 auto-generates a wallet on first run and stores it at
95632
- // ~/.openclaw/blockrun/wallet.key. Users just fund that wallet with USDC.
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, ALPHABET, generateString, node_default;
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
- ALPHABET = {
109655
+ ALPHABET2 = {
109026
109656
  DIGIT,
109027
109657
  ALPHA,
109028
109658
  ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT
109029
109659
  };
109030
- generateString = (size5 = 16, alphabet4 = ALPHABET.ALPHA_DIGIT) => {
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, base3) {
111112
- return useNativeURL ? new URL3(relative, base3) : parseUrl3(url2.resolve(base3, 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 fail(e7) {
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
- fail(e7);
118565
+ fail2(e7);
117936
118566
  return next();
117937
118567
  });
117938
118568
  } else s3 |= 1;
117939
118569
  } catch (e7) {
117940
- fail(e7);
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 base3 = p;
125740
+ let base4 = p;
125111
125741
  for (let window2 = 0; window2 < windows; window2++) {
125112
- base3 = p;
125113
- points.push(base3);
125742
+ base4 = p;
125743
+ points.push(base4);
125114
125744
  for (let i = 1; i < windowSize; i++) {
125115
- base3 = base3.add(p);
125116
- points.push(base3);
125745
+ base4 = base4.add(p);
125746
+ points.push(base4);
125117
125747
  }
125118
- p = base3.double();
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 = (base3) => base3 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
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 = (base3) => base3 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
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 base3 = [
133774
+ const base4 = [
133145
133775
  request2,
133146
133776
  block
133147
133777
  ];
133148
133778
  if (rpcStateOverride && rpcBlockOverrides)
133149
- return [...base3, rpcStateOverride, rpcBlockOverrides];
133779
+ return [...base4, rpcStateOverride, rpcBlockOverrides];
133150
133780
  if (rpcStateOverride)
133151
- return [...base3, rpcStateOverride];
133781
+ return [...base4, rpcStateOverride];
133152
133782
  if (rpcBlockOverrides)
133153
- return [...base3, {}, rpcBlockOverrides];
133154
- return base3;
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(base3) {
135396
+ function extend2(base4) {
134767
135397
  return (extendFn) => {
134768
- const extended = extendFn(base3);
135398
+ const extended = extendFn(base4);
134769
135399
  for (const key3 in client)
134770
135400
  delete extended[key3];
134771
- const combined = { ...base3, ...extended };
135401
+ const combined = { ...base4, ...extended };
134772
135402
  for (const key3 in extended) {
134773
- const a = base3[key3];
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(base3) {
137421
+ function extend2(base4) {
136792
137422
  return (fnOrExtended) => {
136793
- const properties = typeof fnOrExtended === "function" ? fnOrExtended(base3) : fnOrExtended;
136794
- const combined = { ...base3, ...properties };
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, base3, size_] = integerMatch;
138759
+ const [_type, base4, size_] = integerMatch;
138130
138760
  (0, toHex_js_1.numberToHex)(value, {
138131
- signed: base3 === "int",
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 base3 = p;
142553
+ let base4 = p;
141924
142554
  for (let window2 = 0; window2 < windows; window2++) {
141925
- base3 = p;
141926
- points.push(base3);
142555
+ base4 = p;
142556
+ points.push(base4);
141927
142557
  for (let i = 1; i < windowSize; i++) {
141928
- base3 = base3.add(p);
141929
- points.push(base3);
142558
+ base4 = base4.add(p);
142559
+ points.push(base4);
141930
142560
  }
141931
- p = base3.double();
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 base3 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
176074
+ const base4 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
175445
176075
  if (!credential)
175446
- return base3;
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(base3, aaguid, credIdLen, credentialId, coseKey);
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 fail = (error) => {
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
- fail(new Errors.BaseError(msg.message));
180014
+ fail2(new Errors.BaseError(msg.message));
179385
180015
  return;
179386
180016
  }
179387
180017
  };
179388
- const onAbort = () => fail(getAbortError2(value.signal));
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, fail);
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: base3, range } = getChainIdConfig(sourceId2);
179536
- return base3 + zoneId % range;
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, base3, endian) {
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 (base3 === "le" || base3 === "be") {
193152
- endian = base3;
193153
- base3 = 10;
193781
+ if (base4 === "le" || base4 === "be") {
193782
+ endian = base4;
193783
+ base4 = 10;
193154
193784
  }
193155
- this._init(number || 0, base3 || 10, endian || "be");
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, base3, endian) {
193818
+ BN3.prototype._init = function init2(number, base4, endian) {
193189
193819
  if (typeof number === "number") {
193190
- return this._initNumber(number, base3, endian);
193820
+ return this._initNumber(number, base4, endian);
193191
193821
  }
193192
193822
  if (typeof number === "object") {
193193
- return this._initArray(number, base3, endian);
193823
+ return this._initArray(number, base4, endian);
193194
193824
  }
193195
- if (base3 === "hex") {
193196
- base3 = 16;
193825
+ if (base4 === "hex") {
193826
+ base4 = 16;
193197
193827
  }
193198
- assert10(base3 === (base3 | 0) && base3 >= 2 && base3 <= 36);
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 (base3 === 16) {
193836
+ if (base4 === 16) {
193207
193837
  this._parseHex(number, start, endian);
193208
193838
  } else {
193209
- this._parseBase(number, base3, start);
193839
+ this._parseBase(number, base4, start);
193210
193840
  if (endian === "le") {
193211
- this._initArray(this.toArray(), base3, endian);
193841
+ this._initArray(this.toArray(), base4, endian);
193212
193842
  }
193213
193843
  }
193214
193844
  }
193215
193845
  };
193216
- BN3.prototype._initNumber = function _initNumber(number, base3, endian) {
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(), base3, endian);
193870
+ this._initArray(this.toArray(), base4, endian);
193241
193871
  };
193242
- BN3.prototype._initArray = function _initArray(number, base3, endian) {
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, base3, start) {
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 *= base3) {
193989
+ for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *= base4) {
193360
193990
  limbLen++;
193361
193991
  }
193362
193992
  limbLen--;
193363
- limbPow = limbPow / base3 | 0;
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, base3);
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, base3);
194009
+ word = parseBase(number, i, number.length, base4);
193380
194010
  for (i = 0; i < mod5; i++) {
193381
- pow *= base3;
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(base3, padding3) {
193552
- base3 = base3 || 10;
194181
+ BN3.prototype.toString = function toString4(base4, padding3) {
194182
+ base4 = base4 || 10;
193553
194183
  padding3 = padding3 | 0 || 1;
193554
194184
  var out;
193555
- if (base3 === 16 || base3 === "hex") {
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 (base3 === (base3 | 0) && base3 >= 2 && base3 <= 36) {
193586
- var groupSize = groupSizes[base3];
193587
- var groupBase = groupBases[base3];
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(base3);
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, base3) {
204162
- return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
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
- base2.call(this, "short", conf);
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
- base2.BasePoint.call(this, curve, "affine");
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
- base2.BasePoint.call(this, curve, "jacobian");
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, base2, 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;
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
- base2 = BaseCurve;
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, base2);
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, base2.BasePoint);
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, base2.BasePoint);
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 = base2;
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 ALPHABET2 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
211332
+ var ALPHABET3 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
210703
211333
  var ALPHABET_MAP = {};
210704
- for (z = 0; z < ALPHABET2.length; z++) {
210705
- x = ALPHABET2.charAt(z);
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 += ALPHABET2.charAt(x2);
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 += ALPHABET2.charAt(v);
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 ALPHABET2 = {
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 = ALPHABET2.ALPHA_DIGIT) => {
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: ALPHABET2,
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 base3 = await mapClobError(err);
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: `${base3}${/revert|execution reverted|failed/i.test(base3) ? legacyHint : ""}`,
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 base3 = `${this.apiUrl}${normalized}`;
226128
- if (!params) return base3;
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 ? `${base3}?${query}` : base3;
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 base3 = this.apiUrl.endsWith("/api") ? this.apiUrl.slice(0, -"/api".length) : this.apiUrl;
226147
- return `${base3}${url2}`;
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 { join as join16, dirname as dirname4 } from "path";
226920
- import { fileURLToPath as fileURLToPath2 } from "url";
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 getPackageRoot() {
226934
- return join16(dirname4(fileURLToPath2(import.meta.url)), "..");
226935
- }
226936
- function installSkillsToWorkspace(logger48) {
227672
+ function writePrivateJsonSync(path5, value) {
227673
+ const temporary = `${path5}.tmp.${randomUUID()}`;
226937
227674
  try {
226938
- const packageRoot = getPackageRoot();
226939
- const bundledSkillsDir = join16(packageRoot, "skills");
226940
- if (!existsSync4(bundledSkillsDir)) {
226941
- return;
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 pluginEntries = config.plugins?.entries;
227154
- if (pluginEntries && pluginEntries.clawrouter && !pluginEntries[BLOCKRUN_PLUGIN_ID]) {
227155
- pluginEntries[BLOCKRUN_PLUGIN_ID] = pluginEntries.clawrouter;
227156
- delete pluginEntries.clawrouter;
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
- "Migrated plugins.entries.clawrouter -> blockrun-clawrouter (OpenClaw bundles its own `clawrouter` plugin; see #305)"
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
- writeFileSync3(authPath, JSON.stringify(store, null, 2));
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 saved wallet`
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: () => existsSync4(WALLET_FILE),
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: () => existsSync4(WALLET_FILE),
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: () => existsSync4(WALLET_FILE),
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 walletKey;
227948
- let address2;
228642
+ let wallet;
227949
228643
  try {
227950
- if (existsSync4(WALLET_FILE)) {
227951
- walletKey = readTextFileSync(WALLET_FILE).trim();
227952
- if (walletKey.startsWith("0x") && walletKey.length === 66) {
227953
- const account = privateKeyToAccount(walletKey);
227954
- address2 = account.address;
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 (!walletKey || !address2) {
228651
+ if (!wallet) {
227960
228652
  return {
227961
- text: `No ClawRouter wallet found.
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 ~/.openclaw/blockrun && echo "${walletKey}" > ~/.openclaw/blockrun/wallet.key && chmod 600 ~/.openclaw/blockrun/wallet.key\``
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 (!existsSync4(MNEMONIC_FILE)) return "";
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(solKeyBytes);
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:** \`${WALLET_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, BLOCKRUN_PLUGIN_ID, plugin, index_default2;
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 !== "clawrouter" && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
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
- writeFileSync3(authPath, JSON.stringify(store, null, 2));
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
- console.log(` ${green(`Key: ${WALLET_FILE} (${result.wallet.source})`)}`);
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 base3 = `http://127.0.0.1:${port}`;
230176
+ const base4 = `http://127.0.0.1:${port}`;
229439
230177
  async function postJson(path5, body) {
229440
- const resp = await fetch(`${base3}${path5}`, {
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 { existsSync: existsSync5 } = await import("fs");
229575
- const { dirname: dirname5, join: join17 } = await import("path");
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(dirname5(dirname5(npmRoot)), "bin", "openclaw"));
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
- execFileSync(openclawPath, ["plugins", "install", "--force", "@blockrun/clawrouter"], {
229618
- stdio: "inherit"
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
- console.warn(
229623
- ` \u26A0 openclaw plugins install reported a problem: ${err instanceof Error ? err.message : String(err)}`
230530
+ rollbackSetup();
230531
+ console.error(
230532
+ ` \u2717 OpenClaw plugin install failed: ${err instanceof Error ? err.message : String(err)}`
229624
230533
  );
229625
- console.warn(" Continuing with manual config sync \u2014 if validation rejected the install,");
229626
- console.warn(
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
- if (installOk) {
229643
- console.log("\n\u2713 Setup complete.");
229644
- } else {
229645
- console.log("\n\u2713 Models config synced (plugin registration may need a manual retry).");
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 { deriveSolanaKeyBytes: deriveSolanaKeyBytes2, getSolanaAddress: getSolanaAddress2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
230920
+ const { getSolanaAddress: getSolanaAddress2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
230921
+ const wallet2 = await resolveOrGenerateWalletKey();
229956
230922
  let solanaAddr;
229957
- if (existsSync5(MNEMONIC_FILE2)) {
229958
- const { readFileSync: readFileSync4 } = await import("fs");
229959
- const mnemonic = readFileSync4(MNEMONIC_FILE2, "utf8").trim();
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`);