@agentlayer.tech/wallet 0.1.11 → 0.1.13

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.
Files changed (29) hide show
  1. package/.openclaw/extensions/agent-wallet/index.ts +454 -18
  2. package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +96 -0
  3. package/.openclaw/extensions/agent-wallet/skills/wallet-operator/SKILL.md +2 -0
  4. package/CHANGELOG.md +25 -0
  5. package/README.md +43 -51
  6. package/agent-wallet/.env.example +11 -0
  7. package/agent-wallet/README.md +53 -0
  8. package/agent-wallet/agent_wallet/approval.py +4 -0
  9. package/agent-wallet/agent_wallet/config.py +6 -0
  10. package/agent-wallet/agent_wallet/exceptions.py +2 -1
  11. package/agent-wallet/agent_wallet/openclaw_adapter.py +361 -2
  12. package/agent-wallet/agent_wallet/openclaw_cli.py +13 -1
  13. package/agent-wallet/agent_wallet/openclaw_runtime.py +2 -5
  14. package/agent-wallet/agent_wallet/providers/houdini.py +539 -0
  15. package/agent-wallet/agent_wallet/transaction_policy.py +251 -0
  16. package/agent-wallet/agent_wallet/user_wallets.py +83 -0
  17. package/agent-wallet/agent_wallet/wallet_layer/base.py +40 -0
  18. package/agent-wallet/agent_wallet/wallet_layer/solana.py +885 -16
  19. package/agent-wallet/pyproject.toml +1 -1
  20. package/agent-wallet/scripts/bootstrap_openclaw_evm.py +291 -0
  21. package/agent-wallet/scripts/install_agent_wallet.py +54 -2
  22. package/agent-wallet/scripts/install_openclaw_local_config.py +84 -4
  23. package/agent-wallet/scripts/manage_openclaw_evm_wallet.py +343 -0
  24. package/agent-wallet/scripts/setup_evm_wallet.sh +151 -0
  25. package/hermes/plugins/agent_wallet/__init__.py +28 -2
  26. package/hermes/plugins/agent_wallet/plugin.yaml +2 -0
  27. package/hermes/plugins/agent_wallet/schemas.py +72 -0
  28. package/hermes/plugins/agent_wallet/tools.py +193 -9
  29. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@
7
7
  OpenClaw wallet tools or policy.
8
8
  - Added `wallet hermes install --yes` and `AGENT_WALLET_BOOT_KEY_FILE` support
9
9
  for smoother Hermes onboarding without manual `.env` editing.
10
+ - Added Hermes EVM onboarding helpers:
11
+ `agent_wallet_evm_status` and `agent_wallet_evm_setup`.
12
+ - Added host-side EVM bootstrap scripts for packaged/runtime installs:
13
+ `manage_openclaw_evm_wallet.py`, `bootstrap_openclaw_evm.py`, and
14
+ `setup_evm_wallet.sh`.
15
+ - Kept Hermes EVM routing on the existing `wdk-evm-wallet` and
16
+ `provider-gateway` path for `ethereum` and `base`, without copying wallet
17
+ policy or duplicating tool implementations.
10
18
  - Replaced the repo license with `PolyForm Small Business 1.0.0`.
11
19
  - Clarified in `README.md` that individuals can audit, fork, run, and modify
12
20
  the code for themselves, and that company use follows the PolyForm small
@@ -15,6 +23,23 @@
15
23
  `wdk-evm-wallet`; cross-chain swaps now stay on LI.FI/Jupiter-backed paths
16
24
  with Mayan denied as a LI.FI bridge.
17
25
 
26
+ ## v0.1.12 - 2026-05-06
27
+
28
+ ### Added
29
+
30
+ - Hermes EVM runtime helpers for packaged installs:
31
+ `agent_wallet_evm_status` and `agent_wallet_evm_setup`.
32
+ - Host-side EVM lifecycle scripts in the runtime bundle:
33
+ `manage_openclaw_evm_wallet.py`, `bootstrap_openclaw_evm.py`, and
34
+ `setup_evm_wallet.sh`.
35
+
36
+ ### Changed
37
+
38
+ - Hermes installs now support the same local EVM onboarding shape as BTC:
39
+ inspect runtime health, auto-start the local service, create or unlock the
40
+ vault wallet, and bind paired `ethereum/base` networks through the thin
41
+ bridge.
42
+
18
43
  ## v0.1.0-beta.2 - 2026-03-31
19
44
 
20
45
  Second public beta release that expands the stack beyond the initial MCP, wallet, and AgentLayer bridge scope.
package/README.md CHANGED
@@ -1,9 +1,18 @@
1
1
  ![AgentLayer](logo+name.png)
2
- # AgentLayer
2
+
3
+
4
+ [![npm version](https://img.shields.io/npm/v/%40agentlayer.tech%2Fwallet)](https://www.npmjs.com/package/@agentlayer.tech/wallet)
5
+ [![npm downloads](https://img.shields.io/npm/dm/%40agentlayer.tech%2Fwallet)](https://www.npmjs.com/package/@agentlayer.tech/wallet)
6
+ [![license](https://img.shields.io/github/license/lopushok9/Agent-Layer)](https://github.com/lopushok9/Agent-Layer/blob/main/LICENSE)
3
7
 
4
8
  ```bash
5
9
  npx @agentlayer.tech/wallet install --yes
6
10
  ```
11
+ For install to Hermes use
12
+ ```bash
13
+ npx @agentlayer.tech/wallet install --yes && npx @agentlayer.tech/wallet hermes install --yes
14
+ ```
15
+
7
16
  AgentLayer is a beta local-first wallet and finance stack for agents.
8
17
 
9
18
  The repository includes:
@@ -92,28 +101,10 @@ sh agent-wallet/scripts/setup_btc_wallet.sh
92
101
  EVM:
93
102
 
94
103
  ```bash
95
- cd wdk-evm-wallet && sh run-local.sh
96
- ```
97
-
98
- Create a local EVM wallet binding for an OpenClaw user:
99
-
100
- ```bash
101
- printf '%s\n' 'your-local-evm-password' | \
102
- agent-wallet/.venv/bin/python -m agent_wallet.openclaw_cli evm-wallet-create \
103
- --user-id your-user-id \
104
- --password-stdin \
105
- --config-json '{"backend":"wdk_evm_local","network":"base","wdkEvmServiceUrl":"http://127.0.0.1:8081"}'
104
+ sh agent-wallet/scripts/setup_evm_wallet.sh
106
105
  ```
107
106
 
108
- Unlock an existing EVM wallet binding:
109
-
110
- ```bash
111
- printf '%s\n' 'your-local-evm-password' | \
112
- agent-wallet/.venv/bin/python -m agent_wallet.openclaw_cli evm-wallet-unlock \
113
- --user-id your-user-id \
114
- --password-stdin \
115
- --config-json '{"backend":"wdk_evm_local","network":"base","wdkEvmServiceUrl":"http://127.0.0.1:8081"}'
116
- ```
107
+ 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`.
117
108
 
118
109
  That generates three fresh local secrets in the current shell session. If you prefer Python instead of `openssl`:
119
110
 
@@ -149,7 +140,15 @@ OpenClaw remains the primary local environment, but the repo also ships an optio
149
140
  hermes/plugins/agent_wallet
150
141
  ```
151
142
 
152
- It exposes only two Hermes tools: `agent_wallet_tools` for discovery and `agent_wallet_invoke` for forwarding a single call into the existing Python wallet CLI. Install it by symlinking the plugin directory into Hermes:
143
+ It exposes a thin bridge, not a port of wallet logic:
144
+
145
+ - `agent_wallet_tools`
146
+ - `agent_wallet_invoke`
147
+ - `agent_wallet_approve`
148
+ - `agent_wallet_evm_status`
149
+ - `agent_wallet_evm_setup`
150
+
151
+ Install it by symlinking the plugin directory into Hermes:
153
152
 
154
153
  ```bash
155
154
  npx @agentlayer.tech/wallet hermes install --yes
@@ -198,6 +197,16 @@ For Solana specifically, install alone does not make signed transactions availab
198
197
  - read-only mode: `SOLANA_AGENT_PUBLIC_KEY`
199
198
  - signing mode: a sealed `private_key` or `SOLANA_AGENT_KEYPAIR_PATH`
200
199
 
200
+ Optional private Solana payout routing is also available through Houdini. To enable it, add the Houdini partner credentials to the wallet runtime:
201
+
202
+ - `HOUDINI_API_KEY`
203
+ - `HOUDINI_API_SECRET`
204
+ - `HOUDINI_USER_IP`
205
+
206
+ The first supported flow is intentionally narrow: same-token private Solana payouts (`SOL->SOL` and `USDC->USDC`) through the existing preview/prepare/execute safety model. The runtime binds execute to the approved Houdini `quoteId`, creates a single private exchange, and then sends the exact deposit locally from the wallet. That removes the extra Solana batch-tx relay step and keeps signing local.
207
+
208
+ For production, prefer placing the Houdini partner secrets on `provider-gateway` and exposing only the authenticated Houdini relay endpoints to `agent-wallet`. That keeps `HOUDINI_API_KEY` and `HOUDINI_API_SECRET` out of end-user runtimes while preserving local signing.
209
+
201
210
  ## BTC setup
202
211
 
203
212
  The BTC path already has a one-command host bootstrap wrapper:
@@ -229,49 +238,32 @@ sh agent-wallet/scripts/reveal_btc_seed.sh
229
238
 
230
239
  ## EVM setup
231
240
 
232
- The EVM runtime is installed by `setup.sh`, but the host-side wallet onboarding is still a manual CLI flow.
233
-
234
- Start the local EVM service:
241
+ The EVM runtime is installed by `setup.sh`, and the host-side onboarding now has the same one-command shape as BTC:
235
242
 
236
243
  ```bash
237
- cd wdk-evm-wallet && sh run-local.sh
244
+ sh agent-wallet/scripts/setup_evm_wallet.sh
238
245
  ```
239
246
 
240
- Create a local EVM wallet binding for an OpenClaw user:
247
+ That flow:
241
248
 
242
- ```bash
243
- printf '%s\n' 'your-local-evm-password' | \
244
- agent-wallet/.venv/bin/python -m agent_wallet.openclaw_cli evm-wallet-create \
245
- --user-id your-user-id \
246
- --password-stdin \
247
- --config-json '{"backend":"wdk_evm_local","network":"base","wdkEvmServiceUrl":"http://127.0.0.1:8081"}'
248
- ```
249
+ - prompts for `user-id`
250
+ - prompts for `ethereum`, `base`, `sepolia`, or `base-sepolia`
251
+ - defaults to `http://127.0.0.1:8081`
252
+ - can auto-start `wdk-evm-wallet/run-local.sh` if the local service is not already healthy
253
+ - creates or unlocks the local EVM wallet binding
254
+ - also binds the paired EVM network by default: `ethereum <-> base`, `sepolia <-> base-sepolia`
255
+ - patches OpenClaw config to `backend=wdk_evm_local`
249
256
 
250
- Unlock an existing EVM wallet binding:
257
+ You can still use the lower-level CLI if needed:
251
258
 
252
259
  ```bash
253
260
  printf '%s\n' 'your-local-evm-password' | \
254
- agent-wallet/.venv/bin/python -m agent_wallet.openclaw_cli evm-wallet-unlock \
261
+ agent-wallet/.venv/bin/python -m agent_wallet.openclaw_cli evm-wallet-create \
255
262
  --user-id your-user-id \
256
263
  --password-stdin \
257
264
  --config-json '{"backend":"wdk_evm_local","network":"base","wdkEvmServiceUrl":"http://127.0.0.1:8081"}'
258
265
  ```
259
266
 
260
- Then switch the OpenClaw plugin config to the EVM backend:
261
-
262
- ```bash
263
- AGENT_WALLET_BOOT_KEY='...' \
264
- agent-wallet/.venv/bin/python agent-wallet/scripts/install_openclaw_local_config.py \
265
- --backend wdk_evm_local \
266
- --network base \
267
- --user-id your-user-id \
268
- --package-root agent-wallet \
269
- --extension-path .openclaw/extensions/agent-wallet \
270
- --python-bin agent-wallet/.venv/bin/python
271
- ```
272
-
273
- That final config step assumes `~/.openclaw/sealed_keys.json` already exists. The normal path is to let the main installer create it by running install with `AGENT_WALLET_BOOT_KEY`, `AGENT_WALLET_MASTER_KEY`, and `AGENT_WALLET_APPROVAL_SECRET` available.
274
-
275
267
  Important EVM notes:
276
268
 
277
269
  - only localhost service URLs are supported for the OpenClaw EVM flow
@@ -54,6 +54,17 @@ LIFI_API_KEY=
54
54
  LIFI_INTEGRATOR=openclaw
55
55
  LIFI_DEFAULT_DENY_BRIDGES=mayan
56
56
 
57
+ # Houdini Partner API for private Solana payouts.
58
+ # HOUDINI_USER_IP is required because Houdini rejects requests without compliance headers.
59
+ # If PROVIDER_GATEWAY_URL points at a gateway with Houdini enabled,
60
+ # the wallet runtime can omit these partner secrets and route through the gateway instead.
61
+ HOUDINI_API_BASE_URL=https://api-partner.houdiniswap.com/v2
62
+ HOUDINI_API_KEY=
63
+ HOUDINI_API_SECRET=
64
+ HOUDINI_USER_IP=
65
+ HOUDINI_USER_AGENT=AgentLayer/0.1.12
66
+ HOUDINI_USER_TIMEZONE=UTC
67
+
57
68
  # Kamino REST lending
58
69
  KAMINO_API_BASE_URL=https://api.kamino.finance
59
70
  KAMINO_PROGRAM_ID=KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD
@@ -34,6 +34,9 @@ The optional Hermes plugin is intentionally a bridge, not a port of the OpenClaw
34
34
 
35
35
  - `agent_wallet_tools` - read-only discovery for the underlying Python adapter tool specs.
36
36
  - `agent_wallet_invoke` - a dispatcher that calls `python -m agent_wallet.openclaw_cli invoke`.
37
+ - `agent_wallet_approve` - a host approval-token issuer for exact execute operations.
38
+ - `agent_wallet_evm_status` - a read-only EVM runtime and binding inspector.
39
+ - `agent_wallet_evm_setup` - a host-side EVM bootstrap helper for Hermes.
37
40
 
38
41
  Install it with:
39
42
 
@@ -45,6 +48,12 @@ That command symlinks `hermes/plugins/agent_wallet` into `~/.hermes/plugins/agen
45
48
 
46
49
  Hermes tool config must not contain wallet secrets. Use the existing sealed runtime path and host-issued approval tokens for execute flows. `AGENT_WALLET_BOOT_KEY_FILE` lets OpenClaw and Hermes reference one local boot-key file instead of duplicating the boot key across multiple env files.
47
50
 
51
+ For EVM on Hermes, the intended host flow is:
52
+
53
+ - call `agent_wallet_evm_status` to inspect `wdk-evm-wallet` health and current bindings
54
+ - call `agent_wallet_evm_setup` once to auto-start the local service when needed, create or unlock the local EVM wallet, and patch local OpenClaw config to `backend=wdk_evm_local`
55
+ - then use ordinary `agent_wallet_invoke` calls for EVM reads, transfers, swaps, and Aave flows
56
+
48
57
  Current safe tools:
49
58
 
50
59
  - `get_wallet_capabilities`
@@ -80,6 +89,8 @@ Current safe tools:
80
89
  - `stake_sol_native`
81
90
  - `transfer_spl_token`
82
91
  - `swap_solana_tokens`
92
+ - `swap_solana_privately` - Houdini-backed private Solana payout flow for same-token `SOL->SOL` or `USDC->USDC` transfers to a destination wallet.
93
+ - `get_solana_private_swap_status`
83
94
  - `get_jupiter_earn_tokens`
84
95
  - `get_jupiter_earn_positions`
85
96
  - `get_jupiter_earn_earnings`
@@ -107,6 +118,8 @@ Temporarily disabled but kept in the codebase for later re-enable:
107
118
  The signing tool still requires explicit `user_confirmed=true`.
108
119
  Transfer, native staking, swap, and Aave position-management tools support `preview`, `prepare`, and `execute` modes. The safe operational path is still preview-first. `prepare` now returns an execution plan only and never exposes signed transaction bytes to the agent. `execute` works only when the backend has a signer and `sign_only=false`.
109
120
 
121
+ Exception: `swap_solana_privately` is intentionally optimized for `preview -> execute`. Hosts should not insert a separate `prepare` step for Houdini private payouts because it adds no execution value and only burns additional provider quota.
122
+
110
123
  Policy defaults:
111
124
 
112
125
  - read-only tools are always allowed
@@ -176,6 +189,30 @@ For production `mainnet`, prefer a dedicated RPC instead of the public Solana en
176
189
 
177
190
  Production recommendation: treat RPC as deployment-owned config, not wallet logic. Runtime env wins over `openclaw.json` plugin config, so keep `Alchemy/Helius/QuickNode` endpoints in deployment secrets or service env and use plugin `rpcUrl` / `rpcUrls` only as local fallback.
178
191
 
192
+ For Houdini-backed private Solana payouts, also provide:
193
+
194
+ - `HOUDINI_API_KEY`
195
+ - `HOUDINI_API_SECRET`
196
+ - `HOUDINI_USER_IP`
197
+ - optional `HOUDINI_USER_AGENT`
198
+ - optional `HOUDINI_USER_TIMEZONE`
199
+
200
+ The current MVP intentionally keeps the scope narrow:
201
+
202
+ - supported private routes are same-token Solana payouts only
203
+ - `SOL -> SOL`
204
+ - `USDC -> USDC`
205
+ - execution binds to the approved Houdini `quoteId`, creates a single private exchange, and sends the exact Solana deposit locally from the wallet
206
+
207
+ This is a private payout flow expressed in Houdini's swap terminology. Cross-token private swaps can be added later without changing the OpenClaw/Hermes approval model.
208
+
209
+ For production, the cleaner setup is to place Houdini partner secrets on `provider-gateway` and let `agent-wallet` consume the narrow gateway endpoints through `PROVIDER_GATEWAY_URL` and optional `PROVIDER_GATEWAY_BEARER_TOKEN`. In that mode:
210
+
211
+ - the gateway owns `HOUDINI_API_KEY` / `HOUDINI_API_SECRET`
212
+ - the gateway derives the authoritative user IP from ingress
213
+ - `agent-wallet` still performs preview/prepare/execute, local transaction verification, signing, and broadcast
214
+ - direct Houdini env vars can be omitted from the wallet runtime
215
+
179
216
  For OpenClaw onboarding, `agent-wallet` now ships with a hosted default provider gateway:
180
217
 
181
218
  - `https://agent-layer-production.up.railway.app`
@@ -375,6 +412,21 @@ For the local EVM backend (`backend=wdk_evm_local`), the lifecycle mirrors the B
375
412
  - `evm-wallet-unlock`
376
413
  - `evm-wallet-lock`
377
414
 
415
+ For a simpler host-side bootstrap, use:
416
+
417
+ ```bash
418
+ sh agent-wallet/scripts/setup_evm_wallet.sh
419
+ ```
420
+
421
+ That wrapper:
422
+
423
+ - prompts for `user-id` and EVM network when run interactively
424
+ - defaults to `http://127.0.0.1:8081`
425
+ - can auto-start `wdk-evm-wallet/run-local.sh` if the local service is not already healthy
426
+ - creates or unlocks the local EVM wallet binding
427
+ - also binds the paired EVM network by default: `ethereum <-> base`, `sepolia <-> base-sepolia`
428
+ - patches OpenClaw config to `backend=wdk_evm_local`
429
+
378
430
  Example host-side EVM wallet creation:
379
431
 
380
432
  ```bash
@@ -512,6 +564,7 @@ Public-safe helper scripts are available in `agent-wallet/scripts/`:
512
564
  - `finalize_openclaw_local_wallet_config.py`
513
565
 
514
566
  Both scripts now use generic defaults instead of hardcoded local usernames or paths. Sensitive secrets must be supplied via protected environment variables, not config JSON or CLI arguments.
567
+ When `~/.openclaw/agent-wallet-runtime/current` exists, the config installer now prefers that trusted runtime path over a workspace checkout for the plugin manifest, package root, and Python bridge launcher.
515
568
 
516
569
  Recommended devnet setup:
517
570
 
@@ -3,9 +3,11 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import base64
6
+ import functools
6
7
  import hashlib
7
8
  import hmac
8
9
  import json
10
+ import secrets
9
11
  import time
10
12
  from typing import Any
11
13
 
@@ -33,6 +35,7 @@ def _sign_payload(payload: dict[str, Any], secret: str) -> str:
33
35
  return _urlsafe_b64(digest)
34
36
 
35
37
 
38
+ @functools.lru_cache(maxsize=1)
36
39
  def _approval_secret() -> str:
37
40
  secret = resolve_approval_secret().strip()
38
41
  if not secret:
@@ -70,6 +73,7 @@ def issue_approval_token(
70
73
  "v": APPROVAL_TOKEN_VERSION,
71
74
  "iat": now,
72
75
  "exp": now + ttl,
76
+ "jti": secrets.token_urlsafe(16),
73
77
  "issued_by": issued_by,
74
78
  "binding": build_operation_binding(tool_name=tool_name, network=network, summary=summary),
75
79
  "mainnet_confirmed": bool(mainnet_confirmed),
@@ -54,6 +54,12 @@ class Settings(BaseSettings):
54
54
  lifi_api_key: str = ""
55
55
  lifi_integrator: str = "openclaw"
56
56
  lifi_default_deny_bridges: str = "mayan"
57
+ houdini_api_base_url: str = "https://api-partner.houdiniswap.com/v2"
58
+ houdini_api_key: str = ""
59
+ houdini_api_secret: str = ""
60
+ houdini_user_ip: str = ""
61
+ houdini_user_agent: str = "AgentLayer/0.1.12"
62
+ houdini_user_timezone: str = "UTC"
57
63
  kamino_api_base_url: str = "https://api.kamino.finance"
58
64
  kamino_program_id: str = "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
59
65
  alchemy_api_key: str = ""
@@ -4,6 +4,7 @@
4
4
  class ProviderError(Exception):
5
5
  """A provider failed to return data."""
6
6
 
7
- def __init__(self, provider: str, message: str):
7
+ def __init__(self, provider: str, message: str, *, details: dict | None = None):
8
8
  self.provider = provider
9
+ self.details = dict(details) if isinstance(details, dict) else None
9
10
  super().__init__(f"[{provider}] {message}")