@agentlayer.tech/wallet 0.1.70 → 0.1.71

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.
@@ -2,7 +2,7 @@
2
2
  "id": "agent-wallet",
3
3
  "name": "Agent Wallet",
4
4
  "description": "Official OpenClaw plugin bridge for the agent-wallet backends, including Solana, local BTC, and local EVM.",
5
- "version": "0.1.70",
5
+ "version": "0.1.71",
6
6
  "contracts": {
7
7
  "tools": [
8
8
  "agentlayer_autonomous_approve",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentlayertech/agent-wallet-plugin",
3
- "version": "0.1.70",
3
+ "version": "0.1.71",
4
4
  "description": "OpenClaw plugin bridge for the AgentLayer wallet runtime.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN ../../../LICENSE",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v0.1.71 - 2026-07-09
6
+
7
+ - Fixed `wallet update` leaving editor integrations pinned to a stale
8
+ `releases/<version>` path after a runtime upgrade. The installer and
9
+ OpenClaw local config now canonicalize runtime-owned paths back through
10
+ `~/.openclaw/agent-wallet-runtime/current`, and the update command
11
+ proactively refreshes existing Hermes, Codex, and Claude Code installs so a
12
+ successful update rewires old integrations to the new active runtime
13
+ automatically. The `update` CLI path also now returns its final update JSON
14
+ payload directly instead of leaking the nested install payload shape.
15
+ - `bin/openclaw-agent-wallet.mjs`
16
+ - `agent-wallet/scripts/install_openclaw_local_config.py`
17
+ - `agent-wallet/tests/smoke_install_openclaw_local_config_runtime_defaults.py`
18
+ - `agent-wallet/tests/smoke_npm_installer.py`
19
+ - `agent-wallet/tests/smoke_update_repairs_editor_installs.py`
20
+
21
+ - Fixed the EVM live tool list dropping the read-only `x402_*` service tools
22
+ because the adapter returned before appending them. EVM-backed runtimes now
23
+ expose x402 discovery/preview/pay tool specs consistently alongside the rest
24
+ of the EVM wallet surface.
25
+ - `agent-wallet/agent_wallet/openclaw_adapter.py`
26
+ - `agent-wallet/tests/smoke_openclaw_evm_x402_tools.py`
27
+
5
28
  - Fixed the npm `files` allowlist dropping `.env.example` for `wdk-evm-wallet`
6
29
  and `wdk-btc-wallet`. Both templates are tracked in git and correctly
7
30
  un-ignored (`!.env.example` in `.gitignore`), but the root `package.json`
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.70
1
+ 0.1.71
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Keep in sync with package.json, pyproject.toml, and the npm installer version.
4
4
  # scripts/check_release_version.mjs enforces this on release.
5
- __version__ = "0.1.70"
5
+ __version__ = "0.1.71"
6
6
 
7
7
  __all__ = [
8
8
  "config",
@@ -2296,6 +2296,7 @@ class OpenClawWalletAdapter:
2296
2296
  ),
2297
2297
  )
2298
2298
 
2299
+ tools.extend(self._x402_tool_specs())
2299
2300
  tools.extend(self._autonomous_permission_tool_specs())
2300
2301
  return tools
2301
2302
 
@@ -2,7 +2,7 @@
2
2
  "id": "agent-wallet",
3
3
  "name": "Agent Wallet",
4
4
  "description": "Plugin-friendly wallet backend for OpenClaw agents with safe wallet tools and runtime instructions across Solana, local BTC, and local EVM.",
5
- "version": "0.1.70",
5
+ "version": "0.1.71",
6
6
  "skills": ["skills/wallet-operator"],
7
7
  "configSchema": {
8
8
  "type": "object",
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "openclaw-agent-wallet"
7
- version = "0.1.70"
7
+ version = "0.1.71"
8
8
  description = "Plugin-friendly wallet backend for OpenClaw agents"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -137,6 +137,26 @@ def _default_runtime_root() -> Path:
137
137
  return _resolve_openclaw_home() / "agent-wallet-runtime" / "current"
138
138
 
139
139
 
140
+ def _canonical_runtime_path(path_value: str) -> Path:
141
+ """Keep host config pinned to runtime/current instead of releases/<version>.
142
+
143
+ The updater flips ``agent-wallet-runtime/current`` on every release. Host
144
+ configs that store resolved release paths silently pin themselves to stale
145
+ code after the next update, so rewrite any release-local path back through
146
+ ``current`` while preserving its relative suffix.
147
+ """
148
+ candidate = Path(path_value).expanduser().resolve()
149
+ releases_root = (_resolve_openclaw_home() / "agent-wallet-runtime" / "releases").resolve()
150
+ try:
151
+ relative = candidate.relative_to(releases_root)
152
+ except ValueError:
153
+ return candidate
154
+ parts = relative.parts
155
+ if len(parts) < 2:
156
+ return candidate
157
+ return _default_runtime_root() / Path(*parts[1:])
158
+
159
+
140
160
  def _repo_root() -> Path:
141
161
  return Path(__file__).resolve().parents[2]
142
162
 
@@ -300,7 +320,7 @@ def main() -> None:
300
320
 
301
321
  load = plugins.setdefault("load", {})
302
322
  paths = load.setdefault("paths", [])
303
- extension_path_text = str(Path(args.extension_path).expanduser().resolve())
323
+ extension_path_text = str(_canonical_runtime_path(args.extension_path))
304
324
  paths[:] = _normalize_load_paths(list(paths), extension_path_text)
305
325
 
306
326
  entries = plugins.setdefault("entries", {})
@@ -316,6 +336,11 @@ def main() -> None:
316
336
  or str(existing_config.get("userId") or "").strip()
317
337
  or _default_user_id()
318
338
  )
339
+ python_bin_text = args.python_bin
340
+ python_bin_candidate = Path(python_bin_text).expanduser()
341
+ if python_bin_text.startswith("~") or python_bin_candidate.is_absolute():
342
+ python_bin_text = str(_canonical_runtime_path(python_bin_text))
343
+
319
344
  plugin_config = {
320
345
  **existing_config,
321
346
  "userId": resolved_user_id,
@@ -324,8 +349,8 @@ def main() -> None:
324
349
  "signOnly": args.sign_only,
325
350
  "encryptUserWallets": args.encrypt_user_wallets,
326
351
  "migratePlaintextUserWallets": args.migrate_plaintext_user_wallets,
327
- "packageRoot": str(Path(args.package_root).expanduser().resolve()),
328
- "pythonBin": args.python_bin,
352
+ "packageRoot": str(_canonical_runtime_path(args.package_root)),
353
+ "pythonBin": python_bin_text,
329
354
  }
330
355
  if args.rpc_url.strip():
331
356
  plugin_config["rpcUrl"] = args.rpc_url.strip()
@@ -382,7 +407,7 @@ def main() -> None:
382
407
  "config_path": str(config_path),
383
408
  "backup_path": str(backup_path),
384
409
  "extension_path": extension_path_text,
385
- "python_bin": args.python_bin,
410
+ "python_bin": python_bin_text,
386
411
  "package_root": plugin_config["packageRoot"],
387
412
  "plugin_id": args.plugin_id,
388
413
  "user_id": resolved_user_id,
@@ -384,6 +384,17 @@ function currentRuntimePath(env = process.env) {
384
384
  return path.join(resolveRuntimeBase(env), "current");
385
385
  }
386
386
 
387
+ function logicalCurrentRuntimeRoot(env = process.env) {
388
+ const currentPath = currentRuntimePath(env);
389
+ try {
390
+ const stat = fs.lstatSync(currentPath);
391
+ if (stat.isSymbolicLink() || stat.isDirectory()) return currentPath;
392
+ } catch (error) {
393
+ if (error?.code !== "ENOENT") throw error;
394
+ }
395
+ return "";
396
+ }
397
+
387
398
  function resolvedCurrentRuntimeRoot(env = process.env) {
388
399
  const currentPath = currentRuntimePath(env);
389
400
  const currentTarget = readLinkOrNull(currentPath);
@@ -1392,6 +1403,8 @@ function runInstall(args, { commandName = "install" } = {}) {
1392
1403
  }
1393
1404
  }
1394
1405
 
1406
+ const integrationRefresh = refreshInstalledEditorIntegrations(env);
1407
+
1395
1408
  const pythonInfo = activePythonRuntimeInfo(env);
1396
1409
  const nodeInfo = activeNodeRuntimeInfo(env)
1397
1410
  .map((item) => `${item.project_name}:${item.shared ? "shared" : item.exists ? "local" : "missing"}`)
@@ -1410,6 +1423,7 @@ function runInstall(args, { commandName = "install" } = {}) {
1410
1423
  current_runtime: currentPath,
1411
1424
  previous_runtime: readLinkOrNull(previousPath),
1412
1425
  generated_runtime_secrets: Object.keys(generated),
1426
+ integration_refresh: integrationRefresh,
1413
1427
  },
1414
1428
  null,
1415
1429
  2,
@@ -1517,9 +1531,10 @@ function runUpdate(args) {
1517
1531
  }
1518
1532
  }
1519
1533
 
1534
+ const currentVersionBefore = activeVersion();
1520
1535
  let delegated;
1521
1536
  try {
1522
- delegated = runDelegatedInstallForUpdate(args, { captureOutput: false });
1537
+ delegated = runDelegatedInstallForUpdate(args, { captureOutput: true });
1523
1538
  } catch (error) {
1524
1539
  console.error(error.message);
1525
1540
  return 1;
@@ -1528,7 +1543,60 @@ function runUpdate(args) {
1528
1543
  console.error(delegated.result.error.message);
1529
1544
  return 1;
1530
1545
  }
1531
- return delegated.result.status ?? 1;
1546
+ const { result } = delegated;
1547
+ if ((result.status ?? 1) !== 0) {
1548
+ const stderr = String(result.stderr || "").trim();
1549
+ const stdout = String(result.stdout || "").trim();
1550
+ if (stderr) process.stderr.write(`${stderr}\n`);
1551
+ if (stdout) process.stderr.write(`${stdout}\n`);
1552
+ return result.status ?? 1;
1553
+ }
1554
+
1555
+ let installPayload;
1556
+ try {
1557
+ installPayload = extractTrailingJson(result.stderr || "") || extractTrailingJson(result.stdout || "");
1558
+ } catch {
1559
+ try {
1560
+ installPayload = extractTrailingJson(result.stdout || "");
1561
+ } catch (error) {
1562
+ const stderr = String(result.stderr || "").trim();
1563
+ const stdout = String(result.stdout || "").trim();
1564
+ if (stderr) process.stderr.write(`${stderr}\n`);
1565
+ if (stdout) process.stderr.write(`${stdout}\n`);
1566
+ console.error(error.message);
1567
+ return 1;
1568
+ }
1569
+ }
1570
+
1571
+ const stderr = String(result.stderr || "");
1572
+ const summaryLine = stderr
1573
+ .split(/\r?\n/)
1574
+ .map((line) => line.trimEnd())
1575
+ .find((line) => line.startsWith("Update summary:"));
1576
+ if (summaryLine) {
1577
+ console.error(summaryLine);
1578
+ }
1579
+
1580
+ console.log(
1581
+ JSON.stringify(
1582
+ {
1583
+ ...installPayload,
1584
+ command: "update",
1585
+ delegated_via: delegated.delegated_via,
1586
+ target_package_spec: delegated.target_package_spec,
1587
+ target_version:
1588
+ delegated.target_version_hint ||
1589
+ pathVersionFromRuntimeRoot(installPayload?.runtime_root) ||
1590
+ installPayload?.version ||
1591
+ null,
1592
+ previous_version: currentVersionBefore,
1593
+ active_version: activeVersion(),
1594
+ },
1595
+ null,
1596
+ 2,
1597
+ ),
1598
+ );
1599
+ return 0;
1532
1600
  }
1533
1601
 
1534
1602
  function runRollback(args) {
@@ -1571,7 +1639,7 @@ function runRollback(args) {
1571
1639
  }
1572
1640
 
1573
1641
  function resolveHermesPluginSource() {
1574
- const currentRoot = resolvedCurrentRuntimeRoot();
1642
+ const currentRoot = logicalCurrentRuntimeRoot();
1575
1643
  const candidates = [];
1576
1644
  if (currentRoot) {
1577
1645
  candidates.push(path.join(currentRoot, "hermes", "plugins", "agent_wallet"));
@@ -1589,7 +1657,7 @@ function resolveCodexPluginSource() {
1589
1657
  // test/CI override: inject a staged bundle dir
1590
1658
  const override = String(process.env.AGENT_WALLET_CODEX_PLUGIN_SOURCE || "").trim();
1591
1659
  if (override) return path.resolve(expandHome(override));
1592
- const currentRoot = resolvedCurrentRuntimeRoot();
1660
+ const currentRoot = logicalCurrentRuntimeRoot();
1593
1661
  const candidates = [];
1594
1662
  if (currentRoot) {
1595
1663
  candidates.push(path.join(currentRoot, "codex", "plugins", "agent-wallet"));
@@ -1607,7 +1675,7 @@ function resolveClaudeCodePluginSource() {
1607
1675
  // test/CI override: inject a staged bundle dir
1608
1676
  const override = String(process.env.AGENT_WALLET_CLAUDE_CODE_PLUGIN_SOURCE || "").trim();
1609
1677
  if (override) return path.resolve(expandHome(override));
1610
- const currentRoot = resolvedCurrentRuntimeRoot();
1678
+ const currentRoot = logicalCurrentRuntimeRoot();
1611
1679
  const candidates = [];
1612
1680
  if (currentRoot) {
1613
1681
  candidates.push(path.join(currentRoot, "claude-code", "plugins", "agent-wallet"));
@@ -1683,7 +1751,7 @@ function ensureCodexMarketplaceEntry({ marketplacePath, pluginName }) {
1683
1751
  }
1684
1752
 
1685
1753
  function resolveAgentWalletPackageRoot(env = process.env) {
1686
- const currentRoot = resolvedCurrentRuntimeRoot(env);
1754
+ const currentRoot = logicalCurrentRuntimeRoot(env);
1687
1755
  if (currentRoot) {
1688
1756
  const runtimePackage = path.join(currentRoot, "agent-wallet");
1689
1757
  if (fs.existsSync(path.join(runtimePackage, "agent_wallet", "__init__.py"))) {
@@ -2081,6 +2149,79 @@ function runClaudeCodeInstall(args) {
2081
2149
  return enable.skipped || enable.ok ? 0 : 1;
2082
2150
  }
2083
2151
 
2152
+ function hermesInstallPresent(env = process.env) {
2153
+ const hermesHome = resolveHermesHome(env);
2154
+ return (
2155
+ fs.existsSync(path.join(hermesHome, "plugins", "agent_wallet")) ||
2156
+ fs.existsSync(path.join(hermesHome, ".env"))
2157
+ );
2158
+ }
2159
+
2160
+ function codexInstallPresent(env = process.env) {
2161
+ return (
2162
+ fs.existsSync(path.join(resolveCodexPluginInstallRoot(env), "agent-wallet")) ||
2163
+ fs.existsSync(resolveCodexMarketplacePath(env))
2164
+ );
2165
+ }
2166
+
2167
+ function claudeCodeInstallPresent(env = process.env) {
2168
+ const marketplaceDir = resolveClaudeCodeMarketplaceDir(env);
2169
+ const cacheRoot = path.resolve(
2170
+ expandHome(env.AGENT_WALLET_CLAUDE_CODE_CACHE_ROOT || "~/.claude/plugins/cache"),
2171
+ );
2172
+ return (
2173
+ fs.existsSync(path.join(marketplaceDir, "plugins", "agent-wallet")) ||
2174
+ fs.existsSync(path.join(cacheRoot, CLAUDE_CODE_MARKETPLACE_NAME, "agent-wallet"))
2175
+ );
2176
+ }
2177
+
2178
+ function captureInstallerRefresh(name, runFn, args) {
2179
+ const originalLog = console.log;
2180
+ const lines = [];
2181
+ console.log = (...items) => {
2182
+ lines.push(items.join(" "));
2183
+ };
2184
+ try {
2185
+ const code = runFn(args);
2186
+ const output = lines.join("\n");
2187
+ return {
2188
+ name,
2189
+ attempted: true,
2190
+ ok: code === 0,
2191
+ code,
2192
+ payload: output ? extractTrailingJson(output) : null,
2193
+ error: code === 0 ? "" : output.trim(),
2194
+ };
2195
+ } catch (error) {
2196
+ return {
2197
+ name,
2198
+ attempted: true,
2199
+ ok: false,
2200
+ code: 1,
2201
+ payload: null,
2202
+ error: error?.message || String(error),
2203
+ };
2204
+ } finally {
2205
+ console.log = originalLog;
2206
+ }
2207
+ }
2208
+
2209
+ function refreshInstalledEditorIntegrations(env = process.env) {
2210
+ const results = [];
2211
+ if (hermesInstallPresent(env)) {
2212
+ results.push(captureInstallerRefresh("hermes", runHermesInstall, ["--yes", "--force", "--skip-enable"]));
2213
+ }
2214
+ if (codexInstallPresent(env)) {
2215
+ results.push(captureInstallerRefresh("codex", runCodexInstall, ["--yes", "--force", "--skip-enable"]));
2216
+ }
2217
+ if (claudeCodeInstallPresent(env)) {
2218
+ results.push(
2219
+ captureInstallerRefresh("claude-code", runClaudeCodeInstall, ["--yes", "--force", "--skip-enable"]),
2220
+ );
2221
+ }
2222
+ return results;
2223
+ }
2224
+
2084
2225
  const args = process.argv.slice(2);
2085
2226
  const command = args[0] || "install";
2086
2227
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-wallet",
3
3
  "displayName": "Agent Wallet",
4
- "version": "0.1.70",
4
+ "version": "0.1.71",
5
5
  "description": "Claude Code bridge for the existing AgentLayer wallet runtime. Connects to Solana, Bitcoin, and EVM wallets without creating a new one.",
6
6
  "author": {
7
7
  "name": "AgentLayer"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-wallet",
3
- "version": "0.1.70",
3
+ "version": "0.1.71",
4
4
  "description": "Codex plugin bridge for the AgentLayer wallet runtime.",
5
5
  "author": {
6
6
  "name": "AgentLayer"
@@ -1,5 +1,5 @@
1
1
  name: agent-wallet
2
- version: 0.1.70
2
+ version: 0.1.71
3
3
  description: Thin Hermes Agent bridge to the existing AgentLayer/OpenClaw wallet backend
4
4
  provides_tools:
5
5
  - agent_wallet_tools
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentlayer.tech/wallet",
3
- "version": "0.1.70",
3
+ "version": "0.1.71",
4
4
  "description": "NPM installer for the OpenClaw Agent Wallet local runtime.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wdk-btc-wallet",
3
- "version": "0.1.70",
3
+ "version": "0.1.71",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Separate BTC-only wallet service built on Tether WDK.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wdk-evm-wallet",
3
- "version": "0.1.70",
3
+ "version": "0.1.71",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Separate EVM wallet service built on Tether WDK.",