@blockrun/clawrouter 0.4.5 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -125,6 +125,7 @@ ClawRouter's keyword-based routing works with prompts in:
125
125
  | **Chinese (中文)** | Han/CJK | 证明, 定理, 你好, 什么是 |
126
126
  | **Japanese (日本語)** | Kanji + Kana | 証明, こんにちは, アルゴリズム |
127
127
  | **Russian (Русский)** | Cyrillic | доказать, привет, алгоритм |
128
+ | **German (Deutsch)** | Latin | beweisen, hallo, algorithmus |
128
129
 
129
130
  Mixed-language prompts are supported — keywords from all languages are checked simultaneously.
130
131
 
@@ -256,6 +257,60 @@ If you explicitly want to use a different wallet:
256
257
  2. Set `BLOCKRUN_WALLET_KEY=0x...`
257
258
  3. Restart OpenClaw
258
259
 
260
+ ### Wallet Backup & Recovery
261
+
262
+ Your wallet private key is stored at `~/.openclaw/blockrun/wallet.key`. **Back up this file before terminating any VPS or machine!**
263
+
264
+ #### Using the `/wallet` Command
265
+
266
+ ClawRouter provides a built-in command for wallet management:
267
+
268
+ ```bash
269
+ # Check wallet status (address, balance, file location)
270
+ /wallet
271
+
272
+ # Export private key for backup (shows the actual key)
273
+ /wallet export
274
+ ```
275
+
276
+ The `/wallet export` command displays your private key so you can copy it before terminating a machine.
277
+
278
+ #### Manual Backup
279
+
280
+ ```bash
281
+ # Option 1: Copy the key file
282
+ cp ~/.openclaw/blockrun/wallet.key ~/backup-wallet.key
283
+
284
+ # Option 2: View and copy the key
285
+ cat ~/.openclaw/blockrun/wallet.key
286
+ ```
287
+
288
+ #### Restore on a New Machine
289
+
290
+ ```bash
291
+ # Option 1: Set environment variable (before installing ClawRouter)
292
+ export BLOCKRUN_WALLET_KEY=0x...your_key_here...
293
+ openclaw plugins install @blockrun/clawrouter
294
+
295
+ # Option 2: Create the key file directly
296
+ mkdir -p ~/.openclaw/blockrun
297
+ echo "0x...your_key_here..." > ~/.openclaw/blockrun/wallet.key
298
+ chmod 600 ~/.openclaw/blockrun/wallet.key
299
+ openclaw plugins install @blockrun/clawrouter
300
+ ```
301
+
302
+ **Important:** If a saved wallet file exists, it takes priority over the environment variable. To use a different wallet, delete the existing file first.
303
+
304
+ #### Lost Key Recovery
305
+
306
+ If you lose your wallet key, **there is no way to recover it**. The wallet is self-custodial, meaning only you have the private key. We do not store keys or have any way to restore access.
307
+
308
+ **Prevention tips:**
309
+
310
+ - Run `/wallet export` before terminating any VPS
311
+ - Keep a secure backup of `~/.openclaw/blockrun/wallet.key`
312
+ - For production use, consider using a hardware wallet or key management system
313
+
259
314
  ---
260
315
 
261
316
  ## Architecture
package/dist/index.js CHANGED
@@ -730,7 +730,7 @@ var DEFAULT_ROUTING_CONFIG = {
730
730
  },
731
731
  scoring: {
732
732
  tokenCountThresholds: { simple: 50, complex: 500 },
733
- // Multilingual keywords: English + Chinese (中文) + Japanese (日本語) + Russian (Русский)
733
+ // Multilingual keywords: English + Chinese (中文) + Japanese (日本語) + Russian (Русский) + German (Deutsch)
734
734
  codeKeywords: [
735
735
  // English
736
736
  "function",
@@ -773,7 +773,18 @@ var DEFAULT_ROUTING_CONFIG = {
773
773
  "\u043E\u0436\u0438\u0434\u0430\u0442\u044C",
774
774
  "\u043A\u043E\u043D\u0441\u0442\u0430\u043D\u0442\u0430",
775
775
  "\u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u0430\u044F",
776
- "\u0432\u0435\u0440\u043D\u0443\u0442\u044C"
776
+ "\u0432\u0435\u0440\u043D\u0443\u0442\u044C",
777
+ // German
778
+ "funktion",
779
+ "klasse",
780
+ "importieren",
781
+ "definieren",
782
+ "abfrage",
783
+ "asynchron",
784
+ "erwarten",
785
+ "konstante",
786
+ "variable",
787
+ "zur\xFCckgeben"
777
788
  ],
778
789
  reasoningKeywords: [
779
790
  // English
@@ -814,7 +825,17 @@ var DEFAULT_ROUTING_CONFIG = {
814
825
  "\u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043D\u0438",
815
826
  "\u0444\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E",
816
827
  "\u043C\u0430\u0442\u0435\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438",
817
- "\u043B\u043E\u0433\u0438\u0447\u0435\u0441\u043A\u0438"
828
+ "\u043B\u043E\u0433\u0438\u0447\u0435\u0441\u043A\u0438",
829
+ // German
830
+ "beweisen",
831
+ "beweis",
832
+ "theorem",
833
+ "ableiten",
834
+ "schritt f\xFCr schritt",
835
+ "gedankenkette",
836
+ "formal",
837
+ "mathematisch",
838
+ "logisch"
818
839
  ],
819
840
  simpleKeywords: [
820
841
  // English
@@ -856,7 +877,18 @@ var DEFAULT_ROUTING_CONFIG = {
856
877
  "\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043B\u0435\u0442",
857
878
  "\u043A\u0442\u043E \u0442\u0430\u043A\u043E\u0439",
858
879
  "\u043A\u043E\u0433\u0434\u0430",
859
- "\u043E\u0431\u044A\u044F\u0441\u043D\u0438"
880
+ "\u043E\u0431\u044A\u044F\u0441\u043D\u0438",
881
+ // German
882
+ "was ist",
883
+ "definiere",
884
+ "\xFCbersetze",
885
+ "hallo",
886
+ "ja oder nein",
887
+ "hauptstadt",
888
+ "wie alt",
889
+ "wer ist",
890
+ "wann",
891
+ "erkl\xE4re"
860
892
  ],
861
893
  technicalKeywords: [
862
894
  // English
@@ -892,7 +924,16 @@ var DEFAULT_ROUTING_CONFIG = {
892
924
  "\u0440\u0430\u0441\u043F\u0440\u0435\u0434\u0435\u043B\u0451\u043D\u043D\u044B\u0439",
893
925
  "\u043C\u0438\u043A\u0440\u043E\u0441\u0435\u0440\u0432\u0438\u0441",
894
926
  "\u0431\u0430\u0437\u0430 \u0434\u0430\u043D\u043D\u044B\u0445",
895
- "\u0438\u043D\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430"
927
+ "\u0438\u043D\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430",
928
+ // German
929
+ "algorithmus",
930
+ "optimieren",
931
+ "architektur",
932
+ "verteilt",
933
+ "kubernetes",
934
+ "mikroservice",
935
+ "datenbank",
936
+ "infrastruktur"
896
937
  ],
897
938
  creativeKeywords: [
898
939
  // English
@@ -928,7 +969,16 @@ var DEFAULT_ROUTING_CONFIG = {
928
969
  "\u0442\u0432\u043E\u0440\u0447\u0435\u0441\u043A\u0438\u0439",
929
970
  "\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044C",
930
971
  "\u043F\u0440\u0438\u0434\u0443\u043C\u0430\u0439",
931
- "\u043D\u0430\u043F\u0438\u0448\u0438"
972
+ "\u043D\u0430\u043F\u0438\u0448\u0438",
973
+ // German
974
+ "geschichte",
975
+ "gedicht",
976
+ "komponieren",
977
+ "brainstorming",
978
+ "kreativ",
979
+ "vorstellen",
980
+ "schreibe",
981
+ "erz\xE4hlung"
932
982
  ],
933
983
  // New dimension keyword lists (multilingual)
934
984
  imperativeVerbs: [
@@ -978,7 +1028,18 @@ var DEFAULT_ROUTING_CONFIG = {
978
1028
  "\u0440\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C",
979
1029
  "\u0440\u0430\u0437\u0432\u0435\u0440\u043D\u0438",
980
1030
  "\u043D\u0430\u0441\u0442\u0440\u043E\u0438\u0442\u044C",
981
- "\u043D\u0430\u0441\u0442\u0440\u043E\u0439"
1031
+ "\u043D\u0430\u0441\u0442\u0440\u043E\u0439",
1032
+ // German
1033
+ "erstellen",
1034
+ "bauen",
1035
+ "implementieren",
1036
+ "entwerfen",
1037
+ "entwickeln",
1038
+ "konstruieren",
1039
+ "generieren",
1040
+ "bereitstellen",
1041
+ "konfigurieren",
1042
+ "einrichten"
982
1043
  ],
983
1044
  constraintIndicators: [
984
1045
  // English
@@ -1015,7 +1076,16 @@ var DEFAULT_ROUTING_CONFIG = {
1015
1076
  "\u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C",
1016
1077
  "\u043C\u0438\u043D\u0438\u043C\u0443\u043C",
1017
1078
  "\u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u0435",
1018
- "\u0431\u044E\u0434\u0436\u0435\u0442"
1079
+ "\u0431\u044E\u0434\u0436\u0435\u0442",
1080
+ // German
1081
+ "h\xF6chstens",
1082
+ "mindestens",
1083
+ "innerhalb",
1084
+ "nicht mehr als",
1085
+ "maximal",
1086
+ "minimal",
1087
+ "grenze",
1088
+ "budget"
1019
1089
  ],
1020
1090
  outputFormatKeywords: [
1021
1091
  // English
@@ -1039,7 +1109,11 @@ var DEFAULT_ROUTING_CONFIG = {
1039
1109
  // Russian
1040
1110
  "\u0442\u0430\u0431\u043B\u0438\u0446\u0430",
1041
1111
  "\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043A\u0430\u043A",
1042
- "\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439"
1112
+ "\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439",
1113
+ // German
1114
+ "tabelle",
1115
+ "formatieren als",
1116
+ "strukturiert"
1043
1117
  ],
1044
1118
  referenceKeywords: [
1045
1119
  // English
@@ -1075,7 +1149,16 @@ var DEFAULT_ROUTING_CONFIG = {
1075
1149
  "\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044F",
1076
1150
  "\u043A\u043E\u0434",
1077
1151
  "\u0440\u0430\u043D\u0435\u0435",
1078
- "\u0432\u043B\u043E\u0436\u0435\u043D\u0438\u0435"
1152
+ "\u0432\u043B\u043E\u0436\u0435\u043D\u0438\u0435",
1153
+ // German
1154
+ "oben",
1155
+ "unten",
1156
+ "vorherige",
1157
+ "folgende",
1158
+ "dokumentation",
1159
+ "der code",
1160
+ "fr\xFCher",
1161
+ "anhang"
1079
1162
  ],
1080
1163
  negationKeywords: [
1081
1164
  // English
@@ -1109,7 +1192,15 @@ var DEFAULT_ROUTING_CONFIG = {
1109
1192
  "\u0431\u0435\u0437",
1110
1193
  "\u043A\u0440\u043E\u043C\u0435",
1111
1194
  "\u0438\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u044C",
1112
- "\u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435"
1195
+ "\u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435",
1196
+ // German
1197
+ "nicht",
1198
+ "vermeide",
1199
+ "niemals",
1200
+ "ohne",
1201
+ "au\xDFer",
1202
+ "ausschlie\xDFen",
1203
+ "nicht mehr"
1113
1204
  ],
1114
1205
  domainSpecificKeywords: [
1115
1206
  // English
@@ -1147,7 +1238,16 @@ var DEFAULT_ROUTING_CONFIG = {
1147
1238
  "\u0442\u043E\u043F\u043E\u043B\u043E\u0433\u0438\u0447\u0435\u0441\u043A\u0438\u0439",
1148
1239
  "\u0433\u043E\u043C\u043E\u043C\u043E\u0440\u0444\u043D\u044B\u0439",
1149
1240
  "\u0441 \u043D\u0443\u043B\u0435\u0432\u044B\u043C \u0440\u0430\u0437\u0433\u043B\u0430\u0448\u0435\u043D\u0438\u0435\u043C",
1150
- "\u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u0435 \u0440\u0435\u0448\u0451\u0442\u043E\u043A"
1241
+ "\u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u0435 \u0440\u0435\u0448\u0451\u0442\u043E\u043A",
1242
+ // German
1243
+ "quanten",
1244
+ "photonik",
1245
+ "genomik",
1246
+ "proteomik",
1247
+ "topologisch",
1248
+ "homomorph",
1249
+ "zero-knowledge",
1250
+ "gitterbasiert"
1151
1251
  ],
1152
1252
  // Dimension weights (sum to 1.0)
1153
1253
  dimensionWeights: {
@@ -2322,6 +2422,7 @@ async function resolveOrGenerateWalletKey() {
2322
2422
  import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "fs";
2323
2423
  import { homedir as homedir3 } from "os";
2324
2424
  import { join as join4 } from "path";
2425
+ import { privateKeyToAccount as privateKeyToAccount4 } from "viem/accounts";
2325
2426
 
2326
2427
  // src/retry.ts
2327
2428
  var DEFAULT_RETRY_CONFIG = {
@@ -2551,6 +2652,81 @@ async function startProxyInBackground(api) {
2551
2652
  activeProxyHandle = proxy;
2552
2653
  api.logger.info(`BlockRun provider active \u2014 ${proxy.baseUrl}/v1 (smart routing enabled)`);
2553
2654
  }
2655
+ async function createWalletCommand() {
2656
+ return {
2657
+ name: "wallet",
2658
+ description: "Show BlockRun wallet info or export private key for backup",
2659
+ acceptsArgs: true,
2660
+ requireAuth: true,
2661
+ handler: async (ctx) => {
2662
+ const subcommand = ctx.args?.trim().toLowerCase() || "status";
2663
+ let walletKey;
2664
+ let address;
2665
+ try {
2666
+ if (existsSync(WALLET_FILE)) {
2667
+ walletKey = readFileSync(WALLET_FILE, "utf-8").trim();
2668
+ if (walletKey.startsWith("0x") && walletKey.length === 66) {
2669
+ const account = privateKeyToAccount4(walletKey);
2670
+ address = account.address;
2671
+ }
2672
+ }
2673
+ } catch {
2674
+ }
2675
+ if (!walletKey || !address) {
2676
+ return {
2677
+ text: `No ClawRouter wallet found.
2678
+
2679
+ Run \`openclaw plugins install @blockrun/clawrouter\` to generate a wallet.`,
2680
+ isError: true
2681
+ };
2682
+ }
2683
+ if (subcommand === "export") {
2684
+ return {
2685
+ text: [
2686
+ "\u{1F510} **ClawRouter Wallet Export**",
2687
+ "",
2688
+ "\u26A0\uFE0F **SECURITY WARNING**: Your private key controls your wallet funds.",
2689
+ "Never share this key. Anyone with this key can spend your USDC.",
2690
+ "",
2691
+ `**Address:** \`${address}\``,
2692
+ "",
2693
+ `**Private Key:**`,
2694
+ `\`${walletKey}\``,
2695
+ "",
2696
+ "**To restore on a new machine:**",
2697
+ "1. Set the environment variable before running OpenClaw:",
2698
+ ` \`export BLOCKRUN_WALLET_KEY=${walletKey}\``,
2699
+ "2. Or save to file:",
2700
+ ` \`mkdir -p ~/.openclaw/blockrun && echo "${walletKey}" > ~/.openclaw/blockrun/wallet.key && chmod 600 ~/.openclaw/blockrun/wallet.key\``
2701
+ ].join("\n")
2702
+ };
2703
+ }
2704
+ let balanceText = "Balance: (checking...)";
2705
+ try {
2706
+ const monitor = new BalanceMonitor(address);
2707
+ const balance = await monitor.checkBalance();
2708
+ balanceText = `Balance: ${balance.balanceUSD}`;
2709
+ } catch {
2710
+ balanceText = "Balance: (could not check)";
2711
+ }
2712
+ return {
2713
+ text: [
2714
+ "\u{1F99E} **ClawRouter Wallet**",
2715
+ "",
2716
+ `**Address:** \`${address}\``,
2717
+ `**${balanceText}**`,
2718
+ `**Key File:** \`${WALLET_FILE}\``,
2719
+ "",
2720
+ "**Commands:**",
2721
+ "\u2022 `/wallet` - Show this status",
2722
+ "\u2022 `/wallet export` - Export private key for backup",
2723
+ "",
2724
+ `**Fund with USDC on Base:** https://basescan.org/address/${address}`
2725
+ ].join("\n")
2726
+ };
2727
+ }
2728
+ };
2729
+ }
2554
2730
  var plugin = {
2555
2731
  id: "clawrouter",
2556
2732
  name: "ClawRouter",
@@ -2590,6 +2766,13 @@ var plugin = {
2590
2766
  if (!defaults.model) defaults.model = {};
2591
2767
  defaults.model.primary = "blockrun/auto";
2592
2768
  api.logger.info("BlockRun provider registered (30+ models via x402)");
2769
+ createWalletCommand().then((walletCommand) => {
2770
+ api.registerCommand(walletCommand);
2771
+ }).catch((err) => {
2772
+ api.logger.warn(
2773
+ `Failed to register /wallet command: ${err instanceof Error ? err.message : String(err)}`
2774
+ );
2775
+ });
2593
2776
  api.registerService({
2594
2777
  id: "clawrouter-proxy",
2595
2778
  start: () => {