@blockrun/clawrouter 0.12.265 → 0.12.267

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/index.js CHANGED
@@ -8006,15 +8006,15 @@ function wNAF(c, bits) {
8006
8006
  const { windows, windowSize } = calcWOpts(W, bits);
8007
8007
  const points = [];
8008
8008
  let p = elm;
8009
- let base3 = p;
8009
+ let base4 = p;
8010
8010
  for (let window2 = 0; window2 < windows; window2++) {
8011
- base3 = p;
8012
- points.push(base3);
8011
+ base4 = p;
8012
+ points.push(base4);
8013
8013
  for (let i = 1; i < windowSize; i++) {
8014
- base3 = base3.add(p);
8015
- points.push(base3);
8014
+ base4 = base4.add(p);
8015
+ points.push(base4);
8016
8016
  }
8017
- p = base3.double();
8017
+ p = base4.double();
8018
8018
  }
8019
8019
  return points;
8020
8020
  },
@@ -10652,7 +10652,7 @@ async function internal_estimateFeesPerGas(client, args) {
10652
10652
  throw new BaseFeeScalarError();
10653
10653
  const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
10654
10654
  const denominator = 10 ** decimals;
10655
- const multiply = (base3) => base3 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
10655
+ const multiply = (base4) => base4 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
10656
10656
  const block = block_ ? block_ : await getAction(client, getBlock, "getBlock")({});
10657
10657
  if (typeof chain3?.fees?.estimateFeesPerGas === "function") {
10658
10658
  const fees = await chain3.fees.estimateFeesPerGas({
@@ -11123,7 +11123,7 @@ async function fillTransaction(client, parameters) {
11123
11123
  throw new BaseFeeScalarError();
11124
11124
  const decimals = feeMultiplier.toString().split(".")[1]?.length ?? 0;
11125
11125
  const denominator = 10 ** decimals;
11126
- const multiplyFee = (base3) => base3 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
11126
+ const multiplyFee = (base4) => base4 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
11127
11127
  if (!transaction.feePayerSignature) {
11128
11128
  if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
11129
11129
  transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas);
@@ -14081,17 +14081,17 @@ async function call(client, args) {
14081
14081
  }
14082
14082
  }
14083
14083
  const params = (() => {
14084
- const base3 = [
14084
+ const base4 = [
14085
14085
  request2,
14086
14086
  block
14087
14087
  ];
14088
14088
  if (rpcStateOverride && rpcBlockOverrides)
14089
- return [...base3, rpcStateOverride, rpcBlockOverrides];
14089
+ return [...base4, rpcStateOverride, rpcBlockOverrides];
14090
14090
  if (rpcStateOverride)
14091
- return [...base3, rpcStateOverride];
14091
+ return [...base4, rpcStateOverride];
14092
14092
  if (rpcBlockOverrides)
14093
- return [...base3, {}, rpcBlockOverrides];
14094
- return base3;
14093
+ return [...base4, {}, rpcBlockOverrides];
14094
+ return base4;
14095
14095
  })();
14096
14096
  const response = await client.request({
14097
14097
  method: "eth_call",
@@ -15497,14 +15497,14 @@ function createClient(parameters) {
15497
15497
  uid: uid(),
15498
15498
  ...experimental_blockTag ? { experimental_blockTag } : {}
15499
15499
  };
15500
- function extend2(base3) {
15500
+ function extend2(base4) {
15501
15501
  return (extendFn) => {
15502
- const extended = extendFn(base3);
15502
+ const extended = extendFn(base4);
15503
15503
  for (const key3 in client)
15504
15504
  delete extended[key3];
15505
- const combined = { ...base3, ...extended };
15505
+ const combined = { ...base4, ...extended };
15506
15506
  for (const key3 in extended) {
15507
- const a = base3[key3];
15507
+ const a = base4[key3];
15508
15508
  const b = extended[key3];
15509
15509
  if (isPlainObject(a) && isPlainObject(b))
15510
15510
  combined[key3] = { ...a, ...b };
@@ -17257,10 +17257,10 @@ function defineChain(chain3) {
17257
17257
  serializers: void 0,
17258
17258
  ...chain3
17259
17259
  };
17260
- function extend2(base3) {
17260
+ function extend2(base4) {
17261
17261
  return (fnOrExtended) => {
17262
- const properties = typeof fnOrExtended === "function" ? fnOrExtended(base3) : fnOrExtended;
17263
- const combined = { ...base3, ...properties };
17262
+ const properties = typeof fnOrExtended === "function" ? fnOrExtended(base4) : fnOrExtended;
17263
+ const combined = { ...base4, ...properties };
17264
17264
  return Object.assign(combined, { extend: extend2(combined) });
17265
17265
  };
17266
17266
  }
@@ -17624,9 +17624,9 @@ function validateTypedData(parameters) {
17624
17624
  throw new InvalidTypedDataTypeError({ type });
17625
17625
  const integerMatch = type.match(integerRegex2);
17626
17626
  if (integerMatch && (typeof value === "number" || typeof value === "bigint")) {
17627
- const [_type, base3, size_] = integerMatch;
17627
+ const [_type, base4, size_] = integerMatch;
17628
17628
  numberToHex(value, {
17629
- signed: base3 === "int",
17629
+ signed: base4 === "int",
17630
17630
  size: Number.parseInt(size_, 10) / 8
17631
17631
  });
17632
17632
  }
@@ -20255,15 +20255,15 @@ function wNAF2(c, bits) {
20255
20255
  const { windows, windowSize } = calcWOpts2(W, bits);
20256
20256
  const points = [];
20257
20257
  let p = elm;
20258
- let base3 = p;
20258
+ let base4 = p;
20259
20259
  for (let window2 = 0; window2 < windows; window2++) {
20260
- base3 = p;
20261
- points.push(base3);
20260
+ base4 = p;
20261
+ points.push(base4);
20262
20262
  for (let i = 1; i < windowSize; i++) {
20263
- base3 = base3.add(p);
20264
- points.push(base3);
20263
+ base4 = base4.add(p);
20264
+ points.push(base4);
20265
20265
  }
20266
- p = base3.double();
20266
+ p = base4.double();
20267
20267
  }
20268
20268
  return points;
20269
20269
  },
@@ -32847,23 +32847,23 @@ var init_types = __esm({
32847
32847
  }
32848
32848
  if (effect.type === "transform") {
32849
32849
  if (ctx.common.async === false) {
32850
- const base3 = this._def.schema._parseSync({
32850
+ const base4 = this._def.schema._parseSync({
32851
32851
  data: ctx.data,
32852
32852
  path: ctx.path,
32853
32853
  parent: ctx
32854
32854
  });
32855
- if (!isValid(base3))
32855
+ if (!isValid(base4))
32856
32856
  return INVALID;
32857
- const result = effect.transform(base3.value, checkCtx);
32857
+ const result = effect.transform(base4.value, checkCtx);
32858
32858
  if (result instanceof Promise) {
32859
32859
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
32860
32860
  }
32861
32861
  return { status: status.value, value: result };
32862
32862
  } else {
32863
- return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base3) => {
32864
- if (!isValid(base3))
32863
+ return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base4) => {
32864
+ if (!isValid(base4))
32865
32865
  return INVALID;
32866
- return Promise.resolve(effect.transform(base3.value, checkCtx)).then((result) => ({
32866
+ return Promise.resolve(effect.transform(base4.value, checkCtx)).then((result) => ({
32867
32867
  status: status.value,
32868
32868
  value: result
32869
32869
  }));
@@ -34441,6 +34441,11 @@ function cloneLimits(limits) {
34441
34441
  }
34442
34442
  return clone;
34443
34443
  }
34444
+ function canonicalLimits(limits) {
34445
+ return JSON.stringify(
34446
+ Object.fromEntries(Object.entries(limits).sort(([a], [b]) => a < b ? -1 : 1))
34447
+ );
34448
+ }
34444
34449
  function parseQuotedAmountUsd(selected) {
34445
34450
  const raw = selected.amount ?? selected.maxAmountRequired;
34446
34451
  if (typeof raw !== "string" || !CANONICAL_AMOUNT.test(raw)) {
@@ -34516,7 +34521,7 @@ function formatDuration(seconds) {
34516
34521
  return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
34517
34522
  }
34518
34523
  }
34519
- 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;
34524
+ 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;
34520
34525
  var init_spend_control = __esm({
34521
34526
  "src/spend-control.ts"() {
34522
34527
  "use strict";
@@ -34526,6 +34531,7 @@ var init_spend_control = __esm({
34526
34531
  DAY_MS = 24 * HOUR_MS;
34527
34532
  CAIP2_BASE = "eip155:8453";
34528
34533
  CAIP2_SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
34534
+ PAYABLE_NETWORKS = [CAIP2_BASE, CAIP2_SOLANA_MAINNET];
34529
34535
  POLICY_LISTS = [
34530
34536
  "allowedPayees",
34531
34537
  "blockedPayees",
@@ -34542,6 +34548,12 @@ var init_spend_control = __esm({
34542
34548
  this.name = "MalformedSpendPolicyError";
34543
34549
  }
34544
34550
  };
34551
+ SpendPolicyConflictError = class extends Error {
34552
+ constructor() {
34553
+ super("spending.json limits changed underneath this write; nothing was written");
34554
+ this.name = "SpendPolicyConflictError";
34555
+ }
34556
+ };
34545
34557
  FileSpendControlStorage = class {
34546
34558
  spendingFile;
34547
34559
  constructor() {
@@ -34622,6 +34634,25 @@ var init_spend_control = __esm({
34622
34634
  }
34623
34635
  this.save({ limits: storedLimits, history });
34624
34636
  }
34637
+ /**
34638
+ * Persist limits while leaving the stored history exactly as it is on disk.
34639
+ * With `expect`, refuse when the stored limits are no longer the ones the
34640
+ * writer read — a stale instance must not replace another writer's edit.
34641
+ * The re-read happens immediately before the atomic rename, so the race
34642
+ * window is the write itself, not the whole command.
34643
+ */
34644
+ saveLimits(limits, expect) {
34645
+ let current;
34646
+ try {
34647
+ current = this.load();
34648
+ } catch {
34649
+ return;
34650
+ }
34651
+ if (expect !== void 0 && canonicalLimits(current?.limits ?? {}) !== canonicalLimits(expect)) {
34652
+ throw new SpendPolicyConflictError();
34653
+ }
34654
+ this.save({ limits, history: current?.history ?? [] });
34655
+ }
34625
34656
  };
34626
34657
  InMemorySpendControlStorage = class {
34627
34658
  data = null;
@@ -34637,6 +34668,15 @@ var init_spend_control = __esm({
34637
34668
  history: data.history.map((r2) => ({ ...r2 }))
34638
34669
  };
34639
34670
  }
34671
+ saveLimits(limits, expect) {
34672
+ if (expect !== void 0 && canonicalLimits(this.data?.limits ?? {}) !== canonicalLimits(expect)) {
34673
+ throw new SpendPolicyConflictError();
34674
+ }
34675
+ this.data = {
34676
+ limits: cloneLimits(limits),
34677
+ history: this.data?.history.map((r2) => ({ ...r2 })) ?? []
34678
+ };
34679
+ }
34640
34680
  };
34641
34681
  RESERVATION_TTL_MS = 2 * 60 * 1e3;
34642
34682
  SpendControl = class {
@@ -34648,6 +34688,8 @@ var init_spend_control = __esm({
34648
34688
  reservationSeq = 0;
34649
34689
  /** Limits we loaded and have not changed; history-only saves must not clobber operator edits. */
34650
34690
  limitsDirty = false;
34691
+ /** The limits this instance last read from or wrote to storage — the compare-and-swap baseline. */
34692
+ diskLimits = {};
34651
34693
  /** Set when spending.json held an unusable policy list: refuse every payment. */
34652
34694
  policyFileBroken;
34653
34695
  storage;
@@ -34692,6 +34734,15 @@ var init_spend_control = __esm({
34692
34734
  getLimits() {
34693
34735
  return cloneLimits(this.limits);
34694
34736
  }
34737
+ /**
34738
+ * Why spending.json could not be loaded, or undefined when it is usable.
34739
+ * While set, every setter mutates memory only: save() refuses to rewrite a
34740
+ * file it could not fully parse, so callers must check this before
34741
+ * reporting a change as applied.
34742
+ */
34743
+ getPolicyFileError() {
34744
+ return this.policyFileBroken;
34745
+ }
34695
34746
  check(estimatedCost2, counterparty) {
34696
34747
  if (this.policyFileBroken !== void 0) {
34697
34748
  return {
@@ -34952,6 +35003,22 @@ var init_spend_control = __esm({
34952
35003
  this.storage.saveHistory([...this.history]);
34953
35004
  return;
34954
35005
  }
35006
+ if (this.limitsDirty && this.storage.saveLimits) {
35007
+ try {
35008
+ this.storage.saveLimits(cloneLimits(this.limits), cloneLimits(this.diskLimits));
35009
+ } catch (err) {
35010
+ if (err instanceof SpendPolicyConflictError) {
35011
+ const current = this.storage.load();
35012
+ this.limits = cloneLimits(current?.limits ?? {});
35013
+ this.diskLimits = cloneLimits(this.limits);
35014
+ this.limitsDirty = false;
35015
+ }
35016
+ throw err;
35017
+ }
35018
+ this.diskLimits = cloneLimits(this.limits);
35019
+ this.limitsDirty = false;
35020
+ return;
35021
+ }
34955
35022
  this.storage.save({
34956
35023
  limits: cloneLimits(this.limits),
34957
35024
  history: [...this.history]
@@ -34972,6 +35039,7 @@ var init_spend_control = __esm({
34972
35039
  }
34973
35040
  if (data) {
34974
35041
  this.limits = cloneLimits(data.limits);
35042
+ this.diskLimits = cloneLimits(data.limits);
34975
35043
  this.history = data.history;
34976
35044
  this.cleanup();
34977
35045
  }
@@ -35023,6 +35091,7 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
35023
35091
  const cached = !options?.skipPreAuth ? cache2.get(cacheKey2) : void 0;
35024
35092
  const preAuthCovers = cached !== void 0 && Date.now() - cached.cachedAt < ttlMs && cached.coverMicros !== void 0 && needMicros !== void 0 && needMicros <= cached.coverMicros;
35025
35093
  if (preAuthCovers) {
35094
+ let paymentInFlight = false;
35026
35095
  try {
35027
35096
  const payload2 = await client.createPaymentPayload(cached.paymentRequired);
35028
35097
  const headers = httpClient.encodePaymentSignatureHeader(payload2);
@@ -35030,16 +35099,21 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
35030
35099
  for (const [key2, value] of Object.entries(headers)) {
35031
35100
  preAuthRequest.headers.set(key2, value);
35032
35101
  }
35102
+ paymentInFlight = true;
35033
35103
  const response2 = await baseFetch(preAuthRequest);
35034
35104
  if (response2.status !== 402) {
35035
35105
  return response2;
35036
35106
  }
35107
+ paymentInFlight = false;
35037
35108
  cache2.delete(cacheKey2);
35038
35109
  } catch (err) {
35039
35110
  cache2.delete(cacheKey2);
35040
35111
  if (err instanceof SpendPolicyError) {
35041
35112
  throw err;
35042
35113
  }
35114
+ if (paymentInFlight) {
35115
+ throw err;
35116
+ }
35043
35117
  }
35044
35118
  }
35045
35119
  const clonedRequest = request2.clone();
@@ -36624,12 +36698,12 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36624
36698
  const id2 = modelId.toLowerCase();
36625
36699
  const modelName = id2.slice(id2.indexOf("/") + 1);
36626
36700
  const match = (values, score) => values.some((value) => modelName === value) ? score : 0;
36627
- const base3 = 0.68;
36701
+ const base4 = 0.68;
36628
36702
  switch (task) {
36629
36703
  case "code_agent":
36630
36704
  if (terminalToolSignal && agentRisk === "complex_high") {
36631
36705
  return Math.max(
36632
- base3,
36706
+ base4,
36633
36707
  match(["claude-sonnet-5"], 1),
36634
36708
  match(["gpt-5.3-codex"], 0.87),
36635
36709
  match(["gpt-5-mini"], 0.78),
@@ -36637,7 +36711,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36637
36711
  );
36638
36712
  }
36639
36713
  return Math.max(
36640
- base3,
36714
+ base4,
36641
36715
  match(["gpt-5.3-codex"], 1),
36642
36716
  match(["claude-sonnet-5"], 0.98),
36643
36717
  match(["gpt-5-mini"], 0.96),
@@ -36648,7 +36722,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36648
36722
  case "tool_agent":
36649
36723
  if (terminalToolSignal && agentRisk === "complex_high") {
36650
36724
  return Math.max(
36651
- base3,
36725
+ base4,
36652
36726
  match(["claude-sonnet-5"], 1),
36653
36727
  match(["gpt-5.3-codex"], 0.87),
36654
36728
  match(["gpt-5-mini"], 0.78),
@@ -36657,7 +36731,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36657
36731
  }
36658
36732
  if (terminalToolSignal && !terminalSafetySensitive) {
36659
36733
  return Math.max(
36660
- base3,
36734
+ base4,
36661
36735
  match(["gpt-5-mini"], 1),
36662
36736
  match(["gpt-5.3-codex"], 0.98),
36663
36737
  match(["claude-sonnet-5"], 0.9),
@@ -36666,7 +36740,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36666
36740
  }
36667
36741
  if (terminalToolSignal && terminalSafetySensitive) {
36668
36742
  return Math.max(
36669
- base3,
36743
+ base4,
36670
36744
  match(["claude-sonnet-5"], 1),
36671
36745
  match(["claude-opus-4.8"], 0.9),
36672
36746
  match(["gpt-5.3-codex"], 0.84)
@@ -36674,14 +36748,14 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36674
36748
  }
36675
36749
  if (agentDomain === "web_research") {
36676
36750
  return deepWebResearch ? Math.max(
36677
- base3,
36751
+ base4,
36678
36752
  match(["claude-sonnet-5"], 1),
36679
36753
  match(["gpt-5-mini"], 0.88),
36680
36754
  match(["gemini-3.5-flash"], 0.84),
36681
36755
  match(["claude-opus-5"], 0.8),
36682
36756
  match(["claude-opus-4.8"], 0.78)
36683
36757
  ) : Math.max(
36684
- base3,
36758
+ base4,
36685
36759
  match(["claude-sonnet-5"], 1),
36686
36760
  match(["gpt-5-mini"], 0.88),
36687
36761
  match(["gemini-3.5-flash"], 0.86),
@@ -36692,7 +36766,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36692
36766
  if (agentDomain === "retail") {
36693
36767
  if (agentRisk === "standard") {
36694
36768
  return Math.max(
36695
- base3,
36769
+ base4,
36696
36770
  match(["gpt-5-mini"], 1),
36697
36771
  match(["claude-sonnet-5"], 0.88),
36698
36772
  match(["gemini-3.5-flash"], 0.82),
@@ -36703,7 +36777,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36703
36777
  }
36704
36778
  if (agentRisk === "policy_exception") {
36705
36779
  return Math.max(
36706
- base3,
36780
+ base4,
36707
36781
  match(["gpt-4.1"], 1),
36708
36782
  match(["claude-sonnet-5"], 0.9),
36709
36783
  match(["deepseek-v4-pro"], 0.82),
@@ -36713,7 +36787,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36713
36787
  }
36714
36788
  if (agentRisk === "policy_exception_simple") {
36715
36789
  return Math.max(
36716
- base3,
36790
+ base4,
36717
36791
  match(["gpt-5-mini"], 1),
36718
36792
  match(["gpt-4.1"], 0.86),
36719
36793
  match(["deepseek-v4-pro"], 0.82),
@@ -36721,7 +36795,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36721
36795
  );
36722
36796
  }
36723
36797
  return Math.max(
36724
- base3,
36798
+ base4,
36725
36799
  match(["deepseek-v4-pro"], 1),
36726
36800
  match(["claude-sonnet-5"], 0.88),
36727
36801
  match(["gemini-3.5-flash"], 0.82),
@@ -36733,7 +36807,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36733
36807
  if (agentDomain === "airline") {
36734
36808
  if (agentRisk === "complex_high") {
36735
36809
  return Math.max(
36736
- base3,
36810
+ base4,
36737
36811
  match(["claude-sonnet-5"], 1),
36738
36812
  match(["gpt-5-mini"], 0.78),
36739
36813
  match(["gemini-3.5-flash"], 0.76),
@@ -36741,7 +36815,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36741
36815
  );
36742
36816
  }
36743
36817
  return Math.max(
36744
- base3,
36818
+ base4,
36745
36819
  match(["gpt-5-mini"], 1),
36746
36820
  match(["claude-sonnet-5"], 0.9),
36747
36821
  match(["gemini-3.5-flash"], 0.8),
@@ -36749,7 +36823,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36749
36823
  );
36750
36824
  }
36751
36825
  return Math.max(
36752
- base3,
36826
+ base4,
36753
36827
  match(["claude-sonnet-5"], 1),
36754
36828
  match(["gemini-3.5-flash"], 0.88),
36755
36829
  match(["gpt-5.3-codex"], 0.87),
@@ -36760,12 +36834,12 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36760
36834
  case "tool_agent_parallel":
36761
36835
  if (terminalToolSignal) {
36762
36836
  return terminalSafetySensitive ? Math.max(
36763
- base3,
36837
+ base4,
36764
36838
  match(["claude-sonnet-5"], 1),
36765
36839
  match(["claude-opus-4.8"], 0.9),
36766
36840
  match(["gpt-5.3-codex"], 0.86)
36767
36841
  ) : Math.max(
36768
- base3,
36842
+ base4,
36769
36843
  match(["gpt-5-mini"], 1),
36770
36844
  match(["gpt-5.3-codex"], 0.98),
36771
36845
  match(["claude-sonnet-5"], 0.92),
@@ -36774,14 +36848,14 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36774
36848
  }
36775
36849
  if (agentDomain === "web_research") {
36776
36850
  return deepWebResearch ? Math.max(
36777
- base3,
36851
+ base4,
36778
36852
  match(["claude-sonnet-5"], 1),
36779
36853
  match(["gpt-5-mini"], 0.88),
36780
36854
  match(["gemini-3.5-flash"], 0.84),
36781
36855
  match(["claude-opus-5"], 0.8),
36782
36856
  match(["claude-opus-4.8"], 0.78)
36783
36857
  ) : Math.max(
36784
- base3,
36858
+ base4,
36785
36859
  match(["claude-sonnet-5"], 1),
36786
36860
  match(["gpt-5-mini"], 0.88),
36787
36861
  match(["gemini-3.5-flash"], 0.86),
@@ -36792,7 +36866,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36792
36866
  if (agentDomain === "retail") {
36793
36867
  if (agentRisk === "policy_exception") {
36794
36868
  return Math.max(
36795
- base3,
36869
+ base4,
36796
36870
  match(["gpt-4.1"], 1),
36797
36871
  match(["claude-sonnet-5"], 0.9),
36798
36872
  match(["deepseek-v4-pro"], 0.82),
@@ -36802,7 +36876,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36802
36876
  }
36803
36877
  if (agentRisk === "policy_exception_simple") {
36804
36878
  return Math.max(
36805
- base3,
36879
+ base4,
36806
36880
  match(["gpt-5-mini"], 1),
36807
36881
  match(["gpt-4.1"], 0.86),
36808
36882
  match(["deepseek-v4-pro"], 0.82),
@@ -36810,7 +36884,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36810
36884
  );
36811
36885
  }
36812
36886
  return Math.max(
36813
- base3,
36887
+ base4,
36814
36888
  match(["deepseek-v4-pro"], 1),
36815
36889
  match(["claude-sonnet-5"], 0.88),
36816
36890
  match(["claude-opus-4.8"], 0.84),
@@ -36820,20 +36894,20 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36820
36894
  }
36821
36895
  if (agentDomain === "airline") {
36822
36896
  return agentRisk === "complex_high" ? Math.max(
36823
- base3,
36897
+ base4,
36824
36898
  match(["claude-sonnet-5"], 1),
36825
36899
  match(["gpt-5-mini"], 0.78),
36826
36900
  match(["claude-opus-4.8"], 0.76),
36827
36901
  match(["gemini-3.5-flash"], 0.74)
36828
36902
  ) : Math.max(
36829
- base3,
36903
+ base4,
36830
36904
  match(["gpt-5-mini"], 1),
36831
36905
  match(["claude-sonnet-5"], 0.9),
36832
36906
  match(["gemini-3.5-flash"], 0.8)
36833
36907
  );
36834
36908
  }
36835
36909
  return Math.max(
36836
- base3,
36910
+ base4,
36837
36911
  match(["claude-opus-4.8"], 1),
36838
36912
  match(["claude-sonnet-5"], 0.84),
36839
36913
  match(["grok-4.5"], 0.82),
@@ -36843,7 +36917,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36843
36917
  case "code_edit":
36844
36918
  case "debug":
36845
36919
  return Math.max(
36846
- base3,
36920
+ base4,
36847
36921
  match(["gpt-5.3-codex"], 1),
36848
36922
  match(["claude-sonnet-4.6"], 0.94),
36849
36923
  match(["glm-5.2"], 0.9),
@@ -36851,7 +36925,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36851
36925
  );
36852
36926
  case "reasoning":
36853
36927
  return Math.max(
36854
- base3,
36928
+ base4,
36855
36929
  match(["claude-sonnet-5", "claude-sonnet-4.6"], 0.98),
36856
36930
  match(["deepseek-v4-pro"], 0.95),
36857
36931
  match(["grok-4.5"], 0.94),
@@ -36859,7 +36933,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36859
36933
  );
36860
36934
  case "reasoning_mcq":
36861
36935
  return Math.max(
36862
- base3,
36936
+ base4,
36863
36937
  match(["gemini-3-flash-preview"], 1),
36864
36938
  match(["gemini-3.5-flash"], 0.91),
36865
36939
  match(["grok-4.5"], 0.9),
@@ -36868,20 +36942,20 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36868
36942
  );
36869
36943
  case "reasoning_math":
36870
36944
  return Math.max(
36871
- base3,
36945
+ base4,
36872
36946
  match(["gemini-3.5-flash"], 1),
36873
36947
  match(["grok-4.5"], 0.93),
36874
36948
  match(["claude-sonnet-5", "deepseek-v4-pro", "kimi-k3"], 0.9)
36875
36949
  );
36876
36950
  case "vision":
36877
36951
  return Math.max(
36878
- base3,
36952
+ base4,
36879
36953
  match(["gemini-3.1-pro"], 0.96),
36880
36954
  match(["qwen3.7-max", "claude-sonnet-4.6", "kimi-k3", "grok-4.3"], 0.9)
36881
36955
  );
36882
36956
  case "long_context":
36883
36957
  return Math.max(
36884
- base3,
36958
+ base4,
36885
36959
  match(["gemini-3.1-pro"], 1),
36886
36960
  match(["qwen3.7-max", "glm-5.2"], 0.89),
36887
36961
  match(["gemini-3.5-flash"], 0.88),
@@ -36891,7 +36965,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36891
36965
  const kimiExtractionAffinity = language === "zh" ? 1 : 0.9;
36892
36966
  const otherExtractionAffinity = language === "zh" ? 0.88 : 0.9;
36893
36967
  return Math.max(
36894
- base3,
36968
+ base4,
36895
36969
  match(["gemini-3.5-flash", "gemini-2.5-flash", "gpt-4o-mini"], otherExtractionAffinity),
36896
36970
  match(["claude-sonnet-5", "claude-sonnet-4.6"], otherExtractionAffinity),
36897
36971
  match(["kimi-k3"], kimiExtractionAffinity)
@@ -36899,7 +36973,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
36899
36973
  }
36900
36974
  default:
36901
36975
  return Math.max(
36902
- base3,
36976
+ base4,
36903
36977
  match(["gemini-3.5-flash", "gemini-2.5-flash", "kimi-k3"], 0.86)
36904
36978
  );
36905
36979
  }
@@ -38174,13 +38248,13 @@ ${value.slice(-(scanLimit - prefixLength))}`;
38174
38248
  name = "portfolio";
38175
38249
  route(prompt, systemPrompt, maxOutputTokens, options) {
38176
38250
  const features = classifyTask(prompt, systemPrompt, options);
38177
- const base3 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
38251
+ const base4 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
38178
38252
  ...options,
38179
38253
  requiresTools: features.needsTools
38180
38254
  });
38181
- const tierConfigs = base3.tierConfigs;
38182
- if (!tierConfigs) return base3;
38183
- const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (base3.tier === "SIMPLE" || base3.tier === "MEDIUM") ? "REASONING" : base3.tier;
38255
+ const tierConfigs = base4.tierConfigs;
38256
+ if (!tierConfigs) return base4;
38257
+ const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (base4.tier === "SIMPLE" || base4.tier === "MEDIUM") ? "REASONING" : base4.tier;
38184
38258
  const tierConfig = tierConfigs[targetTier];
38185
38259
  const configuredCandidates = tierConfig ? getFallbackChain(targetTier, tierConfigs) : [];
38186
38260
  const unavailable = new Set(options.unavailableModels ?? []);
@@ -38193,7 +38267,7 @@ ${value.slice(-(scanLimit - prefixLength))}`;
38193
38267
  (model2) => isEligible(model2, features, maxOutputTokens, options)
38194
38268
  );
38195
38269
  const eligibleCandidates = eligible.length > 0 ? eligible : chain3;
38196
- if (eligibleCandidates.length === 0) return base3;
38270
+ if (eligibleCandidates.length === 0) return base4;
38197
38271
  const profileName = options.routingProfile === "eco" ? "eco" : options.routingProfile === "premium" ? "premium" : "auto";
38198
38272
  const portfolio = options.config.portfolio ?? DEFAULT_PORTFOLIO_WEIGHTS;
38199
38273
  const getAffinity = (model2) => affinity(
@@ -38266,27 +38340,27 @@ ${value.slice(-(scanLimit - prefixLength))}`;
38266
38340
  (model2) => !scoredModels.includes(model2) && !webResearchFallbackOrder.includes(model2)
38267
38341
  )
38268
38342
  ] : [...scoredModels, ...eligibleCandidates.filter((model2) => !scoredModels.includes(model2))];
38269
- const model = ranked[0] ?? base3.model;
38343
+ const model = ranked[0] ?? base4.model;
38270
38344
  const selectedTierConfigs = {
38271
38345
  ...tierConfigs,
38272
38346
  [targetTier]: { primary: model, fallback: ranked.slice(1) }
38273
38347
  };
38274
38348
  const decision = selectModel(
38275
38349
  targetTier,
38276
- base3.confidence,
38350
+ base4.confidence,
38277
38351
  "portfolio",
38278
- `${base3.reasoning} | v3 task=${features.taskType} agentRisk=${features.agentRisk} deepWebResearch=${features.deepWebResearch} terminalCode=${features.implicitTerminalCode} terminalSafety=${features.terminalSafetySensitive} candidates=${ranked.length}`,
38352
+ `${base4.reasoning} | v3 task=${features.taskType} agentRisk=${features.agentRisk} deepWebResearch=${features.deepWebResearch} terminalCode=${features.implicitTerminalCode} terminalSafety=${features.terminalSafetySensitive} candidates=${ranked.length}`,
38279
38353
  selectedTierConfigs,
38280
38354
  options.modelPricing,
38281
38355
  features.estimatedInputTokens,
38282
38356
  maxOutputTokens,
38283
38357
  options.routingProfile,
38284
- base3.agenticScore
38358
+ base4.agenticScore
38285
38359
  );
38286
38360
  return {
38287
38361
  ...decision,
38288
38362
  tierConfigs: selectedTierConfigs,
38289
- profile: base3.profile,
38363
+ profile: base4.profile,
38290
38364
  candidates: ranked,
38291
38365
  candidateScores: rankedEntries.map(({ model: model2, score, quality, cost, speed, reliability }) => ({
38292
38366
  model: model2,
@@ -40465,7 +40539,7 @@ var init_errors5 = __esm({
40465
40539
  `Options:`,
40466
40540
  ` 1. Fund wallet: ${walletAddress}`,
40467
40541
  ` 2. Use free model: /model free`,
40468
- ` 3. Uninstall: bash ~/.openclaw/extensions/clawrouter/scripts/uninstall.sh`
40542
+ ` 3. Uninstall: bash ~/.openclaw/extensions/blockrun-clawrouter/scripts/uninstall.sh`
40469
40543
  ].join("\n");
40470
40544
  super(msg);
40471
40545
  this.name = "EmptyWalletError";
@@ -40617,6 +40691,154 @@ var init_balance = __esm({
40617
40691
  }
40618
40692
  });
40619
40693
 
40694
+ // node_modules/base-x/src/esm/index.js
40695
+ function base2(ALPHABET3) {
40696
+ if (ALPHABET3.length >= 255) {
40697
+ throw new TypeError("Alphabet too long");
40698
+ }
40699
+ const BASE_MAP = new Uint8Array(256);
40700
+ for (let j = 0; j < BASE_MAP.length; j++) {
40701
+ BASE_MAP[j] = 255;
40702
+ }
40703
+ for (let i = 0; i < ALPHABET3.length; i++) {
40704
+ const x = ALPHABET3.charAt(i);
40705
+ const xc = x.charCodeAt(0);
40706
+ if (BASE_MAP[xc] !== 255) {
40707
+ throw new TypeError(x + " is ambiguous");
40708
+ }
40709
+ BASE_MAP[xc] = i;
40710
+ }
40711
+ const BASE = ALPHABET3.length;
40712
+ const LEADER = ALPHABET3.charAt(0);
40713
+ const FACTOR = Math.log(BASE) / Math.log(256);
40714
+ const iFACTOR = Math.log(256) / Math.log(BASE);
40715
+ function encode9(source) {
40716
+ if (source instanceof Uint8Array) {
40717
+ } else if (ArrayBuffer.isView(source)) {
40718
+ source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
40719
+ } else if (Array.isArray(source)) {
40720
+ source = Uint8Array.from(source);
40721
+ }
40722
+ if (!(source instanceof Uint8Array)) {
40723
+ throw new TypeError("Expected Uint8Array");
40724
+ }
40725
+ if (source.length === 0) {
40726
+ return "";
40727
+ }
40728
+ let zeroes = 0;
40729
+ let length = 0;
40730
+ let pbegin = 0;
40731
+ const pend = source.length;
40732
+ while (pbegin !== pend && source[pbegin] === 0) {
40733
+ pbegin++;
40734
+ zeroes++;
40735
+ }
40736
+ const size5 = (pend - pbegin) * iFACTOR + 1 >>> 0;
40737
+ const b58 = new Uint8Array(size5);
40738
+ while (pbegin !== pend) {
40739
+ let carry2 = source[pbegin];
40740
+ let i = 0;
40741
+ for (let it1 = size5 - 1; (carry2 !== 0 || i < length) && it1 !== -1; it1--, i++) {
40742
+ carry2 += 256 * b58[it1] >>> 0;
40743
+ b58[it1] = carry2 % BASE >>> 0;
40744
+ carry2 = carry2 / BASE >>> 0;
40745
+ }
40746
+ if (carry2 !== 0) {
40747
+ throw new Error("Non-zero carry");
40748
+ }
40749
+ length = i;
40750
+ pbegin++;
40751
+ }
40752
+ let it2 = size5 - length;
40753
+ while (it2 !== size5 && b58[it2] === 0) {
40754
+ it2++;
40755
+ }
40756
+ let str = LEADER.repeat(zeroes);
40757
+ for (; it2 < size5; ++it2) {
40758
+ str += ALPHABET3.charAt(b58[it2]);
40759
+ }
40760
+ return str;
40761
+ }
40762
+ function decodeUnsafe(source) {
40763
+ if (typeof source !== "string") {
40764
+ throw new TypeError("Expected String");
40765
+ }
40766
+ if (source.length === 0) {
40767
+ return new Uint8Array();
40768
+ }
40769
+ let psz = 0;
40770
+ let zeroes = 0;
40771
+ let length = 0;
40772
+ while (source[psz] === LEADER) {
40773
+ zeroes++;
40774
+ psz++;
40775
+ }
40776
+ const size5 = (source.length - psz) * FACTOR + 1 >>> 0;
40777
+ const b256 = new Uint8Array(size5);
40778
+ while (psz < source.length) {
40779
+ const charCode = source.charCodeAt(psz);
40780
+ if (charCode > 255) {
40781
+ return;
40782
+ }
40783
+ let carry2 = BASE_MAP[charCode];
40784
+ if (carry2 === 255) {
40785
+ return;
40786
+ }
40787
+ let i = 0;
40788
+ for (let it3 = size5 - 1; (carry2 !== 0 || i < length) && it3 !== -1; it3--, i++) {
40789
+ carry2 += BASE * b256[it3] >>> 0;
40790
+ b256[it3] = carry2 % 256 >>> 0;
40791
+ carry2 = carry2 / 256 >>> 0;
40792
+ }
40793
+ if (carry2 !== 0) {
40794
+ throw new Error("Non-zero carry");
40795
+ }
40796
+ length = i;
40797
+ psz++;
40798
+ }
40799
+ let it4 = size5 - length;
40800
+ while (it4 !== size5 && b256[it4] === 0) {
40801
+ it4++;
40802
+ }
40803
+ const vch = new Uint8Array(zeroes + (size5 - it4));
40804
+ let j = zeroes;
40805
+ while (it4 !== size5) {
40806
+ vch[j++] = b256[it4++];
40807
+ }
40808
+ return vch;
40809
+ }
40810
+ function decode4(string) {
40811
+ const buffer2 = decodeUnsafe(string);
40812
+ if (buffer2) {
40813
+ return buffer2;
40814
+ }
40815
+ throw new Error("Non-base" + BASE + " character");
40816
+ }
40817
+ return {
40818
+ encode: encode9,
40819
+ decodeUnsafe,
40820
+ decode: decode4
40821
+ };
40822
+ }
40823
+ var esm_default;
40824
+ var init_esm6 = __esm({
40825
+ "node_modules/base-x/src/esm/index.js"() {
40826
+ "use strict";
40827
+ esm_default = base2;
40828
+ }
40829
+ });
40830
+
40831
+ // node_modules/bs58/src/esm/index.js
40832
+ var ALPHABET, esm_default2;
40833
+ var init_esm7 = __esm({
40834
+ "node_modules/bs58/src/esm/index.js"() {
40835
+ "use strict";
40836
+ init_esm6();
40837
+ ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
40838
+ esm_default2 = esm_default(ALPHABET);
40839
+ }
40840
+ });
40841
+
40620
40842
  // node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
40621
40843
  function isBytes7(a) {
40622
40844
  return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
@@ -41785,15 +42007,15 @@ var init_curve3 = __esm({
41785
42007
  const { windows, windowSize } = calcWOpts3(W, this.bits);
41786
42008
  const points = [];
41787
42009
  let p = point3;
41788
- let base3 = p;
42010
+ let base4 = p;
41789
42011
  for (let window2 = 0; window2 < windows; window2++) {
41790
- base3 = p;
41791
- points.push(base3);
42012
+ base4 = p;
42013
+ points.push(base4);
41792
42014
  for (let i = 1; i < windowSize; i++) {
41793
- base3 = base3.add(p);
41794
- points.push(base3);
42015
+ base4 = base4.add(p);
42016
+ points.push(base4);
41795
42017
  }
41796
- p = base3.double();
42018
+ p = base4.double();
41797
42019
  }
41798
42020
  return points;
41799
42021
  }
@@ -44841,6 +45063,37 @@ var init_sha26 = __esm({
44841
45063
  }
44842
45064
  });
44843
45065
 
45066
+ // src/solana-key.ts
45067
+ function deriveSolanaKeyBytes(mnemonic) {
45068
+ const seed = mnemonicToSeedSync(mnemonic);
45069
+ let digest = hmac6(sha5123, new TextEncoder().encode("ed25519 seed"), seed);
45070
+ let key2 = digest.slice(0, 32);
45071
+ let chainCode = digest.slice(32);
45072
+ for (const index2 of SOLANA_HARDENED_INDICES) {
45073
+ const data = new Uint8Array(37);
45074
+ data[0] = 0;
45075
+ data.set(key2, 1);
45076
+ data[33] = index2 >>> 24 & 255;
45077
+ data[34] = index2 >>> 16 & 255;
45078
+ data[35] = index2 >>> 8 & 255;
45079
+ data[36] = index2 & 255;
45080
+ digest = hmac6(sha5123, chainCode, data);
45081
+ key2 = digest.slice(0, 32);
45082
+ chainCode = digest.slice(32);
45083
+ }
45084
+ return new Uint8Array(key2);
45085
+ }
45086
+ var SOLANA_HARDENED_INDICES;
45087
+ var init_solana_key = __esm({
45088
+ "src/solana-key.ts"() {
45089
+ "use strict";
45090
+ init_hmac6();
45091
+ init_sha26();
45092
+ init_esm3();
45093
+ SOLANA_HARDENED_INDICES = [44 + 2147483648, 501 + 2147483648, 0 + 2147483648, 0 + 2147483648];
45094
+ }
45095
+ });
45096
+
44844
45097
  // node_modules/@solana/errors/dist/index.node.mjs
44845
45098
  function encodeValue(value) {
44846
45099
  if (Array.isArray(value)) {
@@ -46282,20 +46535,20 @@ function partitionLeadingZeroes(value, zeroCharacter) {
46282
46535
  return [leadingZeros, tailChars];
46283
46536
  }
46284
46537
  function getBigIntFromBaseX(value, alphabet4) {
46285
- const base3 = BigInt(alphabet4.length);
46538
+ const base4 = BigInt(alphabet4.length);
46286
46539
  let sum = 0n;
46287
46540
  for (const char of value) {
46288
- sum *= base3;
46541
+ sum *= base4;
46289
46542
  sum += BigInt(alphabet4.indexOf(char));
46290
46543
  }
46291
46544
  return sum;
46292
46545
  }
46293
46546
  function getBaseXFromBigInt(value, alphabet4) {
46294
- const base3 = BigInt(alphabet4.length);
46547
+ const base4 = BigInt(alphabet4.length);
46295
46548
  const tailChars = [];
46296
46549
  while (value > 0n) {
46297
- tailChars.unshift(alphabet4[Number(value % base3)]);
46298
- value /= base3;
46550
+ tailChars.unshift(alphabet4[Number(value % base4)]);
46551
+ value /= base4;
46299
46552
  }
46300
46553
  return tailChars.join("");
46301
46554
  }
@@ -48342,20 +48595,20 @@ function partitionLeadingZeroes2(value, zeroCharacter) {
48342
48595
  return [leadingZeros, tailChars];
48343
48596
  }
48344
48597
  function getBigIntFromBaseX2(value, alphabet4) {
48345
- const base3 = BigInt(alphabet4.length);
48598
+ const base4 = BigInt(alphabet4.length);
48346
48599
  let sum = 0n;
48347
48600
  for (const char of value) {
48348
- sum *= base3;
48601
+ sum *= base4;
48349
48602
  sum += BigInt(alphabet4.indexOf(char));
48350
48603
  }
48351
48604
  return sum;
48352
48605
  }
48353
48606
  function getBaseXFromBigInt2(value, alphabet4) {
48354
- const base3 = BigInt(alphabet4.length);
48607
+ const base4 = BigInt(alphabet4.length);
48355
48608
  const tailChars = [];
48356
48609
  while (value > 0n) {
48357
- tailChars.unshift(alphabet4[Number(value % base3)]);
48358
- value /= base3;
48610
+ tailChars.unshift(alphabet4[Number(value % base4)]);
48611
+ value /= base4;
48359
48612
  }
48360
48613
  return tailChars.join("");
48361
48614
  }
@@ -59133,25 +59386,6 @@ function deriveEvmKey(mnemonic) {
59133
59386
  const account = privateKeyToAccount(hex);
59134
59387
  return { privateKey: hex, address: account.address };
59135
59388
  }
59136
- function deriveSolanaKeyBytes(mnemonic) {
59137
- const seed = mnemonicToSeedSync(mnemonic);
59138
- let I = hmac6(sha5123, new TextEncoder().encode("ed25519 seed"), seed);
59139
- let key2 = I.slice(0, 32);
59140
- let chainCode = I.slice(32);
59141
- for (const index2 of SOLANA_HARDENED_INDICES) {
59142
- const data = new Uint8Array(37);
59143
- data[0] = 0;
59144
- data.set(key2, 1);
59145
- data[33] = index2 >>> 24 & 255;
59146
- data[34] = index2 >>> 16 & 255;
59147
- data[35] = index2 >>> 8 & 255;
59148
- data[36] = index2 & 255;
59149
- I = hmac6(sha5123, chainCode, data);
59150
- key2 = I.slice(0, 32);
59151
- chainCode = I.slice(32);
59152
- }
59153
- return new Uint8Array(key2);
59154
- }
59155
59389
  function deriveAllKeys(mnemonic) {
59156
59390
  const { privateKey: evmPrivateKey, address: evmAddress } = deriveEvmKey(mnemonic);
59157
59391
  const solanaPrivateKeyBytes = deriveSolanaKeyBytes(mnemonic);
@@ -59162,22 +59396,22 @@ async function getSolanaAddress(privateKeyBytes) {
59162
59396
  const signer = await createKeyPairSignerFromPrivateKeyBytes2(privateKeyBytes);
59163
59397
  return signer.address;
59164
59398
  }
59165
- var ETH_DERIVATION_PATH, SOLANA_HARDENED_INDICES;
59399
+ var ETH_DERIVATION_PATH;
59166
59400
  var init_wallet2 = __esm({
59167
59401
  "src/wallet.ts"() {
59168
59402
  "use strict";
59169
59403
  init_bip32();
59170
59404
  init_esm3();
59171
59405
  init_english();
59172
- init_hmac6();
59173
- init_sha26();
59174
59406
  init_accounts();
59407
+ init_solana_key();
59408
+ init_solana_key();
59175
59409
  ETH_DERIVATION_PATH = "m/44'/60'/0'/0/0";
59176
- SOLANA_HARDENED_INDICES = [44 + 2147483648, 501 + 2147483648, 0 + 2147483648, 0 + 2147483648];
59177
59410
  }
59178
59411
  });
59179
59412
 
59180
59413
  // src/auth.ts
59414
+ import { createPrivateKey, createPublicKey } from "crypto";
59181
59415
  import { writeFile, mkdir as mkdir2 } from "fs/promises";
59182
59416
  import { join as join7 } from "path";
59183
59417
  import { homedir as homedir4 } from "os";
@@ -59232,7 +59466,67 @@ async function saveMnemonic(mnemonic) {
59232
59466
  await mkdir2(WALLET_DIR2, { recursive: true });
59233
59467
  await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
59234
59468
  }
59235
- async function generateAndSaveWallet() {
59469
+ async function migrateLegacyWalletToCore() {
59470
+ const migrated = { base: false, solana: false, chain: false };
59471
+ const [coreBase, coreSolana, coreChain] = await Promise.all([
59472
+ readExisting(CORE_WALLET_FILE),
59473
+ readExisting(CORE_SOLANA_WALLET_FILE),
59474
+ readExisting(CORE_CHAIN_FILE)
59475
+ ]);
59476
+ if (coreBase === void 0) {
59477
+ const legacyBase = await loadSavedWallet();
59478
+ if (legacyBase) {
59479
+ migrated.base = await writeCoreFileIfMissing(CORE_WALLET_FILE, legacyBase + "\n");
59480
+ }
59481
+ }
59482
+ if (coreSolana === void 0) {
59483
+ const mnemonic = await loadMnemonic();
59484
+ if (mnemonic) {
59485
+ const secret = solanaSecretKeyFromSeed(deriveSolanaKeyBytes(mnemonic));
59486
+ migrated.solana = await writeCoreFileIfMissing(
59487
+ CORE_SOLANA_WALLET_FILE,
59488
+ JSON.stringify([...secret]) + "\n"
59489
+ );
59490
+ }
59491
+ }
59492
+ if (coreChain === void 0) {
59493
+ const legacyChain = await readOptional(CHAIN_FILE);
59494
+ if (legacyChain === "base" || legacyChain === "solana") {
59495
+ migrated.chain = await writeCoreFileIfMissing(CORE_CHAIN_FILE, legacyChain + "\n");
59496
+ }
59497
+ }
59498
+ if (migrated.base || migrated.solana || migrated.chain) {
59499
+ const parts = Object.entries(migrated).filter(([, changed]) => changed).map(([name]) => name).join(", ");
59500
+ console.log(`[ClawRouter] Migrated legacy ${parts} data to ${CORE_WALLET_DIR}`);
59501
+ }
59502
+ return migrated;
59503
+ }
59504
+ async function writeCoreFileIfMissing(path5, value) {
59505
+ await mkdir2(CORE_WALLET_DIR, { recursive: true });
59506
+ try {
59507
+ await writeFile(path5, value, { mode: 384, flag: "wx" });
59508
+ return true;
59509
+ } catch (error) {
59510
+ if (error.code === "EEXIST") return false;
59511
+ throw error;
59512
+ }
59513
+ }
59514
+ async function readExisting(path5) {
59515
+ try {
59516
+ return await readTextFile(path5);
59517
+ } catch (error) {
59518
+ if (error.code === "ENOENT") return void 0;
59519
+ throw error;
59520
+ }
59521
+ }
59522
+ function solanaSecretKeyFromSeed(seed) {
59523
+ const privateDer = Buffer.concat([Buffer.from("302e020100300506032b657004220420", "hex"), seed]);
59524
+ const publicDer = createPublicKey(
59525
+ createPrivateKey({ key: privateDer, format: "der", type: "pkcs8" })
59526
+ ).export({ format: "der", type: "spki" });
59527
+ return Uint8Array.from([...seed, ...Buffer.from(publicDer).subarray(-32)]);
59528
+ }
59529
+ async function generateAndSaveWallet(existingCoreSolanaKey) {
59236
59530
  const existingMnemonic = await loadMnemonic();
59237
59531
  if (existingMnemonic) {
59238
59532
  throw new Error(
@@ -59250,7 +59544,17 @@ Then run: npx @blockrun/clawrouter`
59250
59544
  const derived = deriveAllKeys(mnemonic);
59251
59545
  await mkdir2(WALLET_DIR2, { recursive: true });
59252
59546
  await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
59253
- await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
59547
+ if (!existingCoreSolanaKey) {
59548
+ await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
59549
+ }
59550
+ await writeCoreFileIfMissing(CORE_WALLET_FILE, derived.evmPrivateKey + "\n");
59551
+ if (!existingCoreSolanaKey) {
59552
+ await writeCoreFileIfMissing(
59553
+ CORE_SOLANA_WALLET_FILE,
59554
+ JSON.stringify([...solanaSecretKeyFromSeed(derived.solanaPrivateKeyBytes)]) + "\n"
59555
+ );
59556
+ }
59557
+ const solanaPrivateKeyBytes = existingCoreSolanaKey ?? derived.solanaPrivateKeyBytes;
59254
59558
  try {
59255
59559
  const verification = (await readTextFile(WALLET_FILE)).trim();
59256
59560
  if (verification !== derived.evmPrivateKey) {
@@ -59265,7 +59569,7 @@ Then run: npx @blockrun/clawrouter`
59265
59569
  }
59266
59570
  let solanaAddress;
59267
59571
  try {
59268
- solanaAddress = await getSolanaAddress(derived.solanaPrivateKeyBytes);
59572
+ solanaAddress = await getSolanaAddress(solanaPrivateKeyBytes);
59269
59573
  } catch {
59270
59574
  }
59271
59575
  let solanaDefaultSaved = false;
@@ -59284,8 +59588,11 @@ Then run: npx @blockrun/clawrouter`
59284
59588
  if (solanaAddress) {
59285
59589
  console.log(`[ClawRouter] Solana Address : ${solanaAddress}`);
59286
59590
  }
59287
- console.log(`[ClawRouter] Key file : ${WALLET_FILE}`);
59288
- console.log(`[ClawRouter] Mnemonic : ${MNEMONIC_FILE}`);
59591
+ console.log(`[ClawRouter] Base key : ${CORE_WALLET_FILE}`);
59592
+ console.log(`[ClawRouter] Solana key : ${CORE_SOLANA_WALLET_FILE}`);
59593
+ if (!existingCoreSolanaKey) {
59594
+ console.log(`[ClawRouter] Recovery words : ${MNEMONIC_FILE}`);
59595
+ }
59289
59596
  console.log(`[ClawRouter]`);
59290
59597
  console.log(`[ClawRouter] Both EVM (Base) and Solana wallets are ready.`);
59291
59598
  if (solanaDefaultSaved) {
@@ -59304,44 +59611,50 @@ Then run: npx @blockrun/clawrouter`
59304
59611
  return {
59305
59612
  key: derived.evmPrivateKey,
59306
59613
  address: derived.evmAddress,
59307
- mnemonic,
59308
- solanaPrivateKeyBytes: derived.solanaPrivateKeyBytes
59614
+ ...existingCoreSolanaKey ? {} : { mnemonic },
59615
+ solanaPrivateKeyBytes
59309
59616
  };
59310
59617
  }
59311
- async function resolveOrGenerateWalletKey() {
59618
+ async function resolveExistingWalletKey() {
59619
+ const coreSolanaKey = await loadCoreSolanaKeyForSelectedChain();
59620
+ const envKey = process["env"].BLOCKRUN_WALLET_KEY;
59621
+ if (typeof envKey === "string" && /^0x[0-9a-f]{64}$/i.test(envKey)) {
59622
+ const account = privateKeyToAccount(envKey);
59623
+ return {
59624
+ key: envKey,
59625
+ address: account.address,
59626
+ source: "env",
59627
+ ...await resolvedSolanaMaterial(coreSolanaKey)
59628
+ };
59629
+ }
59630
+ const core = await loadCoreWallet();
59631
+ if (core) {
59632
+ const account = privateKeyToAccount(core);
59633
+ return {
59634
+ key: core,
59635
+ address: account.address,
59636
+ source: "core",
59637
+ ...await resolvedSolanaMaterial(coreSolanaKey)
59638
+ };
59639
+ }
59312
59640
  const saved = await loadSavedWallet();
59313
59641
  if (saved) {
59314
59642
  const account = privateKeyToAccount(saved);
59315
- const mnemonic = await loadMnemonic();
59316
- if (mnemonic) {
59317
- const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59318
- return {
59319
- key: saved,
59320
- address: account.address,
59321
- source: "saved",
59322
- mnemonic,
59323
- solanaPrivateKeyBytes: solanaKeyBytes
59324
- };
59325
- }
59326
- return { key: saved, address: account.address, source: "saved" };
59327
- }
59328
- const envKey = process["env"].BLOCKRUN_WALLET_KEY;
59329
- if (typeof envKey === "string" && envKey.startsWith("0x") && envKey.length === 66) {
59330
- const account = privateKeyToAccount(envKey);
59331
- const mnemonic = await loadMnemonic();
59332
- if (mnemonic) {
59333
- const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59334
- return {
59335
- key: envKey,
59336
- address: account.address,
59337
- source: "env",
59338
- mnemonic,
59339
- solanaPrivateKeyBytes: solanaKeyBytes
59340
- };
59341
- }
59342
- return { key: envKey, address: account.address, source: "env" };
59643
+ return {
59644
+ key: saved,
59645
+ address: account.address,
59646
+ source: "saved",
59647
+ ...await resolvedSolanaMaterial(coreSolanaKey)
59648
+ };
59343
59649
  }
59344
- const result = await generateAndSaveWallet();
59650
+ return void 0;
59651
+ }
59652
+ async function resolveOrGenerateWalletKey() {
59653
+ await migrateLegacyWalletToCore();
59654
+ const existing = await resolveExistingWalletKey();
59655
+ if (existing) return existing;
59656
+ const existingCoreSolanaKey = await loadCoreSolanaKey();
59657
+ const result = await generateAndSaveWallet(existingCoreSolanaKey);
59345
59658
  return {
59346
59659
  key: result.key,
59347
59660
  address: result.address,
@@ -59350,13 +59663,69 @@ async function resolveOrGenerateWalletKey() {
59350
59663
  solanaPrivateKeyBytes: result.solanaPrivateKeyBytes
59351
59664
  };
59352
59665
  }
59666
+ async function loadCoreSolanaKeyForSelectedChain() {
59667
+ try {
59668
+ return await loadCoreSolanaKey();
59669
+ } catch (error) {
59670
+ if (await resolvePaymentChain() === "solana") throw error;
59671
+ return void 0;
59672
+ }
59673
+ }
59674
+ async function loadCoreWallet() {
59675
+ const key2 = (await readExisting(CORE_WALLET_FILE))?.trim();
59676
+ if (key2 === void 0) return void 0;
59677
+ if (/^0x[0-9a-f]{64}$/i.test(key2)) return key2;
59678
+ throw new Error(
59679
+ `BlockRun Core wallet at ${CORE_WALLET_FILE} has an invalid format. Refusing to use another wallet implicitly.`
59680
+ );
59681
+ }
59682
+ async function loadCoreSolanaKey() {
59683
+ const environmentKey = process["env"].SOLANA_WALLET_KEY?.trim();
59684
+ const raw = environmentKey || (await readExisting(CORE_SOLANA_WALLET_FILE))?.trim();
59685
+ if (!raw) return void 0;
59686
+ try {
59687
+ let bytes;
59688
+ if (raw.startsWith("[")) {
59689
+ const parsed = JSON.parse(raw);
59690
+ if (!Array.isArray(parsed) || !parsed.every((item) => Number.isInteger(item) && item >= 0 && item <= 255))
59691
+ throw new Error("expected an array of byte values");
59692
+ bytes = Uint8Array.from(parsed);
59693
+ } else {
59694
+ const hex = raw.replace(/^0x/i, "");
59695
+ bytes = /^[0-9a-f]{128}$/i.test(hex) ? Buffer.from(hex, "hex") : esm_default2.decode(raw);
59696
+ }
59697
+ if (bytes.length !== 64) throw new Error(`expected 64 bytes, received ${bytes.length}`);
59698
+ const expected = solanaSecretKeyFromSeed(bytes.slice(0, 32));
59699
+ if (!Buffer.from(expected).equals(Buffer.from(bytes))) {
59700
+ throw new Error("public key does not match the private seed");
59701
+ }
59702
+ return bytes.slice(0, 32);
59703
+ } catch (error) {
59704
+ throw new Error(
59705
+ `BlockRun Core Solana wallet has an invalid format: ${error instanceof Error ? error.message : String(error)}`,
59706
+ { cause: error }
59707
+ );
59708
+ }
59709
+ }
59710
+ async function readOptional(path5) {
59711
+ try {
59712
+ return (await readTextFile(path5)).trim() || void 0;
59713
+ } catch {
59714
+ return void 0;
59715
+ }
59716
+ }
59717
+ async function resolvedSolanaMaterial(coreSolanaKey) {
59718
+ if (coreSolanaKey) return { solanaPrivateKeyBytes: coreSolanaKey };
59719
+ const mnemonic = await loadMnemonic();
59720
+ return mnemonic ? { mnemonic, solanaPrivateKeyBytes: deriveSolanaKeyBytes(mnemonic) } : {};
59721
+ }
59353
59722
  async function setupSolana() {
59354
59723
  const existing = await loadMnemonic();
59355
59724
  if (existing) {
59356
59725
  throw new Error("Solana wallet already set up. Mnemonic file exists at " + MNEMONIC_FILE);
59357
59726
  }
59358
- const savedKey = await loadSavedWallet();
59359
- if (!savedKey) {
59727
+ const evmKey = await loadCoreWallet() ?? await loadSavedWallet();
59728
+ if (!evmKey) {
59360
59729
  throw new Error(
59361
59730
  "No EVM wallet found. Run ClawRouter first to generate a wallet before setting up Solana."
59362
59731
  );
@@ -59364,16 +59733,28 @@ async function setupSolana() {
59364
59733
  const mnemonic = generateWalletMnemonic();
59365
59734
  const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59366
59735
  await saveMnemonic(mnemonic);
59736
+ await writeCoreFileIfMissing(
59737
+ CORE_SOLANA_WALLET_FILE,
59738
+ JSON.stringify([...solanaSecretKeyFromSeed(solanaKeyBytes)]) + "\n"
59739
+ );
59367
59740
  console.log(`[ClawRouter] Solana wallet set up successfully.`);
59368
- console.log(`[ClawRouter] Mnemonic saved to ${MNEMONIC_FILE}`);
59741
+ console.log(`[ClawRouter] Solana key saved to ${CORE_SOLANA_WALLET_FILE}`);
59742
+ console.log(`[ClawRouter] Recovery mnemonic saved to ${MNEMONIC_FILE}`);
59369
59743
  console.log(`[ClawRouter] Existing EVM wallet unchanged.`);
59370
59744
  return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
59371
59745
  }
59372
59746
  async function savePaymentChain(chain3) {
59373
59747
  await mkdir2(WALLET_DIR2, { recursive: true });
59374
- await writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
59748
+ await mkdir2(CORE_WALLET_DIR, { recursive: true });
59749
+ await Promise.all([
59750
+ writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 }),
59751
+ writeFile(CORE_CHAIN_FILE, chain3 + "\n", { mode: 384 })
59752
+ ]);
59375
59753
  }
59376
59754
  async function loadPaymentChain() {
59755
+ const core = await readOptional(CORE_CHAIN_FILE);
59756
+ if (core === "solana") return "solana";
59757
+ if (core === "base") return "base";
59377
59758
  try {
59378
59759
  const content = (await readTextFile(CHAIN_FILE)).trim();
59379
59760
  if (content === "solana") return "solana";
@@ -59387,17 +59768,22 @@ async function resolvePaymentChain() {
59387
59768
  if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
59388
59769
  return loadPaymentChain();
59389
59770
  }
59390
- var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
59771
+ var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE, CORE_WALLET_DIR, CORE_WALLET_FILE, CORE_SOLANA_WALLET_FILE, CORE_CHAIN_FILE;
59391
59772
  var init_auth = __esm({
59392
59773
  "src/auth.ts"() {
59393
59774
  "use strict";
59394
59775
  init_fs_read();
59776
+ init_esm7();
59395
59777
  init_accounts();
59396
59778
  init_wallet2();
59397
59779
  WALLET_DIR2 = join7(homedir4(), ".openclaw", "blockrun");
59398
59780
  WALLET_FILE = join7(WALLET_DIR2, "wallet.key");
59399
59781
  MNEMONIC_FILE = join7(WALLET_DIR2, "mnemonic");
59400
59782
  CHAIN_FILE = join7(WALLET_DIR2, "payment-chain");
59783
+ CORE_WALLET_DIR = join7(homedir4(), ".blockrun");
59784
+ CORE_WALLET_FILE = join7(CORE_WALLET_DIR, ".session");
59785
+ CORE_SOLANA_WALLET_FILE = join7(CORE_WALLET_DIR, ".solana-session");
59786
+ CORE_CHAIN_FILE = join7(CORE_WALLET_DIR, ".chain");
59401
59787
  }
59402
59788
  });
59403
59789
 
@@ -75550,7 +75936,7 @@ var require_snapshot_recorder = __commonJS({
75550
75936
  "node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
75551
75937
  "use strict";
75552
75938
  var { writeFile: writeFile3, readFile: readFile3, mkdir: mkdir5 } = __require("fs/promises");
75553
- var { dirname: dirname5, resolve } = __require("path");
75939
+ var { dirname: dirname4, resolve } = __require("path");
75554
75940
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
75555
75941
  var { InvalidArgumentError, UndiciError } = require_errors();
75556
75942
  var { hashId, isUrlExcludedFactory, normalizeHeaders: normalizeHeaders3, createHeaderFilters } = require_snapshot_utils();
@@ -75796,7 +76182,7 @@ var require_snapshot_recorder = __commonJS({
75796
76182
  throw new InvalidArgumentError("Snapshot path is required");
75797
76183
  }
75798
76184
  const resolvedPath = resolve(path5);
75799
- await mkdir5(dirname5(resolvedPath), { recursive: true });
76185
+ await mkdir5(dirname4(resolvedPath), { recursive: true });
75800
76186
  const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
75801
76187
  hash: hash5,
75802
76188
  snapshot
@@ -89872,6 +90258,7 @@ var init_client3 = __esm({
89872
90258
 
89873
90259
  // src/proxy.ts
89874
90260
  import { AsyncLocalStorage } from "async_hooks";
90261
+ import { createHmac } from "crypto";
89875
90262
  import { createServer } from "http";
89876
90263
  import { finished } from "stream";
89877
90264
  import { homedir as homedir7 } from "os";
@@ -90497,12 +90884,25 @@ function buildProxyModelList(createdAt = Math.floor(Date.now() / 1e3)) {
90497
90884
  if (seen.has(model.id)) return false;
90498
90885
  seen.add(model.id);
90499
90886
  return true;
90500
- }).map((model) => ({
90501
- id: model.id,
90502
- object: "model",
90503
- created: createdAt,
90504
- owned_by: model.id.includes("/") ? model.id.split("/")[0] ?? "blockrun" : "blockrun"
90505
- }));
90887
+ }).map((model) => {
90888
+ const targetId = MODEL_ALIASES[model.id] ?? model.id;
90889
+ const canonical = BLOCKRUN_MODELS.find((entry) => entry.id === targetId);
90890
+ return {
90891
+ id: model.id,
90892
+ object: "model",
90893
+ created: createdAt,
90894
+ owned_by: targetId.includes("/") ? targetId.split("/")[0] ?? "blockrun" : "blockrun",
90895
+ name: model.name,
90896
+ context_window: model.contextWindow,
90897
+ max_output: model.maxTokens,
90898
+ input_price: model.cost.input,
90899
+ output_price: model.cost.output,
90900
+ reasoning: model.reasoning,
90901
+ vision: model.input.includes("image"),
90902
+ agentic: canonical?.agentic ?? false,
90903
+ tool_calling: canonical?.toolCalling ?? false
90904
+ };
90905
+ });
90506
90906
  }
90507
90907
  function mergeRoutingConfig(overrides) {
90508
90908
  if (!overrides) return DEFAULT_ROUTING_CONFIG;
@@ -90742,7 +91142,7 @@ async function startProxy(options) {
90742
91142
  }
90743
91143
  void loadGatewayCatalog(apiBase);
90744
91144
  const listenPort = options.port ?? getProxyPort();
90745
- const existingProxy = await checkExistingProxy(listenPort);
91145
+ const existingProxy = options.allowExistingProxy === false ? void 0 : await checkExistingProxy(listenPort);
90746
91146
  if (existingProxy) {
90747
91147
  const account2 = privateKeyToAccount(walletKey);
90748
91148
  const baseUrl2 = `http://127.0.0.1:${listenPort}`;
@@ -90897,7 +91297,22 @@ async function startProxy(options) {
90897
91297
  response.balanceError = "Could not fetch balance";
90898
91298
  }
90899
91299
  }
90900
- res.writeHead(200, { "Content-Type": "application/json" });
91300
+ const headers = {
91301
+ "Content-Type": "application/json",
91302
+ "Cache-Control": "no-store"
91303
+ };
91304
+ const challengeValue = req.headers["x-clawrouter-challenge"];
91305
+ const challenge2 = Array.isArray(challengeValue) ? challengeValue[0] : challengeValue;
91306
+ if (challenge2 && /^[a-f0-9]{64}$/i.test(challenge2)) {
91307
+ try {
91308
+ const token = readFileSync2(DESKTOP_SERVICE_TOKEN_FILE, "utf8").trim();
91309
+ if (/^[a-f0-9]{64}$/i.test(token)) {
91310
+ headers["X-ClawRouter-Proof"] = createHmac("sha256", token).update(challenge2).digest("hex");
91311
+ }
91312
+ } catch {
91313
+ }
91314
+ }
91315
+ res.writeHead(200, headers);
90901
91316
  res.end(JSON.stringify(response));
90902
91317
  return;
90903
91318
  }
@@ -91766,6 +92181,10 @@ async function startProxy(options) {
91766
92181
  const onError = async (err) => {
91767
92182
  server.removeListener("error", onError);
91768
92183
  if (err.code === "EADDRINUSE") {
92184
+ if (options.allowExistingProxy === false) {
92185
+ rejectAttempt(err);
92186
+ return;
92187
+ }
91769
92188
  const existingProxy2 = await checkExistingProxy(listenPort);
91770
92189
  if (existingProxy2) {
91771
92190
  console.log(`[ClawRouter] Existing proxy detected on port ${listenPort}, reusing`);
@@ -94170,7 +94589,7 @@ data: [DONE]
94170
94589
  });
94171
94590
  }
94172
94591
  }
94173
- 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;
94592
+ 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;
94174
94593
  var init_proxy = __esm({
94175
94594
  "src/proxy.ts"() {
94176
94595
  "use strict";
@@ -94208,6 +94627,7 @@ var init_proxy = __esm({
94208
94627
  paymentStore = new AsyncLocalStorage();
94209
94628
  BLOCKRUN_API = "https://blockrun.ai/api";
94210
94629
  BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
94630
+ DESKTOP_SERVICE_TOKEN_FILE = process.env.CLAWROUTER_DESKTOP_TOKEN_FILE ?? join10(homedir7(), ".clawrouter-desktop", "service-token");
94211
94631
  IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
94212
94632
  AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
94213
94633
  VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
@@ -94463,8 +94883,8 @@ var init_provider = __esm({
94463
94883
  return buildProviderModels(`http://127.0.0.1:${port}/v1`);
94464
94884
  },
94465
94885
  // No auth required — the x402 proxy handles wallet-based payments internally.
94466
- // The proxy auto-generates a wallet on first run and stores it at
94467
- // ~/.openclaw/blockrun/wallet.key. Users just fund that wallet with USDC.
94886
+ // The proxy uses the shared BlockRun Core wallet under ~/.blockrun, with
94887
+ // automatic non-destructive migration from older ClawRouter wallet files.
94468
94888
  auth: []
94469
94889
  };
94470
94890
  }
@@ -108833,7 +109253,7 @@ var init_URLSearchParams = __esm({
108833
109253
 
108834
109254
  // node_modules/axios/lib/platform/node/index.js
108835
109255
  import crypto6 from "crypto";
108836
- var ALPHA, DIGIT, ALPHABET, generateString, node_default;
109256
+ var ALPHA, DIGIT, ALPHABET2, generateString, node_default;
108837
109257
  var init_node2 = __esm({
108838
109258
  "node_modules/axios/lib/platform/node/index.js"() {
108839
109259
  "use strict";
@@ -108841,12 +109261,12 @@ var init_node2 = __esm({
108841
109261
  init_FormData();
108842
109262
  ALPHA = "abcdefghijklmnopqrstuvwxyz";
108843
109263
  DIGIT = "0123456789";
108844
- ALPHABET = {
109264
+ ALPHABET2 = {
108845
109265
  DIGIT,
108846
109266
  ALPHA,
108847
109267
  ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT
108848
109268
  };
108849
- generateString = (size5 = 16, alphabet4 = ALPHABET.ALPHA_DIGIT) => {
109269
+ generateString = (size5 = 16, alphabet4 = ALPHABET2.ALPHA_DIGIT) => {
108850
109270
  let str = "";
108851
109271
  const { length } = alphabet4;
108852
109272
  const randomValues = new Uint32Array(size5);
@@ -108863,7 +109283,7 @@ var init_node2 = __esm({
108863
109283
  FormData: FormData_default,
108864
109284
  Blob: typeof Blob !== "undefined" && Blob || null
108865
109285
  },
108866
- ALPHABET,
109286
+ ALPHABET: ALPHABET2,
108867
109287
  generateString,
108868
109288
  protocols: ["http", "https", "file", "data"]
108869
109289
  };
@@ -110927,8 +111347,8 @@ var require_follow_redirects = __commonJS({
110927
111347
  }
110928
111348
  return parsed;
110929
111349
  }
110930
- function resolveUrl(relative, base3) {
110931
- return useNativeURL ? new URL3(relative, base3) : parseUrl3(url2.resolve(base3, relative));
111350
+ function resolveUrl(relative, base4) {
111351
+ return useNativeURL ? new URL3(relative, base4) : parseUrl3(url2.resolve(base4, relative));
110932
111352
  }
110933
111353
  function validateUrl(input) {
110934
111354
  if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
@@ -117739,7 +118159,7 @@ function __addDisposableResource(env, value, async) {
117739
118159
  return value;
117740
118160
  }
117741
118161
  function __disposeResources(env) {
117742
- function fail(e7) {
118162
+ function fail2(e7) {
117743
118163
  env.error = env.hasError ? new _SuppressedError(e7, env.error, "An error was suppressed during disposal.") : e7;
117744
118164
  env.hasError = true;
117745
118165
  }
@@ -117751,12 +118171,12 @@ function __disposeResources(env) {
117751
118171
  if (r2.dispose) {
117752
118172
  var result = r2.dispose.call(r2.value);
117753
118173
  if (r2.async) return s3 |= 2, Promise.resolve(result).then(next, function(e7) {
117754
- fail(e7);
118174
+ fail2(e7);
117755
118175
  return next();
117756
118176
  });
117757
118177
  } else s3 |= 1;
117758
118178
  } catch (e7) {
117759
- fail(e7);
118179
+ fail2(e7);
117760
118180
  }
117761
118181
  }
117762
118182
  if (s3 === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
@@ -124926,15 +125346,15 @@ var require_curve = __commonJS({
124926
125346
  const { windows, windowSize } = calcWOpts4(W, bits);
124927
125347
  const points = [];
124928
125348
  let p = elm;
124929
- let base3 = p;
125349
+ let base4 = p;
124930
125350
  for (let window2 = 0; window2 < windows; window2++) {
124931
- base3 = p;
124932
- points.push(base3);
125351
+ base4 = p;
125352
+ points.push(base4);
124933
125353
  for (let i = 1; i < windowSize; i++) {
124934
- base3 = base3.add(p);
124935
- points.push(base3);
125354
+ base4 = base4.add(p);
125355
+ points.push(base4);
124936
125356
  }
124937
- p = base3.double();
125357
+ p = base4.double();
124938
125358
  }
124939
125359
  return points;
124940
125360
  },
@@ -127692,7 +128112,7 @@ var require_estimateFeesPerGas = __commonJS({
127692
128112
  throw new fee_js_1.BaseFeeScalarError();
127693
128113
  const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
127694
128114
  const denominator = 10 ** decimals;
127695
- const multiply = (base3) => base3 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
128115
+ const multiply = (base4) => base4 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
127696
128116
  const block = block_ ? block_ : await (0, getAction_js_1.getAction)(client, getBlock_js_1.getBlock, "getBlock")({});
127697
128117
  if (typeof chain3?.fees?.estimateFeesPerGas === "function") {
127698
128118
  const fees = await chain3.fees.estimateFeesPerGas({
@@ -128202,7 +128622,7 @@ var require_fillTransaction = __commonJS({
128202
128622
  throw new fee_js_1.BaseFeeScalarError();
128203
128623
  const decimals = feeMultiplier.toString().split(".")[1]?.length ?? 0;
128204
128624
  const denominator = 10 ** decimals;
128205
- const multiplyFee = (base3) => base3 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
128625
+ const multiplyFee = (base4) => base4 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
128206
128626
  if (!transaction.feePayerSignature) {
128207
128627
  if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
128208
128628
  transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas);
@@ -132960,17 +133380,17 @@ var require_call = __commonJS({
132960
133380
  }
132961
133381
  }
132962
133382
  const params = (() => {
132963
- const base3 = [
133383
+ const base4 = [
132964
133384
  request2,
132965
133385
  block
132966
133386
  ];
132967
133387
  if (rpcStateOverride && rpcBlockOverrides)
132968
- return [...base3, rpcStateOverride, rpcBlockOverrides];
133388
+ return [...base4, rpcStateOverride, rpcBlockOverrides];
132969
133389
  if (rpcStateOverride)
132970
- return [...base3, rpcStateOverride];
133390
+ return [...base4, rpcStateOverride];
132971
133391
  if (rpcBlockOverrides)
132972
- return [...base3, {}, rpcBlockOverrides];
132973
- return base3;
133392
+ return [...base4, {}, rpcBlockOverrides];
133393
+ return base4;
132974
133394
  })();
132975
133395
  const response = await client.request({
132976
133396
  method: "eth_call",
@@ -134582,14 +135002,14 @@ var require_createClient = __commonJS({
134582
135002
  uid: (0, uid_js_1.uid)(),
134583
135003
  ...experimental_blockTag ? { experimental_blockTag } : {}
134584
135004
  };
134585
- function extend2(base3) {
135005
+ function extend2(base4) {
134586
135006
  return (extendFn) => {
134587
- const extended = extendFn(base3);
135007
+ const extended = extendFn(base4);
134588
135008
  for (const key3 in client)
134589
135009
  delete extended[key3];
134590
- const combined = { ...base3, ...extended };
135010
+ const combined = { ...base4, ...extended };
134591
135011
  for (const key3 in extended) {
134592
- const a = base3[key3];
135012
+ const a = base4[key3];
134593
135013
  const b = extended[key3];
134594
135014
  if (isPlainObject4(a) && isPlainObject4(b))
134595
135015
  combined[key3] = { ...a, ...b };
@@ -136607,10 +137027,10 @@ var require_defineChain = __commonJS({
136607
137027
  serializers: void 0,
136608
137028
  ...chain3
136609
137029
  };
136610
- function extend2(base3) {
137030
+ function extend2(base4) {
136611
137031
  return (fnOrExtended) => {
136612
- const properties = typeof fnOrExtended === "function" ? fnOrExtended(base3) : fnOrExtended;
136613
- const combined = { ...base3, ...properties };
137032
+ const properties = typeof fnOrExtended === "function" ? fnOrExtended(base4) : fnOrExtended;
137033
+ const combined = { ...base4, ...properties };
136614
137034
  return Object.assign(combined, { extend: extend2(combined) });
136615
137035
  };
136616
137036
  }
@@ -137945,9 +138365,9 @@ var require_typedData2 = __commonJS({
137945
138365
  throw new typedData_js_1.InvalidTypedDataTypeError({ type });
137946
138366
  const integerMatch = type.match(regex_js_1.integerRegex);
137947
138367
  if (integerMatch && (typeof value === "number" || typeof value === "bigint")) {
137948
- const [_type, base3, size_] = integerMatch;
138368
+ const [_type, base4, size_] = integerMatch;
137949
138369
  (0, toHex_js_1.numberToHex)(value, {
137950
- signed: base3 === "int",
138370
+ signed: base4 === "int",
137951
138371
  size: Number.parseInt(size_, 10) / 8
137952
138372
  });
137953
138373
  }
@@ -141739,15 +142159,15 @@ var require_curve2 = __commonJS({
141739
142159
  const { windows, windowSize } = calcWOpts4(W, bits);
141740
142160
  const points = [];
141741
142161
  let p = elm;
141742
- let base3 = p;
142162
+ let base4 = p;
141743
142163
  for (let window2 = 0; window2 < windows; window2++) {
141744
- base3 = p;
141745
- points.push(base3);
142164
+ base4 = p;
142165
+ points.push(base4);
141746
142166
  for (let i = 1; i < windowSize; i++) {
141747
- base3 = base3.add(p);
141748
- points.push(base3);
142167
+ base4 = base4.add(p);
142168
+ points.push(base4);
141749
142169
  }
141750
- p = base3.double();
142170
+ p = base4.double();
141751
142171
  }
141752
142172
  return points;
141753
142173
  },
@@ -175260,14 +175680,14 @@ var require_Authenticator = __commonJS({
175260
175680
  const rpIdHash = Hash4.sha256(Hex.fromString(rpId));
175261
175681
  const flag_bytes = Hex.fromNumber(flag, { size: 1 });
175262
175682
  const signCount_bytes = Hex.fromNumber(signCount, { size: 4 });
175263
- const base3 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
175683
+ const base4 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
175264
175684
  if (!credential)
175265
- return base3;
175685
+ return base4;
175266
175686
  const aaguid = Hex.fromBytes(new Uint8Array(16));
175267
175687
  const credentialId = Hex.fromBytes(credential.id);
175268
175688
  const credIdLen = Hex.fromNumber(credential.id.length, { size: 2 });
175269
175689
  const coseKey = CoseKey.fromPublicKey(credential.publicKey);
175270
- return Hex.concat(base3, aaguid, credIdLen, credentialId, coseKey);
175690
+ return Hex.concat(base4, aaguid, credIdLen, credentialId, coseKey);
175271
175691
  }
175272
175692
  function getSignCount(authenticatorData) {
175273
175693
  const bytes = Bytes.fromHex(authenticatorData);
@@ -179175,7 +179595,7 @@ var require_VirtualMaster = __commonJS({
179175
179595
  terminateAll();
179176
179596
  resolve(result);
179177
179597
  };
179178
- const fail = (error) => {
179598
+ const fail2 = (error) => {
179179
179599
  if (settled)
179180
179600
  return;
179181
179601
  settled = true;
@@ -179200,14 +179620,14 @@ var require_VirtualMaster = __commonJS({
179200
179620
  succeed(void 0);
179201
179621
  return;
179202
179622
  case "error":
179203
- fail(new Errors.BaseError(msg.message));
179623
+ fail2(new Errors.BaseError(msg.message));
179204
179624
  return;
179205
179625
  }
179206
179626
  };
179207
- const onAbort = () => fail(getAbortError2(value.signal));
179627
+ const onAbort = () => fail2(getAbortError2(value.signal));
179208
179628
  value.signal?.addEventListener("abort", onAbort, { once: true });
179209
179629
  for (let i = 0; i < value.workerCount; i++) {
179210
- const handle = value.pool.spawn(i, onMessage, fail);
179630
+ const handle = value.pool.spawn(i, onMessage, fail2);
179211
179631
  handles.push(handle);
179212
179632
  handle.postMessage({
179213
179633
  type: "start",
@@ -179351,8 +179771,8 @@ var require_ZoneId = __commonJS({
179351
179771
  return chainId - getChainIdConfig(sourceId2).base;
179352
179772
  }
179353
179773
  function toChainId(zoneId, sourceId2 = defaultSourceId) {
179354
- const { base: base3, range } = getChainIdConfig(sourceId2);
179355
- return base3 + zoneId % range;
179774
+ const { base: base4, range } = getChainIdConfig(sourceId2);
179775
+ return base4 + zoneId % range;
179356
179776
  }
179357
179777
  var UnsupportedSourceIdError = class extends Errors.BaseError {
179358
179778
  constructor({ sourceId: sourceId2 }) {
@@ -192958,7 +193378,7 @@ var require_bn = __commonJS({
192958
193378
  ctor.prototype = new TempCtor();
192959
193379
  ctor.prototype.constructor = ctor;
192960
193380
  }
192961
- function BN3(number, base3, endian) {
193381
+ function BN3(number, base4, endian) {
192962
193382
  if (BN3.isBN(number)) {
192963
193383
  return number;
192964
193384
  }
@@ -192967,11 +193387,11 @@ var require_bn = __commonJS({
192967
193387
  this.length = 0;
192968
193388
  this.red = null;
192969
193389
  if (number !== null) {
192970
- if (base3 === "le" || base3 === "be") {
192971
- endian = base3;
192972
- base3 = 10;
193390
+ if (base4 === "le" || base4 === "be") {
193391
+ endian = base4;
193392
+ base4 = 10;
192973
193393
  }
192974
- this._init(number || 0, base3 || 10, endian || "be");
193394
+ this._init(number || 0, base4 || 10, endian || "be");
192975
193395
  }
192976
193396
  }
192977
193397
  if (typeof module2 === "object") {
@@ -193004,17 +193424,17 @@ var require_bn = __commonJS({
193004
193424
  if (left.cmp(right) < 0) return left;
193005
193425
  return right;
193006
193426
  };
193007
- BN3.prototype._init = function init2(number, base3, endian) {
193427
+ BN3.prototype._init = function init2(number, base4, endian) {
193008
193428
  if (typeof number === "number") {
193009
- return this._initNumber(number, base3, endian);
193429
+ return this._initNumber(number, base4, endian);
193010
193430
  }
193011
193431
  if (typeof number === "object") {
193012
- return this._initArray(number, base3, endian);
193432
+ return this._initArray(number, base4, endian);
193013
193433
  }
193014
- if (base3 === "hex") {
193015
- base3 = 16;
193434
+ if (base4 === "hex") {
193435
+ base4 = 16;
193016
193436
  }
193017
- assert10(base3 === (base3 | 0) && base3 >= 2 && base3 <= 36);
193437
+ assert10(base4 === (base4 | 0) && base4 >= 2 && base4 <= 36);
193018
193438
  number = number.toString().replace(/\s+/g, "");
193019
193439
  var start = 0;
193020
193440
  if (number[0] === "-") {
@@ -193022,17 +193442,17 @@ var require_bn = __commonJS({
193022
193442
  this.negative = 1;
193023
193443
  }
193024
193444
  if (start < number.length) {
193025
- if (base3 === 16) {
193445
+ if (base4 === 16) {
193026
193446
  this._parseHex(number, start, endian);
193027
193447
  } else {
193028
- this._parseBase(number, base3, start);
193448
+ this._parseBase(number, base4, start);
193029
193449
  if (endian === "le") {
193030
- this._initArray(this.toArray(), base3, endian);
193450
+ this._initArray(this.toArray(), base4, endian);
193031
193451
  }
193032
193452
  }
193033
193453
  }
193034
193454
  };
193035
- BN3.prototype._initNumber = function _initNumber(number, base3, endian) {
193455
+ BN3.prototype._initNumber = function _initNumber(number, base4, endian) {
193036
193456
  if (number < 0) {
193037
193457
  this.negative = 1;
193038
193458
  number = -number;
@@ -193056,9 +193476,9 @@ var require_bn = __commonJS({
193056
193476
  this.length = 3;
193057
193477
  }
193058
193478
  if (endian !== "le") return;
193059
- this._initArray(this.toArray(), base3, endian);
193479
+ this._initArray(this.toArray(), base4, endian);
193060
193480
  };
193061
- BN3.prototype._initArray = function _initArray(number, base3, endian) {
193481
+ BN3.prototype._initArray = function _initArray(number, base4, endian) {
193062
193482
  assert10(typeof number.length === "number");
193063
193483
  if (number.length <= 0) {
193064
193484
  this.words = [0];
@@ -193172,20 +193592,20 @@ var require_bn = __commonJS({
193172
193592
  }
193173
193593
  return r2;
193174
193594
  }
193175
- BN3.prototype._parseBase = function _parseBase(number, base3, start) {
193595
+ BN3.prototype._parseBase = function _parseBase(number, base4, start) {
193176
193596
  this.words = [0];
193177
193597
  this.length = 1;
193178
- for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *= base3) {
193598
+ for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *= base4) {
193179
193599
  limbLen++;
193180
193600
  }
193181
193601
  limbLen--;
193182
- limbPow = limbPow / base3 | 0;
193602
+ limbPow = limbPow / base4 | 0;
193183
193603
  var total = number.length - start;
193184
193604
  var mod5 = total % limbLen;
193185
193605
  var end = Math.min(total, total - mod5) + start;
193186
193606
  var word = 0;
193187
193607
  for (var i = start; i < end; i += limbLen) {
193188
- word = parseBase(number, i, i + limbLen, base3);
193608
+ word = parseBase(number, i, i + limbLen, base4);
193189
193609
  this.imuln(limbPow);
193190
193610
  if (this.words[0] + word < 67108864) {
193191
193611
  this.words[0] += word;
@@ -193195,9 +193615,9 @@ var require_bn = __commonJS({
193195
193615
  }
193196
193616
  if (mod5 !== 0) {
193197
193617
  var pow = 1;
193198
- word = parseBase(number, i, number.length, base3);
193618
+ word = parseBase(number, i, number.length, base4);
193199
193619
  for (i = 0; i < mod5; i++) {
193200
- pow *= base3;
193620
+ pow *= base4;
193201
193621
  }
193202
193622
  this.imuln(pow);
193203
193623
  if (this.words[0] + word < 67108864) {
@@ -193367,11 +193787,11 @@ var require_bn = __commonJS({
193367
193787
  52521875,
193368
193788
  60466176
193369
193789
  ];
193370
- BN3.prototype.toString = function toString4(base3, padding3) {
193371
- base3 = base3 || 10;
193790
+ BN3.prototype.toString = function toString4(base4, padding3) {
193791
+ base4 = base4 || 10;
193372
193792
  padding3 = padding3 | 0 || 1;
193373
193793
  var out;
193374
- if (base3 === 16 || base3 === "hex") {
193794
+ if (base4 === 16 || base4 === "hex") {
193375
193795
  out = "";
193376
193796
  var off = 0;
193377
193797
  var carry2 = 0;
@@ -193401,14 +193821,14 @@ var require_bn = __commonJS({
193401
193821
  }
193402
193822
  return out;
193403
193823
  }
193404
- if (base3 === (base3 | 0) && base3 >= 2 && base3 <= 36) {
193405
- var groupSize = groupSizes[base3];
193406
- var groupBase = groupBases[base3];
193824
+ if (base4 === (base4 | 0) && base4 >= 2 && base4 <= 36) {
193825
+ var groupSize = groupSizes[base4];
193826
+ var groupBase = groupBases[base4];
193407
193827
  out = "";
193408
193828
  var c = this.clone();
193409
193829
  c.negative = 0;
193410
193830
  while (!c.isZero()) {
193411
- var r2 = c.modrn(groupBase).toString(base3);
193831
+ var r2 = c.modrn(groupBase).toString(base4);
193412
193832
  c = c.idivn(groupBase);
193413
193833
  if (!c.isZero()) {
193414
193834
  out = zeros2[groupSize - r2.length] + r2 + out;
@@ -203977,8 +204397,8 @@ function createCommonjsModule(fn, basedir, module) {
203977
204397
  return module = {
203978
204398
  path: basedir,
203979
204399
  exports: {},
203980
- require: function(path5, base3) {
203981
- return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
204400
+ require: function(path5, base4) {
204401
+ return commonjsRequire(path5, base4 === void 0 || base4 === null ? module.path : base4);
203982
204402
  }
203983
204403
  }, fn(module, module.exports), module.exports;
203984
204404
  }
@@ -204017,7 +204437,7 @@ function BasePoint(curve, type) {
204017
204437
  this.precomputed = null;
204018
204438
  }
204019
204439
  function ShortCurve(conf) {
204020
- base2.call(this, "short", conf);
204440
+ base3.call(this, "short", conf);
204021
204441
  this.a = new import_bn2.default(conf.a, 16).toRed(this.red);
204022
204442
  this.b = new import_bn2.default(conf.b, 16).toRed(this.red);
204023
204443
  this.tinv = this.two.redInvm();
@@ -204028,7 +204448,7 @@ function ShortCurve(conf) {
204028
204448
  this._endoWnafT2 = new Array(4);
204029
204449
  }
204030
204450
  function Point3(curve, x, y, isRed) {
204031
- base2.BasePoint.call(this, curve, "affine");
204451
+ base3.BasePoint.call(this, curve, "affine");
204032
204452
  if (x === null && y === null) {
204033
204453
  this.x = null;
204034
204454
  this.y = null;
@@ -204048,7 +204468,7 @@ function Point3(curve, x, y, isRed) {
204048
204468
  }
204049
204469
  }
204050
204470
  function JPoint(curve, x, y, z) {
204051
- base2.BasePoint.call(this, curve, "jacobian");
204471
+ base3.BasePoint.call(this, curve, "jacobian");
204052
204472
  if (x === null && y === null && z === null) {
204053
204473
  this.x = this.curve.one;
204054
204474
  this.y = this.curve.one;
@@ -204178,7 +204598,7 @@ function EC(options) {
204178
204598
  this.g.precompute(options.curve.n.bitLength() + 1);
204179
204599
  this.hash = options.hash || options.curve.hash;
204180
204600
  }
204181
- 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;
204601
+ 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;
204182
204602
  var init_elliptic = __esm({
204183
204603
  "node_modules/@ethersproject/signing-key/lib.esm/elliptic.js"() {
204184
204604
  "use strict";
@@ -204346,7 +204766,7 @@ var init_elliptic = __esm({
204346
204766
  getNAF = utils_1$1.getNAF;
204347
204767
  getJSF = utils_1$1.getJSF;
204348
204768
  assert$1 = utils_1$1.assert;
204349
- base2 = BaseCurve;
204769
+ base3 = BaseCurve;
204350
204770
  BaseCurve.prototype.point = function point() {
204351
204771
  throw new Error("Not implemented");
204352
204772
  };
@@ -204658,7 +205078,7 @@ var init_elliptic = __esm({
204658
205078
  }
204659
205079
  });
204660
205080
  assert$2 = utils_1$1.assert;
204661
- inherits_browser(ShortCurve, base2);
205081
+ inherits_browser(ShortCurve, base3);
204662
205082
  short_1 = ShortCurve;
204663
205083
  ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
204664
205084
  if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
@@ -204832,7 +205252,7 @@ var init_elliptic = __esm({
204832
205252
  }
204833
205253
  return res;
204834
205254
  };
204835
- inherits_browser(Point3, base2.BasePoint);
205255
+ inherits_browser(Point3, base3.BasePoint);
204836
205256
  ShortCurve.prototype.point = function point2(x, y, isRed) {
204837
205257
  return new Point3(this, x, y, isRed);
204838
205258
  };
@@ -205007,7 +205427,7 @@ var init_elliptic = __esm({
205007
205427
  var res = this.curve.jpoint(this.x, this.y, this.curve.one);
205008
205428
  return res;
205009
205429
  };
205010
- inherits_browser(JPoint, base2.BasePoint);
205430
+ inherits_browser(JPoint, base3.BasePoint);
205011
205431
  ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
205012
205432
  return new JPoint(this, x, y, z);
205013
205433
  };
@@ -205297,7 +205717,7 @@ var init_elliptic = __esm({
205297
205717
  curve_1 = createCommonjsModule(function(module, exports) {
205298
205718
  "use strict";
205299
205719
  var curve = exports;
205300
- curve.base = base2;
205720
+ curve.base = base3;
205301
205721
  curve.short = short_1;
205302
205722
  curve.mont = /*RicMoo:ethers:require(./mont)*/
205303
205723
  null;
@@ -210518,10 +210938,10 @@ var init_lib28 = __esm({
210518
210938
  var require_bech32 = __commonJS({
210519
210939
  "node_modules/bech32/index.js"(exports, module) {
210520
210940
  "use strict";
210521
- var ALPHABET2 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
210941
+ var ALPHABET3 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
210522
210942
  var ALPHABET_MAP = {};
210523
- for (z = 0; z < ALPHABET2.length; z++) {
210524
- x = ALPHABET2.charAt(z);
210943
+ for (z = 0; z < ALPHABET3.length; z++) {
210944
+ x = ALPHABET3.charAt(z);
210525
210945
  if (ALPHABET_MAP[x] !== void 0) throw new TypeError(x + " is ambiguous");
210526
210946
  ALPHABET_MAP[x] = z;
210527
210947
  }
@@ -210556,7 +210976,7 @@ var require_bech32 = __commonJS({
210556
210976
  var x2 = words2[i];
210557
210977
  if (x2 >> 5 !== 0) throw new Error("Non 5-bit word");
210558
210978
  chk = polymodStep(chk) ^ x2;
210559
- result += ALPHABET2.charAt(x2);
210979
+ result += ALPHABET3.charAt(x2);
210560
210980
  }
210561
210981
  for (i = 0; i < 6; ++i) {
210562
210982
  chk = polymodStep(chk);
@@ -210564,7 +210984,7 @@ var require_bech32 = __commonJS({
210564
210984
  chk ^= 1;
210565
210985
  for (i = 0; i < 6; ++i) {
210566
210986
  var v = chk >> (5 - i) * 5 & 31;
210567
- result += ALPHABET2.charAt(v);
210987
+ result += ALPHABET3.charAt(v);
210568
210988
  }
210569
210989
  return result;
210570
210990
  }
@@ -217944,12 +218364,12 @@ var require_axios = __commonJS({
217944
218364
  var URLSearchParams2 = url2.URLSearchParams;
217945
218365
  var ALPHA2 = "abcdefghijklmnopqrstuvwxyz";
217946
218366
  var DIGIT2 = "0123456789";
217947
- var ALPHABET2 = {
218367
+ var ALPHABET3 = {
217948
218368
  DIGIT: DIGIT2,
217949
218369
  ALPHA: ALPHA2,
217950
218370
  ALPHA_DIGIT: ALPHA2 + ALPHA2.toUpperCase() + DIGIT2
217951
218371
  };
217952
- var generateString2 = (size5 = 16, alphabet4 = ALPHABET2.ALPHA_DIGIT) => {
218372
+ var generateString2 = (size5 = 16, alphabet4 = ALPHABET3.ALPHA_DIGIT) => {
217953
218373
  let str = "";
217954
218374
  const {
217955
218375
  length
@@ -217968,7 +218388,7 @@ var require_axios = __commonJS({
217968
218388
  FormData: FormData$1,
217969
218389
  Blob: typeof Blob !== "undefined" && Blob || null
217970
218390
  },
217971
- ALPHABET: ALPHABET2,
218391
+ ALPHABET: ALPHABET3,
217972
218392
  generateString: generateString2,
217973
218393
  protocols: ["http", "https", "file", "data"]
217974
218394
  };
@@ -225294,10 +225714,10 @@ async function redeemPosition(input, deps) {
225294
225714
  structured: { conditionId, negRisk, transactionHash: txHash, pusdBalance: balanceAfter }
225295
225715
  };
225296
225716
  } catch (err) {
225297
- const base3 = await mapClobError(err);
225717
+ const base4 = await mapClobError(err);
225298
225718
  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.`;
225299
225719
  return {
225300
- text: `${base3}${/revert|execution reverted|failed/i.test(base3) ? legacyHint : ""}`,
225720
+ text: `${base4}${/revert|execution reverted|failed/i.test(base4) ? legacyHint : ""}`,
225301
225721
  isError: true
225302
225722
  };
225303
225723
  }
@@ -225943,8 +226363,8 @@ var init_dist7 = __esm({
225943
226363
  if (normalized.startsWith("/api/")) {
225944
226364
  normalized = normalized.slice(4);
225945
226365
  }
225946
- const base3 = `${this.apiUrl}${normalized}`;
225947
- if (!params) return base3;
226366
+ const base4 = `${this.apiUrl}${normalized}`;
226367
+ if (!params) return base4;
225948
226368
  const qs = new URLSearchParams();
225949
226369
  for (const [key2, value] of Object.entries(params)) {
225950
226370
  if (value === void 0 || value === null) continue;
@@ -225958,12 +226378,12 @@ var init_dist7 = __esm({
225958
226378
  }
225959
226379
  }
225960
226380
  const query = qs.toString();
225961
- return query ? `${base3}?${query}` : base3;
226381
+ return query ? `${base4}?${query}` : base4;
225962
226382
  }
225963
226383
  absolute(url2) {
225964
226384
  if (url2.startsWith("http://") || url2.startsWith("https://")) return url2;
225965
- const base3 = this.apiUrl.endsWith("/api") ? this.apiUrl.slice(0, -"/api".length) : this.apiUrl;
225966
- return `${base3}${url2}`;
226385
+ const base4 = this.apiUrl.endsWith("/api") ? this.apiUrl.slice(0, -"/api".length) : this.apiUrl;
226386
+ return `${base4}${url2}`;
225967
226387
  }
225968
226388
  async requestWithPayment(url2, method, body) {
225969
226389
  const init2 = { method };
@@ -226537,6 +226957,210 @@ var init_exclude = __esm({
226537
226957
  }
226538
226958
  });
226539
226959
 
226960
+ // src/commands/policy.ts
226961
+ function unsetMeaning(key2) {
226962
+ switch (key2) {
226963
+ case "allowedPayees":
226964
+ return "every payee is permitted";
226965
+ case "allowedNetworks":
226966
+ return "every network is permitted";
226967
+ case "allowedAssets":
226968
+ return "every asset is permitted";
226969
+ case "blockedPayees":
226970
+ return "no payee is blocked";
226971
+ default:
226972
+ return `spend in the ${key2} window is uncapped`;
226973
+ }
226974
+ }
226975
+ function fail(text) {
226976
+ return { text, isError: true };
226977
+ }
226978
+ function isPolicyList2(v) {
226979
+ return POLICY_LISTS.includes(v);
226980
+ }
226981
+ function isSpendWindow(v) {
226982
+ return SPEND_WINDOWS.includes(v);
226983
+ }
226984
+ function isListAction(v) {
226985
+ return LIST_ACTIONS.includes(v);
226986
+ }
226987
+ function rejectValue(list, value) {
226988
+ if (list === "allowedNetworks") {
226989
+ 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`;
226990
+ }
226991
+ if (/^0x/i.test(value)) {
226992
+ return EVM_ADDRESS2.test(value) ? void 0 : `"${value}" starts with 0x but is not 0x followed by exactly 40 hex characters`;
226993
+ }
226994
+ 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)`;
226995
+ }
226996
+ function parsePolicyArgs(argv) {
226997
+ const [sub = "", target = "", ...values] = argv;
226998
+ const action = sub.toLowerCase();
226999
+ if (action === "") return { kind: "show" };
227000
+ if (action === "limit") {
227001
+ if (!isSpendWindow(target)) {
227002
+ return fail(
227003
+ `Unknown window "${target}"; expected one of: ${SPEND_WINDOWS.join(", ")}
227004
+ ${USAGE}`
227005
+ );
227006
+ }
227007
+ const raw = values[0];
227008
+ if (raw === void 0 || values.length !== 1) {
227009
+ return fail(`policy limit takes exactly one amount (or "clear")
227010
+ ${USAGE}`);
227011
+ }
227012
+ if (raw === "clear") return { kind: "limit", window: target, usd: void 0 };
227013
+ const usd = Number(raw);
227014
+ if (!USD.test(raw) || !Number.isFinite(usd) || usd <= 0) {
227015
+ return fail(
227016
+ `Rejected amount "${raw}": must be a positive decimal USD value such as 0.10 or 5`
227017
+ );
227018
+ }
227019
+ return { kind: "limit", window: target, usd };
227020
+ }
227021
+ if (!isListAction(action)) return fail(`Unknown subcommand "${sub}"
227022
+ ${USAGE}`);
227023
+ if (!isPolicyList2(target)) {
227024
+ return fail(`Unknown list "${target}"; expected one of: ${POLICY_LISTS.join(", ")}
227025
+ ${USAGE}`);
227026
+ }
227027
+ if (action === "clear" ? values.length !== 0 : values.length === 0) {
227028
+ return fail(
227029
+ `policy ${action} <list> ${action === "clear" ? "takes no values" : "needs at least one value"}
227030
+ ${USAGE}`
227031
+ );
227032
+ }
227033
+ for (const v of values) {
227034
+ const why = rejectValue(target, v);
227035
+ if (why !== void 0) return fail(`Rejected ${target} entry: ${why}`);
227036
+ }
227037
+ return { kind: "list", action, list: target, values };
227038
+ }
227039
+ function nextListValue(current, plan) {
227040
+ const have = current ?? [];
227041
+ const wanted = [...new Set(plan.values.map(normalizePayee))];
227042
+ switch (plan.action) {
227043
+ case "set":
227044
+ return { next: wanted };
227045
+ case "clear":
227046
+ return { next: void 0 };
227047
+ case "add":
227048
+ return { next: [.../* @__PURE__ */ new Set([...have, ...wanted])] };
227049
+ case "remove": {
227050
+ if (have.length === 0) return { reject: `${plan.list} is not configured; nothing to remove` };
227051
+ const missing = wanted.filter((v) => !have.includes(v));
227052
+ if (missing.length > 0) return { reject: `not in ${plan.list}: ${missing.join(", ")}` };
227053
+ const next = have.filter((v) => !wanted.includes(v));
227054
+ if (next.length === 0 && ALLOW_LISTS.includes(plan.list)) {
227055
+ return {
227056
+ 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`
227057
+ };
227058
+ }
227059
+ return { next: next.length > 0 ? next : void 0 };
227060
+ }
227061
+ }
227062
+ }
227063
+ function formatPolicy(limits) {
227064
+ const lines = ["Spend limits (USD):"];
227065
+ for (const w of SPEND_WINDOWS) {
227066
+ const v = limits[w];
227067
+ lines.push(` ${w}: ${v === void 0 ? `(unset \u2014 ${unsetMeaning(w)})` : `$${v}`}`);
227068
+ }
227069
+ lines.push("Policy lists:");
227070
+ for (const l2 of POLICY_LISTS) {
227071
+ const v = limits[l2];
227072
+ lines.push(` ${l2}: ${v && v.length > 0 ? v.join(", ") : `(unset \u2014 ${unsetMeaning(l2)})`}`);
227073
+ }
227074
+ return lines.join("\n");
227075
+ }
227076
+ function runPolicyCommand(argv, options) {
227077
+ const plan = parsePolicyArgs(argv);
227078
+ if (!("kind" in plan)) return plan;
227079
+ const openControl = options?.openControl ?? (() => new SpendControl());
227080
+ const live = options?.liveControl?.();
227081
+ const control = live ?? openControl();
227082
+ const broken = control.getPolicyFileError();
227083
+ if (broken !== void 0) {
227084
+ return fail(`${broken}
227085
+ Nothing was written; repair or delete spending.json, then retry.`);
227086
+ }
227087
+ if (plan.kind === "show") return { text: formatPolicy(control.getLimits()) };
227088
+ const before = openControl().getLimits();
227089
+ const key2 = plan.kind === "limit" ? plan.window : plan.list;
227090
+ let expected;
227091
+ try {
227092
+ if (plan.kind === "limit") {
227093
+ expected = plan.usd;
227094
+ if (plan.usd === void 0) control.clearLimit(plan.window);
227095
+ else control.setLimit(plan.window, plan.usd);
227096
+ } else {
227097
+ const outcome = nextListValue(control.getLimits()[plan.list], plan);
227098
+ if ("reject" in outcome) return fail(`${outcome.reject}; nothing written`);
227099
+ expected = outcome.next;
227100
+ if (outcome.next === void 0) control.clearPolicy(plan.list);
227101
+ else control.setPolicy(plan.list, outcome.next);
227102
+ }
227103
+ } catch (err) {
227104
+ if (err instanceof SpendPolicyConflictError) {
227105
+ return fail(
227106
+ `${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`
227107
+ );
227108
+ }
227109
+ return fail(`Nothing was written: ${err instanceof Error ? err.message : String(err)}`);
227110
+ }
227111
+ const expectedAll = { ...before };
227112
+ if (expected === void 0) delete expectedAll[key2];
227113
+ else expectedAll[key2] = expected;
227114
+ const after = openControl().getLimits();
227115
+ const keys = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after), key2])];
227116
+ const drift = keys.filter((k) => JSON.stringify(after[k]) !== JSON.stringify(expectedAll[k]));
227117
+ if (drift.length > 0) {
227118
+ const show = (v) => v === void 0 ? "(unset)" : JSON.stringify(v);
227119
+ const detail = drift.map((k) => `${k} ${show(after[k])} vs ${show(expectedAll[k])}`).join("; ");
227120
+ return fail(
227121
+ `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`
227122
+ );
227123
+ }
227124
+ const headline = expected === void 0 ? `${key2} is now unset \u2014 ${unsetMeaning(key2)}.` : `${key2}: ${JSON.stringify(expected)}`;
227125
+ return {
227126
+ text: live ? `${headline}
227127
+ ${APPLIED_LIVE}` : `${RESTART_REQUIRED}
227128
+ ${headline}`
227129
+ };
227130
+ }
227131
+ function createPolicyCommand(options) {
227132
+ return {
227133
+ name: "policy",
227134
+ description: "Spend limits and counterparty policy \u2014 /policy [set|add|remove|clear <list> ...] [limit <window> <usd>|clear]",
227135
+ acceptsArgs: true,
227136
+ requireAuth: true,
227137
+ handler: async (ctx) => runPolicyCommand((ctx.args ?? "").trim().split(/\s+/).filter(Boolean), options)
227138
+ };
227139
+ }
227140
+ var SPEND_WINDOWS, USD, EVM_ADDRESS2, BASE58_ADDRESS, LIST_ACTIONS, ALLOW_LISTS, USAGE, RESTART_REQUIRED, APPLIED_LIVE;
227141
+ var init_policy = __esm({
227142
+ "src/commands/policy.ts"() {
227143
+ "use strict";
227144
+ init_spend_control();
227145
+ SPEND_WINDOWS = ["perRequest", "hourly", "daily", "session"];
227146
+ USD = /^\d+(\.\d+)?$/;
227147
+ EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/;
227148
+ BASE58_ADDRESS = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
227149
+ LIST_ACTIONS = ["set", "add", "remove", "clear"];
227150
+ ALLOW_LISTS = ["allowedPayees", "allowedNetworks", "allowedAssets"];
227151
+ USAGE = [
227152
+ "Usage:",
227153
+ " policy show limits and lists on disk",
227154
+ ` policy set|add|remove <list> <v>... <list>: ${POLICY_LISTS.join(" | ")}`,
227155
+ " policy clear <list>",
227156
+ ` policy limit <window> <usd>|clear <window>: ${SPEND_WINDOWS.join(" | ")}`,
227157
+ `Networks are CAIP-2 ids: ${CAIP2_BASE} (Base) or ${CAIP2_SOLANA_MAINNET} (Solana mainnet).`
227158
+ ].join("\n");
227159
+ 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.";
227160
+ APPLIED_LIVE = "Applied to the running proxy and saved to spending.json.";
227161
+ }
227162
+ });
227163
+
226540
227164
  // src/mcp-config.ts
226541
227165
  function isRecord(value) {
226542
227166
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -226587,6 +227211,108 @@ var init_mcp_config = __esm({
226587
227211
  }
226588
227212
  });
226589
227213
 
227214
+ // src/openclaw-plugin-config.ts
227215
+ function asObject2(value) {
227216
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
227217
+ }
227218
+ function prepareBlockRunPluginConfig(config, options = {}) {
227219
+ if (!options.explicitSetup && !options.legacyBlockRunInstall && !options.stripUnsupportedInstalls) {
227220
+ return false;
227221
+ }
227222
+ let changed = false;
227223
+ let plugins = asObject2(config.plugins);
227224
+ if (!plugins) {
227225
+ plugins = {};
227226
+ config.plugins = plugins;
227227
+ changed = true;
227228
+ }
227229
+ let entries = asObject2(plugins.entries);
227230
+ if (!entries) {
227231
+ entries = {};
227232
+ plugins.entries = entries;
227233
+ changed = true;
227234
+ }
227235
+ const legacyEntry = asObject2(entries.clawrouter);
227236
+ const currentEntry = asObject2(entries[BLOCKRUN_PLUGIN_ID]);
227237
+ if (options.legacyBlockRunInstall && legacyEntry) {
227238
+ const migratedEntry = currentEntry ?? {};
227239
+ if (!currentEntry && typeof legacyEntry.enabled === "boolean") {
227240
+ migratedEntry.enabled = legacyEntry.enabled;
227241
+ }
227242
+ for (const key2 of ["walletKey", "routing"]) {
227243
+ if (!(key2 in migratedEntry) && key2 in legacyEntry) {
227244
+ migratedEntry[key2] = legacyEntry[key2];
227245
+ }
227246
+ if (key2 in legacyEntry) {
227247
+ delete legacyEntry[key2];
227248
+ changed = true;
227249
+ }
227250
+ }
227251
+ const legacyConfig = asObject2(legacyEntry.config);
227252
+ if (legacyConfig) {
227253
+ const currentConfig = asObject2(migratedEntry.config) ?? {};
227254
+ for (const key2 of ["walletKey", "routing"]) {
227255
+ if (!(key2 in currentConfig) && key2 in legacyConfig) {
227256
+ currentConfig[key2] = legacyConfig[key2];
227257
+ }
227258
+ if (key2 in legacyConfig) {
227259
+ delete legacyConfig[key2];
227260
+ changed = true;
227261
+ }
227262
+ }
227263
+ if (Object.keys(currentConfig).length > 0) migratedEntry.config = currentConfig;
227264
+ if (Object.keys(legacyConfig).length === 0) {
227265
+ delete legacyEntry.config;
227266
+ changed = true;
227267
+ }
227268
+ }
227269
+ if (!currentEntry || entries[BLOCKRUN_PLUGIN_ID] !== migratedEntry) {
227270
+ entries[BLOCKRUN_PLUGIN_ID] = migratedEntry;
227271
+ changed = true;
227272
+ }
227273
+ }
227274
+ if (options.explicitSetup) {
227275
+ const next = asObject2(entries[BLOCKRUN_PLUGIN_ID]) ?? {};
227276
+ if (next.enabled !== true) {
227277
+ entries[BLOCKRUN_PLUGIN_ID] = { ...next, enabled: true };
227278
+ changed = true;
227279
+ }
227280
+ }
227281
+ const allow = plugins.allow;
227282
+ if (Array.isArray(allow)) {
227283
+ const shouldAllow = options.explicitSetup || options.legacyBlockRunInstall && allow.includes("clawrouter");
227284
+ if (shouldAllow && !allow.includes(BLOCKRUN_PLUGIN_ID)) {
227285
+ allow.push(BLOCKRUN_PLUGIN_ID);
227286
+ changed = true;
227287
+ }
227288
+ }
227289
+ const deny = plugins.deny;
227290
+ if (Array.isArray(deny)) {
227291
+ if (options.explicitSetup) {
227292
+ const next = deny.filter((id2) => id2 !== BLOCKRUN_PLUGIN_ID);
227293
+ if (next.length !== deny.length) {
227294
+ plugins.deny = next;
227295
+ changed = true;
227296
+ }
227297
+ } else if (options.legacyBlockRunInstall && deny.includes("clawrouter") && !deny.includes(BLOCKRUN_PLUGIN_ID)) {
227298
+ deny.push(BLOCKRUN_PLUGIN_ID);
227299
+ changed = true;
227300
+ }
227301
+ }
227302
+ if (options.stripUnsupportedInstalls && "installs" in plugins) {
227303
+ delete plugins.installs;
227304
+ changed = true;
227305
+ }
227306
+ return changed;
227307
+ }
227308
+ var BLOCKRUN_PLUGIN_ID;
227309
+ var init_openclaw_plugin_config = __esm({
227310
+ "src/openclaw-plugin-config.ts"() {
227311
+ "use strict";
227312
+ BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
227313
+ }
227314
+ });
227315
+
226590
227316
  // src/retry.ts
226591
227317
  function sleep3(ms) {
226592
227318
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -226656,13 +227382,14 @@ import {
226656
227382
  readdirSync,
226657
227383
  mkdirSync as mkdirSync3,
226658
227384
  copyFileSync,
227385
+ chmodSync,
226659
227386
  renameSync as renameSync2,
226660
227387
  unlinkSync
226661
227388
  } from "fs";
226662
227389
  import { readFile as readFileAsync } from "fs/promises";
226663
227390
  import { homedir as homedir13 } from "os";
226664
- import { join as join16, dirname as dirname4 } from "path";
226665
- import { fileURLToPath as fileURLToPath2 } from "url";
227391
+ import { randomUUID } from "crypto";
227392
+ import { join as join16 } from "path";
226666
227393
  async function waitForProxyHealth(port, timeoutMs = 3e3) {
226667
227394
  const start = Date.now();
226668
227395
  while (Date.now() - start < timeoutMs) {
@@ -226675,53 +227402,21 @@ async function waitForProxyHealth(port, timeoutMs = 3e3) {
226675
227402
  }
226676
227403
  return false;
226677
227404
  }
226678
- function getPackageRoot() {
226679
- return join16(dirname4(fileURLToPath2(import.meta.url)), "..");
226680
- }
226681
- function installSkillsToWorkspace(logger48) {
227405
+ function writePrivateJsonSync(path5, value) {
227406
+ const temporary = `${path5}.tmp.${randomUUID()}`;
226682
227407
  try {
226683
- const packageRoot = getPackageRoot();
226684
- const bundledSkillsDir = join16(packageRoot, "skills");
226685
- if (!existsSync3(bundledSkillsDir)) {
226686
- return;
226687
- }
226688
- const profile = (process["env"].OPENCLAW_PROFILE ?? "").trim().toLowerCase();
226689
- const workspaceDirName = profile && profile !== "default" ? `workspace-${profile}` : "workspace";
226690
- const workspaceSkillsDir = join16(homedir13(), ".openclaw", workspaceDirName, "skills");
226691
- mkdirSync3(workspaceSkillsDir, { recursive: true });
226692
- const INTERNAL_SKILLS = /* @__PURE__ */ new Set(["release"]);
226693
- const entries = readdirSync(bundledSkillsDir, { withFileTypes: true });
226694
- let installed = 0;
226695
- for (const entry of entries) {
226696
- if (!entry.isDirectory()) continue;
226697
- const skillName = entry.name;
226698
- if (INTERNAL_SKILLS.has(skillName)) continue;
226699
- const srcSkillFile = join16(bundledSkillsDir, skillName, "SKILL.md");
226700
- if (!existsSync3(srcSkillFile)) continue;
226701
- const destDir = join16(workspaceSkillsDir, skillName);
226702
- const destSkillFile = join16(destDir, "SKILL.md");
226703
- let needsUpdate = true;
226704
- if (existsSync3(destSkillFile)) {
226705
- try {
226706
- const srcContent = readTextFileSync(srcSkillFile);
226707
- const destContent = readTextFileSync(destSkillFile);
226708
- if (srcContent === destContent) needsUpdate = false;
226709
- } catch {
226710
- }
226711
- }
226712
- if (needsUpdate) {
226713
- mkdirSync3(destDir, { recursive: true });
226714
- copyFileSync(srcSkillFile, destSkillFile);
226715
- installed++;
226716
- }
226717
- }
226718
- if (installed > 0) {
226719
- logger48.info(`Installed ${installed} skill(s) to ${workspaceSkillsDir}`);
226720
- }
226721
- } catch (err) {
226722
- logger48.warn(`Failed to install skills: ${err instanceof Error ? err.message : String(err)}`);
227408
+ writeFileSync3(temporary, JSON.stringify(value, null, 2), { mode: 384 });
227409
+ renameSync2(temporary, path5);
227410
+ chmodSync(path5, 384);
227411
+ } finally {
227412
+ if (existsSync3(temporary)) unlinkSync(temporary);
226723
227413
  }
226724
227414
  }
227415
+ function hasConfiguredWallet() {
227416
+ return Boolean(
227417
+ process["env"].BLOCKRUN_WALLET_KEY || existsSync3(CORE_WALLET_FILE) || existsSync3(WALLET_FILE)
227418
+ );
227419
+ }
226725
227420
  function isCompletionMode() {
226726
227421
  const args = process.argv;
226727
227422
  return args.some((arg, i) => arg === "completion" && i >= 1 && i <= 3);
@@ -226895,35 +227590,19 @@ function injectModelsConfig(logger48, options = {}) {
226895
227590
  logger48.info(`Added ${addedCount} models to allowlist (${TOP_MODELS.length} total)`);
226896
227591
  }
226897
227592
  }
226898
- const pluginEntries = config.plugins?.entries;
226899
- if (pluginEntries && pluginEntries.clawrouter && !pluginEntries[BLOCKRUN_PLUGIN_ID]) {
226900
- pluginEntries[BLOCKRUN_PLUGIN_ID] = pluginEntries.clawrouter;
226901
- delete pluginEntries.clawrouter;
227593
+ const legacyEntry = config.plugins?.entries?.clawrouter;
227594
+ const legacyEntryConfig = legacyEntry?.config;
227595
+ const legacyBlockRunInstall = Boolean(
227596
+ legacyEntry && ["walletKey", "routing"].some(
227597
+ (key2) => key2 in legacyEntry || (legacyEntryConfig ? key2 in legacyEntryConfig : false)
227598
+ )
227599
+ );
227600
+ if (legacyBlockRunInstall && prepareBlockRunPluginConfig(config, { legacyBlockRunInstall })) {
226902
227601
  needsWrite = true;
226903
227602
  logger48.info(
226904
- "Migrated plugins.entries.clawrouter -> blockrun-clawrouter (OpenClaw bundles its own `clawrouter` plugin; see #305)"
227603
+ `Migrated legacy BlockRun plugin config to ${BLOCKRUN_PLUGIN_ID} (renamed from clawrouter; see #305)`
226905
227604
  );
226906
227605
  }
226907
- const pluginsCfg = config.plugins;
226908
- const allow = pluginsCfg?.allow;
226909
- if (Array.isArray(allow) && allow.includes("clawrouter") && !allow.includes(BLOCKRUN_PLUGIN_ID)) {
226910
- allow.push(BLOCKRUN_PLUGIN_ID);
226911
- needsWrite = true;
226912
- logger48.info(`Added ${BLOCKRUN_PLUGIN_ID} to plugins.allow (renamed from clawrouter; see #305)`);
226913
- }
226914
- const deny = pluginsCfg?.deny;
226915
- if (Array.isArray(deny) && deny.includes("clawrouter") && !deny.includes(BLOCKRUN_PLUGIN_ID)) {
226916
- deny.push(BLOCKRUN_PLUGIN_ID);
226917
- needsWrite = true;
226918
- logger48.info(`Added ${BLOCKRUN_PLUGIN_ID} to plugins.deny (renamed from clawrouter; see #305)`);
226919
- }
226920
- const installs = pluginsCfg?.installs;
226921
- if (installs && installs.clawrouter && !installs[BLOCKRUN_PLUGIN_ID]) {
226922
- installs[BLOCKRUN_PLUGIN_ID] = installs.clawrouter;
226923
- delete installs.clawrouter;
226924
- needsWrite = true;
226925
- logger48.info(`Migrated plugins.installs.clawrouter -> ${BLOCKRUN_PLUGIN_ID} (see #305)`);
226926
- }
226927
227606
  if (!config.tools || typeof config.tools !== "object" || Array.isArray(config.tools)) {
226928
227607
  config.tools = {};
226929
227608
  needsWrite = true;
@@ -226963,8 +227642,9 @@ function injectModelsConfig(logger48, options = {}) {
226963
227642
  }
226964
227643
  try {
226965
227644
  const tmpPath = `${configPath}.tmp.${process.pid}`;
226966
- writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
227645
+ writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
226967
227646
  renameSync2(tmpPath, configPath);
227647
+ chmodSync(configPath, 384);
226968
227648
  logger48.info("Smart routing enabled (blockrun/auto)");
226969
227649
  } catch (err) {
226970
227650
  logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
@@ -226999,7 +227679,7 @@ function syncAgentModelCache(logger48, options = {}) {
226999
227679
  const staleCount = Array.isArray(current) ? current.length : 0;
227000
227680
  entry.models = VISIBLE_OPENCLAW_MODELS;
227001
227681
  const tmpPath = `${cachePath}.tmp.${process.pid}`;
227002
- writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
227682
+ writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2), { mode: 384 });
227003
227683
  renameSync2(tmpPath, cachePath);
227004
227684
  logger48.info(
227005
227685
  `Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
@@ -227070,7 +227750,7 @@ function injectAuthProfile(logger48) {
227070
227750
  key: "x402-proxy-handles-auth"
227071
227751
  };
227072
227752
  try {
227073
- writeFileSync3(authPath, JSON.stringify(store, null, 2));
227753
+ writePrivateJsonSync(authPath, store);
227074
227754
  logger48.info(`Injected BlockRun auth profile for agent: ${agentId}`);
227075
227755
  } catch (err) {
227076
227756
  logger48.info(
@@ -227186,7 +227866,7 @@ async function startProxyInBackground(api, startupGeneration) {
227186
227866
  } else {
227187
227867
  if (configKey !== void 0) {
227188
227868
  api.logger.warn(
227189
- `pluginConfig.walletKey is set but invalid (expected 0x + 64 hex chars) \u2014 falling back to saved wallet`
227869
+ `pluginConfig.walletKey is set but invalid (expected 0x + 64 hex chars) \u2014 falling back to the BlockRun wallet`
227190
227870
  );
227191
227871
  }
227192
227872
  wallet = await resolveOrGenerateWalletKey();
@@ -227198,6 +227878,8 @@ async function startProxyInBackground(api, startupGeneration) {
227198
227878
  api.logger.warn(` Run /wallet export to get your private key`);
227199
227879
  api.logger.warn(` Losing this key = losing your USDC funds`);
227200
227880
  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`);
227881
+ } else if (wallet.source === "core") {
227882
+ api.logger.info(`Using BlockRun Core wallet: ${wallet.address}`);
227201
227883
  } else if (wallet.source === "saved") {
227202
227884
  api.logger.info(`Using saved wallet: ${wallet.address}`);
227203
227885
  } else if (wallet.source === "config") {
@@ -227218,6 +227900,7 @@ async function startProxyInBackground(api, startupGeneration) {
227218
227900
  routingConfig,
227219
227901
  maxCostPerRunUsd,
227220
227902
  maxCostPerRunMode,
227903
+ spendControl: liveSpendControl = new SpendControl(),
227221
227904
  onReady: (port) => {
227222
227905
  api.logger.info(`BlockRun x402 proxy listening on port ${port}`);
227223
227906
  },
@@ -227484,7 +228167,7 @@ function buildImageGenerationProvider() {
227484
228167
  ]
227485
228168
  }
227486
228169
  },
227487
- isConfigured: () => existsSync3(WALLET_FILE),
228170
+ isConfigured: hasConfiguredWallet,
227488
228171
  generateImage: async (req) => {
227489
228172
  const port = getProxyPort();
227490
228173
  const body = JSON.stringify({
@@ -227534,7 +228217,7 @@ function buildMusicGenerationProvider() {
227534
228217
  supportsFormat: true,
227535
228218
  supportedFormats: ["mp3"]
227536
228219
  },
227537
- isConfigured: () => existsSync3(WALLET_FILE),
228220
+ isConfigured: hasConfiguredWallet,
227538
228221
  generateMusic: async (req) => {
227539
228222
  const port = getProxyPort();
227540
228223
  const body = JSON.stringify({
@@ -227610,7 +228293,7 @@ function buildVideoGenerationProvider() {
227610
228293
  supportedDurationSeconds: [5, 8, 10]
227611
228294
  }
227612
228295
  },
227613
- isConfigured: () => existsSync3(WALLET_FILE),
228296
+ isConfigured: hasConfiguredWallet,
227614
228297
  generateVideo: async (req) => {
227615
228298
  const port = getProxyPort();
227616
228299
  const imageUrl = req.inputImages?.[0]?.url;
@@ -227689,26 +228372,25 @@ function createWalletCommand(api) {
227689
228372
  requireAuth: true,
227690
228373
  handler: async (ctx) => {
227691
228374
  const subcommand = ctx.args?.trim().toLowerCase() || "status";
227692
- let walletKey;
227693
- let address2;
228375
+ let wallet;
227694
228376
  try {
227695
- if (existsSync3(WALLET_FILE)) {
227696
- walletKey = readTextFileSync(WALLET_FILE).trim();
227697
- if (walletKey.startsWith("0x") && walletKey.length === 66) {
227698
- const account = privateKeyToAccount(walletKey);
227699
- address2 = account.address;
227700
- }
227701
- }
227702
- } catch {
228377
+ wallet = subcommand === "status" || subcommand === "export" ? await resolveExistingWalletKey() : await resolveOrGenerateWalletKey();
228378
+ } catch (error) {
228379
+ return {
228380
+ text: `Could not load the BlockRun wallet: ${error instanceof Error ? error.message : String(error)}`,
228381
+ isError: true
228382
+ };
227703
228383
  }
227704
- if (!walletKey || !address2) {
228384
+ if (!wallet) {
227705
228385
  return {
227706
- text: `No ClawRouter wallet found.
227707
-
227708
- Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228386
+ text: "No BlockRun wallet found. Run `clawrouter setup` or connect an agent in ClawRouter Desktop to create one.",
227709
228387
  isError: true
227710
228388
  };
227711
228389
  }
228390
+ const walletKey = wallet.key;
228391
+ const address2 = wallet.address;
228392
+ const resolvedSolanaKey = wallet.solanaPrivateKeyBytes;
228393
+ const walletPath = wallet.source === "core" ? CORE_WALLET_FILE : WALLET_FILE;
227712
228394
  if (subcommand === "export") {
227713
228395
  const lines = [
227714
228396
  "**ClawRouter Wallet Export**",
@@ -227745,13 +228427,26 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
227745
228427
  }
227746
228428
  } catch {
227747
228429
  }
228430
+ if (!hasMnemonic3 && resolvedSolanaKey) {
228431
+ try {
228432
+ const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes2 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
228433
+ const signer = await createKeyPairSignerFromPrivateKeyBytes2(resolvedSolanaKey);
228434
+ lines.push(
228435
+ "",
228436
+ "**Solana:**",
228437
+ ` Address: \`${signer.address}\``,
228438
+ wallet.source === "core" ? ` Private key managed by BlockRun Core: \`${CORE_SOLANA_WALLET_FILE}\`` : " Private key is managed by the configured wallet source."
228439
+ );
228440
+ } catch {
228441
+ }
228442
+ }
227748
228443
  lines.push(
227749
228444
  "",
227750
228445
  "**To restore on a new machine:**",
227751
228446
  "1. Set the environment variable before running OpenClaw:",
227752
228447
  ` \`export BLOCKRUN_WALLET_KEY=${walletKey}\``,
227753
228448
  "2. Or save to file:",
227754
- ` \`mkdir -p ~/.openclaw/blockrun && echo "${walletKey}" > ~/.openclaw/blockrun/wallet.key && chmod 600 ~/.openclaw/blockrun/wallet.key\``
228449
+ ` \`mkdir -p ~/.blockrun && echo "${walletKey}" > ~/.blockrun/.session && chmod 600 ~/.blockrun/.session\``
227755
228450
  );
227756
228451
  if (hasMnemonic3) {
227757
228452
  lines.push(
@@ -227764,6 +228459,22 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
227764
228459
  if (subcommand === "solana") {
227765
228460
  try {
227766
228461
  let solanaAddr;
228462
+ if (resolvedSolanaKey) {
228463
+ await savePaymentChain("solana");
228464
+ const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes3 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
228465
+ const signer2 = await createKeyPairSignerFromPrivateKeyBytes3(resolvedSolanaKey);
228466
+ solanaAddr = signer2.address;
228467
+ if (api) restartProxyForChainSwitch(api);
228468
+ return {
228469
+ text: [
228470
+ "\u2713 Payment chain switched to **Solana**.",
228471
+ api ? "Proxy restarting in background (~2s)." : "Restart the gateway to apply.",
228472
+ "",
228473
+ `**Solana Address:** \`${solanaAddr}\``,
228474
+ `**Fund with USDC on Solana:** https://solscan.io/account/${solanaAddr}`
228475
+ ].join("\n")
228476
+ };
228477
+ }
227767
228478
  if (existsSync3(MNEMONIC_FILE)) {
227768
228479
  const existingMnemonic = readTextFileSync(MNEMONIC_FILE).trim();
227769
228480
  if (existingMnemonic) {
@@ -227835,13 +228546,9 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
227835
228546
  })();
227836
228547
  const solanaPromise = (async () => {
227837
228548
  try {
227838
- if (!existsSync3(MNEMONIC_FILE)) return "";
227839
- const { deriveSolanaKeyBytes: deriveSolanaKeyBytes2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
227840
- const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
227841
- if (!mnemonic) return "";
227842
- const solKeyBytes = deriveSolanaKeyBytes2(mnemonic);
228549
+ if (!resolvedSolanaKey) return "";
227843
228550
  const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes2 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
227844
- const signer = await createKeyPairSignerFromPrivateKeyBytes2(solKeyBytes);
228551
+ const signer = await createKeyPairSignerFromPrivateKeyBytes2(resolvedSolanaKey);
227845
228552
  const solAddr = signer.address;
227846
228553
  let solBalanceText = "Balance: (could not check)";
227847
228554
  try {
@@ -227902,7 +228609,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
227902
228609
  solanaSection,
227903
228610
  usageSection,
227904
228611
  "",
227905
- `**Key File:** \`${WALLET_FILE}\``,
228612
+ `**Key File:** \`${walletPath}\``,
227906
228613
  "",
227907
228614
  "**Commands:**",
227908
228615
  "\u2022 `/wallet` - Show this status",
@@ -227916,7 +228623,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
227916
228623
  }
227917
228624
  };
227918
228625
  }
227919
- var activeProxyHandle, pendingConfiguredStartupApi, IMAGE_DIR2, AUDIO_DIR2, VIDEO_DIR2, BLOCKRUN_PLUGIN_ID, plugin, index_default2;
228626
+ var activeProxyHandle, liveSpendControl, pendingConfiguredStartupApi, IMAGE_DIR2, AUDIO_DIR2, VIDEO_DIR2, plugin, index_default2;
227920
228627
  var init_index = __esm({
227921
228628
  "src/index.ts"() {
227922
228629
  init_provider();
@@ -227935,7 +228642,11 @@ var init_index = __esm({
227935
228642
  init_tool();
227936
228643
  init_stats2();
227937
228644
  init_exclude();
228645
+ init_policy();
228646
+ init_spend_control();
227938
228647
  init_mcp_config();
228648
+ init_openclaw_plugin_config();
228649
+ init_openclaw_plugin_config();
227939
228650
  init_proxy();
227940
228651
  init_provider();
227941
228652
  init_models();
@@ -227954,11 +228665,11 @@ var init_index = __esm({
227954
228665
  init_response_cache();
227955
228666
  init_partners();
227956
228667
  activeProxyHandle = null;
228668
+ liveSpendControl = null;
227957
228669
  pendingConfiguredStartupApi = null;
227958
228670
  IMAGE_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "images");
227959
228671
  AUDIO_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "audio");
227960
228672
  VIDEO_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "videos");
227961
- BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
227962
228673
  plugin = {
227963
228674
  // NOT "clawrouter". OpenClaw bundles its own plugin under that id since the
227964
228675
  // 2026.7.1 line (vendored at dist/extensions/clawrouter, provider `clawrouter/*`,
@@ -227976,7 +228687,6 @@ var init_index = __esm({
227976
228687
  api.logger.info("ClawRouter disabled (CLAWROUTER_DISABLED=true). Using default routing.");
227977
228688
  return;
227978
228689
  }
227979
- installSkillsToWorkspace(api.logger);
227980
228690
  const proc = process;
227981
228691
  const proxyAlreadyStarted = !!proc.__clawrouterProxyStarted;
227982
228692
  if (isCompletionMode()) {
@@ -228269,9 +228979,14 @@ ${errText}`
228269
228979
  }
228270
228980
  api.registerCommand(createStatsCommand());
228271
228981
  api.registerCommand(createExcludeCommand());
228982
+ api.registerCommand(
228983
+ createPolicyCommand({
228984
+ liveControl: () => activeProxyHandle ? liveSpendControl ?? void 0 : void 0
228985
+ })
228986
+ );
228272
228987
  if (shouldLogRegistration) {
228273
228988
  api.logger.info(
228274
- "Commands registered: /wallet, /blockrun, /stats, /exclude, /partners, /cr-imagegen, /videogen, /cr-call"
228989
+ "Commands registered: /wallet, /blockrun, /stats, /exclude, /policy, /partners, /cr-imagegen, /videogen, /cr-call"
228275
228990
  );
228276
228991
  }
228277
228992
  api.registerService({
@@ -228303,6 +229018,8 @@ ${errText}`
228303
229018
  api.logger.warn(` Run /wallet export to get your private key`);
228304
229019
  api.logger.warn(` Losing this key = losing your USDC funds`);
228305
229020
  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`);
229021
+ } else if (source === "core") {
229022
+ api.logger.info(`Using BlockRun Core wallet: ${address2}`);
228306
229023
  } else if (source === "saved") {
228307
229024
  api.logger.info(`Using saved wallet: ${address2}`);
228308
229025
  } else if (source === "config") {
@@ -228376,18 +229093,18 @@ ${errText}`
228376
229093
  delete config.models.providers.blockrun;
228377
229094
  }
228378
229095
  removeManagedBlockrunMcpServerConfig(config);
228379
- for (const key2 of [
228380
- BLOCKRUN_PLUGIN_ID,
228381
- "clawrouter",
228382
- "ClawRouter",
228383
- "@blockrun/clawrouter"
228384
- ]) {
229096
+ for (const key2 of [BLOCKRUN_PLUGIN_ID, "ClawRouter", "@blockrun/clawrouter"]) {
228385
229097
  if (config.plugins?.entries?.[key2]) delete config.plugins.entries[key2];
228386
229098
  if (config.plugins?.installs?.[key2]) delete config.plugins.installs[key2];
228387
229099
  }
228388
229100
  if (Array.isArray(config.plugins?.allow)) {
228389
229101
  config.plugins.allow = config.plugins.allow.filter(
228390
- (p) => p !== BLOCKRUN_PLUGIN_ID && p !== "clawrouter" && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
229102
+ (p) => p !== BLOCKRUN_PLUGIN_ID && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
229103
+ );
229104
+ }
229105
+ if (Array.isArray(config.plugins?.deny)) {
229106
+ config.plugins.deny = config.plugins.deny.filter(
229107
+ (p) => p !== BLOCKRUN_PLUGIN_ID && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
228391
229108
  );
228392
229109
  }
228393
229110
  if (config.agents?.defaults?.models) {
@@ -228402,8 +229119,9 @@ ${errText}`
228402
229119
  delete config.tools.web.search.provider;
228403
229120
  }
228404
229121
  const tmpPath = `${configPath}.tmp.${process.pid}`;
228405
- writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
229122
+ writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
228406
229123
  renameSync2(tmpPath, configPath);
229124
+ chmodSync(configPath, 384);
228407
229125
  api.logger.info("ClawRouter config cleaned up");
228408
229126
  }
228409
229127
  } catch (err) {
@@ -228420,7 +229138,7 @@ ${errText}`
228420
229138
  const store = JSON.parse(readTextFileSync(authPath));
228421
229139
  if (store.profiles?.["blockrun:default"]) {
228422
229140
  delete store.profiles["blockrun:default"];
228423
- writeFileSync3(authPath, JSON.stringify(store, null, 2));
229141
+ writePrivateJsonSync(authPath, store);
228424
229142
  }
228425
229143
  } catch {
228426
229144
  }
@@ -228453,6 +229171,7 @@ export {
228453
229171
  MalformedSpendPolicyError,
228454
229172
  OPENCLAW_MODELS,
228455
229173
  PARTNER_SERVICES,
229174
+ PAYABLE_NETWORKS,
228456
229175
  RequestDeduplicator,
228457
229176
  ResponseCache,
228458
229177
  RpcError2 as RpcError,