@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/cli.js CHANGED
@@ -5786,15 +5786,15 @@ function wNAF(c, bits) {
5786
5786
  const { windows, windowSize } = calcWOpts(W, bits);
5787
5787
  const points = [];
5788
5788
  let p = elm;
5789
- let base3 = p;
5789
+ let base4 = p;
5790
5790
  for (let window2 = 0; window2 < windows; window2++) {
5791
- base3 = p;
5792
- points.push(base3);
5791
+ base4 = p;
5792
+ points.push(base4);
5793
5793
  for (let i = 1; i < windowSize; i++) {
5794
- base3 = base3.add(p);
5795
- points.push(base3);
5794
+ base4 = base4.add(p);
5795
+ points.push(base4);
5796
5796
  }
5797
- p = base3.double();
5797
+ p = base4.double();
5798
5798
  }
5799
5799
  return points;
5800
5800
  },
@@ -8432,7 +8432,7 @@ async function internal_estimateFeesPerGas(client, args) {
8432
8432
  throw new BaseFeeScalarError();
8433
8433
  const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
8434
8434
  const denominator = 10 ** decimals;
8435
- const multiply = (base3) => base3 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
8435
+ const multiply = (base4) => base4 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
8436
8436
  const block = block_ ? block_ : await getAction(client, getBlock, "getBlock")({});
8437
8437
  if (typeof chain3?.fees?.estimateFeesPerGas === "function") {
8438
8438
  const fees = await chain3.fees.estimateFeesPerGas({
@@ -8903,7 +8903,7 @@ async function fillTransaction(client, parameters) {
8903
8903
  throw new BaseFeeScalarError();
8904
8904
  const decimals = feeMultiplier.toString().split(".")[1]?.length ?? 0;
8905
8905
  const denominator = 10 ** decimals;
8906
- const multiplyFee = (base3) => base3 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
8906
+ const multiplyFee = (base4) => base4 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
8907
8907
  if (!transaction.feePayerSignature) {
8908
8908
  if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
8909
8909
  transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas);
@@ -11861,17 +11861,17 @@ async function call(client, args) {
11861
11861
  }
11862
11862
  }
11863
11863
  const params = (() => {
11864
- const base3 = [
11864
+ const base4 = [
11865
11865
  request2,
11866
11866
  block
11867
11867
  ];
11868
11868
  if (rpcStateOverride && rpcBlockOverrides)
11869
- return [...base3, rpcStateOverride, rpcBlockOverrides];
11869
+ return [...base4, rpcStateOverride, rpcBlockOverrides];
11870
11870
  if (rpcStateOverride)
11871
- return [...base3, rpcStateOverride];
11871
+ return [...base4, rpcStateOverride];
11872
11872
  if (rpcBlockOverrides)
11873
- return [...base3, {}, rpcBlockOverrides];
11874
- return base3;
11873
+ return [...base4, {}, rpcBlockOverrides];
11874
+ return base4;
11875
11875
  })();
11876
11876
  const response = await client.request({
11877
11877
  method: "eth_call",
@@ -13277,14 +13277,14 @@ function createClient(parameters) {
13277
13277
  uid: uid(),
13278
13278
  ...experimental_blockTag ? { experimental_blockTag } : {}
13279
13279
  };
13280
- function extend2(base3) {
13280
+ function extend2(base4) {
13281
13281
  return (extendFn) => {
13282
- const extended = extendFn(base3);
13282
+ const extended = extendFn(base4);
13283
13283
  for (const key3 in client)
13284
13284
  delete extended[key3];
13285
- const combined = { ...base3, ...extended };
13285
+ const combined = { ...base4, ...extended };
13286
13286
  for (const key3 in extended) {
13287
- const a = base3[key3];
13287
+ const a = base4[key3];
13288
13288
  const b = extended[key3];
13289
13289
  if (isPlainObject(a) && isPlainObject(b))
13290
13290
  combined[key3] = { ...a, ...b };
@@ -15037,10 +15037,10 @@ function defineChain(chain3) {
15037
15037
  serializers: void 0,
15038
15038
  ...chain3
15039
15039
  };
15040
- function extend2(base3) {
15040
+ function extend2(base4) {
15041
15041
  return (fnOrExtended) => {
15042
- const properties = typeof fnOrExtended === "function" ? fnOrExtended(base3) : fnOrExtended;
15043
- const combined = { ...base3, ...properties };
15042
+ const properties = typeof fnOrExtended === "function" ? fnOrExtended(base4) : fnOrExtended;
15043
+ const combined = { ...base4, ...properties };
15044
15044
  return Object.assign(combined, { extend: extend2(combined) });
15045
15045
  };
15046
15046
  }
@@ -15404,9 +15404,9 @@ function validateTypedData(parameters) {
15404
15404
  throw new InvalidTypedDataTypeError({ type });
15405
15405
  const integerMatch = type.match(integerRegex2);
15406
15406
  if (integerMatch && (typeof value === "number" || typeof value === "bigint")) {
15407
- const [_type, base3, size_] = integerMatch;
15407
+ const [_type, base4, size_] = integerMatch;
15408
15408
  numberToHex(value, {
15409
- signed: base3 === "int",
15409
+ signed: base4 === "int",
15410
15410
  size: Number.parseInt(size_, 10) / 8
15411
15411
  });
15412
15412
  }
@@ -18035,15 +18035,15 @@ function wNAF2(c, bits) {
18035
18035
  const { windows, windowSize } = calcWOpts2(W, bits);
18036
18036
  const points = [];
18037
18037
  let p = elm;
18038
- let base3 = p;
18038
+ let base4 = p;
18039
18039
  for (let window2 = 0; window2 < windows; window2++) {
18040
- base3 = p;
18041
- points.push(base3);
18040
+ base4 = p;
18041
+ points.push(base4);
18042
18042
  for (let i = 1; i < windowSize; i++) {
18043
- base3 = base3.add(p);
18044
- points.push(base3);
18043
+ base4 = base4.add(p);
18044
+ points.push(base4);
18045
18045
  }
18046
- p = base3.double();
18046
+ p = base4.double();
18047
18047
  }
18048
18048
  return points;
18049
18049
  },
@@ -30627,23 +30627,23 @@ var init_types = __esm({
30627
30627
  }
30628
30628
  if (effect.type === "transform") {
30629
30629
  if (ctx.common.async === false) {
30630
- const base3 = this._def.schema._parseSync({
30630
+ const base4 = this._def.schema._parseSync({
30631
30631
  data: ctx.data,
30632
30632
  path: ctx.path,
30633
30633
  parent: ctx
30634
30634
  });
30635
- if (!isValid(base3))
30635
+ if (!isValid(base4))
30636
30636
  return INVALID;
30637
- const result = effect.transform(base3.value, checkCtx);
30637
+ const result = effect.transform(base4.value, checkCtx);
30638
30638
  if (result instanceof Promise) {
30639
30639
  throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
30640
30640
  }
30641
30641
  return { status: status.value, value: result };
30642
30642
  } else {
30643
- return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base3) => {
30644
- if (!isValid(base3))
30643
+ return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base4) => {
30644
+ if (!isValid(base4))
30645
30645
  return INVALID;
30646
- return Promise.resolve(effect.transform(base3.value, checkCtx)).then((result) => ({
30646
+ return Promise.resolve(effect.transform(base4.value, checkCtx)).then((result) => ({
30647
30647
  status: status.value,
30648
30648
  value: result
30649
30649
  }));
@@ -32305,6 +32305,11 @@ function cloneLimits(limits) {
32305
32305
  }
32306
32306
  return clone;
32307
32307
  }
32308
+ function canonicalLimits(limits) {
32309
+ return JSON.stringify(
32310
+ Object.fromEntries(Object.entries(limits).sort(([a], [b]) => a < b ? -1 : 1))
32311
+ );
32312
+ }
32308
32313
  function parseQuotedAmountUsd(selected) {
32309
32314
  const raw = selected.amount ?? selected.maxAmountRequired;
32310
32315
  if (typeof raw !== "string" || !CANONICAL_AMOUNT.test(raw)) {
@@ -32380,7 +32385,7 @@ function formatDuration(seconds) {
32380
32385
  return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
32381
32386
  }
32382
32387
  }
32383
- var WALLET_DIR, HOUR_MS, DAY_MS, CAIP2_BASE, CAIP2_SOLANA_MAINNET, POLICY_LISTS, ADDRESS_LISTS, EVM_ADDRESS, MalformedSpendPolicyError, FileSpendControlStorage, InMemorySpendControlStorage, RESERVATION_TTL_MS, SpendControl, SpendPolicyError, CANONICAL_AMOUNT;
32388
+ var WALLET_DIR, HOUR_MS, DAY_MS, CAIP2_BASE, CAIP2_SOLANA_MAINNET, PAYABLE_NETWORKS, POLICY_LISTS, ADDRESS_LISTS, EVM_ADDRESS, MalformedSpendPolicyError, SpendPolicyConflictError, FileSpendControlStorage, InMemorySpendControlStorage, RESERVATION_TTL_MS, SpendControl, SpendPolicyError, CANONICAL_AMOUNT;
32384
32389
  var init_spend_control = __esm({
32385
32390
  "src/spend-control.ts"() {
32386
32391
  "use strict";
@@ -32390,6 +32395,7 @@ var init_spend_control = __esm({
32390
32395
  DAY_MS = 24 * HOUR_MS;
32391
32396
  CAIP2_BASE = "eip155:8453";
32392
32397
  CAIP2_SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
32398
+ PAYABLE_NETWORKS = [CAIP2_BASE, CAIP2_SOLANA_MAINNET];
32393
32399
  POLICY_LISTS = [
32394
32400
  "allowedPayees",
32395
32401
  "blockedPayees",
@@ -32406,6 +32412,12 @@ var init_spend_control = __esm({
32406
32412
  this.name = "MalformedSpendPolicyError";
32407
32413
  }
32408
32414
  };
32415
+ SpendPolicyConflictError = class extends Error {
32416
+ constructor() {
32417
+ super("spending.json limits changed underneath this write; nothing was written");
32418
+ this.name = "SpendPolicyConflictError";
32419
+ }
32420
+ };
32409
32421
  FileSpendControlStorage = class {
32410
32422
  spendingFile;
32411
32423
  constructor() {
@@ -32486,6 +32498,25 @@ var init_spend_control = __esm({
32486
32498
  }
32487
32499
  this.save({ limits: storedLimits, history });
32488
32500
  }
32501
+ /**
32502
+ * Persist limits while leaving the stored history exactly as it is on disk.
32503
+ * With `expect`, refuse when the stored limits are no longer the ones the
32504
+ * writer read — a stale instance must not replace another writer's edit.
32505
+ * The re-read happens immediately before the atomic rename, so the race
32506
+ * window is the write itself, not the whole command.
32507
+ */
32508
+ saveLimits(limits, expect) {
32509
+ let current;
32510
+ try {
32511
+ current = this.load();
32512
+ } catch {
32513
+ return;
32514
+ }
32515
+ if (expect !== void 0 && canonicalLimits(current?.limits ?? {}) !== canonicalLimits(expect)) {
32516
+ throw new SpendPolicyConflictError();
32517
+ }
32518
+ this.save({ limits, history: current?.history ?? [] });
32519
+ }
32489
32520
  };
32490
32521
  InMemorySpendControlStorage = class {
32491
32522
  data = null;
@@ -32501,6 +32532,15 @@ var init_spend_control = __esm({
32501
32532
  history: data.history.map((r2) => ({ ...r2 }))
32502
32533
  };
32503
32534
  }
32535
+ saveLimits(limits, expect) {
32536
+ if (expect !== void 0 && canonicalLimits(this.data?.limits ?? {}) !== canonicalLimits(expect)) {
32537
+ throw new SpendPolicyConflictError();
32538
+ }
32539
+ this.data = {
32540
+ limits: cloneLimits(limits),
32541
+ history: this.data?.history.map((r2) => ({ ...r2 })) ?? []
32542
+ };
32543
+ }
32504
32544
  };
32505
32545
  RESERVATION_TTL_MS = 2 * 60 * 1e3;
32506
32546
  SpendControl = class {
@@ -32512,6 +32552,8 @@ var init_spend_control = __esm({
32512
32552
  reservationSeq = 0;
32513
32553
  /** Limits we loaded and have not changed; history-only saves must not clobber operator edits. */
32514
32554
  limitsDirty = false;
32555
+ /** The limits this instance last read from or wrote to storage — the compare-and-swap baseline. */
32556
+ diskLimits = {};
32515
32557
  /** Set when spending.json held an unusable policy list: refuse every payment. */
32516
32558
  policyFileBroken;
32517
32559
  storage;
@@ -32556,6 +32598,15 @@ var init_spend_control = __esm({
32556
32598
  getLimits() {
32557
32599
  return cloneLimits(this.limits);
32558
32600
  }
32601
+ /**
32602
+ * Why spending.json could not be loaded, or undefined when it is usable.
32603
+ * While set, every setter mutates memory only: save() refuses to rewrite a
32604
+ * file it could not fully parse, so callers must check this before
32605
+ * reporting a change as applied.
32606
+ */
32607
+ getPolicyFileError() {
32608
+ return this.policyFileBroken;
32609
+ }
32559
32610
  check(estimatedCost2, counterparty) {
32560
32611
  if (this.policyFileBroken !== void 0) {
32561
32612
  return {
@@ -32816,6 +32867,22 @@ var init_spend_control = __esm({
32816
32867
  this.storage.saveHistory([...this.history]);
32817
32868
  return;
32818
32869
  }
32870
+ if (this.limitsDirty && this.storage.saveLimits) {
32871
+ try {
32872
+ this.storage.saveLimits(cloneLimits(this.limits), cloneLimits(this.diskLimits));
32873
+ } catch (err) {
32874
+ if (err instanceof SpendPolicyConflictError) {
32875
+ const current = this.storage.load();
32876
+ this.limits = cloneLimits(current?.limits ?? {});
32877
+ this.diskLimits = cloneLimits(this.limits);
32878
+ this.limitsDirty = false;
32879
+ }
32880
+ throw err;
32881
+ }
32882
+ this.diskLimits = cloneLimits(this.limits);
32883
+ this.limitsDirty = false;
32884
+ return;
32885
+ }
32819
32886
  this.storage.save({
32820
32887
  limits: cloneLimits(this.limits),
32821
32888
  history: [...this.history]
@@ -32836,6 +32903,7 @@ var init_spend_control = __esm({
32836
32903
  }
32837
32904
  if (data) {
32838
32905
  this.limits = cloneLimits(data.limits);
32906
+ this.diskLimits = cloneLimits(data.limits);
32839
32907
  this.history = data.history;
32840
32908
  this.cleanup();
32841
32909
  }
@@ -32887,6 +32955,7 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
32887
32955
  const cached = !options?.skipPreAuth ? cache2.get(cacheKey2) : void 0;
32888
32956
  const preAuthCovers = cached !== void 0 && Date.now() - cached.cachedAt < ttlMs && cached.coverMicros !== void 0 && needMicros !== void 0 && needMicros <= cached.coverMicros;
32889
32957
  if (preAuthCovers) {
32958
+ let paymentInFlight = false;
32890
32959
  try {
32891
32960
  const payload2 = await client.createPaymentPayload(cached.paymentRequired);
32892
32961
  const headers = httpClient.encodePaymentSignatureHeader(payload2);
@@ -32894,16 +32963,21 @@ function createPayFetchWithPreAuth(baseFetch, client, ttlMs = DEFAULT_TTL_MS, op
32894
32963
  for (const [key2, value] of Object.entries(headers)) {
32895
32964
  preAuthRequest.headers.set(key2, value);
32896
32965
  }
32966
+ paymentInFlight = true;
32897
32967
  const response2 = await baseFetch(preAuthRequest);
32898
32968
  if (response2.status !== 402) {
32899
32969
  return response2;
32900
32970
  }
32971
+ paymentInFlight = false;
32901
32972
  cache2.delete(cacheKey2);
32902
32973
  } catch (err) {
32903
32974
  cache2.delete(cacheKey2);
32904
32975
  if (err instanceof SpendPolicyError) {
32905
32976
  throw err;
32906
32977
  }
32978
+ if (paymentInFlight) {
32979
+ throw err;
32980
+ }
32907
32981
  }
32908
32982
  }
32909
32983
  const clonedRequest = request2.clone();
@@ -34488,12 +34562,12 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34488
34562
  const id2 = modelId.toLowerCase();
34489
34563
  const modelName = id2.slice(id2.indexOf("/") + 1);
34490
34564
  const match = (values, score) => values.some((value) => modelName === value) ? score : 0;
34491
- const base3 = 0.68;
34565
+ const base4 = 0.68;
34492
34566
  switch (task) {
34493
34567
  case "code_agent":
34494
34568
  if (terminalToolSignal && agentRisk === "complex_high") {
34495
34569
  return Math.max(
34496
- base3,
34570
+ base4,
34497
34571
  match(["claude-sonnet-5"], 1),
34498
34572
  match(["gpt-5.3-codex"], 0.87),
34499
34573
  match(["gpt-5-mini"], 0.78),
@@ -34501,7 +34575,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34501
34575
  );
34502
34576
  }
34503
34577
  return Math.max(
34504
- base3,
34578
+ base4,
34505
34579
  match(["gpt-5.3-codex"], 1),
34506
34580
  match(["claude-sonnet-5"], 0.98),
34507
34581
  match(["gpt-5-mini"], 0.96),
@@ -34512,7 +34586,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34512
34586
  case "tool_agent":
34513
34587
  if (terminalToolSignal && agentRisk === "complex_high") {
34514
34588
  return Math.max(
34515
- base3,
34589
+ base4,
34516
34590
  match(["claude-sonnet-5"], 1),
34517
34591
  match(["gpt-5.3-codex"], 0.87),
34518
34592
  match(["gpt-5-mini"], 0.78),
@@ -34521,7 +34595,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34521
34595
  }
34522
34596
  if (terminalToolSignal && !terminalSafetySensitive) {
34523
34597
  return Math.max(
34524
- base3,
34598
+ base4,
34525
34599
  match(["gpt-5-mini"], 1),
34526
34600
  match(["gpt-5.3-codex"], 0.98),
34527
34601
  match(["claude-sonnet-5"], 0.9),
@@ -34530,7 +34604,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34530
34604
  }
34531
34605
  if (terminalToolSignal && terminalSafetySensitive) {
34532
34606
  return Math.max(
34533
- base3,
34607
+ base4,
34534
34608
  match(["claude-sonnet-5"], 1),
34535
34609
  match(["claude-opus-4.8"], 0.9),
34536
34610
  match(["gpt-5.3-codex"], 0.84)
@@ -34538,14 +34612,14 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34538
34612
  }
34539
34613
  if (agentDomain === "web_research") {
34540
34614
  return deepWebResearch ? Math.max(
34541
- base3,
34615
+ base4,
34542
34616
  match(["claude-sonnet-5"], 1),
34543
34617
  match(["gpt-5-mini"], 0.88),
34544
34618
  match(["gemini-3.5-flash"], 0.84),
34545
34619
  match(["claude-opus-5"], 0.8),
34546
34620
  match(["claude-opus-4.8"], 0.78)
34547
34621
  ) : Math.max(
34548
- base3,
34622
+ base4,
34549
34623
  match(["claude-sonnet-5"], 1),
34550
34624
  match(["gpt-5-mini"], 0.88),
34551
34625
  match(["gemini-3.5-flash"], 0.86),
@@ -34556,7 +34630,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34556
34630
  if (agentDomain === "retail") {
34557
34631
  if (agentRisk === "standard") {
34558
34632
  return Math.max(
34559
- base3,
34633
+ base4,
34560
34634
  match(["gpt-5-mini"], 1),
34561
34635
  match(["claude-sonnet-5"], 0.88),
34562
34636
  match(["gemini-3.5-flash"], 0.82),
@@ -34567,7 +34641,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34567
34641
  }
34568
34642
  if (agentRisk === "policy_exception") {
34569
34643
  return Math.max(
34570
- base3,
34644
+ base4,
34571
34645
  match(["gpt-4.1"], 1),
34572
34646
  match(["claude-sonnet-5"], 0.9),
34573
34647
  match(["deepseek-v4-pro"], 0.82),
@@ -34577,7 +34651,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34577
34651
  }
34578
34652
  if (agentRisk === "policy_exception_simple") {
34579
34653
  return Math.max(
34580
- base3,
34654
+ base4,
34581
34655
  match(["gpt-5-mini"], 1),
34582
34656
  match(["gpt-4.1"], 0.86),
34583
34657
  match(["deepseek-v4-pro"], 0.82),
@@ -34585,7 +34659,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34585
34659
  );
34586
34660
  }
34587
34661
  return Math.max(
34588
- base3,
34662
+ base4,
34589
34663
  match(["deepseek-v4-pro"], 1),
34590
34664
  match(["claude-sonnet-5"], 0.88),
34591
34665
  match(["gemini-3.5-flash"], 0.82),
@@ -34597,7 +34671,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34597
34671
  if (agentDomain === "airline") {
34598
34672
  if (agentRisk === "complex_high") {
34599
34673
  return Math.max(
34600
- base3,
34674
+ base4,
34601
34675
  match(["claude-sonnet-5"], 1),
34602
34676
  match(["gpt-5-mini"], 0.78),
34603
34677
  match(["gemini-3.5-flash"], 0.76),
@@ -34605,7 +34679,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34605
34679
  );
34606
34680
  }
34607
34681
  return Math.max(
34608
- base3,
34682
+ base4,
34609
34683
  match(["gpt-5-mini"], 1),
34610
34684
  match(["claude-sonnet-5"], 0.9),
34611
34685
  match(["gemini-3.5-flash"], 0.8),
@@ -34613,7 +34687,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34613
34687
  );
34614
34688
  }
34615
34689
  return Math.max(
34616
- base3,
34690
+ base4,
34617
34691
  match(["claude-sonnet-5"], 1),
34618
34692
  match(["gemini-3.5-flash"], 0.88),
34619
34693
  match(["gpt-5.3-codex"], 0.87),
@@ -34624,12 +34698,12 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34624
34698
  case "tool_agent_parallel":
34625
34699
  if (terminalToolSignal) {
34626
34700
  return terminalSafetySensitive ? Math.max(
34627
- base3,
34701
+ base4,
34628
34702
  match(["claude-sonnet-5"], 1),
34629
34703
  match(["claude-opus-4.8"], 0.9),
34630
34704
  match(["gpt-5.3-codex"], 0.86)
34631
34705
  ) : Math.max(
34632
- base3,
34706
+ base4,
34633
34707
  match(["gpt-5-mini"], 1),
34634
34708
  match(["gpt-5.3-codex"], 0.98),
34635
34709
  match(["claude-sonnet-5"], 0.92),
@@ -34638,14 +34712,14 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34638
34712
  }
34639
34713
  if (agentDomain === "web_research") {
34640
34714
  return deepWebResearch ? Math.max(
34641
- base3,
34715
+ base4,
34642
34716
  match(["claude-sonnet-5"], 1),
34643
34717
  match(["gpt-5-mini"], 0.88),
34644
34718
  match(["gemini-3.5-flash"], 0.84),
34645
34719
  match(["claude-opus-5"], 0.8),
34646
34720
  match(["claude-opus-4.8"], 0.78)
34647
34721
  ) : Math.max(
34648
- base3,
34722
+ base4,
34649
34723
  match(["claude-sonnet-5"], 1),
34650
34724
  match(["gpt-5-mini"], 0.88),
34651
34725
  match(["gemini-3.5-flash"], 0.86),
@@ -34656,7 +34730,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34656
34730
  if (agentDomain === "retail") {
34657
34731
  if (agentRisk === "policy_exception") {
34658
34732
  return Math.max(
34659
- base3,
34733
+ base4,
34660
34734
  match(["gpt-4.1"], 1),
34661
34735
  match(["claude-sonnet-5"], 0.9),
34662
34736
  match(["deepseek-v4-pro"], 0.82),
@@ -34666,7 +34740,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34666
34740
  }
34667
34741
  if (agentRisk === "policy_exception_simple") {
34668
34742
  return Math.max(
34669
- base3,
34743
+ base4,
34670
34744
  match(["gpt-5-mini"], 1),
34671
34745
  match(["gpt-4.1"], 0.86),
34672
34746
  match(["deepseek-v4-pro"], 0.82),
@@ -34674,7 +34748,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34674
34748
  );
34675
34749
  }
34676
34750
  return Math.max(
34677
- base3,
34751
+ base4,
34678
34752
  match(["deepseek-v4-pro"], 1),
34679
34753
  match(["claude-sonnet-5"], 0.88),
34680
34754
  match(["claude-opus-4.8"], 0.84),
@@ -34684,20 +34758,20 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34684
34758
  }
34685
34759
  if (agentDomain === "airline") {
34686
34760
  return agentRisk === "complex_high" ? Math.max(
34687
- base3,
34761
+ base4,
34688
34762
  match(["claude-sonnet-5"], 1),
34689
34763
  match(["gpt-5-mini"], 0.78),
34690
34764
  match(["claude-opus-4.8"], 0.76),
34691
34765
  match(["gemini-3.5-flash"], 0.74)
34692
34766
  ) : Math.max(
34693
- base3,
34767
+ base4,
34694
34768
  match(["gpt-5-mini"], 1),
34695
34769
  match(["claude-sonnet-5"], 0.9),
34696
34770
  match(["gemini-3.5-flash"], 0.8)
34697
34771
  );
34698
34772
  }
34699
34773
  return Math.max(
34700
- base3,
34774
+ base4,
34701
34775
  match(["claude-opus-4.8"], 1),
34702
34776
  match(["claude-sonnet-5"], 0.84),
34703
34777
  match(["grok-4.5"], 0.82),
@@ -34707,7 +34781,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34707
34781
  case "code_edit":
34708
34782
  case "debug":
34709
34783
  return Math.max(
34710
- base3,
34784
+ base4,
34711
34785
  match(["gpt-5.3-codex"], 1),
34712
34786
  match(["claude-sonnet-4.6"], 0.94),
34713
34787
  match(["glm-5.2"], 0.9),
@@ -34715,7 +34789,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34715
34789
  );
34716
34790
  case "reasoning":
34717
34791
  return Math.max(
34718
- base3,
34792
+ base4,
34719
34793
  match(["claude-sonnet-5", "claude-sonnet-4.6"], 0.98),
34720
34794
  match(["deepseek-v4-pro"], 0.95),
34721
34795
  match(["grok-4.5"], 0.94),
@@ -34723,7 +34797,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34723
34797
  );
34724
34798
  case "reasoning_mcq":
34725
34799
  return Math.max(
34726
- base3,
34800
+ base4,
34727
34801
  match(["gemini-3-flash-preview"], 1),
34728
34802
  match(["gemini-3.5-flash"], 0.91),
34729
34803
  match(["grok-4.5"], 0.9),
@@ -34732,20 +34806,20 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34732
34806
  );
34733
34807
  case "reasoning_math":
34734
34808
  return Math.max(
34735
- base3,
34809
+ base4,
34736
34810
  match(["gemini-3.5-flash"], 1),
34737
34811
  match(["grok-4.5"], 0.93),
34738
34812
  match(["claude-sonnet-5", "deepseek-v4-pro", "kimi-k3"], 0.9)
34739
34813
  );
34740
34814
  case "vision":
34741
34815
  return Math.max(
34742
- base3,
34816
+ base4,
34743
34817
  match(["gemini-3.1-pro"], 0.96),
34744
34818
  match(["qwen3.7-max", "claude-sonnet-4.6", "kimi-k3", "grok-4.3"], 0.9)
34745
34819
  );
34746
34820
  case "long_context":
34747
34821
  return Math.max(
34748
- base3,
34822
+ base4,
34749
34823
  match(["gemini-3.1-pro"], 1),
34750
34824
  match(["qwen3.7-max", "glm-5.2"], 0.89),
34751
34825
  match(["gemini-3.5-flash"], 0.88),
@@ -34755,7 +34829,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34755
34829
  const kimiExtractionAffinity = language === "zh" ? 1 : 0.9;
34756
34830
  const otherExtractionAffinity = language === "zh" ? 0.88 : 0.9;
34757
34831
  return Math.max(
34758
- base3,
34832
+ base4,
34759
34833
  match(["gemini-3.5-flash", "gemini-2.5-flash", "gpt-4o-mini"], otherExtractionAffinity),
34760
34834
  match(["claude-sonnet-5", "claude-sonnet-4.6"], otherExtractionAffinity),
34761
34835
  match(["kimi-k3"], kimiExtractionAffinity)
@@ -34763,7 +34837,7 @@ function affinity(modelId, task, language = "other", agentDomain = "other", deep
34763
34837
  }
34764
34838
  default:
34765
34839
  return Math.max(
34766
- base3,
34840
+ base4,
34767
34841
  match(["gemini-3.5-flash", "gemini-2.5-flash", "kimi-k3"], 0.86)
34768
34842
  );
34769
34843
  }
@@ -36038,13 +36112,13 @@ ${value.slice(-(scanLimit - prefixLength))}`;
36038
36112
  name = "portfolio";
36039
36113
  route(prompt, systemPrompt, maxOutputTokens, options) {
36040
36114
  const features = classifyTask(prompt, systemPrompt, options);
36041
- const base3 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
36115
+ const base4 = new RulesStrategy().route(prompt, systemPrompt, maxOutputTokens, {
36042
36116
  ...options,
36043
36117
  requiresTools: features.needsTools
36044
36118
  });
36045
- const tierConfigs = base3.tierConfigs;
36046
- if (!tierConfigs) return base3;
36047
- const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (base3.tier === "SIMPLE" || base3.tier === "MEDIUM") ? "REASONING" : base3.tier;
36119
+ const tierConfigs = base4.tierConfigs;
36120
+ if (!tierConfigs) return base4;
36121
+ const targetTier = (features.taskType === "reasoning_mcq" || features.taskType === "reasoning_math") && (base4.tier === "SIMPLE" || base4.tier === "MEDIUM") ? "REASONING" : base4.tier;
36048
36122
  const tierConfig = tierConfigs[targetTier];
36049
36123
  const configuredCandidates = tierConfig ? getFallbackChain(targetTier, tierConfigs) : [];
36050
36124
  const unavailable = new Set(options.unavailableModels ?? []);
@@ -36057,7 +36131,7 @@ ${value.slice(-(scanLimit - prefixLength))}`;
36057
36131
  (model2) => isEligible(model2, features, maxOutputTokens, options)
36058
36132
  );
36059
36133
  const eligibleCandidates = eligible.length > 0 ? eligible : chain3;
36060
- if (eligibleCandidates.length === 0) return base3;
36134
+ if (eligibleCandidates.length === 0) return base4;
36061
36135
  const profileName = options.routingProfile === "eco" ? "eco" : options.routingProfile === "premium" ? "premium" : "auto";
36062
36136
  const portfolio = options.config.portfolio ?? DEFAULT_PORTFOLIO_WEIGHTS;
36063
36137
  const getAffinity = (model2) => affinity(
@@ -36130,27 +36204,27 @@ ${value.slice(-(scanLimit - prefixLength))}`;
36130
36204
  (model2) => !scoredModels.includes(model2) && !webResearchFallbackOrder.includes(model2)
36131
36205
  )
36132
36206
  ] : [...scoredModels, ...eligibleCandidates.filter((model2) => !scoredModels.includes(model2))];
36133
- const model = ranked[0] ?? base3.model;
36207
+ const model = ranked[0] ?? base4.model;
36134
36208
  const selectedTierConfigs = {
36135
36209
  ...tierConfigs,
36136
36210
  [targetTier]: { primary: model, fallback: ranked.slice(1) }
36137
36211
  };
36138
36212
  const decision = selectModel(
36139
36213
  targetTier,
36140
- base3.confidence,
36214
+ base4.confidence,
36141
36215
  "portfolio",
36142
- `${base3.reasoning} | v3 task=${features.taskType} agentRisk=${features.agentRisk} deepWebResearch=${features.deepWebResearch} terminalCode=${features.implicitTerminalCode} terminalSafety=${features.terminalSafetySensitive} candidates=${ranked.length}`,
36216
+ `${base4.reasoning} | v3 task=${features.taskType} agentRisk=${features.agentRisk} deepWebResearch=${features.deepWebResearch} terminalCode=${features.implicitTerminalCode} terminalSafety=${features.terminalSafetySensitive} candidates=${ranked.length}`,
36143
36217
  selectedTierConfigs,
36144
36218
  options.modelPricing,
36145
36219
  features.estimatedInputTokens,
36146
36220
  maxOutputTokens,
36147
36221
  options.routingProfile,
36148
- base3.agenticScore
36222
+ base4.agenticScore
36149
36223
  );
36150
36224
  return {
36151
36225
  ...decision,
36152
36226
  tierConfigs: selectedTierConfigs,
36153
- profile: base3.profile,
36227
+ profile: base4.profile,
36154
36228
  candidates: ranked,
36155
36229
  candidateScores: rankedEntries.map(({ model: model2, score, quality, cost, speed, reliability }) => ({
36156
36230
  model: model2,
@@ -40597,7 +40671,7 @@ var init_errors5 = __esm({
40597
40671
  `Options:`,
40598
40672
  ` 1. Fund wallet: ${walletAddress}`,
40599
40673
  ` 2. Use free model: /model free`,
40600
- ` 3. Uninstall: bash ~/.openclaw/extensions/clawrouter/scripts/uninstall.sh`
40674
+ ` 3. Uninstall: bash ~/.openclaw/extensions/blockrun-clawrouter/scripts/uninstall.sh`
40601
40675
  ].join("\n");
40602
40676
  super(msg);
40603
40677
  this.name = "EmptyWalletError";
@@ -40749,6 +40823,154 @@ var init_balance = __esm({
40749
40823
  }
40750
40824
  });
40751
40825
 
40826
+ // node_modules/base-x/src/esm/index.js
40827
+ function base2(ALPHABET3) {
40828
+ if (ALPHABET3.length >= 255) {
40829
+ throw new TypeError("Alphabet too long");
40830
+ }
40831
+ const BASE_MAP = new Uint8Array(256);
40832
+ for (let j = 0; j < BASE_MAP.length; j++) {
40833
+ BASE_MAP[j] = 255;
40834
+ }
40835
+ for (let i = 0; i < ALPHABET3.length; i++) {
40836
+ const x = ALPHABET3.charAt(i);
40837
+ const xc = x.charCodeAt(0);
40838
+ if (BASE_MAP[xc] !== 255) {
40839
+ throw new TypeError(x + " is ambiguous");
40840
+ }
40841
+ BASE_MAP[xc] = i;
40842
+ }
40843
+ const BASE = ALPHABET3.length;
40844
+ const LEADER = ALPHABET3.charAt(0);
40845
+ const FACTOR = Math.log(BASE) / Math.log(256);
40846
+ const iFACTOR = Math.log(256) / Math.log(BASE);
40847
+ function encode9(source) {
40848
+ if (source instanceof Uint8Array) {
40849
+ } else if (ArrayBuffer.isView(source)) {
40850
+ source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
40851
+ } else if (Array.isArray(source)) {
40852
+ source = Uint8Array.from(source);
40853
+ }
40854
+ if (!(source instanceof Uint8Array)) {
40855
+ throw new TypeError("Expected Uint8Array");
40856
+ }
40857
+ if (source.length === 0) {
40858
+ return "";
40859
+ }
40860
+ let zeroes = 0;
40861
+ let length = 0;
40862
+ let pbegin = 0;
40863
+ const pend = source.length;
40864
+ while (pbegin !== pend && source[pbegin] === 0) {
40865
+ pbegin++;
40866
+ zeroes++;
40867
+ }
40868
+ const size5 = (pend - pbegin) * iFACTOR + 1 >>> 0;
40869
+ const b58 = new Uint8Array(size5);
40870
+ while (pbegin !== pend) {
40871
+ let carry2 = source[pbegin];
40872
+ let i = 0;
40873
+ for (let it1 = size5 - 1; (carry2 !== 0 || i < length) && it1 !== -1; it1--, i++) {
40874
+ carry2 += 256 * b58[it1] >>> 0;
40875
+ b58[it1] = carry2 % BASE >>> 0;
40876
+ carry2 = carry2 / BASE >>> 0;
40877
+ }
40878
+ if (carry2 !== 0) {
40879
+ throw new Error("Non-zero carry");
40880
+ }
40881
+ length = i;
40882
+ pbegin++;
40883
+ }
40884
+ let it2 = size5 - length;
40885
+ while (it2 !== size5 && b58[it2] === 0) {
40886
+ it2++;
40887
+ }
40888
+ let str = LEADER.repeat(zeroes);
40889
+ for (; it2 < size5; ++it2) {
40890
+ str += ALPHABET3.charAt(b58[it2]);
40891
+ }
40892
+ return str;
40893
+ }
40894
+ function decodeUnsafe(source) {
40895
+ if (typeof source !== "string") {
40896
+ throw new TypeError("Expected String");
40897
+ }
40898
+ if (source.length === 0) {
40899
+ return new Uint8Array();
40900
+ }
40901
+ let psz = 0;
40902
+ let zeroes = 0;
40903
+ let length = 0;
40904
+ while (source[psz] === LEADER) {
40905
+ zeroes++;
40906
+ psz++;
40907
+ }
40908
+ const size5 = (source.length - psz) * FACTOR + 1 >>> 0;
40909
+ const b256 = new Uint8Array(size5);
40910
+ while (psz < source.length) {
40911
+ const charCode = source.charCodeAt(psz);
40912
+ if (charCode > 255) {
40913
+ return;
40914
+ }
40915
+ let carry2 = BASE_MAP[charCode];
40916
+ if (carry2 === 255) {
40917
+ return;
40918
+ }
40919
+ let i = 0;
40920
+ for (let it3 = size5 - 1; (carry2 !== 0 || i < length) && it3 !== -1; it3--, i++) {
40921
+ carry2 += BASE * b256[it3] >>> 0;
40922
+ b256[it3] = carry2 % 256 >>> 0;
40923
+ carry2 = carry2 / 256 >>> 0;
40924
+ }
40925
+ if (carry2 !== 0) {
40926
+ throw new Error("Non-zero carry");
40927
+ }
40928
+ length = i;
40929
+ psz++;
40930
+ }
40931
+ let it4 = size5 - length;
40932
+ while (it4 !== size5 && b256[it4] === 0) {
40933
+ it4++;
40934
+ }
40935
+ const vch = new Uint8Array(zeroes + (size5 - it4));
40936
+ let j = zeroes;
40937
+ while (it4 !== size5) {
40938
+ vch[j++] = b256[it4++];
40939
+ }
40940
+ return vch;
40941
+ }
40942
+ function decode4(string) {
40943
+ const buffer2 = decodeUnsafe(string);
40944
+ if (buffer2) {
40945
+ return buffer2;
40946
+ }
40947
+ throw new Error("Non-base" + BASE + " character");
40948
+ }
40949
+ return {
40950
+ encode: encode9,
40951
+ decodeUnsafe,
40952
+ decode: decode4
40953
+ };
40954
+ }
40955
+ var esm_default;
40956
+ var init_esm6 = __esm({
40957
+ "node_modules/base-x/src/esm/index.js"() {
40958
+ "use strict";
40959
+ esm_default = base2;
40960
+ }
40961
+ });
40962
+
40963
+ // node_modules/bs58/src/esm/index.js
40964
+ var ALPHABET, esm_default2;
40965
+ var init_esm7 = __esm({
40966
+ "node_modules/bs58/src/esm/index.js"() {
40967
+ "use strict";
40968
+ init_esm6();
40969
+ ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
40970
+ esm_default2 = esm_default(ALPHABET);
40971
+ }
40972
+ });
40973
+
40752
40974
  // node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
40753
40975
  function isBytes7(a) {
40754
40976
  return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
@@ -41917,15 +42139,15 @@ var init_curve3 = __esm({
41917
42139
  const { windows, windowSize } = calcWOpts3(W, this.bits);
41918
42140
  const points = [];
41919
42141
  let p = point3;
41920
- let base3 = p;
42142
+ let base4 = p;
41921
42143
  for (let window2 = 0; window2 < windows; window2++) {
41922
- base3 = p;
41923
- points.push(base3);
42144
+ base4 = p;
42145
+ points.push(base4);
41924
42146
  for (let i = 1; i < windowSize; i++) {
41925
- base3 = base3.add(p);
41926
- points.push(base3);
42147
+ base4 = base4.add(p);
42148
+ points.push(base4);
41927
42149
  }
41928
- p = base3.double();
42150
+ p = base4.double();
41929
42151
  }
41930
42152
  return points;
41931
42153
  }
@@ -44973,6 +45195,37 @@ var init_sha26 = __esm({
44973
45195
  }
44974
45196
  });
44975
45197
 
45198
+ // src/solana-key.ts
45199
+ function deriveSolanaKeyBytes(mnemonic) {
45200
+ const seed = mnemonicToSeedSync(mnemonic);
45201
+ let digest = hmac6(sha5123, new TextEncoder().encode("ed25519 seed"), seed);
45202
+ let key2 = digest.slice(0, 32);
45203
+ let chainCode = digest.slice(32);
45204
+ for (const index2 of SOLANA_HARDENED_INDICES) {
45205
+ const data = new Uint8Array(37);
45206
+ data[0] = 0;
45207
+ data.set(key2, 1);
45208
+ data[33] = index2 >>> 24 & 255;
45209
+ data[34] = index2 >>> 16 & 255;
45210
+ data[35] = index2 >>> 8 & 255;
45211
+ data[36] = index2 & 255;
45212
+ digest = hmac6(sha5123, chainCode, data);
45213
+ key2 = digest.slice(0, 32);
45214
+ chainCode = digest.slice(32);
45215
+ }
45216
+ return new Uint8Array(key2);
45217
+ }
45218
+ var SOLANA_HARDENED_INDICES;
45219
+ var init_solana_key = __esm({
45220
+ "src/solana-key.ts"() {
45221
+ "use strict";
45222
+ init_hmac6();
45223
+ init_sha26();
45224
+ init_esm3();
45225
+ SOLANA_HARDENED_INDICES = [44 + 2147483648, 501 + 2147483648, 0 + 2147483648, 0 + 2147483648];
45226
+ }
45227
+ });
45228
+
44976
45229
  // node_modules/@solana/errors/dist/index.node.mjs
44977
45230
  function encodeValue(value) {
44978
45231
  if (Array.isArray(value)) {
@@ -46414,20 +46667,20 @@ function partitionLeadingZeroes(value, zeroCharacter) {
46414
46667
  return [leadingZeros, tailChars];
46415
46668
  }
46416
46669
  function getBigIntFromBaseX(value, alphabet4) {
46417
- const base3 = BigInt(alphabet4.length);
46670
+ const base4 = BigInt(alphabet4.length);
46418
46671
  let sum = 0n;
46419
46672
  for (const char of value) {
46420
- sum *= base3;
46673
+ sum *= base4;
46421
46674
  sum += BigInt(alphabet4.indexOf(char));
46422
46675
  }
46423
46676
  return sum;
46424
46677
  }
46425
46678
  function getBaseXFromBigInt(value, alphabet4) {
46426
- const base3 = BigInt(alphabet4.length);
46679
+ const base4 = BigInt(alphabet4.length);
46427
46680
  const tailChars = [];
46428
46681
  while (value > 0n) {
46429
- tailChars.unshift(alphabet4[Number(value % base3)]);
46430
- value /= base3;
46682
+ tailChars.unshift(alphabet4[Number(value % base4)]);
46683
+ value /= base4;
46431
46684
  }
46432
46685
  return tailChars.join("");
46433
46686
  }
@@ -48474,20 +48727,20 @@ function partitionLeadingZeroes2(value, zeroCharacter) {
48474
48727
  return [leadingZeros, tailChars];
48475
48728
  }
48476
48729
  function getBigIntFromBaseX2(value, alphabet4) {
48477
- const base3 = BigInt(alphabet4.length);
48730
+ const base4 = BigInt(alphabet4.length);
48478
48731
  let sum = 0n;
48479
48732
  for (const char of value) {
48480
- sum *= base3;
48733
+ sum *= base4;
48481
48734
  sum += BigInt(alphabet4.indexOf(char));
48482
48735
  }
48483
48736
  return sum;
48484
48737
  }
48485
48738
  function getBaseXFromBigInt2(value, alphabet4) {
48486
- const base3 = BigInt(alphabet4.length);
48739
+ const base4 = BigInt(alphabet4.length);
48487
48740
  const tailChars = [];
48488
48741
  while (value > 0n) {
48489
- tailChars.unshift(alphabet4[Number(value % base3)]);
48490
- value /= base3;
48742
+ tailChars.unshift(alphabet4[Number(value % base4)]);
48743
+ value /= base4;
48491
48744
  }
48492
48745
  return tailChars.join("");
48493
48746
  }
@@ -59265,25 +59518,6 @@ function deriveEvmKey(mnemonic) {
59265
59518
  const account = privateKeyToAccount(hex);
59266
59519
  return { privateKey: hex, address: account.address };
59267
59520
  }
59268
- function deriveSolanaKeyBytes(mnemonic) {
59269
- const seed = mnemonicToSeedSync(mnemonic);
59270
- let I = hmac6(sha5123, new TextEncoder().encode("ed25519 seed"), seed);
59271
- let key2 = I.slice(0, 32);
59272
- let chainCode = I.slice(32);
59273
- for (const index2 of SOLANA_HARDENED_INDICES) {
59274
- const data = new Uint8Array(37);
59275
- data[0] = 0;
59276
- data.set(key2, 1);
59277
- data[33] = index2 >>> 24 & 255;
59278
- data[34] = index2 >>> 16 & 255;
59279
- data[35] = index2 >>> 8 & 255;
59280
- data[36] = index2 & 255;
59281
- I = hmac6(sha5123, chainCode, data);
59282
- key2 = I.slice(0, 32);
59283
- chainCode = I.slice(32);
59284
- }
59285
- return new Uint8Array(key2);
59286
- }
59287
59521
  function deriveAllKeys(mnemonic) {
59288
59522
  const { privateKey: evmPrivateKey, address: evmAddress } = deriveEvmKey(mnemonic);
59289
59523
  const solanaPrivateKeyBytes = deriveSolanaKeyBytes(mnemonic);
@@ -59294,18 +59528,17 @@ async function getSolanaAddress(privateKeyBytes) {
59294
59528
  const signer = await createKeyPairSignerFromPrivateKeyBytes2(privateKeyBytes);
59295
59529
  return signer.address;
59296
59530
  }
59297
- var ETH_DERIVATION_PATH, SOLANA_HARDENED_INDICES;
59531
+ var ETH_DERIVATION_PATH;
59298
59532
  var init_wallet2 = __esm({
59299
59533
  "src/wallet.ts"() {
59300
59534
  "use strict";
59301
59535
  init_bip32();
59302
59536
  init_esm3();
59303
59537
  init_english();
59304
- init_hmac6();
59305
- init_sha26();
59306
59538
  init_accounts();
59539
+ init_solana_key();
59540
+ init_solana_key();
59307
59541
  ETH_DERIVATION_PATH = "m/44'/60'/0'/0/0";
59308
- SOLANA_HARDENED_INDICES = [44 + 2147483648, 501 + 2147483648, 0 + 2147483648, 0 + 2147483648];
59309
59542
  }
59310
59543
  });
59311
59544
 
@@ -59313,15 +59546,21 @@ var init_wallet2 = __esm({
59313
59546
  var auth_exports = {};
59314
59547
  __export(auth_exports, {
59315
59548
  CHAIN_FILE: () => CHAIN_FILE,
59549
+ CORE_CHAIN_FILE: () => CORE_CHAIN_FILE,
59550
+ CORE_SOLANA_WALLET_FILE: () => CORE_SOLANA_WALLET_FILE,
59551
+ CORE_WALLET_FILE: () => CORE_WALLET_FILE,
59316
59552
  MNEMONIC_FILE: () => MNEMONIC_FILE,
59317
59553
  WALLET_FILE: () => WALLET_FILE,
59318
59554
  loadPaymentChain: () => loadPaymentChain,
59555
+ migrateLegacyWalletToCore: () => migrateLegacyWalletToCore,
59319
59556
  recoverWalletFromMnemonic: () => recoverWalletFromMnemonic,
59557
+ resolveExistingWalletKey: () => resolveExistingWalletKey,
59320
59558
  resolveOrGenerateWalletKey: () => resolveOrGenerateWalletKey,
59321
59559
  resolvePaymentChain: () => resolvePaymentChain,
59322
59560
  savePaymentChain: () => savePaymentChain,
59323
59561
  setupSolana: () => setupSolana
59324
59562
  });
59563
+ import { createPrivateKey, createPublicKey } from "crypto";
59325
59564
  import { writeFile, mkdir as mkdir2 } from "fs/promises";
59326
59565
  import { join as join7 } from "path";
59327
59566
  import { homedir as homedir4 } from "os";
@@ -59376,7 +59615,67 @@ async function saveMnemonic(mnemonic) {
59376
59615
  await mkdir2(WALLET_DIR2, { recursive: true });
59377
59616
  await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
59378
59617
  }
59379
- async function generateAndSaveWallet() {
59618
+ async function migrateLegacyWalletToCore() {
59619
+ const migrated = { base: false, solana: false, chain: false };
59620
+ const [coreBase, coreSolana, coreChain] = await Promise.all([
59621
+ readExisting(CORE_WALLET_FILE),
59622
+ readExisting(CORE_SOLANA_WALLET_FILE),
59623
+ readExisting(CORE_CHAIN_FILE)
59624
+ ]);
59625
+ if (coreBase === void 0) {
59626
+ const legacyBase = await loadSavedWallet();
59627
+ if (legacyBase) {
59628
+ migrated.base = await writeCoreFileIfMissing(CORE_WALLET_FILE, legacyBase + "\n");
59629
+ }
59630
+ }
59631
+ if (coreSolana === void 0) {
59632
+ const mnemonic = await loadMnemonic();
59633
+ if (mnemonic) {
59634
+ const secret = solanaSecretKeyFromSeed(deriveSolanaKeyBytes(mnemonic));
59635
+ migrated.solana = await writeCoreFileIfMissing(
59636
+ CORE_SOLANA_WALLET_FILE,
59637
+ JSON.stringify([...secret]) + "\n"
59638
+ );
59639
+ }
59640
+ }
59641
+ if (coreChain === void 0) {
59642
+ const legacyChain = await readOptional(CHAIN_FILE);
59643
+ if (legacyChain === "base" || legacyChain === "solana") {
59644
+ migrated.chain = await writeCoreFileIfMissing(CORE_CHAIN_FILE, legacyChain + "\n");
59645
+ }
59646
+ }
59647
+ if (migrated.base || migrated.solana || migrated.chain) {
59648
+ const parts = Object.entries(migrated).filter(([, changed]) => changed).map(([name]) => name).join(", ");
59649
+ console.log(`[ClawRouter] Migrated legacy ${parts} data to ${CORE_WALLET_DIR}`);
59650
+ }
59651
+ return migrated;
59652
+ }
59653
+ async function writeCoreFileIfMissing(path5, value) {
59654
+ await mkdir2(CORE_WALLET_DIR, { recursive: true });
59655
+ try {
59656
+ await writeFile(path5, value, { mode: 384, flag: "wx" });
59657
+ return true;
59658
+ } catch (error) {
59659
+ if (error.code === "EEXIST") return false;
59660
+ throw error;
59661
+ }
59662
+ }
59663
+ async function readExisting(path5) {
59664
+ try {
59665
+ return await readTextFile(path5);
59666
+ } catch (error) {
59667
+ if (error.code === "ENOENT") return void 0;
59668
+ throw error;
59669
+ }
59670
+ }
59671
+ function solanaSecretKeyFromSeed(seed) {
59672
+ const privateDer = Buffer.concat([Buffer.from("302e020100300506032b657004220420", "hex"), seed]);
59673
+ const publicDer = createPublicKey(
59674
+ createPrivateKey({ key: privateDer, format: "der", type: "pkcs8" })
59675
+ ).export({ format: "der", type: "spki" });
59676
+ return Uint8Array.from([...seed, ...Buffer.from(publicDer).subarray(-32)]);
59677
+ }
59678
+ async function generateAndSaveWallet(existingCoreSolanaKey) {
59380
59679
  const existingMnemonic = await loadMnemonic();
59381
59680
  if (existingMnemonic) {
59382
59681
  throw new Error(
@@ -59394,7 +59693,17 @@ Then run: npx @blockrun/clawrouter`
59394
59693
  const derived = deriveAllKeys(mnemonic);
59395
59694
  await mkdir2(WALLET_DIR2, { recursive: true });
59396
59695
  await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
59397
- await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
59696
+ if (!existingCoreSolanaKey) {
59697
+ await writeFile(MNEMONIC_FILE, mnemonic + "\n", { mode: 384 });
59698
+ }
59699
+ await writeCoreFileIfMissing(CORE_WALLET_FILE, derived.evmPrivateKey + "\n");
59700
+ if (!existingCoreSolanaKey) {
59701
+ await writeCoreFileIfMissing(
59702
+ CORE_SOLANA_WALLET_FILE,
59703
+ JSON.stringify([...solanaSecretKeyFromSeed(derived.solanaPrivateKeyBytes)]) + "\n"
59704
+ );
59705
+ }
59706
+ const solanaPrivateKeyBytes = existingCoreSolanaKey ?? derived.solanaPrivateKeyBytes;
59398
59707
  try {
59399
59708
  const verification = (await readTextFile(WALLET_FILE)).trim();
59400
59709
  if (verification !== derived.evmPrivateKey) {
@@ -59409,7 +59718,7 @@ Then run: npx @blockrun/clawrouter`
59409
59718
  }
59410
59719
  let solanaAddress;
59411
59720
  try {
59412
- solanaAddress = await getSolanaAddress(derived.solanaPrivateKeyBytes);
59721
+ solanaAddress = await getSolanaAddress(solanaPrivateKeyBytes);
59413
59722
  } catch {
59414
59723
  }
59415
59724
  let solanaDefaultSaved = false;
@@ -59428,8 +59737,11 @@ Then run: npx @blockrun/clawrouter`
59428
59737
  if (solanaAddress) {
59429
59738
  console.log(`[ClawRouter] Solana Address : ${solanaAddress}`);
59430
59739
  }
59431
- console.log(`[ClawRouter] Key file : ${WALLET_FILE}`);
59432
- console.log(`[ClawRouter] Mnemonic : ${MNEMONIC_FILE}`);
59740
+ console.log(`[ClawRouter] Base key : ${CORE_WALLET_FILE}`);
59741
+ console.log(`[ClawRouter] Solana key : ${CORE_SOLANA_WALLET_FILE}`);
59742
+ if (!existingCoreSolanaKey) {
59743
+ console.log(`[ClawRouter] Recovery words : ${MNEMONIC_FILE}`);
59744
+ }
59433
59745
  console.log(`[ClawRouter]`);
59434
59746
  console.log(`[ClawRouter] Both EVM (Base) and Solana wallets are ready.`);
59435
59747
  if (solanaDefaultSaved) {
@@ -59448,44 +59760,50 @@ Then run: npx @blockrun/clawrouter`
59448
59760
  return {
59449
59761
  key: derived.evmPrivateKey,
59450
59762
  address: derived.evmAddress,
59451
- mnemonic,
59452
- solanaPrivateKeyBytes: derived.solanaPrivateKeyBytes
59763
+ ...existingCoreSolanaKey ? {} : { mnemonic },
59764
+ solanaPrivateKeyBytes
59453
59765
  };
59454
59766
  }
59455
- async function resolveOrGenerateWalletKey() {
59767
+ async function resolveExistingWalletKey() {
59768
+ const coreSolanaKey = await loadCoreSolanaKeyForSelectedChain();
59769
+ const envKey = process["env"].BLOCKRUN_WALLET_KEY;
59770
+ if (typeof envKey === "string" && /^0x[0-9a-f]{64}$/i.test(envKey)) {
59771
+ const account = privateKeyToAccount(envKey);
59772
+ return {
59773
+ key: envKey,
59774
+ address: account.address,
59775
+ source: "env",
59776
+ ...await resolvedSolanaMaterial(coreSolanaKey)
59777
+ };
59778
+ }
59779
+ const core = await loadCoreWallet();
59780
+ if (core) {
59781
+ const account = privateKeyToAccount(core);
59782
+ return {
59783
+ key: core,
59784
+ address: account.address,
59785
+ source: "core",
59786
+ ...await resolvedSolanaMaterial(coreSolanaKey)
59787
+ };
59788
+ }
59456
59789
  const saved = await loadSavedWallet();
59457
59790
  if (saved) {
59458
59791
  const account = privateKeyToAccount(saved);
59459
- const mnemonic = await loadMnemonic();
59460
- if (mnemonic) {
59461
- const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59462
- return {
59463
- key: saved,
59464
- address: account.address,
59465
- source: "saved",
59466
- mnemonic,
59467
- solanaPrivateKeyBytes: solanaKeyBytes
59468
- };
59469
- }
59470
- return { key: saved, address: account.address, source: "saved" };
59471
- }
59472
- const envKey = process["env"].BLOCKRUN_WALLET_KEY;
59473
- if (typeof envKey === "string" && envKey.startsWith("0x") && envKey.length === 66) {
59474
- const account = privateKeyToAccount(envKey);
59475
- const mnemonic = await loadMnemonic();
59476
- if (mnemonic) {
59477
- const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59478
- return {
59479
- key: envKey,
59480
- address: account.address,
59481
- source: "env",
59482
- mnemonic,
59483
- solanaPrivateKeyBytes: solanaKeyBytes
59484
- };
59485
- }
59486
- return { key: envKey, address: account.address, source: "env" };
59792
+ return {
59793
+ key: saved,
59794
+ address: account.address,
59795
+ source: "saved",
59796
+ ...await resolvedSolanaMaterial(coreSolanaKey)
59797
+ };
59487
59798
  }
59488
- const result = await generateAndSaveWallet();
59799
+ return void 0;
59800
+ }
59801
+ async function resolveOrGenerateWalletKey() {
59802
+ await migrateLegacyWalletToCore();
59803
+ const existing = await resolveExistingWalletKey();
59804
+ if (existing) return existing;
59805
+ const existingCoreSolanaKey = await loadCoreSolanaKey();
59806
+ const result = await generateAndSaveWallet(existingCoreSolanaKey);
59489
59807
  return {
59490
59808
  key: result.key,
59491
59809
  address: result.address,
@@ -59494,6 +59812,62 @@ async function resolveOrGenerateWalletKey() {
59494
59812
  solanaPrivateKeyBytes: result.solanaPrivateKeyBytes
59495
59813
  };
59496
59814
  }
59815
+ async function loadCoreSolanaKeyForSelectedChain() {
59816
+ try {
59817
+ return await loadCoreSolanaKey();
59818
+ } catch (error) {
59819
+ if (await resolvePaymentChain() === "solana") throw error;
59820
+ return void 0;
59821
+ }
59822
+ }
59823
+ async function loadCoreWallet() {
59824
+ const key2 = (await readExisting(CORE_WALLET_FILE))?.trim();
59825
+ if (key2 === void 0) return void 0;
59826
+ if (/^0x[0-9a-f]{64}$/i.test(key2)) return key2;
59827
+ throw new Error(
59828
+ `BlockRun Core wallet at ${CORE_WALLET_FILE} has an invalid format. Refusing to use another wallet implicitly.`
59829
+ );
59830
+ }
59831
+ async function loadCoreSolanaKey() {
59832
+ const environmentKey = process["env"].SOLANA_WALLET_KEY?.trim();
59833
+ const raw = environmentKey || (await readExisting(CORE_SOLANA_WALLET_FILE))?.trim();
59834
+ if (!raw) return void 0;
59835
+ try {
59836
+ let bytes;
59837
+ if (raw.startsWith("[")) {
59838
+ const parsed = JSON.parse(raw);
59839
+ if (!Array.isArray(parsed) || !parsed.every((item) => Number.isInteger(item) && item >= 0 && item <= 255))
59840
+ throw new Error("expected an array of byte values");
59841
+ bytes = Uint8Array.from(parsed);
59842
+ } else {
59843
+ const hex = raw.replace(/^0x/i, "");
59844
+ bytes = /^[0-9a-f]{128}$/i.test(hex) ? Buffer.from(hex, "hex") : esm_default2.decode(raw);
59845
+ }
59846
+ if (bytes.length !== 64) throw new Error(`expected 64 bytes, received ${bytes.length}`);
59847
+ const expected = solanaSecretKeyFromSeed(bytes.slice(0, 32));
59848
+ if (!Buffer.from(expected).equals(Buffer.from(bytes))) {
59849
+ throw new Error("public key does not match the private seed");
59850
+ }
59851
+ return bytes.slice(0, 32);
59852
+ } catch (error) {
59853
+ throw new Error(
59854
+ `BlockRun Core Solana wallet has an invalid format: ${error instanceof Error ? error.message : String(error)}`,
59855
+ { cause: error }
59856
+ );
59857
+ }
59858
+ }
59859
+ async function readOptional(path5) {
59860
+ try {
59861
+ return (await readTextFile(path5)).trim() || void 0;
59862
+ } catch {
59863
+ return void 0;
59864
+ }
59865
+ }
59866
+ async function resolvedSolanaMaterial(coreSolanaKey) {
59867
+ if (coreSolanaKey) return { solanaPrivateKeyBytes: coreSolanaKey };
59868
+ const mnemonic = await loadMnemonic();
59869
+ return mnemonic ? { mnemonic, solanaPrivateKeyBytes: deriveSolanaKeyBytes(mnemonic) } : {};
59870
+ }
59497
59871
  async function recoverWalletFromMnemonic() {
59498
59872
  const mnemonic = await loadMnemonic();
59499
59873
  if (!mnemonic) {
@@ -59501,6 +59875,12 @@ async function recoverWalletFromMnemonic() {
59501
59875
  console.error(`[ClawRouter] Cannot recover \u2014 no mnemonic to derive from.`);
59502
59876
  process.exit(1);
59503
59877
  }
59878
+ const existingCore = await loadCoreWallet();
59879
+ if (existingCore) {
59880
+ console.error(`[ClawRouter] BlockRun Core wallet already exists at ${CORE_WALLET_FILE}`);
59881
+ console.error(`[ClawRouter] Recovery not needed.`);
59882
+ process.exit(1);
59883
+ }
59504
59884
  const existing = await loadSavedWallet().catch(() => void 0);
59505
59885
  if (existing) {
59506
59886
  console.error(`[ClawRouter] wallet.key already exists at ${WALLET_FILE}`);
@@ -59527,7 +59907,8 @@ async function recoverWalletFromMnemonic() {
59527
59907
  console.log(`[ClawRouter]`);
59528
59908
  await mkdir2(WALLET_DIR2, { recursive: true });
59529
59909
  await writeFile(WALLET_FILE, derived.evmPrivateKey + "\n", { mode: 384 });
59530
- console.log(`[ClawRouter] \u2713 wallet.key restored at ${WALLET_FILE}`);
59910
+ await migrateLegacyWalletToCore();
59911
+ console.log(`[ClawRouter] \u2713 Wallet restored into BlockRun Core at ${CORE_WALLET_DIR}`);
59531
59912
  console.log(`[ClawRouter] Run: npx @blockrun/clawrouter`);
59532
59913
  console.log(`[ClawRouter]`);
59533
59914
  }
@@ -59536,8 +59917,8 @@ async function setupSolana() {
59536
59917
  if (existing) {
59537
59918
  throw new Error("Solana wallet already set up. Mnemonic file exists at " + MNEMONIC_FILE);
59538
59919
  }
59539
- const savedKey = await loadSavedWallet();
59540
- if (!savedKey) {
59920
+ const evmKey = await loadCoreWallet() ?? await loadSavedWallet();
59921
+ if (!evmKey) {
59541
59922
  throw new Error(
59542
59923
  "No EVM wallet found. Run ClawRouter first to generate a wallet before setting up Solana."
59543
59924
  );
@@ -59545,16 +59926,28 @@ async function setupSolana() {
59545
59926
  const mnemonic = generateWalletMnemonic();
59546
59927
  const solanaKeyBytes = deriveSolanaKeyBytes(mnemonic);
59547
59928
  await saveMnemonic(mnemonic);
59929
+ await writeCoreFileIfMissing(
59930
+ CORE_SOLANA_WALLET_FILE,
59931
+ JSON.stringify([...solanaSecretKeyFromSeed(solanaKeyBytes)]) + "\n"
59932
+ );
59548
59933
  console.log(`[ClawRouter] Solana wallet set up successfully.`);
59549
- console.log(`[ClawRouter] Mnemonic saved to ${MNEMONIC_FILE}`);
59934
+ console.log(`[ClawRouter] Solana key saved to ${CORE_SOLANA_WALLET_FILE}`);
59935
+ console.log(`[ClawRouter] Recovery mnemonic saved to ${MNEMONIC_FILE}`);
59550
59936
  console.log(`[ClawRouter] Existing EVM wallet unchanged.`);
59551
59937
  return { mnemonic, solanaPrivateKeyBytes: solanaKeyBytes };
59552
59938
  }
59553
59939
  async function savePaymentChain(chain3) {
59554
59940
  await mkdir2(WALLET_DIR2, { recursive: true });
59555
- await writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 });
59941
+ await mkdir2(CORE_WALLET_DIR, { recursive: true });
59942
+ await Promise.all([
59943
+ writeFile(CHAIN_FILE, chain3 + "\n", { mode: 384 }),
59944
+ writeFile(CORE_CHAIN_FILE, chain3 + "\n", { mode: 384 })
59945
+ ]);
59556
59946
  }
59557
59947
  async function loadPaymentChain() {
59948
+ const core = await readOptional(CORE_CHAIN_FILE);
59949
+ if (core === "solana") return "solana";
59950
+ if (core === "base") return "base";
59558
59951
  try {
59559
59952
  const content = (await readTextFile(CHAIN_FILE)).trim();
59560
59953
  if (content === "solana") return "solana";
@@ -59568,17 +59961,22 @@ async function resolvePaymentChain() {
59568
59961
  if (process["env"].CLAWROUTER_PAYMENT_CHAIN === "base") return "base";
59569
59962
  return loadPaymentChain();
59570
59963
  }
59571
- var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE;
59964
+ var WALLET_DIR2, WALLET_FILE, MNEMONIC_FILE, CHAIN_FILE, CORE_WALLET_DIR, CORE_WALLET_FILE, CORE_SOLANA_WALLET_FILE, CORE_CHAIN_FILE;
59572
59965
  var init_auth = __esm({
59573
59966
  "src/auth.ts"() {
59574
59967
  "use strict";
59575
59968
  init_fs_read();
59969
+ init_esm7();
59576
59970
  init_accounts();
59577
59971
  init_wallet2();
59578
59972
  WALLET_DIR2 = join7(homedir4(), ".openclaw", "blockrun");
59579
59973
  WALLET_FILE = join7(WALLET_DIR2, "wallet.key");
59580
59974
  MNEMONIC_FILE = join7(WALLET_DIR2, "mnemonic");
59581
59975
  CHAIN_FILE = join7(WALLET_DIR2, "payment-chain");
59976
+ CORE_WALLET_DIR = join7(homedir4(), ".blockrun");
59977
+ CORE_WALLET_FILE = join7(CORE_WALLET_DIR, ".session");
59978
+ CORE_SOLANA_WALLET_FILE = join7(CORE_WALLET_DIR, ".solana-session");
59979
+ CORE_CHAIN_FILE = join7(CORE_WALLET_DIR, ".chain");
59582
59980
  }
59583
59981
  });
59584
59982
 
@@ -75731,7 +76129,7 @@ var require_snapshot_recorder = __commonJS({
75731
76129
  "node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
75732
76130
  "use strict";
75733
76131
  var { writeFile: writeFile3, readFile: readFile3, mkdir: mkdir5 } = __require("fs/promises");
75734
- var { dirname: dirname5, resolve } = __require("path");
76132
+ var { dirname: dirname4, resolve } = __require("path");
75735
76133
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
75736
76134
  var { InvalidArgumentError, UndiciError } = require_errors();
75737
76135
  var { hashId, isUrlExcludedFactory, normalizeHeaders: normalizeHeaders3, createHeaderFilters } = require_snapshot_utils();
@@ -75977,7 +76375,7 @@ var require_snapshot_recorder = __commonJS({
75977
76375
  throw new InvalidArgumentError("Snapshot path is required");
75978
76376
  }
75979
76377
  const resolvedPath = resolve(path5);
75980
- await mkdir5(dirname5(resolvedPath), { recursive: true });
76378
+ await mkdir5(dirname4(resolvedPath), { recursive: true });
75981
76379
  const data = Array.from(this.#snapshots.entries()).map(([hash5, snapshot]) => ({
75982
76380
  hash: hash5,
75983
76381
  snapshot
@@ -90053,6 +90451,7 @@ var init_client3 = __esm({
90053
90451
 
90054
90452
  // src/proxy.ts
90055
90453
  import { AsyncLocalStorage } from "async_hooks";
90454
+ import { createHmac } from "crypto";
90056
90455
  import { createServer } from "http";
90057
90456
  import { finished } from "stream";
90058
90457
  import { homedir as homedir7 } from "os";
@@ -90678,12 +91077,25 @@ function buildProxyModelList(createdAt = Math.floor(Date.now() / 1e3)) {
90678
91077
  if (seen.has(model.id)) return false;
90679
91078
  seen.add(model.id);
90680
91079
  return true;
90681
- }).map((model) => ({
90682
- id: model.id,
90683
- object: "model",
90684
- created: createdAt,
90685
- owned_by: model.id.includes("/") ? model.id.split("/")[0] ?? "blockrun" : "blockrun"
90686
- }));
91080
+ }).map((model) => {
91081
+ const targetId = MODEL_ALIASES[model.id] ?? model.id;
91082
+ const canonical = BLOCKRUN_MODELS.find((entry) => entry.id === targetId);
91083
+ return {
91084
+ id: model.id,
91085
+ object: "model",
91086
+ created: createdAt,
91087
+ owned_by: targetId.includes("/") ? targetId.split("/")[0] ?? "blockrun" : "blockrun",
91088
+ name: model.name,
91089
+ context_window: model.contextWindow,
91090
+ max_output: model.maxTokens,
91091
+ input_price: model.cost.input,
91092
+ output_price: model.cost.output,
91093
+ reasoning: model.reasoning,
91094
+ vision: model.input.includes("image"),
91095
+ agentic: canonical?.agentic ?? false,
91096
+ tool_calling: canonical?.toolCalling ?? false
91097
+ };
91098
+ });
90687
91099
  }
90688
91100
  function mergeRoutingConfig(overrides) {
90689
91101
  if (!overrides) return DEFAULT_ROUTING_CONFIG;
@@ -90923,7 +91335,7 @@ async function startProxy(options) {
90923
91335
  }
90924
91336
  void loadGatewayCatalog(apiBase);
90925
91337
  const listenPort = options.port ?? getProxyPort();
90926
- const existingProxy = await checkExistingProxy(listenPort);
91338
+ const existingProxy = options.allowExistingProxy === false ? void 0 : await checkExistingProxy(listenPort);
90927
91339
  if (existingProxy) {
90928
91340
  const account2 = privateKeyToAccount(walletKey);
90929
91341
  const baseUrl2 = `http://127.0.0.1:${listenPort}`;
@@ -91078,7 +91490,22 @@ async function startProxy(options) {
91078
91490
  response.balanceError = "Could not fetch balance";
91079
91491
  }
91080
91492
  }
91081
- res.writeHead(200, { "Content-Type": "application/json" });
91493
+ const headers = {
91494
+ "Content-Type": "application/json",
91495
+ "Cache-Control": "no-store"
91496
+ };
91497
+ const challengeValue = req.headers["x-clawrouter-challenge"];
91498
+ const challenge2 = Array.isArray(challengeValue) ? challengeValue[0] : challengeValue;
91499
+ if (challenge2 && /^[a-f0-9]{64}$/i.test(challenge2)) {
91500
+ try {
91501
+ const token = readFileSync2(DESKTOP_SERVICE_TOKEN_FILE, "utf8").trim();
91502
+ if (/^[a-f0-9]{64}$/i.test(token)) {
91503
+ headers["X-ClawRouter-Proof"] = createHmac("sha256", token).update(challenge2).digest("hex");
91504
+ }
91505
+ } catch {
91506
+ }
91507
+ }
91508
+ res.writeHead(200, headers);
91082
91509
  res.end(JSON.stringify(response));
91083
91510
  return;
91084
91511
  }
@@ -91947,6 +92374,10 @@ async function startProxy(options) {
91947
92374
  const onError = async (err) => {
91948
92375
  server.removeListener("error", onError);
91949
92376
  if (err.code === "EADDRINUSE") {
92377
+ if (options.allowExistingProxy === false) {
92378
+ rejectAttempt(err);
92379
+ return;
92380
+ }
91950
92381
  const existingProxy2 = await checkExistingProxy(listenPort);
91951
92382
  if (existingProxy2) {
91952
92383
  console.log(`[ClawRouter] Existing proxy detected on port ${listenPort}, reusing`);
@@ -94351,7 +94782,7 @@ data: [DONE]
94351
94782
  });
94352
94783
  }
94353
94784
  }
94354
- var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, gatewayModelIds, FREE_MODEL, FREE_UPSTREAM_OVERRIDES, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, GATEWAY_CATALOG_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
94785
+ var paymentStore, BLOCKRUN_API, BLOCKRUN_SOLANA_API, DESKTOP_SERVICE_TOKEN_FILE, IMAGE_DIR, AUDIO_DIR, VIDEO_DIR, AUTO_MODEL, ROUTING_PROFILES, FREE_MODELS, gatewayModelIds, FREE_MODEL, FREE_UPSTREAM_OVERRIDES, MAX_MESSAGES, CONTEXT_LIMIT_KB, HEARTBEAT_INTERVAL_MS, BALANCE_CHECK_TIMEOUT_MS, GATEWAY_CATALOG_TIMEOUT_MS, DEFAULT_REQUEST_TIMEOUT_MS, PER_MODEL_TIMEOUT_MS, REASONING_MODEL_TIMEOUT_MS, REASONING_MODEL_IDS, MAX_FALLBACK_ATTEMPTS, HEALTH_CHECK_TIMEOUT_MS, RATE_LIMIT_COOLDOWN_MS, OVERLOAD_COOLDOWN_MS, PORT_RETRY_ATTEMPTS, PORT_RETRY_DELAY_MS, MODEL_BODY_READ_TIMEOUT_MS, ERROR_BODY_READ_TIMEOUT_MS, ClientDisconnectedError, rateLimitedModels, overloadedModels, perProviderErrors, BALANCE_CHECK_BUFFER, BALANCE_PREFLIGHT_OUTPUT_TOKEN_CAP, PROVIDER_ERROR_PATTERNS, DEGRADED_RESPONSE_PATTERNS, DEGRADED_LOOP_PATTERNS, VALID_ROLES, ROLE_MAPPINGS, VALID_TOOL_ID_PATTERN, KIMI_BLOCK_RE, KIMI_TOKEN_RE, THINKING_TAG_RE, THINKING_BLOCK_RE, BLOCKRUN_MODEL_BY_ID, IMAGE_PRICING, IMAGE_MODEL_IDS, IMAGE_MODEL_SIZES, IMAGE_MODEL_ALIASES, VIDEO_PRICING, PHONE_PRICING;
94355
94786
  var init_proxy = __esm({
94356
94787
  "src/proxy.ts"() {
94357
94788
  "use strict";
@@ -94389,6 +94820,7 @@ var init_proxy = __esm({
94389
94820
  paymentStore = new AsyncLocalStorage();
94390
94821
  BLOCKRUN_API = "https://blockrun.ai/api";
94391
94822
  BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
94823
+ DESKTOP_SERVICE_TOKEN_FILE = process.env.CLAWROUTER_DESKTOP_TOKEN_FILE ?? join10(homedir7(), ".clawrouter-desktop", "service-token");
94392
94824
  IMAGE_DIR = join10(homedir7(), ".openclaw", "blockrun", "images");
94393
94825
  AUDIO_DIR = join10(homedir7(), ".openclaw", "blockrun", "audio");
94394
94826
  VIDEO_DIR = join10(homedir7(), ".openclaw", "blockrun", "videos");
@@ -95597,6 +96029,210 @@ var init_partners = __esm({
95597
96029
  }
95598
96030
  });
95599
96031
 
96032
+ // src/commands/policy.ts
96033
+ function unsetMeaning(key2) {
96034
+ switch (key2) {
96035
+ case "allowedPayees":
96036
+ return "every payee is permitted";
96037
+ case "allowedNetworks":
96038
+ return "every network is permitted";
96039
+ case "allowedAssets":
96040
+ return "every asset is permitted";
96041
+ case "blockedPayees":
96042
+ return "no payee is blocked";
96043
+ default:
96044
+ return `spend in the ${key2} window is uncapped`;
96045
+ }
96046
+ }
96047
+ function fail(text) {
96048
+ return { text, isError: true };
96049
+ }
96050
+ function isPolicyList2(v) {
96051
+ return POLICY_LISTS.includes(v);
96052
+ }
96053
+ function isSpendWindow(v) {
96054
+ return SPEND_WINDOWS.includes(v);
96055
+ }
96056
+ function isListAction(v) {
96057
+ return LIST_ACTIONS.includes(v);
96058
+ }
96059
+ function rejectValue(list, value) {
96060
+ if (list === "allowedNetworks") {
96061
+ 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`;
96062
+ }
96063
+ if (/^0x/i.test(value)) {
96064
+ return EVM_ADDRESS2.test(value) ? void 0 : `"${value}" starts with 0x but is not 0x followed by exactly 40 hex characters`;
96065
+ }
96066
+ 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)`;
96067
+ }
96068
+ function parsePolicyArgs(argv) {
96069
+ const [sub = "", target = "", ...values] = argv;
96070
+ const action = sub.toLowerCase();
96071
+ if (action === "") return { kind: "show" };
96072
+ if (action === "limit") {
96073
+ if (!isSpendWindow(target)) {
96074
+ return fail(
96075
+ `Unknown window "${target}"; expected one of: ${SPEND_WINDOWS.join(", ")}
96076
+ ${USAGE}`
96077
+ );
96078
+ }
96079
+ const raw = values[0];
96080
+ if (raw === void 0 || values.length !== 1) {
96081
+ return fail(`policy limit takes exactly one amount (or "clear")
96082
+ ${USAGE}`);
96083
+ }
96084
+ if (raw === "clear") return { kind: "limit", window: target, usd: void 0 };
96085
+ const usd = Number(raw);
96086
+ if (!USD.test(raw) || !Number.isFinite(usd) || usd <= 0) {
96087
+ return fail(
96088
+ `Rejected amount "${raw}": must be a positive decimal USD value such as 0.10 or 5`
96089
+ );
96090
+ }
96091
+ return { kind: "limit", window: target, usd };
96092
+ }
96093
+ if (!isListAction(action)) return fail(`Unknown subcommand "${sub}"
96094
+ ${USAGE}`);
96095
+ if (!isPolicyList2(target)) {
96096
+ return fail(`Unknown list "${target}"; expected one of: ${POLICY_LISTS.join(", ")}
96097
+ ${USAGE}`);
96098
+ }
96099
+ if (action === "clear" ? values.length !== 0 : values.length === 0) {
96100
+ return fail(
96101
+ `policy ${action} <list> ${action === "clear" ? "takes no values" : "needs at least one value"}
96102
+ ${USAGE}`
96103
+ );
96104
+ }
96105
+ for (const v of values) {
96106
+ const why = rejectValue(target, v);
96107
+ if (why !== void 0) return fail(`Rejected ${target} entry: ${why}`);
96108
+ }
96109
+ return { kind: "list", action, list: target, values };
96110
+ }
96111
+ function nextListValue(current, plan) {
96112
+ const have = current ?? [];
96113
+ const wanted = [...new Set(plan.values.map(normalizePayee))];
96114
+ switch (plan.action) {
96115
+ case "set":
96116
+ return { next: wanted };
96117
+ case "clear":
96118
+ return { next: void 0 };
96119
+ case "add":
96120
+ return { next: [.../* @__PURE__ */ new Set([...have, ...wanted])] };
96121
+ case "remove": {
96122
+ if (have.length === 0) return { reject: `${plan.list} is not configured; nothing to remove` };
96123
+ const missing = wanted.filter((v) => !have.includes(v));
96124
+ if (missing.length > 0) return { reject: `not in ${plan.list}: ${missing.join(", ")}` };
96125
+ const next = have.filter((v) => !wanted.includes(v));
96126
+ if (next.length === 0 && ALLOW_LISTS.includes(plan.list)) {
96127
+ return {
96128
+ 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`
96129
+ };
96130
+ }
96131
+ return { next: next.length > 0 ? next : void 0 };
96132
+ }
96133
+ }
96134
+ }
96135
+ function formatPolicy(limits) {
96136
+ const lines = ["Spend limits (USD):"];
96137
+ for (const w of SPEND_WINDOWS) {
96138
+ const v = limits[w];
96139
+ lines.push(` ${w}: ${v === void 0 ? `(unset \u2014 ${unsetMeaning(w)})` : `$${v}`}`);
96140
+ }
96141
+ lines.push("Policy lists:");
96142
+ for (const l2 of POLICY_LISTS) {
96143
+ const v = limits[l2];
96144
+ lines.push(` ${l2}: ${v && v.length > 0 ? v.join(", ") : `(unset \u2014 ${unsetMeaning(l2)})`}`);
96145
+ }
96146
+ return lines.join("\n");
96147
+ }
96148
+ function runPolicyCommand(argv, options) {
96149
+ const plan = parsePolicyArgs(argv);
96150
+ if (!("kind" in plan)) return plan;
96151
+ const openControl = options?.openControl ?? (() => new SpendControl());
96152
+ const live = options?.liveControl?.();
96153
+ const control = live ?? openControl();
96154
+ const broken = control.getPolicyFileError();
96155
+ if (broken !== void 0) {
96156
+ return fail(`${broken}
96157
+ Nothing was written; repair or delete spending.json, then retry.`);
96158
+ }
96159
+ if (plan.kind === "show") return { text: formatPolicy(control.getLimits()) };
96160
+ const before = openControl().getLimits();
96161
+ const key2 = plan.kind === "limit" ? plan.window : plan.list;
96162
+ let expected;
96163
+ try {
96164
+ if (plan.kind === "limit") {
96165
+ expected = plan.usd;
96166
+ if (plan.usd === void 0) control.clearLimit(plan.window);
96167
+ else control.setLimit(plan.window, plan.usd);
96168
+ } else {
96169
+ const outcome = nextListValue(control.getLimits()[plan.list], plan);
96170
+ if ("reject" in outcome) return fail(`${outcome.reject}; nothing written`);
96171
+ expected = outcome.next;
96172
+ if (outcome.next === void 0) control.clearPolicy(plan.list);
96173
+ else control.setPolicy(plan.list, outcome.next);
96174
+ }
96175
+ } catch (err) {
96176
+ if (err instanceof SpendPolicyConflictError) {
96177
+ return fail(
96178
+ `${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`
96179
+ );
96180
+ }
96181
+ return fail(`Nothing was written: ${err instanceof Error ? err.message : String(err)}`);
96182
+ }
96183
+ const expectedAll = { ...before };
96184
+ if (expected === void 0) delete expectedAll[key2];
96185
+ else expectedAll[key2] = expected;
96186
+ const after = openControl().getLimits();
96187
+ const keys = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after), key2])];
96188
+ const drift = keys.filter((k) => JSON.stringify(after[k]) !== JSON.stringify(expectedAll[k]));
96189
+ if (drift.length > 0) {
96190
+ const show = (v) => v === void 0 ? "(unset)" : JSON.stringify(v);
96191
+ const detail = drift.map((k) => `${k} ${show(after[k])} vs ${show(expectedAll[k])}`).join("; ");
96192
+ return fail(
96193
+ `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`
96194
+ );
96195
+ }
96196
+ const headline = expected === void 0 ? `${key2} is now unset \u2014 ${unsetMeaning(key2)}.` : `${key2}: ${JSON.stringify(expected)}`;
96197
+ return {
96198
+ text: live ? `${headline}
96199
+ ${APPLIED_LIVE}` : `${RESTART_REQUIRED}
96200
+ ${headline}`
96201
+ };
96202
+ }
96203
+ function createPolicyCommand(options) {
96204
+ return {
96205
+ name: "policy",
96206
+ description: "Spend limits and counterparty policy \u2014 /policy [set|add|remove|clear <list> ...] [limit <window> <usd>|clear]",
96207
+ acceptsArgs: true,
96208
+ requireAuth: true,
96209
+ handler: async (ctx) => runPolicyCommand((ctx.args ?? "").trim().split(/\s+/).filter(Boolean), options)
96210
+ };
96211
+ }
96212
+ var SPEND_WINDOWS, USD, EVM_ADDRESS2, BASE58_ADDRESS, LIST_ACTIONS, ALLOW_LISTS, USAGE, RESTART_REQUIRED, APPLIED_LIVE;
96213
+ var init_policy = __esm({
96214
+ "src/commands/policy.ts"() {
96215
+ "use strict";
96216
+ init_spend_control();
96217
+ SPEND_WINDOWS = ["perRequest", "hourly", "daily", "session"];
96218
+ USD = /^\d+(\.\d+)?$/;
96219
+ EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/;
96220
+ BASE58_ADDRESS = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
96221
+ LIST_ACTIONS = ["set", "add", "remove", "clear"];
96222
+ ALLOW_LISTS = ["allowedPayees", "allowedNetworks", "allowedAssets"];
96223
+ USAGE = [
96224
+ "Usage:",
96225
+ " policy show limits and lists on disk",
96226
+ ` policy set|add|remove <list> <v>... <list>: ${POLICY_LISTS.join(" | ")}`,
96227
+ " policy clear <list>",
96228
+ ` policy limit <window> <usd>|clear <window>: ${SPEND_WINDOWS.join(" | ")}`,
96229
+ `Networks are CAIP-2 ids: ${CAIP2_BASE} (Base) or ${CAIP2_SOLANA_MAINNET} (Solana mainnet).`
96230
+ ].join("\n");
96231
+ 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.";
96232
+ APPLIED_LIVE = "Applied to the running proxy and saved to spending.json.";
96233
+ }
96234
+ });
96235
+
95600
96236
  // src/provider.ts
95601
96237
  function setActiveProxy(proxy) {
95602
96238
  activeProxy = proxy;
@@ -95628,8 +96264,8 @@ var init_provider = __esm({
95628
96264
  return buildProviderModels(`http://127.0.0.1:${port}/v1`);
95629
96265
  },
95630
96266
  // No auth required — the x402 proxy handles wallet-based payments internally.
95631
- // The proxy auto-generates a wallet on first run and stores it at
95632
- // ~/.openclaw/blockrun/wallet.key. Users just fund that wallet with USDC.
96267
+ // The proxy uses the shared BlockRun Core wallet under ~/.blockrun, with
96268
+ // automatic non-destructive migration from older ClawRouter wallet files.
95633
96269
  auth: []
95634
96270
  };
95635
96271
  }
@@ -109014,7 +109650,7 @@ var init_URLSearchParams = __esm({
109014
109650
 
109015
109651
  // node_modules/axios/lib/platform/node/index.js
109016
109652
  import crypto6 from "crypto";
109017
- var ALPHA, DIGIT, ALPHABET, generateString, node_default;
109653
+ var ALPHA, DIGIT, ALPHABET2, generateString, node_default;
109018
109654
  var init_node2 = __esm({
109019
109655
  "node_modules/axios/lib/platform/node/index.js"() {
109020
109656
  "use strict";
@@ -109022,12 +109658,12 @@ var init_node2 = __esm({
109022
109658
  init_FormData();
109023
109659
  ALPHA = "abcdefghijklmnopqrstuvwxyz";
109024
109660
  DIGIT = "0123456789";
109025
- ALPHABET = {
109661
+ ALPHABET2 = {
109026
109662
  DIGIT,
109027
109663
  ALPHA,
109028
109664
  ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT
109029
109665
  };
109030
- generateString = (size5 = 16, alphabet4 = ALPHABET.ALPHA_DIGIT) => {
109666
+ generateString = (size5 = 16, alphabet4 = ALPHABET2.ALPHA_DIGIT) => {
109031
109667
  let str = "";
109032
109668
  const { length } = alphabet4;
109033
109669
  const randomValues = new Uint32Array(size5);
@@ -109044,7 +109680,7 @@ var init_node2 = __esm({
109044
109680
  FormData: FormData_default,
109045
109681
  Blob: typeof Blob !== "undefined" && Blob || null
109046
109682
  },
109047
- ALPHABET,
109683
+ ALPHABET: ALPHABET2,
109048
109684
  generateString,
109049
109685
  protocols: ["http", "https", "file", "data"]
109050
109686
  };
@@ -111108,8 +111744,8 @@ var require_follow_redirects = __commonJS({
111108
111744
  }
111109
111745
  return parsed;
111110
111746
  }
111111
- function resolveUrl(relative, base3) {
111112
- return useNativeURL ? new URL3(relative, base3) : parseUrl3(url2.resolve(base3, relative));
111747
+ function resolveUrl(relative, base4) {
111748
+ return useNativeURL ? new URL3(relative, base4) : parseUrl3(url2.resolve(base4, relative));
111113
111749
  }
111114
111750
  function validateUrl(input) {
111115
111751
  if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
@@ -117920,7 +118556,7 @@ function __addDisposableResource(env, value, async) {
117920
118556
  return value;
117921
118557
  }
117922
118558
  function __disposeResources(env) {
117923
- function fail(e7) {
118559
+ function fail2(e7) {
117924
118560
  env.error = env.hasError ? new _SuppressedError(e7, env.error, "An error was suppressed during disposal.") : e7;
117925
118561
  env.hasError = true;
117926
118562
  }
@@ -117932,12 +118568,12 @@ function __disposeResources(env) {
117932
118568
  if (r2.dispose) {
117933
118569
  var result = r2.dispose.call(r2.value);
117934
118570
  if (r2.async) return s3 |= 2, Promise.resolve(result).then(next, function(e7) {
117935
- fail(e7);
118571
+ fail2(e7);
117936
118572
  return next();
117937
118573
  });
117938
118574
  } else s3 |= 1;
117939
118575
  } catch (e7) {
117940
- fail(e7);
118576
+ fail2(e7);
117941
118577
  }
117942
118578
  }
117943
118579
  if (s3 === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
@@ -125107,15 +125743,15 @@ var require_curve = __commonJS({
125107
125743
  const { windows, windowSize } = calcWOpts4(W, bits);
125108
125744
  const points = [];
125109
125745
  let p = elm;
125110
- let base3 = p;
125746
+ let base4 = p;
125111
125747
  for (let window2 = 0; window2 < windows; window2++) {
125112
- base3 = p;
125113
- points.push(base3);
125748
+ base4 = p;
125749
+ points.push(base4);
125114
125750
  for (let i = 1; i < windowSize; i++) {
125115
- base3 = base3.add(p);
125116
- points.push(base3);
125751
+ base4 = base4.add(p);
125752
+ points.push(base4);
125117
125753
  }
125118
- p = base3.double();
125754
+ p = base4.double();
125119
125755
  }
125120
125756
  return points;
125121
125757
  },
@@ -127873,7 +128509,7 @@ var require_estimateFeesPerGas = __commonJS({
127873
128509
  throw new fee_js_1.BaseFeeScalarError();
127874
128510
  const decimals = baseFeeMultiplier.toString().split(".")[1]?.length ?? 0;
127875
128511
  const denominator = 10 ** decimals;
127876
- const multiply = (base3) => base3 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
128512
+ const multiply = (base4) => base4 * BigInt(Math.round(baseFeeMultiplier * denominator)) / BigInt(denominator);
127877
128513
  const block = block_ ? block_ : await (0, getAction_js_1.getAction)(client, getBlock_js_1.getBlock, "getBlock")({});
127878
128514
  if (typeof chain3?.fees?.estimateFeesPerGas === "function") {
127879
128515
  const fees = await chain3.fees.estimateFeesPerGas({
@@ -128383,7 +129019,7 @@ var require_fillTransaction = __commonJS({
128383
129019
  throw new fee_js_1.BaseFeeScalarError();
128384
129020
  const decimals = feeMultiplier.toString().split(".")[1]?.length ?? 0;
128385
129021
  const denominator = 10 ** decimals;
128386
- const multiplyFee = (base3) => base3 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
129022
+ const multiplyFee = (base4) => base4 * BigInt(Math.round(feeMultiplier * denominator)) / BigInt(denominator);
128387
129023
  if (!transaction.feePayerSignature) {
128388
129024
  if (transaction.maxFeePerGas && !parameters.maxFeePerGas)
128389
129025
  transaction.maxFeePerGas = multiplyFee(transaction.maxFeePerGas);
@@ -133141,17 +133777,17 @@ var require_call = __commonJS({
133141
133777
  }
133142
133778
  }
133143
133779
  const params = (() => {
133144
- const base3 = [
133780
+ const base4 = [
133145
133781
  request2,
133146
133782
  block
133147
133783
  ];
133148
133784
  if (rpcStateOverride && rpcBlockOverrides)
133149
- return [...base3, rpcStateOverride, rpcBlockOverrides];
133785
+ return [...base4, rpcStateOverride, rpcBlockOverrides];
133150
133786
  if (rpcStateOverride)
133151
- return [...base3, rpcStateOverride];
133787
+ return [...base4, rpcStateOverride];
133152
133788
  if (rpcBlockOverrides)
133153
- return [...base3, {}, rpcBlockOverrides];
133154
- return base3;
133789
+ return [...base4, {}, rpcBlockOverrides];
133790
+ return base4;
133155
133791
  })();
133156
133792
  const response = await client.request({
133157
133793
  method: "eth_call",
@@ -134763,14 +135399,14 @@ var require_createClient = __commonJS({
134763
135399
  uid: (0, uid_js_1.uid)(),
134764
135400
  ...experimental_blockTag ? { experimental_blockTag } : {}
134765
135401
  };
134766
- function extend2(base3) {
135402
+ function extend2(base4) {
134767
135403
  return (extendFn) => {
134768
- const extended = extendFn(base3);
135404
+ const extended = extendFn(base4);
134769
135405
  for (const key3 in client)
134770
135406
  delete extended[key3];
134771
- const combined = { ...base3, ...extended };
135407
+ const combined = { ...base4, ...extended };
134772
135408
  for (const key3 in extended) {
134773
- const a = base3[key3];
135409
+ const a = base4[key3];
134774
135410
  const b = extended[key3];
134775
135411
  if (isPlainObject4(a) && isPlainObject4(b))
134776
135412
  combined[key3] = { ...a, ...b };
@@ -136788,10 +137424,10 @@ var require_defineChain = __commonJS({
136788
137424
  serializers: void 0,
136789
137425
  ...chain3
136790
137426
  };
136791
- function extend2(base3) {
137427
+ function extend2(base4) {
136792
137428
  return (fnOrExtended) => {
136793
- const properties = typeof fnOrExtended === "function" ? fnOrExtended(base3) : fnOrExtended;
136794
- const combined = { ...base3, ...properties };
137429
+ const properties = typeof fnOrExtended === "function" ? fnOrExtended(base4) : fnOrExtended;
137430
+ const combined = { ...base4, ...properties };
136795
137431
  return Object.assign(combined, { extend: extend2(combined) });
136796
137432
  };
136797
137433
  }
@@ -138126,9 +138762,9 @@ var require_typedData2 = __commonJS({
138126
138762
  throw new typedData_js_1.InvalidTypedDataTypeError({ type });
138127
138763
  const integerMatch = type.match(regex_js_1.integerRegex);
138128
138764
  if (integerMatch && (typeof value === "number" || typeof value === "bigint")) {
138129
- const [_type, base3, size_] = integerMatch;
138765
+ const [_type, base4, size_] = integerMatch;
138130
138766
  (0, toHex_js_1.numberToHex)(value, {
138131
- signed: base3 === "int",
138767
+ signed: base4 === "int",
138132
138768
  size: Number.parseInt(size_, 10) / 8
138133
138769
  });
138134
138770
  }
@@ -141920,15 +142556,15 @@ var require_curve2 = __commonJS({
141920
142556
  const { windows, windowSize } = calcWOpts4(W, bits);
141921
142557
  const points = [];
141922
142558
  let p = elm;
141923
- let base3 = p;
142559
+ let base4 = p;
141924
142560
  for (let window2 = 0; window2 < windows; window2++) {
141925
- base3 = p;
141926
- points.push(base3);
142561
+ base4 = p;
142562
+ points.push(base4);
141927
142563
  for (let i = 1; i < windowSize; i++) {
141928
- base3 = base3.add(p);
141929
- points.push(base3);
142564
+ base4 = base4.add(p);
142565
+ points.push(base4);
141930
142566
  }
141931
- p = base3.double();
142567
+ p = base4.double();
141932
142568
  }
141933
142569
  return points;
141934
142570
  },
@@ -175441,14 +176077,14 @@ var require_Authenticator = __commonJS({
175441
176077
  const rpIdHash = Hash4.sha256(Hex.fromString(rpId));
175442
176078
  const flag_bytes = Hex.fromNumber(flag, { size: 1 });
175443
176079
  const signCount_bytes = Hex.fromNumber(signCount, { size: 4 });
175444
- const base3 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
176080
+ const base4 = Hex.concat(rpIdHash, flag_bytes, signCount_bytes);
175445
176081
  if (!credential)
175446
- return base3;
176082
+ return base4;
175447
176083
  const aaguid = Hex.fromBytes(new Uint8Array(16));
175448
176084
  const credentialId = Hex.fromBytes(credential.id);
175449
176085
  const credIdLen = Hex.fromNumber(credential.id.length, { size: 2 });
175450
176086
  const coseKey = CoseKey.fromPublicKey(credential.publicKey);
175451
- return Hex.concat(base3, aaguid, credIdLen, credentialId, coseKey);
176087
+ return Hex.concat(base4, aaguid, credIdLen, credentialId, coseKey);
175452
176088
  }
175453
176089
  function getSignCount(authenticatorData) {
175454
176090
  const bytes = Bytes.fromHex(authenticatorData);
@@ -179356,7 +179992,7 @@ var require_VirtualMaster = __commonJS({
179356
179992
  terminateAll();
179357
179993
  resolve(result);
179358
179994
  };
179359
- const fail = (error) => {
179995
+ const fail2 = (error) => {
179360
179996
  if (settled)
179361
179997
  return;
179362
179998
  settled = true;
@@ -179381,14 +180017,14 @@ var require_VirtualMaster = __commonJS({
179381
180017
  succeed(void 0);
179382
180018
  return;
179383
180019
  case "error":
179384
- fail(new Errors.BaseError(msg.message));
180020
+ fail2(new Errors.BaseError(msg.message));
179385
180021
  return;
179386
180022
  }
179387
180023
  };
179388
- const onAbort = () => fail(getAbortError2(value.signal));
180024
+ const onAbort = () => fail2(getAbortError2(value.signal));
179389
180025
  value.signal?.addEventListener("abort", onAbort, { once: true });
179390
180026
  for (let i = 0; i < value.workerCount; i++) {
179391
- const handle = value.pool.spawn(i, onMessage, fail);
180027
+ const handle = value.pool.spawn(i, onMessage, fail2);
179392
180028
  handles.push(handle);
179393
180029
  handle.postMessage({
179394
180030
  type: "start",
@@ -179532,8 +180168,8 @@ var require_ZoneId = __commonJS({
179532
180168
  return chainId - getChainIdConfig(sourceId2).base;
179533
180169
  }
179534
180170
  function toChainId(zoneId, sourceId2 = defaultSourceId) {
179535
- const { base: base3, range } = getChainIdConfig(sourceId2);
179536
- return base3 + zoneId % range;
180171
+ const { base: base4, range } = getChainIdConfig(sourceId2);
180172
+ return base4 + zoneId % range;
179537
180173
  }
179538
180174
  var UnsupportedSourceIdError = class extends Errors.BaseError {
179539
180175
  constructor({ sourceId: sourceId2 }) {
@@ -193139,7 +193775,7 @@ var require_bn = __commonJS({
193139
193775
  ctor.prototype = new TempCtor();
193140
193776
  ctor.prototype.constructor = ctor;
193141
193777
  }
193142
- function BN3(number, base3, endian) {
193778
+ function BN3(number, base4, endian) {
193143
193779
  if (BN3.isBN(number)) {
193144
193780
  return number;
193145
193781
  }
@@ -193148,11 +193784,11 @@ var require_bn = __commonJS({
193148
193784
  this.length = 0;
193149
193785
  this.red = null;
193150
193786
  if (number !== null) {
193151
- if (base3 === "le" || base3 === "be") {
193152
- endian = base3;
193153
- base3 = 10;
193787
+ if (base4 === "le" || base4 === "be") {
193788
+ endian = base4;
193789
+ base4 = 10;
193154
193790
  }
193155
- this._init(number || 0, base3 || 10, endian || "be");
193791
+ this._init(number || 0, base4 || 10, endian || "be");
193156
193792
  }
193157
193793
  }
193158
193794
  if (typeof module2 === "object") {
@@ -193185,17 +193821,17 @@ var require_bn = __commonJS({
193185
193821
  if (left.cmp(right) < 0) return left;
193186
193822
  return right;
193187
193823
  };
193188
- BN3.prototype._init = function init2(number, base3, endian) {
193824
+ BN3.prototype._init = function init2(number, base4, endian) {
193189
193825
  if (typeof number === "number") {
193190
- return this._initNumber(number, base3, endian);
193826
+ return this._initNumber(number, base4, endian);
193191
193827
  }
193192
193828
  if (typeof number === "object") {
193193
- return this._initArray(number, base3, endian);
193829
+ return this._initArray(number, base4, endian);
193194
193830
  }
193195
- if (base3 === "hex") {
193196
- base3 = 16;
193831
+ if (base4 === "hex") {
193832
+ base4 = 16;
193197
193833
  }
193198
- assert10(base3 === (base3 | 0) && base3 >= 2 && base3 <= 36);
193834
+ assert10(base4 === (base4 | 0) && base4 >= 2 && base4 <= 36);
193199
193835
  number = number.toString().replace(/\s+/g, "");
193200
193836
  var start = 0;
193201
193837
  if (number[0] === "-") {
@@ -193203,17 +193839,17 @@ var require_bn = __commonJS({
193203
193839
  this.negative = 1;
193204
193840
  }
193205
193841
  if (start < number.length) {
193206
- if (base3 === 16) {
193842
+ if (base4 === 16) {
193207
193843
  this._parseHex(number, start, endian);
193208
193844
  } else {
193209
- this._parseBase(number, base3, start);
193845
+ this._parseBase(number, base4, start);
193210
193846
  if (endian === "le") {
193211
- this._initArray(this.toArray(), base3, endian);
193847
+ this._initArray(this.toArray(), base4, endian);
193212
193848
  }
193213
193849
  }
193214
193850
  }
193215
193851
  };
193216
- BN3.prototype._initNumber = function _initNumber(number, base3, endian) {
193852
+ BN3.prototype._initNumber = function _initNumber(number, base4, endian) {
193217
193853
  if (number < 0) {
193218
193854
  this.negative = 1;
193219
193855
  number = -number;
@@ -193237,9 +193873,9 @@ var require_bn = __commonJS({
193237
193873
  this.length = 3;
193238
193874
  }
193239
193875
  if (endian !== "le") return;
193240
- this._initArray(this.toArray(), base3, endian);
193876
+ this._initArray(this.toArray(), base4, endian);
193241
193877
  };
193242
- BN3.prototype._initArray = function _initArray(number, base3, endian) {
193878
+ BN3.prototype._initArray = function _initArray(number, base4, endian) {
193243
193879
  assert10(typeof number.length === "number");
193244
193880
  if (number.length <= 0) {
193245
193881
  this.words = [0];
@@ -193353,20 +193989,20 @@ var require_bn = __commonJS({
193353
193989
  }
193354
193990
  return r2;
193355
193991
  }
193356
- BN3.prototype._parseBase = function _parseBase(number, base3, start) {
193992
+ BN3.prototype._parseBase = function _parseBase(number, base4, start) {
193357
193993
  this.words = [0];
193358
193994
  this.length = 1;
193359
- for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *= base3) {
193995
+ for (var limbLen = 0, limbPow = 1; limbPow <= 67108863; limbPow *= base4) {
193360
193996
  limbLen++;
193361
193997
  }
193362
193998
  limbLen--;
193363
- limbPow = limbPow / base3 | 0;
193999
+ limbPow = limbPow / base4 | 0;
193364
194000
  var total = number.length - start;
193365
194001
  var mod5 = total % limbLen;
193366
194002
  var end = Math.min(total, total - mod5) + start;
193367
194003
  var word = 0;
193368
194004
  for (var i = start; i < end; i += limbLen) {
193369
- word = parseBase(number, i, i + limbLen, base3);
194005
+ word = parseBase(number, i, i + limbLen, base4);
193370
194006
  this.imuln(limbPow);
193371
194007
  if (this.words[0] + word < 67108864) {
193372
194008
  this.words[0] += word;
@@ -193376,9 +194012,9 @@ var require_bn = __commonJS({
193376
194012
  }
193377
194013
  if (mod5 !== 0) {
193378
194014
  var pow = 1;
193379
- word = parseBase(number, i, number.length, base3);
194015
+ word = parseBase(number, i, number.length, base4);
193380
194016
  for (i = 0; i < mod5; i++) {
193381
- pow *= base3;
194017
+ pow *= base4;
193382
194018
  }
193383
194019
  this.imuln(pow);
193384
194020
  if (this.words[0] + word < 67108864) {
@@ -193548,11 +194184,11 @@ var require_bn = __commonJS({
193548
194184
  52521875,
193549
194185
  60466176
193550
194186
  ];
193551
- BN3.prototype.toString = function toString4(base3, padding3) {
193552
- base3 = base3 || 10;
194187
+ BN3.prototype.toString = function toString4(base4, padding3) {
194188
+ base4 = base4 || 10;
193553
194189
  padding3 = padding3 | 0 || 1;
193554
194190
  var out;
193555
- if (base3 === 16 || base3 === "hex") {
194191
+ if (base4 === 16 || base4 === "hex") {
193556
194192
  out = "";
193557
194193
  var off = 0;
193558
194194
  var carry2 = 0;
@@ -193582,14 +194218,14 @@ var require_bn = __commonJS({
193582
194218
  }
193583
194219
  return out;
193584
194220
  }
193585
- if (base3 === (base3 | 0) && base3 >= 2 && base3 <= 36) {
193586
- var groupSize = groupSizes[base3];
193587
- var groupBase = groupBases[base3];
194221
+ if (base4 === (base4 | 0) && base4 >= 2 && base4 <= 36) {
194222
+ var groupSize = groupSizes[base4];
194223
+ var groupBase = groupBases[base4];
193588
194224
  out = "";
193589
194225
  var c = this.clone();
193590
194226
  c.negative = 0;
193591
194227
  while (!c.isZero()) {
193592
- var r2 = c.modrn(groupBase).toString(base3);
194228
+ var r2 = c.modrn(groupBase).toString(base4);
193593
194229
  c = c.idivn(groupBase);
193594
194230
  if (!c.isZero()) {
193595
194231
  out = zeros2[groupSize - r2.length] + r2 + out;
@@ -204158,8 +204794,8 @@ function createCommonjsModule(fn, basedir, module) {
204158
204794
  return module = {
204159
204795
  path: basedir,
204160
204796
  exports: {},
204161
- require: function(path5, base3) {
204162
- return commonjsRequire(path5, base3 === void 0 || base3 === null ? module.path : base3);
204797
+ require: function(path5, base4) {
204798
+ return commonjsRequire(path5, base4 === void 0 || base4 === null ? module.path : base4);
204163
204799
  }
204164
204800
  }, fn(module, module.exports), module.exports;
204165
204801
  }
@@ -204198,7 +204834,7 @@ function BasePoint(curve, type) {
204198
204834
  this.precomputed = null;
204199
204835
  }
204200
204836
  function ShortCurve(conf) {
204201
- base2.call(this, "short", conf);
204837
+ base3.call(this, "short", conf);
204202
204838
  this.a = new import_bn2.default(conf.a, 16).toRed(this.red);
204203
204839
  this.b = new import_bn2.default(conf.b, 16).toRed(this.red);
204204
204840
  this.tinv = this.two.redInvm();
@@ -204209,7 +204845,7 @@ function ShortCurve(conf) {
204209
204845
  this._endoWnafT2 = new Array(4);
204210
204846
  }
204211
204847
  function Point3(curve, x, y, isRed) {
204212
- base2.BasePoint.call(this, curve, "affine");
204848
+ base3.BasePoint.call(this, curve, "affine");
204213
204849
  if (x === null && y === null) {
204214
204850
  this.x = null;
204215
204851
  this.y = null;
@@ -204229,7 +204865,7 @@ function Point3(curve, x, y, isRed) {
204229
204865
  }
204230
204866
  }
204231
204867
  function JPoint(curve, x, y, z) {
204232
- base2.BasePoint.call(this, curve, "jacobian");
204868
+ base3.BasePoint.call(this, curve, "jacobian");
204233
204869
  if (x === null && y === null && z === null) {
204234
204870
  this.x = this.curve.one;
204235
204871
  this.y = this.curve.one;
@@ -204359,7 +204995,7 @@ function EC(options) {
204359
204995
  this.g.precompute(options.curve.n.bitLength() + 1);
204360
204996
  this.hash = options.hash || options.curve.hash;
204361
204997
  }
204362
- var import_bn2, import_hash2, minimalisticAssert, utils_1, utils_1$1, getNAF, getJSF, assert$1, base2, inherits_browser, assert$2, short_1, curve_1, curves_1, hmacDrbg, assert$3, key, assert$4, signature2, rand, assert$5, ec, elliptic_1, EC$1;
204998
+ var import_bn2, import_hash2, minimalisticAssert, utils_1, utils_1$1, getNAF, getJSF, assert$1, base3, inherits_browser, assert$2, short_1, curve_1, curves_1, hmacDrbg, assert$3, key, assert$4, signature2, rand, assert$5, ec, elliptic_1, EC$1;
204363
204999
  var init_elliptic = __esm({
204364
205000
  "node_modules/@ethersproject/signing-key/lib.esm/elliptic.js"() {
204365
205001
  "use strict";
@@ -204527,7 +205163,7 @@ var init_elliptic = __esm({
204527
205163
  getNAF = utils_1$1.getNAF;
204528
205164
  getJSF = utils_1$1.getJSF;
204529
205165
  assert$1 = utils_1$1.assert;
204530
- base2 = BaseCurve;
205166
+ base3 = BaseCurve;
204531
205167
  BaseCurve.prototype.point = function point() {
204532
205168
  throw new Error("Not implemented");
204533
205169
  };
@@ -204839,7 +205475,7 @@ var init_elliptic = __esm({
204839
205475
  }
204840
205476
  });
204841
205477
  assert$2 = utils_1$1.assert;
204842
- inherits_browser(ShortCurve, base2);
205478
+ inherits_browser(ShortCurve, base3);
204843
205479
  short_1 = ShortCurve;
204844
205480
  ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
204845
205481
  if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
@@ -205013,7 +205649,7 @@ var init_elliptic = __esm({
205013
205649
  }
205014
205650
  return res;
205015
205651
  };
205016
- inherits_browser(Point3, base2.BasePoint);
205652
+ inherits_browser(Point3, base3.BasePoint);
205017
205653
  ShortCurve.prototype.point = function point2(x, y, isRed) {
205018
205654
  return new Point3(this, x, y, isRed);
205019
205655
  };
@@ -205188,7 +205824,7 @@ var init_elliptic = __esm({
205188
205824
  var res = this.curve.jpoint(this.x, this.y, this.curve.one);
205189
205825
  return res;
205190
205826
  };
205191
- inherits_browser(JPoint, base2.BasePoint);
205827
+ inherits_browser(JPoint, base3.BasePoint);
205192
205828
  ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
205193
205829
  return new JPoint(this, x, y, z);
205194
205830
  };
@@ -205478,7 +206114,7 @@ var init_elliptic = __esm({
205478
206114
  curve_1 = createCommonjsModule(function(module, exports) {
205479
206115
  "use strict";
205480
206116
  var curve = exports;
205481
- curve.base = base2;
206117
+ curve.base = base3;
205482
206118
  curve.short = short_1;
205483
206119
  curve.mont = /*RicMoo:ethers:require(./mont)*/
205484
206120
  null;
@@ -210699,10 +211335,10 @@ var init_lib28 = __esm({
210699
211335
  var require_bech32 = __commonJS({
210700
211336
  "node_modules/bech32/index.js"(exports, module) {
210701
211337
  "use strict";
210702
- var ALPHABET2 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
211338
+ var ALPHABET3 = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
210703
211339
  var ALPHABET_MAP = {};
210704
- for (z = 0; z < ALPHABET2.length; z++) {
210705
- x = ALPHABET2.charAt(z);
211340
+ for (z = 0; z < ALPHABET3.length; z++) {
211341
+ x = ALPHABET3.charAt(z);
210706
211342
  if (ALPHABET_MAP[x] !== void 0) throw new TypeError(x + " is ambiguous");
210707
211343
  ALPHABET_MAP[x] = z;
210708
211344
  }
@@ -210737,7 +211373,7 @@ var require_bech32 = __commonJS({
210737
211373
  var x2 = words2[i];
210738
211374
  if (x2 >> 5 !== 0) throw new Error("Non 5-bit word");
210739
211375
  chk = polymodStep(chk) ^ x2;
210740
- result += ALPHABET2.charAt(x2);
211376
+ result += ALPHABET3.charAt(x2);
210741
211377
  }
210742
211378
  for (i = 0; i < 6; ++i) {
210743
211379
  chk = polymodStep(chk);
@@ -210745,7 +211381,7 @@ var require_bech32 = __commonJS({
210745
211381
  chk ^= 1;
210746
211382
  for (i = 0; i < 6; ++i) {
210747
211383
  var v = chk >> (5 - i) * 5 & 31;
210748
- result += ALPHABET2.charAt(v);
211384
+ result += ALPHABET3.charAt(v);
210749
211385
  }
210750
211386
  return result;
210751
211387
  }
@@ -218125,12 +218761,12 @@ var require_axios = __commonJS({
218125
218761
  var URLSearchParams2 = url2.URLSearchParams;
218126
218762
  var ALPHA2 = "abcdefghijklmnopqrstuvwxyz";
218127
218763
  var DIGIT2 = "0123456789";
218128
- var ALPHABET2 = {
218764
+ var ALPHABET3 = {
218129
218765
  DIGIT: DIGIT2,
218130
218766
  ALPHA: ALPHA2,
218131
218767
  ALPHA_DIGIT: ALPHA2 + ALPHA2.toUpperCase() + DIGIT2
218132
218768
  };
218133
- var generateString2 = (size5 = 16, alphabet4 = ALPHABET2.ALPHA_DIGIT) => {
218769
+ var generateString2 = (size5 = 16, alphabet4 = ALPHABET3.ALPHA_DIGIT) => {
218134
218770
  let str = "";
218135
218771
  const {
218136
218772
  length
@@ -218149,7 +218785,7 @@ var require_axios = __commonJS({
218149
218785
  FormData: FormData$1,
218150
218786
  Blob: typeof Blob !== "undefined" && Blob || null
218151
218787
  },
218152
- ALPHABET: ALPHABET2,
218788
+ ALPHABET: ALPHABET3,
218153
218789
  generateString: generateString2,
218154
218790
  protocols: ["http", "https", "file", "data"]
218155
218791
  };
@@ -225475,10 +226111,10 @@ async function redeemPosition(input, deps) {
225475
226111
  structured: { conditionId, negRisk, transactionHash: txHash, pusdBalance: balanceAfter }
225476
226112
  };
225477
226113
  } catch (err) {
225478
- const base3 = await mapClobError(err);
226114
+ const base4 = await mapClobError(err);
225479
226115
  const legacyHint = ` If this market predates the 2026-04-28 V2 cutover it may settle in legacy USDC.e collateral, which this tool does not auto-detect yet \u2014 redeem it once via the Polymarket UI.`;
225480
226116
  return {
225481
- text: `${base3}${/revert|execution reverted|failed/i.test(base3) ? legacyHint : ""}`,
226117
+ text: `${base4}${/revert|execution reverted|failed/i.test(base4) ? legacyHint : ""}`,
225482
226118
  isError: true
225483
226119
  };
225484
226120
  }
@@ -226124,8 +226760,8 @@ var init_dist7 = __esm({
226124
226760
  if (normalized.startsWith("/api/")) {
226125
226761
  normalized = normalized.slice(4);
226126
226762
  }
226127
- const base3 = `${this.apiUrl}${normalized}`;
226128
- if (!params) return base3;
226763
+ const base4 = `${this.apiUrl}${normalized}`;
226764
+ if (!params) return base4;
226129
226765
  const qs = new URLSearchParams();
226130
226766
  for (const [key2, value] of Object.entries(params)) {
226131
226767
  if (value === void 0 || value === null) continue;
@@ -226139,12 +226775,12 @@ var init_dist7 = __esm({
226139
226775
  }
226140
226776
  }
226141
226777
  const query = qs.toString();
226142
- return query ? `${base3}?${query}` : base3;
226778
+ return query ? `${base4}?${query}` : base4;
226143
226779
  }
226144
226780
  absolute(url2) {
226145
226781
  if (url2.startsWith("http://") || url2.startsWith("https://")) return url2;
226146
- const base3 = this.apiUrl.endsWith("/api") ? this.apiUrl.slice(0, -"/api".length) : this.apiUrl;
226147
- return `${base3}${url2}`;
226782
+ const base4 = this.apiUrl.endsWith("/api") ? this.apiUrl.slice(0, -"/api".length) : this.apiUrl;
226783
+ return `${base4}${url2}`;
226148
226784
  }
226149
226785
  async requestWithPayment(url2, method, body) {
226150
226786
  const init2 = { method };
@@ -226768,6 +227404,113 @@ var init_mcp_config = __esm({
226768
227404
  }
226769
227405
  });
226770
227406
 
227407
+ // src/openclaw-plugin-config.ts
227408
+ var openclaw_plugin_config_exports = {};
227409
+ __export(openclaw_plugin_config_exports, {
227410
+ BLOCKRUN_PLUGIN_ID: () => BLOCKRUN_PLUGIN_ID,
227411
+ prepareBlockRunPluginConfig: () => prepareBlockRunPluginConfig
227412
+ });
227413
+ function asObject2(value) {
227414
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
227415
+ }
227416
+ function prepareBlockRunPluginConfig(config, options = {}) {
227417
+ if (!options.explicitSetup && !options.legacyBlockRunInstall && !options.stripUnsupportedInstalls) {
227418
+ return false;
227419
+ }
227420
+ let changed = false;
227421
+ let plugins = asObject2(config.plugins);
227422
+ if (!plugins) {
227423
+ plugins = {};
227424
+ config.plugins = plugins;
227425
+ changed = true;
227426
+ }
227427
+ let entries = asObject2(plugins.entries);
227428
+ if (!entries) {
227429
+ entries = {};
227430
+ plugins.entries = entries;
227431
+ changed = true;
227432
+ }
227433
+ const legacyEntry = asObject2(entries.clawrouter);
227434
+ const currentEntry = asObject2(entries[BLOCKRUN_PLUGIN_ID]);
227435
+ if (options.legacyBlockRunInstall && legacyEntry) {
227436
+ const migratedEntry = currentEntry ?? {};
227437
+ if (!currentEntry && typeof legacyEntry.enabled === "boolean") {
227438
+ migratedEntry.enabled = legacyEntry.enabled;
227439
+ }
227440
+ for (const key2 of ["walletKey", "routing"]) {
227441
+ if (!(key2 in migratedEntry) && key2 in legacyEntry) {
227442
+ migratedEntry[key2] = legacyEntry[key2];
227443
+ }
227444
+ if (key2 in legacyEntry) {
227445
+ delete legacyEntry[key2];
227446
+ changed = true;
227447
+ }
227448
+ }
227449
+ const legacyConfig = asObject2(legacyEntry.config);
227450
+ if (legacyConfig) {
227451
+ const currentConfig = asObject2(migratedEntry.config) ?? {};
227452
+ for (const key2 of ["walletKey", "routing"]) {
227453
+ if (!(key2 in currentConfig) && key2 in legacyConfig) {
227454
+ currentConfig[key2] = legacyConfig[key2];
227455
+ }
227456
+ if (key2 in legacyConfig) {
227457
+ delete legacyConfig[key2];
227458
+ changed = true;
227459
+ }
227460
+ }
227461
+ if (Object.keys(currentConfig).length > 0) migratedEntry.config = currentConfig;
227462
+ if (Object.keys(legacyConfig).length === 0) {
227463
+ delete legacyEntry.config;
227464
+ changed = true;
227465
+ }
227466
+ }
227467
+ if (!currentEntry || entries[BLOCKRUN_PLUGIN_ID] !== migratedEntry) {
227468
+ entries[BLOCKRUN_PLUGIN_ID] = migratedEntry;
227469
+ changed = true;
227470
+ }
227471
+ }
227472
+ if (options.explicitSetup) {
227473
+ const next = asObject2(entries[BLOCKRUN_PLUGIN_ID]) ?? {};
227474
+ if (next.enabled !== true) {
227475
+ entries[BLOCKRUN_PLUGIN_ID] = { ...next, enabled: true };
227476
+ changed = true;
227477
+ }
227478
+ }
227479
+ const allow = plugins.allow;
227480
+ if (Array.isArray(allow)) {
227481
+ const shouldAllow = options.explicitSetup || options.legacyBlockRunInstall && allow.includes("clawrouter");
227482
+ if (shouldAllow && !allow.includes(BLOCKRUN_PLUGIN_ID)) {
227483
+ allow.push(BLOCKRUN_PLUGIN_ID);
227484
+ changed = true;
227485
+ }
227486
+ }
227487
+ const deny = plugins.deny;
227488
+ if (Array.isArray(deny)) {
227489
+ if (options.explicitSetup) {
227490
+ const next = deny.filter((id2) => id2 !== BLOCKRUN_PLUGIN_ID);
227491
+ if (next.length !== deny.length) {
227492
+ plugins.deny = next;
227493
+ changed = true;
227494
+ }
227495
+ } else if (options.legacyBlockRunInstall && deny.includes("clawrouter") && !deny.includes(BLOCKRUN_PLUGIN_ID)) {
227496
+ deny.push(BLOCKRUN_PLUGIN_ID);
227497
+ changed = true;
227498
+ }
227499
+ }
227500
+ if (options.stripUnsupportedInstalls && "installs" in plugins) {
227501
+ delete plugins.installs;
227502
+ changed = true;
227503
+ }
227504
+ return changed;
227505
+ }
227506
+ var BLOCKRUN_PLUGIN_ID;
227507
+ var init_openclaw_plugin_config = __esm({
227508
+ "src/openclaw-plugin-config.ts"() {
227509
+ "use strict";
227510
+ BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
227511
+ }
227512
+ });
227513
+
226771
227514
  // src/retry.ts
226772
227515
  function sleep3(ms) {
226773
227516
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -226850,6 +227593,7 @@ __export(index_exports, {
226850
227593
  MalformedSpendPolicyError: () => MalformedSpendPolicyError,
226851
227594
  OPENCLAW_MODELS: () => OPENCLAW_MODELS,
226852
227595
  PARTNER_SERVICES: () => PARTNER_SERVICES,
227596
+ PAYABLE_NETWORKS: () => PAYABLE_NETWORKS,
226853
227597
  RequestDeduplicator: () => RequestDeduplicator,
226854
227598
  ResponseCache: () => ResponseCache,
226855
227599
  RpcError: () => RpcError2,
@@ -226911,13 +227655,14 @@ import {
226911
227655
  readdirSync,
226912
227656
  mkdirSync as mkdirSync3,
226913
227657
  copyFileSync,
227658
+ chmodSync,
226914
227659
  renameSync as renameSync2,
226915
227660
  unlinkSync
226916
227661
  } from "fs";
226917
227662
  import { readFile as readFileAsync } from "fs/promises";
226918
227663
  import { homedir as homedir13 } from "os";
226919
- import { join as join16, dirname as dirname4 } from "path";
226920
- import { fileURLToPath as fileURLToPath2 } from "url";
227664
+ import { randomUUID } from "crypto";
227665
+ import { join as join16 } from "path";
226921
227666
  async function waitForProxyHealth(port, timeoutMs = 3e3) {
226922
227667
  const start = Date.now();
226923
227668
  while (Date.now() - start < timeoutMs) {
@@ -226930,53 +227675,21 @@ async function waitForProxyHealth(port, timeoutMs = 3e3) {
226930
227675
  }
226931
227676
  return false;
226932
227677
  }
226933
- function getPackageRoot() {
226934
- return join16(dirname4(fileURLToPath2(import.meta.url)), "..");
226935
- }
226936
- function installSkillsToWorkspace(logger48) {
227678
+ function writePrivateJsonSync(path5, value) {
227679
+ const temporary = `${path5}.tmp.${randomUUID()}`;
226937
227680
  try {
226938
- const packageRoot = getPackageRoot();
226939
- const bundledSkillsDir = join16(packageRoot, "skills");
226940
- if (!existsSync4(bundledSkillsDir)) {
226941
- return;
226942
- }
226943
- const profile = (process["env"].OPENCLAW_PROFILE ?? "").trim().toLowerCase();
226944
- const workspaceDirName = profile && profile !== "default" ? `workspace-${profile}` : "workspace";
226945
- const workspaceSkillsDir = join16(homedir13(), ".openclaw", workspaceDirName, "skills");
226946
- mkdirSync3(workspaceSkillsDir, { recursive: true });
226947
- const INTERNAL_SKILLS = /* @__PURE__ */ new Set(["release"]);
226948
- const entries = readdirSync(bundledSkillsDir, { withFileTypes: true });
226949
- let installed = 0;
226950
- for (const entry of entries) {
226951
- if (!entry.isDirectory()) continue;
226952
- const skillName = entry.name;
226953
- if (INTERNAL_SKILLS.has(skillName)) continue;
226954
- const srcSkillFile = join16(bundledSkillsDir, skillName, "SKILL.md");
226955
- if (!existsSync4(srcSkillFile)) continue;
226956
- const destDir = join16(workspaceSkillsDir, skillName);
226957
- const destSkillFile = join16(destDir, "SKILL.md");
226958
- let needsUpdate = true;
226959
- if (existsSync4(destSkillFile)) {
226960
- try {
226961
- const srcContent = readTextFileSync(srcSkillFile);
226962
- const destContent = readTextFileSync(destSkillFile);
226963
- if (srcContent === destContent) needsUpdate = false;
226964
- } catch {
226965
- }
226966
- }
226967
- if (needsUpdate) {
226968
- mkdirSync3(destDir, { recursive: true });
226969
- copyFileSync(srcSkillFile, destSkillFile);
226970
- installed++;
226971
- }
226972
- }
226973
- if (installed > 0) {
226974
- logger48.info(`Installed ${installed} skill(s) to ${workspaceSkillsDir}`);
226975
- }
226976
- } catch (err) {
226977
- logger48.warn(`Failed to install skills: ${err instanceof Error ? err.message : String(err)}`);
227681
+ writeFileSync3(temporary, JSON.stringify(value, null, 2), { mode: 384 });
227682
+ renameSync2(temporary, path5);
227683
+ chmodSync(path5, 384);
227684
+ } finally {
227685
+ if (existsSync4(temporary)) unlinkSync(temporary);
226978
227686
  }
226979
227687
  }
227688
+ function hasConfiguredWallet() {
227689
+ return Boolean(
227690
+ process["env"].BLOCKRUN_WALLET_KEY || existsSync4(CORE_WALLET_FILE) || existsSync4(WALLET_FILE)
227691
+ );
227692
+ }
226980
227693
  function isCompletionMode() {
226981
227694
  const args = process.argv;
226982
227695
  return args.some((arg, i) => arg === "completion" && i >= 1 && i <= 3);
@@ -227150,35 +227863,19 @@ function injectModelsConfig(logger48, options = {}) {
227150
227863
  logger48.info(`Added ${addedCount} models to allowlist (${TOP_MODELS.length} total)`);
227151
227864
  }
227152
227865
  }
227153
- const pluginEntries = config.plugins?.entries;
227154
- if (pluginEntries && pluginEntries.clawrouter && !pluginEntries[BLOCKRUN_PLUGIN_ID]) {
227155
- pluginEntries[BLOCKRUN_PLUGIN_ID] = pluginEntries.clawrouter;
227156
- delete pluginEntries.clawrouter;
227866
+ const legacyEntry = config.plugins?.entries?.clawrouter;
227867
+ const legacyEntryConfig = legacyEntry?.config;
227868
+ const legacyBlockRunInstall = Boolean(
227869
+ legacyEntry && ["walletKey", "routing"].some(
227870
+ (key2) => key2 in legacyEntry || (legacyEntryConfig ? key2 in legacyEntryConfig : false)
227871
+ )
227872
+ );
227873
+ if (legacyBlockRunInstall && prepareBlockRunPluginConfig(config, { legacyBlockRunInstall })) {
227157
227874
  needsWrite = true;
227158
227875
  logger48.info(
227159
- "Migrated plugins.entries.clawrouter -> blockrun-clawrouter (OpenClaw bundles its own `clawrouter` plugin; see #305)"
227876
+ `Migrated legacy BlockRun plugin config to ${BLOCKRUN_PLUGIN_ID} (renamed from clawrouter; see #305)`
227160
227877
  );
227161
227878
  }
227162
- const pluginsCfg = config.plugins;
227163
- const allow = pluginsCfg?.allow;
227164
- if (Array.isArray(allow) && allow.includes("clawrouter") && !allow.includes(BLOCKRUN_PLUGIN_ID)) {
227165
- allow.push(BLOCKRUN_PLUGIN_ID);
227166
- needsWrite = true;
227167
- logger48.info(`Added ${BLOCKRUN_PLUGIN_ID} to plugins.allow (renamed from clawrouter; see #305)`);
227168
- }
227169
- const deny = pluginsCfg?.deny;
227170
- if (Array.isArray(deny) && deny.includes("clawrouter") && !deny.includes(BLOCKRUN_PLUGIN_ID)) {
227171
- deny.push(BLOCKRUN_PLUGIN_ID);
227172
- needsWrite = true;
227173
- logger48.info(`Added ${BLOCKRUN_PLUGIN_ID} to plugins.deny (renamed from clawrouter; see #305)`);
227174
- }
227175
- const installs = pluginsCfg?.installs;
227176
- if (installs && installs.clawrouter && !installs[BLOCKRUN_PLUGIN_ID]) {
227177
- installs[BLOCKRUN_PLUGIN_ID] = installs.clawrouter;
227178
- delete installs.clawrouter;
227179
- needsWrite = true;
227180
- logger48.info(`Migrated plugins.installs.clawrouter -> ${BLOCKRUN_PLUGIN_ID} (see #305)`);
227181
- }
227182
227879
  if (!config.tools || typeof config.tools !== "object" || Array.isArray(config.tools)) {
227183
227880
  config.tools = {};
227184
227881
  needsWrite = true;
@@ -227218,8 +227915,9 @@ function injectModelsConfig(logger48, options = {}) {
227218
227915
  }
227219
227916
  try {
227220
227917
  const tmpPath = `${configPath}.tmp.${process.pid}`;
227221
- writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
227918
+ writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
227222
227919
  renameSync2(tmpPath, configPath);
227920
+ chmodSync(configPath, 384);
227223
227921
  logger48.info("Smart routing enabled (blockrun/auto)");
227224
227922
  } catch (err) {
227225
227923
  logger48.info(`Failed to write config: ${err instanceof Error ? err.message : String(err)}`);
@@ -227254,7 +227952,7 @@ function syncAgentModelCache(logger48, options = {}) {
227254
227952
  const staleCount = Array.isArray(current) ? current.length : 0;
227255
227953
  entry.models = VISIBLE_OPENCLAW_MODELS;
227256
227954
  const tmpPath = `${cachePath}.tmp.${process.pid}`;
227257
- writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2));
227955
+ writeFileSync3(tmpPath, JSON.stringify(cache2, null, 2), { mode: 384 });
227258
227956
  renameSync2(tmpPath, cachePath);
227259
227957
  logger48.info(
227260
227958
  `Repaired ${agent} model cache: ${staleCount} \u2192 ${expectedIds.length} BlockRun models`
@@ -227325,7 +228023,7 @@ function injectAuthProfile(logger48) {
227325
228023
  key: "x402-proxy-handles-auth"
227326
228024
  };
227327
228025
  try {
227328
- writeFileSync3(authPath, JSON.stringify(store, null, 2));
228026
+ writePrivateJsonSync(authPath, store);
227329
228027
  logger48.info(`Injected BlockRun auth profile for agent: ${agentId}`);
227330
228028
  } catch (err) {
227331
228029
  logger48.info(
@@ -227441,7 +228139,7 @@ async function startProxyInBackground(api, startupGeneration) {
227441
228139
  } else {
227442
228140
  if (configKey !== void 0) {
227443
228141
  api.logger.warn(
227444
- `pluginConfig.walletKey is set but invalid (expected 0x + 64 hex chars) \u2014 falling back to saved wallet`
228142
+ `pluginConfig.walletKey is set but invalid (expected 0x + 64 hex chars) \u2014 falling back to the BlockRun wallet`
227445
228143
  );
227446
228144
  }
227447
228145
  wallet = await resolveOrGenerateWalletKey();
@@ -227453,6 +228151,8 @@ async function startProxyInBackground(api, startupGeneration) {
227453
228151
  api.logger.warn(` Run /wallet export to get your private key`);
227454
228152
  api.logger.warn(` Losing this key = losing your USDC funds`);
227455
228153
  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`);
228154
+ } else if (wallet.source === "core") {
228155
+ api.logger.info(`Using BlockRun Core wallet: ${wallet.address}`);
227456
228156
  } else if (wallet.source === "saved") {
227457
228157
  api.logger.info(`Using saved wallet: ${wallet.address}`);
227458
228158
  } else if (wallet.source === "config") {
@@ -227473,6 +228173,7 @@ async function startProxyInBackground(api, startupGeneration) {
227473
228173
  routingConfig,
227474
228174
  maxCostPerRunUsd,
227475
228175
  maxCostPerRunMode,
228176
+ spendControl: liveSpendControl = new SpendControl(),
227476
228177
  onReady: (port) => {
227477
228178
  api.logger.info(`BlockRun x402 proxy listening on port ${port}`);
227478
228179
  },
@@ -227739,7 +228440,7 @@ function buildImageGenerationProvider() {
227739
228440
  ]
227740
228441
  }
227741
228442
  },
227742
- isConfigured: () => existsSync4(WALLET_FILE),
228443
+ isConfigured: hasConfiguredWallet,
227743
228444
  generateImage: async (req) => {
227744
228445
  const port = getProxyPort();
227745
228446
  const body = JSON.stringify({
@@ -227789,7 +228490,7 @@ function buildMusicGenerationProvider() {
227789
228490
  supportsFormat: true,
227790
228491
  supportedFormats: ["mp3"]
227791
228492
  },
227792
- isConfigured: () => existsSync4(WALLET_FILE),
228493
+ isConfigured: hasConfiguredWallet,
227793
228494
  generateMusic: async (req) => {
227794
228495
  const port = getProxyPort();
227795
228496
  const body = JSON.stringify({
@@ -227865,7 +228566,7 @@ function buildVideoGenerationProvider() {
227865
228566
  supportedDurationSeconds: [5, 8, 10]
227866
228567
  }
227867
228568
  },
227868
- isConfigured: () => existsSync4(WALLET_FILE),
228569
+ isConfigured: hasConfiguredWallet,
227869
228570
  generateVideo: async (req) => {
227870
228571
  const port = getProxyPort();
227871
228572
  const imageUrl = req.inputImages?.[0]?.url;
@@ -227944,26 +228645,25 @@ function createWalletCommand(api) {
227944
228645
  requireAuth: true,
227945
228646
  handler: async (ctx) => {
227946
228647
  const subcommand = ctx.args?.trim().toLowerCase() || "status";
227947
- let walletKey;
227948
- let address2;
228648
+ let wallet;
227949
228649
  try {
227950
- if (existsSync4(WALLET_FILE)) {
227951
- walletKey = readTextFileSync(WALLET_FILE).trim();
227952
- if (walletKey.startsWith("0x") && walletKey.length === 66) {
227953
- const account = privateKeyToAccount(walletKey);
227954
- address2 = account.address;
227955
- }
227956
- }
227957
- } catch {
228650
+ wallet = subcommand === "status" || subcommand === "export" ? await resolveExistingWalletKey() : await resolveOrGenerateWalletKey();
228651
+ } catch (error) {
228652
+ return {
228653
+ text: `Could not load the BlockRun wallet: ${error instanceof Error ? error.message : String(error)}`,
228654
+ isError: true
228655
+ };
227958
228656
  }
227959
- if (!walletKey || !address2) {
228657
+ if (!wallet) {
227960
228658
  return {
227961
- text: `No ClawRouter wallet found.
227962
-
227963
- Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228659
+ text: "No BlockRun wallet found. Run `clawrouter setup` or connect an agent in ClawRouter Desktop to create one.",
227964
228660
  isError: true
227965
228661
  };
227966
228662
  }
228663
+ const walletKey = wallet.key;
228664
+ const address2 = wallet.address;
228665
+ const resolvedSolanaKey = wallet.solanaPrivateKeyBytes;
228666
+ const walletPath = wallet.source === "core" ? CORE_WALLET_FILE : WALLET_FILE;
227967
228667
  if (subcommand === "export") {
227968
228668
  const lines = [
227969
228669
  "**ClawRouter Wallet Export**",
@@ -228000,13 +228700,26 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228000
228700
  }
228001
228701
  } catch {
228002
228702
  }
228703
+ if (!hasMnemonic3 && resolvedSolanaKey) {
228704
+ try {
228705
+ const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes2 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
228706
+ const signer = await createKeyPairSignerFromPrivateKeyBytes2(resolvedSolanaKey);
228707
+ lines.push(
228708
+ "",
228709
+ "**Solana:**",
228710
+ ` Address: \`${signer.address}\``,
228711
+ wallet.source === "core" ? ` Private key managed by BlockRun Core: \`${CORE_SOLANA_WALLET_FILE}\`` : " Private key is managed by the configured wallet source."
228712
+ );
228713
+ } catch {
228714
+ }
228715
+ }
228003
228716
  lines.push(
228004
228717
  "",
228005
228718
  "**To restore on a new machine:**",
228006
228719
  "1. Set the environment variable before running OpenClaw:",
228007
228720
  ` \`export BLOCKRUN_WALLET_KEY=${walletKey}\``,
228008
228721
  "2. Or save to file:",
228009
- ` \`mkdir -p ~/.openclaw/blockrun && echo "${walletKey}" > ~/.openclaw/blockrun/wallet.key && chmod 600 ~/.openclaw/blockrun/wallet.key\``
228722
+ ` \`mkdir -p ~/.blockrun && echo "${walletKey}" > ~/.blockrun/.session && chmod 600 ~/.blockrun/.session\``
228010
228723
  );
228011
228724
  if (hasMnemonic3) {
228012
228725
  lines.push(
@@ -228019,6 +228732,22 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228019
228732
  if (subcommand === "solana") {
228020
228733
  try {
228021
228734
  let solanaAddr;
228735
+ if (resolvedSolanaKey) {
228736
+ await savePaymentChain("solana");
228737
+ const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes3 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
228738
+ const signer2 = await createKeyPairSignerFromPrivateKeyBytes3(resolvedSolanaKey);
228739
+ solanaAddr = signer2.address;
228740
+ if (api) restartProxyForChainSwitch(api);
228741
+ return {
228742
+ text: [
228743
+ "\u2713 Payment chain switched to **Solana**.",
228744
+ api ? "Proxy restarting in background (~2s)." : "Restart the gateway to apply.",
228745
+ "",
228746
+ `**Solana Address:** \`${solanaAddr}\``,
228747
+ `**Fund with USDC on Solana:** https://solscan.io/account/${solanaAddr}`
228748
+ ].join("\n")
228749
+ };
228750
+ }
228022
228751
  if (existsSync4(MNEMONIC_FILE)) {
228023
228752
  const existingMnemonic = readTextFileSync(MNEMONIC_FILE).trim();
228024
228753
  if (existingMnemonic) {
@@ -228090,13 +228819,9 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228090
228819
  })();
228091
228820
  const solanaPromise = (async () => {
228092
228821
  try {
228093
- if (!existsSync4(MNEMONIC_FILE)) return "";
228094
- const { deriveSolanaKeyBytes: deriveSolanaKeyBytes2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
228095
- const mnemonic = readTextFileSync(MNEMONIC_FILE).trim();
228096
- if (!mnemonic) return "";
228097
- const solKeyBytes = deriveSolanaKeyBytes2(mnemonic);
228822
+ if (!resolvedSolanaKey) return "";
228098
228823
  const { createKeyPairSignerFromPrivateKeyBytes: createKeyPairSignerFromPrivateKeyBytes2 } = await Promise.resolve().then(() => (init_index_node37(), index_node_exports));
228099
- const signer = await createKeyPairSignerFromPrivateKeyBytes2(solKeyBytes);
228824
+ const signer = await createKeyPairSignerFromPrivateKeyBytes2(resolvedSolanaKey);
228100
228825
  const solAddr = signer.address;
228101
228826
  let solBalanceText = "Balance: (could not check)";
228102
228827
  try {
@@ -228157,7 +228882,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228157
228882
  solanaSection,
228158
228883
  usageSection,
228159
228884
  "",
228160
- `**Key File:** \`${WALLET_FILE}\``,
228885
+ `**Key File:** \`${walletPath}\``,
228161
228886
  "",
228162
228887
  "**Commands:**",
228163
228888
  "\u2022 `/wallet` - Show this status",
@@ -228171,7 +228896,7 @@ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
228171
228896
  }
228172
228897
  };
228173
228898
  }
228174
- var activeProxyHandle, pendingConfiguredStartupApi, IMAGE_DIR2, AUDIO_DIR2, VIDEO_DIR2, BLOCKRUN_PLUGIN_ID, plugin, index_default2;
228899
+ var activeProxyHandle, liveSpendControl, pendingConfiguredStartupApi, IMAGE_DIR2, AUDIO_DIR2, VIDEO_DIR2, plugin, index_default2;
228175
228900
  var init_index = __esm({
228176
228901
  "src/index.ts"() {
228177
228902
  "use strict";
@@ -228191,7 +228916,11 @@ var init_index = __esm({
228191
228916
  init_tool();
228192
228917
  init_stats2();
228193
228918
  init_exclude();
228919
+ init_policy();
228920
+ init_spend_control();
228194
228921
  init_mcp_config();
228922
+ init_openclaw_plugin_config();
228923
+ init_openclaw_plugin_config();
228195
228924
  init_proxy();
228196
228925
  init_provider();
228197
228926
  init_models();
@@ -228210,11 +228939,11 @@ var init_index = __esm({
228210
228939
  init_response_cache();
228211
228940
  init_partners();
228212
228941
  activeProxyHandle = null;
228942
+ liveSpendControl = null;
228213
228943
  pendingConfiguredStartupApi = null;
228214
228944
  IMAGE_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "images");
228215
228945
  AUDIO_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "audio");
228216
228946
  VIDEO_DIR2 = join16(homedir13(), ".openclaw", "blockrun", "videos");
228217
- BLOCKRUN_PLUGIN_ID = "blockrun-clawrouter";
228218
228947
  plugin = {
228219
228948
  // NOT "clawrouter". OpenClaw bundles its own plugin under that id since the
228220
228949
  // 2026.7.1 line (vendored at dist/extensions/clawrouter, provider `clawrouter/*`,
@@ -228232,7 +228961,6 @@ var init_index = __esm({
228232
228961
  api.logger.info("ClawRouter disabled (CLAWROUTER_DISABLED=true). Using default routing.");
228233
228962
  return;
228234
228963
  }
228235
- installSkillsToWorkspace(api.logger);
228236
228964
  const proc = process;
228237
228965
  const proxyAlreadyStarted = !!proc.__clawrouterProxyStarted;
228238
228966
  if (isCompletionMode()) {
@@ -228525,9 +229253,14 @@ ${errText}`
228525
229253
  }
228526
229254
  api.registerCommand(createStatsCommand());
228527
229255
  api.registerCommand(createExcludeCommand());
229256
+ api.registerCommand(
229257
+ createPolicyCommand({
229258
+ liveControl: () => activeProxyHandle ? liveSpendControl ?? void 0 : void 0
229259
+ })
229260
+ );
228528
229261
  if (shouldLogRegistration) {
228529
229262
  api.logger.info(
228530
- "Commands registered: /wallet, /blockrun, /stats, /exclude, /partners, /cr-imagegen, /videogen, /cr-call"
229263
+ "Commands registered: /wallet, /blockrun, /stats, /exclude, /policy, /partners, /cr-imagegen, /videogen, /cr-call"
228531
229264
  );
228532
229265
  }
228533
229266
  api.registerService({
@@ -228559,6 +229292,8 @@ ${errText}`
228559
229292
  api.logger.warn(` Run /wallet export to get your private key`);
228560
229293
  api.logger.warn(` Losing this key = losing your USDC funds`);
228561
229294
  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`);
229295
+ } else if (source === "core") {
229296
+ api.logger.info(`Using BlockRun Core wallet: ${address2}`);
228562
229297
  } else if (source === "saved") {
228563
229298
  api.logger.info(`Using saved wallet: ${address2}`);
228564
229299
  } else if (source === "config") {
@@ -228632,18 +229367,18 @@ ${errText}`
228632
229367
  delete config.models.providers.blockrun;
228633
229368
  }
228634
229369
  removeManagedBlockrunMcpServerConfig(config);
228635
- for (const key2 of [
228636
- BLOCKRUN_PLUGIN_ID,
228637
- "clawrouter",
228638
- "ClawRouter",
228639
- "@blockrun/clawrouter"
228640
- ]) {
229370
+ for (const key2 of [BLOCKRUN_PLUGIN_ID, "ClawRouter", "@blockrun/clawrouter"]) {
228641
229371
  if (config.plugins?.entries?.[key2]) delete config.plugins.entries[key2];
228642
229372
  if (config.plugins?.installs?.[key2]) delete config.plugins.installs[key2];
228643
229373
  }
228644
229374
  if (Array.isArray(config.plugins?.allow)) {
228645
229375
  config.plugins.allow = config.plugins.allow.filter(
228646
- (p) => p !== BLOCKRUN_PLUGIN_ID && p !== "clawrouter" && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
229376
+ (p) => p !== BLOCKRUN_PLUGIN_ID && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
229377
+ );
229378
+ }
229379
+ if (Array.isArray(config.plugins?.deny)) {
229380
+ config.plugins.deny = config.plugins.deny.filter(
229381
+ (p) => p !== BLOCKRUN_PLUGIN_ID && p !== "ClawRouter" && p !== "@blockrun/clawrouter"
228647
229382
  );
228648
229383
  }
228649
229384
  if (config.agents?.defaults?.models) {
@@ -228658,8 +229393,9 @@ ${errText}`
228658
229393
  delete config.tools.web.search.provider;
228659
229394
  }
228660
229395
  const tmpPath = `${configPath}.tmp.${process.pid}`;
228661
- writeFileSync3(tmpPath, JSON.stringify(config, null, 2));
229396
+ writeFileSync3(tmpPath, JSON.stringify(config, null, 2), { mode: 384 });
228662
229397
  renameSync2(tmpPath, configPath);
229398
+ chmodSync(configPath, 384);
228663
229399
  api.logger.info("ClawRouter config cleaned up");
228664
229400
  }
228665
229401
  } catch (err) {
@@ -228676,7 +229412,7 @@ ${errText}`
228676
229412
  const store = JSON.parse(readTextFileSync(authPath));
228677
229413
  if (store.profiles?.["blockrun:default"]) {
228678
229414
  delete store.profiles["blockrun:default"];
228679
- writeFileSync3(authPath, JSON.stringify(store, null, 2));
229415
+ writePrivateJsonSync(authPath, store);
228680
229416
  }
228681
229417
  } catch {
228682
229418
  }
@@ -228956,7 +229692,8 @@ function printDiagnostics(result) {
228956
229692
  );
228957
229693
  console.log("\nWallet");
228958
229694
  if (result.wallet.exists && result.wallet.valid) {
228959
- console.log(` ${green(`Key: ${WALLET_FILE} (${result.wallet.source})`)}`);
229695
+ const walletPath = result.wallet.source === "core" ? CORE_WALLET_FILE : WALLET_FILE;
229696
+ console.log(` ${green(`Key: ${walletPath} (${result.wallet.source})`)}`);
228960
229697
  console.log(` ${green(`EVM Address: ${result.wallet.address}`)}`);
228961
229698
  if (result.wallet.solanaAddress) {
228962
229699
  console.log(` ${green(`Solana Address: ${result.wallet.solanaAddress}`)}`);
@@ -229151,6 +229888,7 @@ async function runDoctor(userQuestion, model = "sonnet") {
229151
229888
 
229152
229889
  // src/cli.ts
229153
229890
  init_partners();
229891
+ init_policy();
229154
229892
  function printHelp() {
229155
229893
  console.log(`
229156
229894
  ClawRouter v${VERSION} - Smart LLM Router
@@ -229166,6 +229904,10 @@ Usage:
229166
229904
  clawrouter report [daily|weekly|monthly] [--json]
229167
229905
  clawrouter logs [--days <n>]
229168
229906
  clawrouter setup # Finish OpenClaw integration after npm install -g
229907
+ clawrouter policy # Spend limits + payee/network/asset lists on disk
229908
+ clawrouter policy set|add|remove <list> <value>...
229909
+ clawrouter policy clear <list> # <list>: allowedPayees|blockedPayees|allowedNetworks|allowedAssets
229910
+ clawrouter policy limit <window> <usd>|clear # <window>: perRequest|hourly|daily|session
229169
229911
  clawrouter share last [--as=<im>] # Convert most recent response for IM (default: feishu)
229170
229912
  clawrouter share list [--limit=<n>] # Recent response ids + summaries
229171
229913
  clawrouter share <id> [--as=<im>] # Convert a specific response by id
@@ -229182,6 +229924,7 @@ Options:
229182
229924
  --version, -v Show version number
229183
229925
  --help, -h Show this help message
229184
229926
  --port <number> Port to listen on (default: ${getProxyPort()})
229927
+ --no-reuse Refuse an existing listener (used by managed Desktop startup)
229185
229928
 
229186
229929
  Query Commands (talk to running proxy on localhost:${getProxyPort()}):
229187
229930
  status Proxy status: wallet, balance, payment chain
@@ -229204,6 +229947,7 @@ Management Commands:
229204
229947
  wallet recover Restore wallet.key from mnemonic (if generated by ClawRouter)
229205
229948
  chain solana Switch to Solana (persists)
229206
229949
  chain base Switch to Base EVM (persists)
229950
+ policy Edit spend limits and counterparty lists (fail-closed; restart proxy to apply)
229207
229951
 
229208
229952
  Environment Variables:
229209
229953
  BLOCKRUN_WALLET_KEY Private key for x402 payments (auto-generated if not set)
@@ -229435,9 +230179,9 @@ Usage Stats (last ${days} days)
229435
230179
  }
229436
230180
  }
229437
230181
  async function cmdPhone(port, subcommand, numbersAction, arg, areaCode) {
229438
- const base3 = `http://127.0.0.1:${port}`;
230182
+ const base4 = `http://127.0.0.1:${port}`;
229439
230183
  async function postJson(path5, body) {
229440
- const resp = await fetch(`${base3}${path5}`, {
230184
+ const resp = await fetch(`${base4}${path5}`, {
229441
230185
  method: "POST",
229442
230186
  headers: { "content-type": "application/json" },
229443
230187
  body: JSON.stringify(body)
@@ -229571,10 +230315,22 @@ Cache Stats
229571
230315
  }
229572
230316
  async function cmdSetup() {
229573
230317
  const { execFileSync, execSync } = await import("child_process");
229574
- const { existsSync: existsSync5 } = await import("fs");
229575
- const { dirname: dirname5, join: join17 } = await import("path");
230318
+ const {
230319
+ copyFileSync: copyFileSync2,
230320
+ cpSync,
230321
+ existsSync: existsSync5,
230322
+ mkdirSync: mkdirSync4,
230323
+ readFileSync: readFileSync4,
230324
+ readdirSync: readdirSync2,
230325
+ renameSync: renameSync3,
230326
+ rmSync,
230327
+ unlinkSync: unlinkSync2,
230328
+ writeFileSync: writeFileSync4
230329
+ } = await import("fs");
230330
+ const { dirname: dirname4, join: join17 } = await import("path");
229576
230331
  const { homedir: homedir14 } = await import("os");
229577
230332
  const { injectModelsConfig: injectModelsConfig2, injectAuthProfile: injectAuthProfile2, syncAgentModelCache: syncAgentModelCache2, VISIBLE_OPENCLAW_MODELS: VISIBLE_OPENCLAW_MODELS2 } = await Promise.resolve().then(() => (init_index(), index_exports));
230333
+ const { BLOCKRUN_PLUGIN_ID: BLOCKRUN_PLUGIN_ID2, prepareBlockRunPluginConfig: prepareBlockRunPluginConfig2 } = await Promise.resolve().then(() => (init_openclaw_plugin_config(), openclaw_plugin_config_exports));
229578
230334
  console.log("\u{1F99E} ClawRouter setup\n");
229579
230335
  const openclawPath = (() => {
229580
230336
  const candidates = [];
@@ -229594,7 +230350,7 @@ async function cmdSetup() {
229594
230350
  encoding: "utf8",
229595
230351
  stdio: ["ignore", "pipe", "ignore"]
229596
230352
  }).trim();
229597
- if (npmRoot) candidates.push(join17(dirname5(dirname5(npmRoot)), "bin", "openclaw"));
230353
+ if (npmRoot) candidates.push(join17(dirname4(dirname4(npmRoot)), "bin", "openclaw"));
229598
230354
  } catch {
229599
230355
  }
229600
230356
  candidates.push(
@@ -229611,38 +230367,236 @@ async function cmdSetup() {
229611
230367
  process.exit(1);
229612
230368
  }
229613
230369
  console.log(` \u2713 Found openclaw at ${openclawPath}`);
230370
+ const configPath = join17(homedir14(), ".openclaw", "openclaw.json");
230371
+ const configInitiallyExisted = existsSync5(configPath);
230372
+ const configRollbackBackup = configInitiallyExisted ? `${configPath}.before-${BLOCKRUN_PLUGIN_ID2}.${Date.now()}` : void 0;
230373
+ if (configRollbackBackup) copyFileSync2(configPath, configRollbackBackup);
230374
+ const ensureConfigRollbackBackup = () => {
230375
+ return configRollbackBackup;
230376
+ };
230377
+ let installAttempted = false;
230378
+ const openclawRoot = join17(homedir14(), ".openclaw");
230379
+ const findManagedBlockRunInstalls = () => {
230380
+ const candidates = [
230381
+ join17(openclawRoot, "extensions", BLOCKRUN_PLUGIN_ID2),
230382
+ join17(openclawRoot, "extensions", "clawrouter"),
230383
+ join17(openclawRoot, "npm", "node_modules", "@blockrun", "clawrouter")
230384
+ ];
230385
+ const projectsDir = join17(openclawRoot, "npm", "projects");
230386
+ try {
230387
+ for (const project of readdirSync2(projectsDir)) {
230388
+ candidates.push(join17(projectsDir, project, "node_modules", "@blockrun", "clawrouter"));
230389
+ }
230390
+ } catch {
230391
+ }
230392
+ return [...new Set(candidates)].filter((candidate) => {
230393
+ try {
230394
+ const metadata = JSON.parse(readFileSync4(join17(candidate, "package.json"), "utf8"));
230395
+ return metadata.name === "@blockrun/clawrouter";
230396
+ } catch {
230397
+ return false;
230398
+ }
230399
+ });
230400
+ };
230401
+ const initialPluginDirs = findManagedBlockRunInstalls();
230402
+ const setupRollbackRoot = join17(
230403
+ openclawRoot,
230404
+ "blockrun",
230405
+ "setup-rollbacks",
230406
+ `${Date.now()}-${process.pid}`
230407
+ );
230408
+ const pluginRollbackBackups = /* @__PURE__ */ new Map();
230409
+ if (initialPluginDirs.length > 0) {
230410
+ mkdirSync4(setupRollbackRoot, { recursive: true, mode: 448 });
230411
+ for (const [index2, pluginDir] of initialPluginDirs.entries()) {
230412
+ const backup = join17(setupRollbackRoot, String(index2));
230413
+ cpSync(pluginDir, backup, { recursive: true });
230414
+ pluginRollbackBackups.set(pluginDir, backup);
230415
+ }
230416
+ }
230417
+ const restoreSetupConfig = () => {
230418
+ if (configRollbackBackup && existsSync5(configRollbackBackup)) {
230419
+ copyFileSync2(configRollbackBackup, configPath);
230420
+ console.error(` \u2713 Restored original OpenClaw config from ${configRollbackBackup}`);
230421
+ } else if (!configInitiallyExisted && existsSync5(configPath)) {
230422
+ rmSync(configPath);
230423
+ console.error(" \u2713 Removed the partially created OpenClaw config");
230424
+ }
230425
+ };
230426
+ const rollbackSetup = () => {
230427
+ if (installAttempted) {
230428
+ if (initialPluginDirs.length === 0) {
230429
+ try {
230430
+ execFileSync(openclawPath, ["plugins", "uninstall", "--force", BLOCKRUN_PLUGIN_ID2], {
230431
+ stdio: "ignore",
230432
+ timeout: 3e4
230433
+ });
230434
+ } catch {
230435
+ }
230436
+ }
230437
+ for (const currentDir of findManagedBlockRunInstalls()) {
230438
+ if (!pluginRollbackBackups.has(currentDir)) {
230439
+ rmSync(currentDir, { recursive: true, force: true });
230440
+ }
230441
+ }
230442
+ for (const [pluginDir, backup] of pluginRollbackBackups) {
230443
+ if (!existsSync5(backup)) continue;
230444
+ rmSync(pluginDir, { recursive: true, force: true });
230445
+ mkdirSync4(dirname4(pluginDir), { recursive: true });
230446
+ cpSync(backup, pluginDir, { recursive: true });
230447
+ }
230448
+ }
230449
+ restoreSetupConfig();
230450
+ rmSync(setupRollbackRoot, { recursive: true, force: true });
230451
+ };
230452
+ let legacyBlockRunInstall = false;
230453
+ let stagedLegacyEntry;
230454
+ if (existsSync5(configPath)) {
230455
+ try {
230456
+ const config = JSON.parse(readFileSync4(configPath, "utf8"));
230457
+ const legacyPackagePath = join17(
230458
+ homedir14(),
230459
+ ".openclaw",
230460
+ "extensions",
230461
+ "clawrouter",
230462
+ "package.json"
230463
+ );
230464
+ if (existsSync5(legacyPackagePath)) {
230465
+ try {
230466
+ const legacyPackage = JSON.parse(readFileSync4(legacyPackagePath, "utf8"));
230467
+ legacyBlockRunInstall = legacyPackage.name === "@blockrun/clawrouter";
230468
+ } catch {
230469
+ }
230470
+ }
230471
+ let stripUnsupportedInstalls = false;
230472
+ try {
230473
+ execFileSync(openclawPath, ["config", "validate"], {
230474
+ encoding: "utf8",
230475
+ stdio: ["ignore", "pipe", "pipe"],
230476
+ timeout: 3e4
230477
+ });
230478
+ } catch (error) {
230479
+ const output = `${error instanceof Error ? error.message : String(error)} ${typeof error === "object" && error && "stdout" in error ? String(error.stdout) : ""} ${typeof error === "object" && error && "stderr" in error ? String(error.stderr) : ""}`;
230480
+ stripUnsupportedInstalls = output.includes("Unrecognized key") && output.includes("installs");
230481
+ }
230482
+ let configChanged = false;
230483
+ if (legacyBlockRunInstall) {
230484
+ const stagedConfig = structuredClone(config);
230485
+ prepareBlockRunPluginConfig2(stagedConfig, { legacyBlockRunInstall: true });
230486
+ const stagedPlugins = stagedConfig.plugins;
230487
+ const stagedEntries = stagedPlugins?.entries;
230488
+ stagedLegacyEntry = stagedEntries?.[BLOCKRUN_PLUGIN_ID2];
230489
+ const livePlugins = config.plugins;
230490
+ if (stagedEntries?.clawrouter && livePlugins?.entries?.clawrouter) {
230491
+ if (JSON.stringify(livePlugins.entries.clawrouter) !== JSON.stringify(stagedEntries.clawrouter)) {
230492
+ livePlugins.entries.clawrouter = stagedEntries.clawrouter;
230493
+ configChanged = true;
230494
+ }
230495
+ }
230496
+ }
230497
+ configChanged = prepareBlockRunPluginConfig2(config, { stripUnsupportedInstalls }) || configChanged;
230498
+ if (configChanged) {
230499
+ const backupPath = ensureConfigRollbackBackup();
230500
+ const tmpPath = `${configPath}.tmp.${process.pid}`;
230501
+ writeFileSync4(tmpPath, `${JSON.stringify(config, null, 2)}
230502
+ `, { mode: 384 });
230503
+ renameSync3(tmpPath, configPath);
230504
+ console.log(` \u2713 Prepared OpenClaw 2.0 config (backup: ${backupPath})`);
230505
+ }
230506
+ } catch (err) {
230507
+ rollbackSetup();
230508
+ console.error(
230509
+ ` \u2717 Cannot safely prepare OpenClaw config: ${err instanceof Error ? err.message : String(err)}`
230510
+ );
230511
+ process.exit(1);
230512
+ }
230513
+ }
229614
230514
  console.log("\n\u2192 Registering ClawRouter with OpenClaw...");
229615
- let installOk = false;
229616
230515
  try {
229617
- execFileSync(openclawPath, ["plugins", "install", "--force", "@blockrun/clawrouter"], {
229618
- stdio: "inherit"
230516
+ let acceptsCapabilities = false;
230517
+ try {
230518
+ const help = execFileSync(openclawPath, ["plugins", "install", "--help"], {
230519
+ encoding: "utf8",
230520
+ stdio: ["ignore", "pipe", "pipe"],
230521
+ timeout: 15e3
230522
+ });
230523
+ acceptsCapabilities = help.includes("--accept-capabilities");
230524
+ } catch {
230525
+ }
230526
+ const installSpec = process.env.BLOCKRUN_CLAWROUTER_INSTALL_SPEC ?? "@blockrun/clawrouter";
230527
+ const installArgs = ["plugins", "install", "--force"];
230528
+ if (acceptsCapabilities) installArgs.push("--accept-capabilities");
230529
+ installArgs.push(installSpec);
230530
+ installAttempted = true;
230531
+ execFileSync(openclawPath, installArgs, {
230532
+ stdio: "inherit",
230533
+ timeout: 18e4
229619
230534
  });
229620
- installOk = true;
229621
230535
  } catch (err) {
229622
- console.warn(
229623
- ` \u26A0 openclaw plugins install reported a problem: ${err instanceof Error ? err.message : String(err)}`
230536
+ rollbackSetup();
230537
+ console.error(
230538
+ ` \u2717 OpenClaw plugin install failed: ${err instanceof Error ? err.message : String(err)}`
229624
230539
  );
229625
- console.warn(" Continuing with manual config sync \u2014 if validation rejected the install,");
229626
- console.warn(
229627
- " re-run `openclaw plugins install --force @blockrun/clawrouter` after gateway start."
230540
+ console.error(
230541
+ " Configuration was rolled back. Fix the error and run `clawrouter setup` again."
229628
230542
  );
230543
+ process.exit(1);
230544
+ }
230545
+ if (existsSync5(configPath)) {
230546
+ try {
230547
+ const config = JSON.parse(readFileSync4(configPath, "utf8"));
230548
+ if (stagedLegacyEntry) {
230549
+ const plugins = config.plugins ??= {};
230550
+ const entries = plugins.entries ??= {};
230551
+ const current = entries[BLOCKRUN_PLUGIN_ID2] ?? {};
230552
+ const stagedConfig = stagedLegacyEntry.config;
230553
+ const currentConfig = current.config;
230554
+ entries[BLOCKRUN_PLUGIN_ID2] = {
230555
+ ...stagedLegacyEntry,
230556
+ ...current,
230557
+ ...stagedConfig || currentConfig ? { config: { ...stagedConfig, ...currentConfig } } : {}
230558
+ };
230559
+ }
230560
+ const configChanged = prepareBlockRunPluginConfig2(config, {
230561
+ explicitSetup: true,
230562
+ legacyBlockRunInstall
230563
+ });
230564
+ if (stagedLegacyEntry || configChanged) {
230565
+ const backupPath = ensureConfigRollbackBackup();
230566
+ const tmpPath = `${configPath}.tmp.${process.pid}`;
230567
+ writeFileSync4(tmpPath, `${JSON.stringify(config, null, 2)}
230568
+ `, { mode: 384 });
230569
+ renameSync3(tmpPath, configPath);
230570
+ console.log(
230571
+ ` \u2713 Enabled ${BLOCKRUN_PLUGIN_ID2}${backupPath ? ` (backup: ${backupPath})` : ""}`
230572
+ );
230573
+ }
230574
+ } catch (err) {
230575
+ rollbackSetup();
230576
+ console.error(
230577
+ ` \u2717 Plugin installed, but its config could not be enabled safely: ${err instanceof Error ? err.message : String(err)}`
230578
+ );
230579
+ process.exit(1);
230580
+ }
229629
230581
  }
229630
230582
  console.log("\n\u2192 Syncing models allowlist + auth profile...");
229631
230583
  const setupLogger = {
229632
230584
  info: (msg) => console.log(` ${msg}`)
229633
230585
  };
229634
230586
  try {
230587
+ if (existsSync5(configPath)) ensureConfigRollbackBackup();
229635
230588
  injectModelsConfig2(setupLogger, { forceWrite: true });
229636
230589
  syncAgentModelCache2(setupLogger, { forceWrite: true });
229637
230590
  injectAuthProfile2(setupLogger);
229638
230591
  } catch (err) {
230592
+ rollbackSetup();
229639
230593
  console.error(` \u2717 Config sync failed: ${err instanceof Error ? err.message : String(err)}`);
229640
230594
  process.exit(1);
229641
230595
  }
229642
- if (installOk) {
229643
- console.log("\n\u2713 Setup complete.");
229644
- } else {
229645
- console.log("\n\u2713 Models config synced (plugin registration may need a manual retry).");
230596
+ console.log("\n\u2713 Setup complete.");
230597
+ rmSync(setupRollbackRoot, { recursive: true, force: true });
230598
+ if (configRollbackBackup && existsSync5(configRollbackBackup)) {
230599
+ unlinkSync2(configRollbackBackup);
229646
230600
  }
229647
230601
  console.log("\nNext: restart the gateway to load ClawRouter:");
229648
230602
  console.log(" openclaw gateway restart");
@@ -229666,6 +230620,7 @@ function parseArgs(args) {
229666
230620
  walletRecover: false,
229667
230621
  chain: void 0,
229668
230622
  port: void 0,
230623
+ noReuse: false,
229669
230624
  queryStatus: false,
229670
230625
  queryWallet: false,
229671
230626
  queryModels: false,
@@ -229682,7 +230637,9 @@ function parseArgs(args) {
229682
230637
  phoneSubcommand: void 0,
229683
230638
  phoneNumbersAction: void 0,
229684
230639
  phoneArg: void 0,
229685
- phoneAreaCode: void 0
230640
+ phoneAreaCode: void 0,
230641
+ policy: false,
230642
+ policyArgs: []
229686
230643
  };
229687
230644
  for (let i = 0; i < args.length; i++) {
229688
230645
  const arg = args[i];
@@ -229743,9 +230700,15 @@ function parseArgs(args) {
229743
230700
  } else if ((arg === "chain" || arg === "/wallet") && (args[i + 1] === "solana" || args[i + 1] === "base")) {
229744
230701
  result.chain = args[i + 1];
229745
230702
  i++;
230703
+ } else if (arg === "policy") {
230704
+ result.policy = true;
230705
+ result.policyArgs = args.slice(i + 1);
230706
+ break;
229746
230707
  } else if (arg === "--port" && args[i + 1]) {
229747
230708
  result.port = parseInt(args[i + 1], 10);
229748
230709
  i++;
230710
+ } else if (arg === "--no-reuse") {
230711
+ result.noReuse = true;
229749
230712
  } else if (arg === "setup") {
229750
230713
  result.setup = true;
229751
230714
  } else if (arg === "phone") {
@@ -229833,6 +230796,15 @@ async function main() {
229833
230796
  await cmdSetup();
229834
230797
  process.exit(0);
229835
230798
  }
230799
+ if (args.policy) {
230800
+ const result = runPolicyCommand(args.policyArgs);
230801
+ if (result.isError) {
230802
+ console.error(`\u2717 ${result.text}`);
230803
+ process.exit(1);
230804
+ }
230805
+ console.log(result.text);
230806
+ process.exit(0);
230807
+ }
229836
230808
  const queryPort = args.port ?? getProxyPort();
229837
230809
  if (args.queryStatus) {
229838
230810
  await cmdStatus(queryPort);
@@ -229950,16 +230922,13 @@ ClawRouter Partner APIs (v${VERSION})
229950
230922
  if (args.chain) {
229951
230923
  const targetChain = args.chain;
229952
230924
  if (targetChain === "solana") {
229953
- const { existsSync: existsSync5 } = await import("fs");
229954
230925
  const { MNEMONIC_FILE: MNEMONIC_FILE2, setupSolana: setupSolana2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
229955
- const { deriveSolanaKeyBytes: deriveSolanaKeyBytes2, getSolanaAddress: getSolanaAddress2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
230926
+ const { getSolanaAddress: getSolanaAddress2 } = await Promise.resolve().then(() => (init_wallet2(), wallet_exports));
230927
+ const wallet2 = await resolveOrGenerateWalletKey();
229956
230928
  let solanaAddr;
229957
- if (existsSync5(MNEMONIC_FILE2)) {
229958
- const { readFileSync: readFileSync4 } = await import("fs");
229959
- const mnemonic = readFileSync4(MNEMONIC_FILE2, "utf8").trim();
229960
- const keyBytes = deriveSolanaKeyBytes2(mnemonic);
229961
- solanaAddr = await getSolanaAddress2(keyBytes);
229962
- console.log(`[ClawRouter] Solana wallet already set up.`);
230929
+ if (wallet2.solanaPrivateKeyBytes) {
230930
+ solanaAddr = await getSolanaAddress2(wallet2.solanaPrivateKeyBytes);
230931
+ console.log(`[ClawRouter] Using BlockRun Core Solana wallet.`);
229963
230932
  } else {
229964
230933
  console.log(`[ClawRouter] Setting up Solana wallet...`);
229965
230934
  const { solanaPrivateKeyBytes } = await setupSolana2();
@@ -229989,6 +230958,8 @@ ClawRouter Partner APIs (v${VERSION})
229989
230958
  const wallet = await resolveOrGenerateWalletKey();
229990
230959
  if (wallet.source === "generated") {
229991
230960
  console.log(`[ClawRouter] Generated new wallet: ${wallet.address}`);
230961
+ } else if (wallet.source === "core") {
230962
+ console.log(`[ClawRouter] Using BlockRun Core wallet: ${wallet.address}`);
229992
230963
  } else if (wallet.source === "saved") {
229993
230964
  console.log(`[ClawRouter] Using saved wallet: ${wallet.address}`);
229994
230965
  } else if (wallet.source === "config") {
@@ -230006,6 +230977,7 @@ ClawRouter Partner APIs (v${VERSION})
230006
230977
  const proxy = await startProxy({
230007
230978
  wallet,
230008
230979
  port: args.port,
230980
+ allowExistingProxy: !args.noReuse,
230009
230981
  onReady: (port) => {
230010
230982
  console.log(`[ClawRouter] v${VERSION} | Proxy listening on http://127.0.0.1:${port}`);
230011
230983
  console.log(`[ClawRouter] Health check: http://127.0.0.1:${port}/health`);