@blockrun/clawrouter 0.12.99 → 0.12.101

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.
@@ -1 +1 @@
1
- {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,KAAK,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,UAAU,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQ7F;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAwBjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAI3D;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,eAAe,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAInF"}
1
+ {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,KAAK,MAAM,EAAE,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,UAAU,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQ7F;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAyBjE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAI3D;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,eAAe,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAInF"}
package/dist/wallet.js CHANGED
@@ -54,7 +54,8 @@ export function deriveEvmKey(mnemonic) {
54
54
  export function deriveSolanaKeyBytes(mnemonic) {
55
55
  const seed = mnemonicToSeedSync(mnemonic);
56
56
  // Master key from SLIP-10
57
- let I = hmac(sha512, "ed25519 seed", seed);
57
+ // @noble/hashes v2 requires Uint8Array keys (v1 accepted strings)
58
+ let I = hmac(sha512, new TextEncoder().encode("ed25519 seed"), seed);
58
59
  let key = I.slice(0, 32);
59
60
  let chainCode = I.slice(32);
60
61
  // Derive each hardened child: m/44'/501'/0'/0'
@@ -1 +1 @@
1
- {"version":3,"file":"wallet.js","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wallet.js","sourceRoot":"","sources":["../src/wallet.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/clawrouter",
3
- "version": "0.12.99",
3
+ "version": "0.12.101",
4
4
  "description": "Smart LLM router — save 85% on inference costs. 55+ models (11 free), one wallet, x402 micropayments.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -256,6 +256,52 @@ if (fs.existsSync(configPath)) {
256
256
  }
257
257
  "
258
258
 
259
+ # 5b. Ensure provider baseUrl is set (must happen BEFORE openclaw plugins install,
260
+ # which validates the config and fails if baseUrl is missing)
261
+ echo "→ Verifying provider config..."
262
+ node -e "
263
+ const os = require('os');
264
+ const fs = require('fs');
265
+ const path = require('path');
266
+ const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
267
+
268
+ if (!fs.existsSync(configPath)) {
269
+ console.log(' No config file found, skipping');
270
+ process.exit(0);
271
+ }
272
+
273
+ try {
274
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
275
+ const provider = config?.models?.providers?.blockrun;
276
+ if (!provider) {
277
+ console.log(' No blockrun provider found, skipping');
278
+ process.exit(0);
279
+ }
280
+
281
+ let changed = false;
282
+ if (!provider.baseUrl) {
283
+ provider.baseUrl = 'http://127.0.0.1:8402/v1';
284
+ changed = true;
285
+ console.log(' Fixed missing baseUrl');
286
+ }
287
+ if (!provider.apiKey) {
288
+ provider.apiKey = 'x402-proxy-handles-auth';
289
+ changed = true;
290
+ console.log(' Fixed missing apiKey');
291
+ }
292
+
293
+ if (changed) {
294
+ const tmpPath = configPath + '.tmp.' + process.pid;
295
+ fs.writeFileSync(tmpPath, JSON.stringify(config, null, 2));
296
+ fs.renameSync(tmpPath, configPath);
297
+ } else {
298
+ console.log(' Provider config OK');
299
+ }
300
+ } catch (err) {
301
+ console.log(' Skipped: ' + err.message);
302
+ }
303
+ "
304
+
259
305
  # 6. Install plugin (config is ready, but no allow list yet to avoid validation error)
260
306
  # Back up OpenClaw credentials (channels, WhatsApp/Telegram state) before plugin install
261
307
  CREDS_DIR="$HOME/.openclaw/credentials"
@@ -437,51 +483,6 @@ if (fs.existsSync(configPath)) {
437
483
  }
438
484
  "
439
485
 
440
- # 8. Ensure provider baseUrl is set (prevents "baseUrl: undefined" on gateway restart)
441
- echo "→ Verifying provider config..."
442
- node -e "
443
- const os = require('os');
444
- const fs = require('fs');
445
- const path = require('path');
446
- const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
447
-
448
- if (!fs.existsSync(configPath)) {
449
- console.log(' No config file found, skipping');
450
- process.exit(0);
451
- }
452
-
453
- try {
454
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
455
- const provider = config?.models?.providers?.blockrun;
456
- if (!provider) {
457
- console.log(' No blockrun provider found, skipping');
458
- process.exit(0);
459
- }
460
-
461
- let changed = false;
462
- if (!provider.baseUrl) {
463
- provider.baseUrl = 'http://127.0.0.1:8402/v1';
464
- changed = true;
465
- console.log(' Fixed missing baseUrl');
466
- }
467
- if (!provider.apiKey) {
468
- provider.apiKey = 'x402-proxy-handles-auth';
469
- changed = true;
470
- console.log(' Fixed missing apiKey');
471
- }
472
-
473
- if (changed) {
474
- const tmpPath = configPath + '.tmp.' + process.pid;
475
- fs.writeFileSync(tmpPath, JSON.stringify(config, null, 2));
476
- fs.renameSync(tmpPath, configPath);
477
- } else {
478
- console.log(' Provider config OK');
479
- }
480
- } catch (err) {
481
- console.log(' Skipped: ' + err.message);
482
- }
483
- "
484
-
485
486
  # Final: verify wallet survived reinstall
486
487
  echo "→ Verifying wallet integrity..."
487
488
  if [ -f "$WALLET_FILE" ]; then
package/scripts/update.sh CHANGED
@@ -169,6 +169,27 @@ try {
169
169
  }
170
170
  "
171
171
 
172
+ # ── Step 3b: Ensure baseUrl is set (must happen BEFORE install, which validates config) ──
173
+ echo "→ Verifying provider config..."
174
+ node -e "
175
+ const fs = require('fs');
176
+ const configPath = '$CONFIG_PATH';
177
+ if (!fs.existsSync(configPath)) { console.log(' No config, skipping'); process.exit(0); }
178
+ try {
179
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
180
+ const provider = config?.models?.providers?.blockrun;
181
+ if (!provider) { console.log(' No blockrun provider, skipping'); process.exit(0); }
182
+ let changed = false;
183
+ if (!provider.baseUrl) { provider.baseUrl = 'http://127.0.0.1:8402/v1'; changed = true; console.log(' Fixed missing baseUrl'); }
184
+ if (!provider.apiKey) { provider.apiKey = 'x402-proxy-handles-auth'; changed = true; console.log(' Fixed missing apiKey'); }
185
+ if (changed) {
186
+ const tmp = configPath + '.tmp.' + process.pid;
187
+ fs.writeFileSync(tmp, JSON.stringify(config, null, 2));
188
+ fs.renameSync(tmp, configPath);
189
+ } else { console.log(' Provider config OK'); }
190
+ } catch (err) { console.log(' Skipped: ' + err.message); }
191
+ "
192
+
172
193
  # ── Step 4: Install latest version ─────────────────────────────
173
194
  # Back up OpenClaw credentials (channels, WhatsApp/Telegram state) before plugin install
174
195
  CREDS_DIR="$HOME/.openclaw/credentials"
@@ -350,51 +371,6 @@ try {
350
371
  }
351
372
  "
352
373
 
353
- # ── Step 9: Ensure baseUrl is set ─────────────────────────────
354
- echo "→ Verifying provider config..."
355
- node -e "
356
- const os = require('os');
357
- const fs = require('fs');
358
- const path = require('path');
359
- const configPath = path.join(os.homedir(), '.openclaw', 'openclaw.json');
360
-
361
- if (!fs.existsSync(configPath)) {
362
- console.log(' No config file found, skipping');
363
- process.exit(0);
364
- }
365
-
366
- try {
367
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
368
- const provider = config?.models?.providers?.blockrun;
369
- if (!provider) {
370
- console.log(' No blockrun provider found, skipping');
371
- process.exit(0);
372
- }
373
-
374
- let changed = false;
375
- if (!provider.baseUrl) {
376
- provider.baseUrl = 'http://127.0.0.1:8402/v1';
377
- changed = true;
378
- console.log(' Fixed missing baseUrl');
379
- }
380
- if (!provider.apiKey) {
381
- provider.apiKey = 'x402-proxy-handles-auth';
382
- changed = true;
383
- console.log(' Fixed missing apiKey');
384
- }
385
-
386
- if (changed) {
387
- const tmpPath = configPath + '.tmp.' + process.pid;
388
- fs.writeFileSync(tmpPath, JSON.stringify(config, null, 2));
389
- fs.renameSync(tmpPath, configPath);
390
- } else {
391
- console.log(' Provider config OK');
392
- }
393
- } catch (err) {
394
- console.log(' Skipped: ' + err.message);
395
- }
396
- "
397
-
398
374
  # ── Summary ─────────────────────────────────────────────────────
399
375
  echo ""
400
376
  echo "✓ ClawRouter updated successfully!"