@agentlayer.tech/wallet 0.1.23 → 0.1.25

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
@@ -249,15 +249,19 @@ Lido:
249
249
 
250
250
  Across these service-backed flows, read operations remain directly callable, while write operations stay behind preview, explicit intent, and host-issued approval tokens before execution.
251
251
 
252
- If you want the installer to finish the OpenClaw plugin wiring in the same pass, provide the runtime secrets first:
253
-
254
- Solana:
252
+ For the default Solana flow, run the installer directly:
255
253
 
256
254
  ```bash
257
- export AGENT_WALLET_BOOT_KEY="$(openssl rand -base64 32)"
258
- export AGENT_WALLET_MASTER_KEY="$(openssl rand -base64 32)"
259
- export AGENT_WALLET_APPROVAL_SECRET="$(openssl rand -base64 32)"
255
+ npx @agentlayer.tech/wallet install --yes
260
256
  ```
257
+
258
+ That installs the runtime, patches the OpenClaw plugin config, generates local
259
+ runtime secrets when missing, and creates the first encrypted per-user Solana
260
+ mainnet wallet. The agent receives the public address and guarded wallet tools,
261
+ not the private key.
262
+
263
+ BTC and EVM are separate host-side setup flows.
264
+
261
265
  Bitcoin:
262
266
 
263
267
  ```bash
@@ -272,7 +276,17 @@ sh agent-wallet/scripts/setup_evm_wallet.sh
272
276
 
273
277
  That host-side bootstrap can auto-start the local `wdk-evm-wallet` service, create or unlock the vault wallet, bind both `base` and `ethereum` for the same local user, and patch OpenClaw config to `backend=wdk_evm_local`.
274
278
 
275
- That generates three fresh local secrets in the current shell session. If you prefer Python instead of `openssl`:
279
+ Advanced operators can still supply their own runtime provisioning secrets
280
+ instead of using `--yes` auto-generation:
281
+
282
+ ```bash
283
+ export AGENT_WALLET_BOOT_KEY="$(openssl rand -base64 32)"
284
+ export AGENT_WALLET_MASTER_KEY="$(openssl rand -base64 32)"
285
+ export AGENT_WALLET_APPROVAL_SECRET="$(openssl rand -base64 32)"
286
+ npx @agentlayer.tech/wallet install --no-auto-secrets
287
+ ```
288
+
289
+ If you prefer Python instead of `openssl`:
276
290
 
277
291
  ```bash
278
292
  python3 -c "import secrets; print(secrets.token_urlsafe(32))"
@@ -284,7 +298,10 @@ Run it three times and assign the outputs to:
284
298
  - `AGENT_WALLET_MASTER_KEY`
285
299
  - `AGENT_WALLET_APPROVAL_SECRET`
286
300
 
287
- Without those secrets, the installer still lays down the runtime and installs dependencies, but stops before the final hardened OpenClaw config step and prints the exact `next_configure_command` to run later.
301
+ These variables are provisioning inputs only. Runtime secrets are sealed into
302
+ `~/.openclaw/sealed_keys.json`; normal runtime execution should use
303
+ `AGENT_WALLET_BOOT_KEY` or `AGENT_WALLET_BOOT_KEY_FILE`, not direct
304
+ `AGENT_WALLET_MASTER_KEY` / `AGENT_WALLET_APPROVAL_SECRET` env loading.
288
305
 
289
306
  ## Connect the MCP server
290
307
 
@@ -129,8 +129,9 @@ Policy defaults:
129
129
  - read-only tools are always allowed
130
130
  - `prepare` requires `user_intent=true`
131
131
  - `prepare` does not return signed transaction bytes
132
- - `execute` requires a host-issued `approval_token` bound to the exact previewed operation
133
- - on mainnet networks, that `approval_token` must include explicit mainnet confirmation
132
+ - backend `execute` requires an internal authorization token bound to the exact previewed operation
133
+ - in OpenClaw, the extension handles that internal authorization automatically after the user explicitly confirms the shown summary in chat; do not ask OpenClaw users for `/approve`, buttons, popups, or a manual token
134
+ - on mainnet networks, that internal authorization must include explicit mainnet confirmation
134
135
  - on mainnet networks, preview and prepare responses include a `confirmation_summary` and `mainnet_warning` to force a clearer final confirmation step
135
136
 
136
137
  ## Install
@@ -4428,19 +4428,6 @@ class OpenClawWalletAdapter:
4428
4428
  raise WalletBackendError(
4429
4429
  "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
4430
4430
  )
4431
- preview_summary = self._build_confirmation_summary(
4432
- action_label="Flash Trade open position",
4433
- payload=approved_preview,
4434
- )
4435
- summary_without_digest = {
4436
- key: value
4437
- for key, value in approval_summary_copy.items()
4438
- if key != "_preview_digest"
4439
- }
4440
- if preview_summary != summary_without_digest:
4441
- raise WalletBackendError(
4442
- "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
4443
- )
4444
4431
  execute_preview = dict(approved_preview)
4445
4432
  else:
4446
4433
  execute_preview = await active_backend.preview_flash_trade_open_position(
@@ -4567,19 +4554,6 @@ class OpenClawWalletAdapter:
4567
4554
  raise WalletBackendError(
4568
4555
  "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
4569
4556
  )
4570
- preview_summary = self._build_confirmation_summary(
4571
- action_label="Flash Trade close position",
4572
- payload=approved_preview,
4573
- )
4574
- summary_without_digest = {
4575
- key: value
4576
- for key, value in approval_summary_copy.items()
4577
- if key != "_preview_digest"
4578
- }
4579
- if preview_summary != summary_without_digest:
4580
- raise WalletBackendError(
4581
- "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
4582
- )
4583
4557
  execute_preview = dict(approved_preview)
4584
4558
  else:
4585
4559
  execute_preview = await active_backend.preview_flash_trade_close_position(
@@ -5376,19 +5350,6 @@ class OpenClawWalletAdapter:
5376
5350
  raise WalletBackendError(
5377
5351
  "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
5378
5352
  )
5379
- preview_summary = self._build_confirmation_summary(
5380
- action_label="Swap",
5381
- payload=approved_preview,
5382
- )
5383
- summary_without_digest = {
5384
- key: value
5385
- for key, value in approval_summary_copy.items()
5386
- if key != "_preview_digest"
5387
- }
5388
- if preview_summary != summary_without_digest:
5389
- raise WalletBackendError(
5390
- "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
5391
- )
5392
5353
  execute_preview = dict(approved_preview)
5393
5354
  else:
5394
5355
  execute_preview = await self.backend.preview_swap(
@@ -5525,19 +5486,6 @@ class OpenClawWalletAdapter:
5525
5486
  raise WalletBackendError(
5526
5487
  "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
5527
5488
  )
5528
- preview_summary = self._build_confirmation_summary(
5529
- action_label="Solana private swap",
5530
- payload=approved_preview,
5531
- )
5532
- summary_without_digest = {
5533
- key: value
5534
- for key, value in approval_summary_copy.items()
5535
- if key != "_preview_digest"
5536
- }
5537
- if preview_summary != summary_without_digest:
5538
- raise WalletBackendError(
5539
- "approved preview payload does not match the approval token. Generate a new preview and approval before execute."
5540
- )
5541
5489
  execute_preview = dict(approved_preview)
5542
5490
 
5543
5491
  self._require_execute_approval(
@@ -5593,20 +5541,6 @@ class OpenClawWalletAdapter:
5593
5541
  raise WalletBackendError(
5594
5542
  "approved preview payload does not match the approval token. Generate a new preview and approval before continue."
5595
5543
  )
5596
- preview_summary = self._build_confirmation_summary(
5597
- action_label="Solana private swap",
5598
- payload=approved_preview,
5599
- )
5600
- summary_without_digest = {
5601
- key: value
5602
- for key, value in approval_summary_copy.items()
5603
- if key != "_preview_digest"
5604
- }
5605
- if preview_summary != summary_without_digest:
5606
- raise WalletBackendError(
5607
- "approved preview payload does not match the approval token. Generate a new preview and approval before continue."
5608
- )
5609
-
5610
5544
  self._require_execute_approval(
5611
5545
  approval_token=approval_token,
5612
5546
  tool_name="swap_solana_privately",
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "openclaw-agent-wallet"
7
- version = "0.1.23"
7
+ version = "0.1.25"
8
8
  description = "Plugin-friendly wallet backend for OpenClaw agents"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -16,7 +16,7 @@ from agent_wallet.file_ops import atomic_write_text, chmod_if_exists
16
16
  from agent_wallet.sealed_keys import resolve_sealed_keys_path, seal_keys, unseal_keys
17
17
  from security_utils import write_redacted_backup
18
18
 
19
- OPTIONAL_TOOLS = [
19
+ LEGACY_ALLOWLIST_TOOLS = [
20
20
  "get_wallet_capabilities",
21
21
  "get_wallet_address",
22
22
  "get_wallet_balance",
@@ -57,6 +57,62 @@ X402_TOOLS = [
57
57
  ]
58
58
 
59
59
 
60
+ def _extract_tool_allowlist_from_manifest(manifest_path: Path) -> list[str]:
61
+ try:
62
+ manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
63
+ except (FileNotFoundError, json.JSONDecodeError):
64
+ return []
65
+
66
+ tools = manifest.get("contracts", {}).get("tools", [])
67
+ if not isinstance(tools, list):
68
+ return []
69
+
70
+ allowlist: list[str] = []
71
+ for item in tools:
72
+ tool_name = str(item).strip()
73
+ if tool_name and tool_name not in allowlist:
74
+ allowlist.append(tool_name)
75
+ return allowlist
76
+
77
+
78
+ def _load_extension_tool_allowlist(extension_path: Path) -> list[str]:
79
+ manifest_candidates = [
80
+ extension_path / "openclaw.plugin.json",
81
+ _repo_root() / ".openclaw" / "extensions" / "agent-wallet" / "openclaw.plugin.json",
82
+ ]
83
+ for manifest_path in manifest_candidates:
84
+ allowlist = _extract_tool_allowlist_from_manifest(manifest_path)
85
+ if allowlist:
86
+ return allowlist
87
+ return LEGACY_ALLOWLIST_TOOLS + X402_TOOLS
88
+
89
+
90
+ def _is_agent_wallet_extension_path(value: object) -> bool:
91
+ return "extensions/agent-wallet" in str(value).replace("\\", "/")
92
+
93
+
94
+ def _normalize_load_paths(paths: list[object], extension_path_text: str) -> list[str]:
95
+ normalized: list[str] = []
96
+ seen: set[str] = set()
97
+
98
+ for item in paths:
99
+ item_text = str(item).strip()
100
+ if not item_text:
101
+ continue
102
+ if "extensions/pay-bridge" in item_text:
103
+ continue
104
+ if _is_agent_wallet_extension_path(item_text) and item_text != extension_path_text:
105
+ continue
106
+ if item_text in seen:
107
+ continue
108
+ normalized.append(item_text)
109
+ seen.add(item_text)
110
+
111
+ if extension_path_text not in seen:
112
+ normalized.append(extension_path_text)
113
+ return normalized
114
+
115
+
60
116
  def _default_config_path() -> Path:
61
117
  return Path(os.path.expanduser("~/.openclaw/openclaw.json"))
62
118
 
@@ -239,9 +295,7 @@ def main() -> None:
239
295
  load = plugins.setdefault("load", {})
240
296
  paths = load.setdefault("paths", [])
241
297
  extension_path_text = str(Path(args.extension_path).expanduser().resolve())
242
- if extension_path_text not in paths:
243
- paths.append(extension_path_text)
244
- paths[:] = [item for item in paths if "extensions/pay-bridge" not in str(item)]
298
+ paths[:] = _normalize_load_paths(list(paths), extension_path_text)
245
299
 
246
300
  entries = plugins.setdefault("entries", {})
247
301
  effective_network = _normalize_network(args.backend, args.network)
@@ -306,7 +360,7 @@ def main() -> None:
306
360
  "pay_api_request",
307
361
  }
308
362
  also_allow[:] = [tool_name for tool_name in also_allow if tool_name not in removed_pay_tools]
309
- for tool_name in OPTIONAL_TOOLS + X402_TOOLS:
363
+ for tool_name in _load_extension_tool_allowlist(Path(extension_path_text)):
310
364
  if tool_name not in also_allow:
311
365
  also_allow.append(tool_name)
312
366
 
@@ -5,16 +5,16 @@ description: Use when operating OpenClaw wallet tools: balances, transfers, swap
5
5
 
6
6
  # Wallet Operator
7
7
 
8
- Use this skill before calling OpenClaw wallet tools. It is the routing guide for wallet commands, providers, units, and approval flow.
8
+ Use this skill before calling OpenClaw wallet tools. It is the routing guide for wallet commands, providers, units, and confirmation flow.
9
9
 
10
10
  ## Core Rules
11
11
 
12
12
  1. Start with `get_wallet_capabilities` when the active chain, signing support, or available tools are unclear.
13
13
  2. Use `get_wallet_address` before asking for deposits or confirming a recipient/source wallet.
14
14
  3. Use `get_wallet_balance` before spending, swapping, bridging, staking, lending, or claiming.
15
- 4. Use `preview` first for every write action. Use `prepare` only after explicit user intent. Use `execute` only with a host-issued `approval_token`.
15
+ 4. Use `preview` first for every write action. Use `prepare` only after explicit user intent. In OpenClaw, use `execute` only after the user explicitly confirms the shown summary in chat; do not ask the user for `/approve`, buttons, popups, or a manual token.
16
16
  5. `prepare` returns an execution plan only; it must not return signed transaction bytes.
17
- 6. On mainnet, `execute` requires approval that includes explicit mainnet confirmation.
17
+ 6. On mainnet, restate the network and material terms before `execute`; the OpenClaw plugin handles the internal execution authorization after chat confirmation.
18
18
  7. If backend is `sign_only`, do not execute; use `prepare` and state that nothing was broadcast.
19
19
  8. Never claim a transfer, swap, bridge, stake, claim, deposit, borrow, repay, or withdrawal happened unless the tool result says it was broadcast/confirmed.
20
20
  9. Do not use Mayan. Direct Mayan paths were removed. Cross-chain swaps must go through LI.FI with Mayan denied.
@@ -63,7 +63,7 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
63
63
  ## Transfer Commands
64
64
 
65
65
  - SOL transfer: `transfer_sol`
66
- - Params: `recipient`, `amount` in SOL UI units, `mode`, `purpose`, optional `user_intent`, `approval_token`.
66
+ - Params: `recipient`, `amount` in SOL UI units, `mode`, `purpose`, optional `user_intent`.
67
67
  - SPL transfer: `transfer_spl_token`
68
68
  - Params: `recipient`, `mint`, `amount` in UI units, optional `decimals`, `mode`, `purpose`.
69
69
  - EVM native transfer: `transfer_evm_native`
@@ -118,7 +118,7 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
118
118
  1. Call the write tool with `mode=preview` and a concrete `purpose`.
119
119
  2. Show the user the important fields: chain, token, amount, destination, provider, estimated output/minimum output, fees, and route/tool when present.
120
120
  3. For `prepare`, call same tool with `mode=prepare`, same params, `user_intent=true`.
121
- 4. For `execute`, use the same semantic params and pass the `approval_token`. Do not mutate amount, token, destination, network, slippage, or minimum output between preview and execute.
121
+ 4. For `execute`, use the same semantic params after the user's chat confirmation. Do not mutate amount, token, destination, network, slippage, or minimum output between preview and execute; do not ask the user for a token or out-of-chat approval action.
122
122
  5. For cross-chain swaps, after execute, offer `get_lifi_transfer_status` using the source tx hash and bridge/tool if returned.
123
123
 
124
124
  ## Disabled Or Avoided Paths
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentlayer.tech/wallet",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "NPM installer for the OpenClaw Agent Wallet local runtime.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -11,7 +11,9 @@
11
11
  "url": "https://github.com/lopushok9/Agent-Layer/issues"
12
12
  },
13
13
  "homepage": "https://github.com/lopushok9/Agent-Layer#readme",
14
- "bin": "./bin/openclaw-agent-wallet.mjs",
14
+ "bin": {
15
+ "wallet": "./bin/openclaw-agent-wallet.mjs"
16
+ },
15
17
  "scripts": {
16
18
  "check": "node --check bin/openclaw-agent-wallet.mjs",
17
19
  "build:openclaw-plugins": "node scripts/manage_openclaw_plugin_packages.mjs build",
@@ -72,4 +74,4 @@
72
74
  "evm"
73
75
  ],
74
76
  "license": "SEE LICENSE IN LICENSE"
75
- }
77
+ }