@agentlayer.tech/wallet 0.1.93 → 0.1.95

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 (30) hide show
  1. package/.openclaw/extensions/agent-wallet/dist/index.js +79 -0
  2. package/.openclaw/extensions/agent-wallet/index.ts +79 -0
  3. package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +6 -1
  4. package/.openclaw/extensions/agent-wallet/package.json +1 -1
  5. package/CHANGELOG.md +18 -0
  6. package/VERSION +1 -1
  7. package/agent-wallet/agent_wallet/__init__.py +1 -1
  8. package/agent-wallet/agent_wallet/autonomous_permissions.py +1 -0
  9. package/agent-wallet/agent_wallet/openclaw_adapter.py +262 -0
  10. package/agent-wallet/agent_wallet/providers/wdk_evm_local.py +2 -0
  11. package/agent-wallet/agent_wallet/wallet_layer/base.py +37 -0
  12. package/agent-wallet/agent_wallet/wallet_layer/wdk_evm.py +157 -0
  13. package/agent-wallet/openclaw.plugin.json +1 -1
  14. package/agent-wallet/pyproject.toml +1 -1
  15. package/agent-wallet/scripts/install_agent_wallet.py +29 -1
  16. package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +1 -1
  17. package/claude-code/plugins/agent-wallet/AGENTLAYER_AGENT_GUIDE.md +282 -0
  18. package/claude-code/plugins/agent-wallet/README.md +2 -0
  19. package/claude-code/plugins/agent-wallet/commands/guide.md +40 -0
  20. package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +1 -1
  21. package/codex/plugins/agent-wallet/server.py +1 -0
  22. package/hermes/plugins/agent_wallet/plugin.yaml +1 -1
  23. package/package.json +1 -1
  24. package/wdk-btc-wallet/package.json +1 -1
  25. package/wdk-evm-wallet/.env.example +3 -0
  26. package/wdk-evm-wallet/README.md +6 -0
  27. package/wdk-evm-wallet/package.json +1 -1
  28. package/wdk-evm-wallet/src/config.js +9 -0
  29. package/wdk-evm-wallet/src/server.js +24 -0
  30. package/wdk-evm-wallet/src/wdk_evm_wallet.js +469 -0
@@ -1957,6 +1957,66 @@ class WdkEvmLocalWalletBackend(AgentWalletBackend):
1957
1957
  "source": "dexscreener",
1958
1958
  }
1959
1959
 
1960
+ async def get_uniswap_liquidity_pools(
1961
+ self,
1962
+ *,
1963
+ protocol: str,
1964
+ pool_parameters: dict[str, Any] | None = None,
1965
+ pool_references: list[dict[str, Any]] | None = None,
1966
+ page_size: int = 20,
1967
+ current_page: int = 1,
1968
+ ) -> dict[str, Any]:
1969
+ if protocol not in {"V3", "V4"}:
1970
+ raise WalletBackendError("protocol must be V3 or V4.")
1971
+ if (pool_parameters is None) == (pool_references is None):
1972
+ raise WalletBackendError("Provide exactly one of pool_parameters or pool_references.")
1973
+ if pool_parameters is not None and not isinstance(pool_parameters, dict):
1974
+ raise WalletBackendError("pool_parameters must be an object.")
1975
+ if pool_references is not None:
1976
+ if not isinstance(pool_references, list) or not 1 <= len(pool_references) <= 20:
1977
+ raise WalletBackendError("pool_references must contain between 1 and 20 objects.")
1978
+ if any(not isinstance(reference, dict) for reference in pool_references):
1979
+ raise WalletBackendError("pool_references must contain only objects.")
1980
+ if not isinstance(page_size, int) or not 1 <= page_size <= 20:
1981
+ raise WalletBackendError("page_size must be an integer between 1 and 20.")
1982
+ if not isinstance(current_page, int) or current_page < 1:
1983
+ raise WalletBackendError("current_page must be a positive integer.")
1984
+ body: dict[str, Any] = {
1985
+ "network": self.network,
1986
+ "protocol": protocol,
1987
+ "pageSize": page_size,
1988
+ "currentPage": current_page,
1989
+ }
1990
+ if pool_parameters is not None:
1991
+ body["poolParameters"] = pool_parameters
1992
+ else:
1993
+ body["poolReferences"] = pool_references
1994
+ data = await self.client.post("/v1/evm/uniswap/liquidity/pools", body)
1995
+ return dict(data)
1996
+
1997
+ async def get_uniswap_liquidity_positions(
1998
+ self,
1999
+ *,
2000
+ protocol: str = "V3",
2001
+ limit: int = 20,
2002
+ ) -> dict[str, Any]:
2003
+ if protocol not in {"V3", "V4"}:
2004
+ raise WalletBackendError("protocol must be V3 or V4.")
2005
+ if not isinstance(limit, int) or not 1 <= limit <= 100:
2006
+ raise WalletBackendError("limit must be an integer between 1 and 100.")
2007
+ data = await self.client.post(
2008
+ "/v1/evm/uniswap/liquidity/positions",
2009
+ {
2010
+ "walletId": self.wallet_id,
2011
+ "address": await self.get_address(),
2012
+ "accountIndex": self.account_index,
2013
+ "network": self.network,
2014
+ "protocol": protocol,
2015
+ "limit": limit,
2016
+ },
2017
+ )
2018
+ return dict(data)
2019
+
1960
2020
  async def send_uniswap_swap(
1961
2021
  self,
1962
2022
  *,
@@ -2028,6 +2088,103 @@ class WdkEvmLocalWalletBackend(AgentWalletBackend):
2028
2088
  "source": str(data.get("source") or "wdk-evm-wallet"),
2029
2089
  }
2030
2090
 
2091
+ def _normalize_uniswap_liquidity_payload(
2092
+ self,
2093
+ data: dict[str, Any],
2094
+ *,
2095
+ action: str,
2096
+ protocol: str,
2097
+ ) -> dict[str, Any]:
2098
+ transaction = dict(data.get("transaction") or {})
2099
+ result = dict(data.get("result") or {})
2100
+ request = dict(data.get("request") or {})
2101
+ return {
2102
+ "chain": self.chain,
2103
+ "network": self.network,
2104
+ "asset_type": "evm-uniswap-liquidity",
2105
+ "protocol": str(data.get("protocol") or "uniswap"),
2106
+ "liquidity_action": str(data.get("liquidityAction") or action),
2107
+ "liquidity_protocol": str(data.get("liquidityProtocol") or protocol).upper(),
2108
+ "from_address": str(data.get("address") or "").strip() or None,
2109
+ "request": request,
2110
+ "request_id": str(data.get("requestId") or "").strip() or None,
2111
+ "token0": data.get("token0"),
2112
+ "token1": data.get("token1"),
2113
+ "tick_lower": data.get("tickLower"),
2114
+ "tick_upper": data.get("tickUpper"),
2115
+ "adjusted_min_price": data.get("adjustedMinPrice"),
2116
+ "adjusted_max_price": data.get("adjustedMaxPrice"),
2117
+ "position_token_id": str(data.get("positionTokenId") or "").strip() or None,
2118
+ "position_manager": str(data.get("positionManager") or "").strip() or None,
2119
+ "gas_fee": str(data.get("gasFee")) if data.get("gasFee") is not None else None,
2120
+ "approvals": list(data.get("approvals") or []),
2121
+ "approval_results": list(data.get("approvalResults") or []),
2122
+ "simulation": _normalize_swap_simulation(data.get("simulation")),
2123
+ "transaction": {
2124
+ "to": str(transaction.get("to") or "").strip() or None,
2125
+ "value": str(transaction.get("value") or "0"),
2126
+ "data_hash": str(transaction.get("dataHash") or "").strip() or None,
2127
+ },
2128
+ "hash": result.get("hash"),
2129
+ "result": result,
2130
+ "chain_id": int(data.get("chainId") or 0),
2131
+ "broadcasted": bool(result.get("hash")),
2132
+ "confirmed": bool(data.get("confirmed")),
2133
+ "source": str(data.get("source") or "wdk-evm-wallet"),
2134
+ }
2135
+
2136
+ async def preview_uniswap_liquidity(
2137
+ self,
2138
+ *,
2139
+ action: str,
2140
+ protocol: str,
2141
+ request: dict[str, Any],
2142
+ ) -> dict[str, Any]:
2143
+ if not isinstance(request, dict):
2144
+ raise WalletBackendError("Uniswap liquidity request must be an object.")
2145
+ data = await self.client.post(
2146
+ "/v1/evm/uniswap/liquidity/quote",
2147
+ {
2148
+ "walletId": self.wallet_id,
2149
+ "address": await self.get_address(),
2150
+ "accountIndex": self.account_index,
2151
+ "network": self.network,
2152
+ "action": action,
2153
+ "protocol": protocol,
2154
+ "request": request,
2155
+ },
2156
+ )
2157
+ normalized = self._normalize_uniswap_liquidity_payload(data, action=action, protocol=protocol)
2158
+ normalized["from_address"] = await self.get_address()
2159
+ normalized["execution_supported"] = not self.sign_only
2160
+ return normalized
2161
+
2162
+ async def send_uniswap_liquidity(
2163
+ self,
2164
+ *,
2165
+ action: str,
2166
+ protocol: str,
2167
+ request: dict[str, Any],
2168
+ ) -> dict[str, Any]:
2169
+ if self.sign_only:
2170
+ raise WalletBackendError("wdk_evm_local is configured as sign_only.")
2171
+ if not isinstance(request, dict):
2172
+ raise WalletBackendError("Uniswap liquidity request must be an object.")
2173
+ data = await self.client.post(
2174
+ "/v1/evm/uniswap/liquidity/send",
2175
+ {
2176
+ "walletId": self.wallet_id,
2177
+ "accountIndex": self.account_index,
2178
+ "network": self.network,
2179
+ "action": action,
2180
+ "protocol": protocol,
2181
+ "request": request,
2182
+ },
2183
+ )
2184
+ normalized = self._normalize_uniswap_liquidity_payload(data, action=action, protocol=protocol)
2185
+ normalized["from_address"] = await self.get_address()
2186
+ return normalized
2187
+
2031
2188
  async def preview_evm_lifi_cross_chain_swap(
2032
2189
  self,
2033
2190
  *,
@@ -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.93",
5
+ "version": "0.1.95",
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.93"
7
+ version = "0.1.95"
8
8
  description = "Plugin-friendly wallet backend for OpenClaw agents"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -513,6 +513,26 @@ def _pip_install_editable(python_bin: Path, package_root: Path) -> None:
513
513
  )
514
514
 
515
515
 
516
+ def _python_runtime_is_healthy(python_bin: Path) -> bool:
517
+ """Return whether a reusable venv has the installer dependencies available.
518
+
519
+ A shared runtime can be left half-created when an install is interrupted
520
+ between ``venv`` creation and the editable pip install. The interpreter
521
+ itself then exists, but the next update must repair it rather than treating
522
+ it as a valid cache entry.
523
+ """
524
+ try:
525
+ result = subprocess.run(
526
+ [str(python_bin), "-c", "import pydantic, pydantic_settings"],
527
+ capture_output=True,
528
+ text=True,
529
+ check=False,
530
+ )
531
+ except OSError:
532
+ return False
533
+ return result.returncode == 0
534
+
535
+
516
536
  def _ensure_python_runtime(
517
537
  venv_path: Path,
518
538
  package_root: Path,
@@ -529,9 +549,17 @@ def _ensure_python_runtime(
529
549
  created = True
530
550
  _bootstrap_venv_pip(python_bin)
531
551
  _pip_install_editable(python_bin, package_root)
552
+ elif not _python_runtime_is_healthy(python_bin):
553
+ # A prior update may have been interrupted after creating the venv
554
+ # but before pip finished. Repair the cache in place; release links
555
+ # continue to point at one verified shared environment.
556
+ _bootstrap_venv_pip(python_bin)
557
+ _pip_install_editable(python_bin, package_root)
558
+ plan["action"] = "repair"
532
559
  shared_wrapper = _ensure_python_wrapper(shared_venv_path)
533
560
  _replace_with_directory_symlink(venv_path, shared_venv_path)
534
- plan["action"] = "create" if created else "reuse"
561
+ if created:
562
+ plan["action"] = "create"
535
563
  plan["exists"] = True
536
564
  return (
537
565
  venv_path / shared_wrapper.relative_to(shared_venv_path),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-wallet",
3
3
  "displayName": "Agent Wallet",
4
- "version": "0.1.93",
4
+ "version": "0.1.95",
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"
@@ -0,0 +1,282 @@
1
+ # AgentLayer Wallet — Agent Guide
2
+
3
+ > **Relationship to `skills/wallet-operator/SKILL.md`:** that file is the
4
+ > authoritative, terse routing skill actually loaded by hosts (provider map, param
5
+ > tables, approval-flow template) — keep changes to tool routing/params there, not
6
+ > here. This document is a narrative companion: written the way an agent (or a human
7
+ > reading over its shoulder) would want the product *explained*, not just routed —
8
+ > modeled on how the `catena` CLI ships a self-contained `catena guide` command
9
+ > alongside its terse `--help` output; the `/guide` command in this plugin serves
10
+ > that exact role. Tool names below are short; the full MCP name is
11
+ > `mcp__plugin_agent-wallet_agent-wallet__<name>`.
12
+
13
+ This server holds funds in the local AgentLayer wallet across Solana, EVM
14
+ (Ethereum, Base, Robinhood chain), and Bitcoin. It is not a generic
15
+ crypto-data tool — every write here moves real money unless stated as
16
+ mainnet-gated preview. Leverage markets (Flash Trade perps:
17
+ `flash_trade_open_position`, `flash_trade_close_position`,
18
+ `get_flash_trade_markets`, `get_flash_trade_positions`) are out of scope for
19
+ this guide — do not use them without separate instructions.
20
+
21
+ ## What You Can Do
22
+
23
+ - **Solana**: transfers, swaps via Jupiter, native staking, Kamino (lending +
24
+ earn vaults + LP positions), token launches via Bags.
25
+ - **EVM** (Ethereum / Base / Robinhood): transfers, swaps (Velora or
26
+ Uniswap), and DeFi — Aave (lending), Lido (ETH staking), Morpho (markets +
27
+ vaults), and Uniswap concentrated liquidity positions (create / increase /
28
+ decrease / claim fees, V3 and V4 — existing V4 positions can't be
29
+ auto-discovered, only V3; for a V4 position the id has to come from the
30
+ user).
31
+ - **Cross-chain bridging** (LI.FI): Ethereum / Base / Solana to each other.
32
+ - **x402**: pay per-request HTTP 402 paywalls straight from the wallet —
33
+ preview the payment terms for free, then pay in one call.
34
+
35
+ See the sections below for exact tool names and parameters.
36
+
37
+ ## Setup & Session State
38
+
39
+ 1. `get_active_wallet_backend` — which backend (solana / evm / btc) is live
40
+ for this session, and whether it differs from the startup default.
41
+ 2. `get_wallet_address` — the address for the active backend.
42
+ 3. `get_wallet_capabilities` — chain, backend, and the safety limits in force.
43
+ 4. `set_wallet_backend` (`backend`: solana / evm / ethereum / base /
44
+ robinhood / btc / bitcoin, optional `network`) — switch backend for this
45
+ session without touching config files.
46
+ 5. For EVM specifically: `get_evm_network` shows the effective network and
47
+ which networks support swaps; `set_evm_network` (ethereum / base /
48
+ robinhood) changes it.
49
+
50
+ Balance reads (Solana): `get_wallet_balance` / `get_wallet_portfolio` are the
51
+ same enriched payload (native SOL + non-zero SPL accounts + USD pricing via
52
+ Jupiter) — `_portfolio` is just the more detailed name for the same call.
53
+ `get_wallet_overview` does the same lookup for an arbitrary backend/network/
54
+ address **without** switching the session's active wallet — use it to peek at
55
+ another chain or address in passing.
56
+
57
+ ## Quick Commands (Claude Code slash commands)
58
+
59
+ The plugin also ships fixed-format slash commands for the most common
60
+ requests — faster and more predictable than a free-form tool call, but each
61
+ covers only its one exact use case:
62
+
63
+ | Command | What it does |
64
+ |---|---|
65
+ | `/wallet-setup` | Install or repair the local wallet backend runtime. |
66
+ | `/wallet-sol` | Print the Solana wallet portfolio. |
67
+ | `/wallet-evm` | Print the EVM wallet overview for the current/default network. |
68
+ | `/wallet-base` | Print the Base wallet overview, and switch the session's active backend to Base. |
69
+ | `/wallet-ethereum` | Print the Ethereum mainnet wallet overview. |
70
+ | `/cards` | Buy a Laso Finance prepaid card (US or international), paid via x402 from the connected wallet. |
71
+ | `/agentlayer-autonomous-approve` | Turn on the full autonomous permission group (see below), with an in-command confirmation step first. |
72
+ | `/agentlayer-autonomous-revoke` | Turn it back off. |
73
+ | `/guide` | Walk a new user through this document conversationally. |
74
+
75
+ Every command except `/wallet-setup` requires the user to type it themselves
76
+ — the agent cannot trigger them on its own.
77
+
78
+ ## The preview → prepare → execute → approve Pattern
79
+
80
+ Nearly every write tool (transfers, swaps, staking, DeFi positions, BTC
81
+ sends, token launch) shares one lifecycle via a `mode` argument:
82
+
83
+ - `preview` — read-only summary of what the operation would do. No signing,
84
+ no broadcast. Always do this first.
85
+ - `prepare` — returns an execution plan (unsigned) for the same operation.
86
+ Requires `user_intent: true`. Used when the host needs to inspect the plan
87
+ before approving.
88
+ - `execute` — actually signs and broadcasts. Requires a host-issued approval
89
+ token bound to the exact previewed operation. In an interactive session the
90
+ host's own confirmation dialog supplies this. When it doesn't,
91
+ `issue_wallet_approval` is the explicit bridge step: call it with the
92
+ `tool_name` and the verbatim `confirmation_summary` from the prepare
93
+ response, plus `mainnet_confirmed: true` to acknowledge real funds are at
94
+ stake.
95
+
96
+ In Claude Code, don't call `issue_wallet_approval` or ask the user for a raw
97
+ `approval_token` yourself — the host's own confirmation dialog supplies it
98
+ once the user approves the call.
99
+
100
+ Never skip straight to `execute` on a mainnet operation the user has not
101
+ explicitly approved. Preview it, show the human what it does, then execute.
102
+
103
+ Always pass a short `purpose` string on write calls — it's the human-facing
104
+ audit label for what the transaction is for.
105
+
106
+ ## Standing Authority: Autonomous Sessions
107
+
108
+ Two separate mechanisms remove the per-transaction approval step. Both grant
109
+ broad, real-money authority and must only be turned on when the user has
110
+ explicitly asked for it:
111
+
112
+ - **Scoped autonomous session** — `start_autonomous_session` (preview then
113
+ execute) opens a bounded session: `allowed_tools`, `allowed_networks`,
114
+ `allowed_recipients`, per-tx / hourly / daily spend caps, tx-rate cap,
115
+ operation count cap, and a session TTL. `allow_mainnet: true` is required to
116
+ let it touch real funds. `get_autonomous_session` reads current status
117
+ (active, limits, operations used, expiry); `stop_autonomous_session` always
118
+ works and hands control back to per-transaction approval.
119
+ - **Full high-trust permission group** — `agentlayer_autonomous_approve`
120
+ (scope `all`) is broader and unbounded by comparison: it covers *every*
121
+ wallet write tool (transfers, bridges, Solana swaps, staking, x402
122
+ payments, contract calls, EVM DeFi management) with no per-operation
123
+ allow-list. Requires `user_intent: true` and an explicit purpose.
124
+ `agentlayer_autonomous_status` reads it; `agentlayer_autonomous_revoke`
125
+ turns it off.
126
+
127
+ Prefer the scoped session over the full permission group whenever the task
128
+ has a defined boundary (a specific token, a specific recipient, a spend cap)
129
+ — it's the difference between "let the agent do this one job unattended" and
130
+ "let the agent spend freely until told to stop."
131
+
132
+ There is no narrower version of the full permission group — pass `scope:
133
+ "all"`; for a bounded grant, use the scoped session instead.
134
+
135
+ ## Solana
136
+
137
+ - **Transfers**: `transfer_sol` (native), `transfer_spl_token` (by mint
138
+ address, optional `decimals` override).
139
+ - **Swaps**: `swap_solana_tokens` routes through Jupiter. Prefer
140
+ `mode: intent_preview` then `intent_execute` — it re-quotes fresh
141
+ immediately before sending and only executes within the previously
142
+ approved limits, which matters because Jupiter quotes expire fast. Legacy
143
+ `preview`/`prepare`/`execute` still works but is not preferred.
144
+ - **Prices**: `get_solana_token_prices` — Jupiter prices for a list of mints.
145
+ - **Housekeeping**: `close_empty_token_accounts` reclaims rent from
146
+ zero-balance SPL token accounts (preview lists them, execute closes up to
147
+ `limit`, default 8).
148
+ - **Native staking** (Solana Stake Program, not a DeFi protocol):
149
+ `stake_sol_native` (to a validator vote account), `get_solana_stake_account`
150
+ (activation status of one stake account), `get_solana_staking_validators`
151
+ (list validators by commission/activated stake), `deactivate_solana_stake`,
152
+ `withdraw_solana_stake`.
153
+ - **Kamino** (Solana's largest lend/earn/liquidity protocol):
154
+ - Discovery (read-only): `get_kamino_lend_markets` → main market first;
155
+ `get_kamino_lend_market_reserves` for per-token supply/borrow APY and
156
+ maxLtv; `get_kamino_vaults` for Earn-vault discovery
157
+ (`include_metrics: true` for APY/TVL, `token_mint` to filter).
158
+ - Lending writes: `kamino_lend_deposit`, `kamino_lend_borrow`,
159
+ `kamino_lend_repay`, `kamino_lend_withdraw` — all take `market`, `reserve`,
160
+ `amount_ui`; prefer `intent_preview` → `intent_execute` for the same
161
+ re-quote-before-send reason as swaps.
162
+ - Earn vault writes: `kamino_earn_deposit`, `kamino_earn_withdraw` (take
163
+ `kvault`, `amount_ui`).
164
+ - Position reads: `get_kamino_lend_user_obligations` (one market),
165
+ `get_kamino_open_positions` (all lending positions across markets),
166
+ `get_kamino_earn_positions`, `get_kamino_liquidity_positions`,
167
+ `get_kamino_lend_user_rewards`, and `get_kamino_portfolio` for the single
168
+ unified view across lending/earn/liquidity/staking.
169
+ - **Token launch**: `launch_bags_token` creates a token via Bags with a
170
+ fee-share config (`claimers` + `basis_points`, must sum to 10000) and an
171
+ optional `initial_buy_sol`. Same preview/prepare/execute lifecycle.
172
+
173
+ ## EVM (Ethereum, Base, Robinhood chain)
174
+
175
+ - **Read utilities**: `get_evm_token_balance`, `get_evm_token_metadata`,
176
+ `get_evm_transaction_receipt` (by tx hash), `get_evm_fee_rates`.
177
+ - **Transfers**: `transfer_evm_native` (wei), `transfer_evm_token` (ERC-20,
178
+ raw base units + `token_address`).
179
+ - **Swaps — two independent routers, pick one**:
180
+ - Velora: `get_evm_swap_quote` (read-only) → `swap_evm_tokens`. Ethereum/
181
+ Base only.
182
+ - Uniswap: `get_uniswap_swap_quote` → `swap_evm_uniswap_tokens`. Covers
183
+ CLASSIC pools, UniswapX orders, and ETH↔WETH wrap/unwrap; supports
184
+ Ethereum, Base, and Robinhood chain; has a `slippage_bps` param (default
185
+ 300 = 3%).
186
+ - `search_uniswap_pairs` finds a token's contract address by ticker/name
187
+ via DexScreener — **security note**: free-text ticker search can surface
188
+ impersonator tokens with fabricated liquidity/FDV, especially for tickers
189
+ claiming to represent a real-world stock/ETF. Verify the resolved
190
+ `token_address` independently (`get_evm_token_metadata`, or the chain's
191
+ official contract list) before quoting or swapping a real-world-asset
192
+ ticker — a successful quote does not itself prove legitimacy.
193
+ - **DeFi protocols** (read tools are free; every write follows preview →
194
+ execute):
195
+ - **Aave v3** (lending): `get_evm_aave_account` (health factor etc.),
196
+ `get_evm_aave_positions` (per-reserve supplied/borrowed),
197
+ `get_evm_aave_reserves` (market catalog) →
198
+ `manage_evm_aave_position` with `operation`: supply / withdraw / borrow /
199
+ repay.
200
+ - **Lido** (ETH liquid staking, Ethereum mainnet only):
201
+ `get_evm_lido_overview`, `get_evm_lido_positions` (stETH/wstETH),
202
+ `get_evm_lido_withdrawal_requests` →
203
+ `manage_evm_lido_position` (`stake_eth_for_wsteth` / `wrap_steth` /
204
+ `unwrap_wsteth`) and `manage_evm_lido_withdrawal`
205
+ (`request_withdrawal_steth` / `request_withdrawal_wsteth` /
206
+ `claim_withdrawal`, needs `request_id` to claim).
207
+ - **Morpho** (lending markets + curated vaults): `get_evm_morpho_markets` /
208
+ `get_evm_morpho_vaults` for discovery (filter by asset, sort by APY —
209
+ pair APY sorts with a `min_supply_usd`/`min_tvl_usd` floor to skip dust),
210
+ `get_evm_morpho_positions` for what the wallet currently holds →
211
+ `manage_evm_morpho_market_position` (supply_collateral / borrow / repay /
212
+ withdraw_collateral, isolated market by `market_id` or `market_preset`)
213
+ and `manage_evm_morpho_vault_position` (supply / withdraw, by
214
+ `vault_address` or `vault_preset`).
215
+ - **Uniswap Liquidity Provisioning** (concentrated LP positions, V3 and
216
+ V4): discovery first — `get_evm_uniswap_pools` finds an existing pool by
217
+ token pair and returns its `poolReferenceIdentifier`;
218
+ `get_evm_uniswap_positions` lists the wallet's V3 position NFTs (fee
219
+ tier, tick range, owed fees) — V4 position discovery isn't available
220
+ (V4's PositionManager isn't enumerable on-chain the way V3's is) →
221
+ `manage_evm_uniswap_liquidity` with `action`: create / increase /
222
+ decrease / claim_fees. `create` needs `existingPool.poolReference` (the
223
+ discovery tool's `poolReferenceIdentifier` value, under a different
224
+ field name); increase/decrease/claim_fees need the position's NFT token
225
+ id. Never guess either identifier — always discover it first, the tool
226
+ rejects the call outright if it's missing. This is a thin pass-through
227
+ to Uniswap's own official Liquidity API; deploying a brand-new pool is
228
+ out of scope.
229
+
230
+ ## Cross-Chain Bridging (LI.FI)
231
+
232
+ - `get_lifi_supported_chains` — currently allowed chains for routing.
233
+ - `get_lifi_quote` — read-only quote between any two of Ethereum / Base /
234
+ Solana (bridge preferences via `allow_bridges` / `deny_bridges` /
235
+ `prefer_bridges`, slippage as a decimal fraction).
236
+ - `swap_evm_lifi_cross_chain_tokens` — execute EVM-origin (Ethereum/Base) →
237
+ Ethereum/Base/Solana.
238
+ - `swap_solana_lifi_cross_chain_tokens` — execute Solana-origin →
239
+ Ethereum/Base.
240
+ - `get_lifi_transfer_status` — poll a bridge transfer by source tx hash.
241
+
242
+ Same preview/prepare/execute + approval-token discipline as everything else.
243
+ Mayan routes are deliberately denied — see `skills/wallet-operator/SKILL.md`.
244
+
245
+ ## Bitcoin
246
+
247
+ - `transfer_btc` — amount in `amount_sats`, optional `fee_rate` (sats/vB) or
248
+ `confirmation_target`.
249
+ - `get_btc_fee_rates`, `get_btc_max_spendable` (post-fee spendable estimate),
250
+ `get_btc_transfer_history` (filter by `direction`, paginate with
251
+ `limit`/`skip`).
252
+
253
+ ## x402 — Paying HTTP 402 Endpoints
254
+
255
+ - `x402_search_services` — read-only discovery of paid services via CDP
256
+ Bazaar or Agentic Market (filter by `query`, `max_usd_price`, `network`).
257
+ - `x402_get_service_details` — resolve one service/resource URL into details.
258
+ - `x402_preview_request` — makes the *unpaid* request, reads the 402
259
+ challenge, and summarizes payment options. Does not pay.
260
+ - `x402_pay_request` — does the whole flow in one call: probes the endpoint,
261
+ validates it, signs the payment from the active wallet backend, and
262
+ returns the paid response. Requires `purpose`.
263
+
264
+ This is the same x402 v2 protocol the `catena` MCP/CLI speaks — a discrete
265
+ pay-per-request charge, not a subscription or usage meter — but here the
266
+ payer is this wallet directly rather than a governed bank rail, so there is
267
+ no separate approval-parking step: the preview → execute discipline above is
268
+ what stands between the agent and the payment.
269
+
270
+ ## Explaining This to a Human
271
+
272
+ If asked to summarize this server in plain terms: it's a direct line to the
273
+ local AgentLayer wallet — Solana, an EVM chain (Ethereum/Base/Robinhood),
274
+ and Bitcoin — plus the major yield/lending/LP protocols on those chains
275
+ (Kamino, Aave, Lido, Morpho, Uniswap concentrated liquidity) and the ability
276
+ to pay per-request API/data paywalls (x402) straight from the wallet.
277
+ Everything that moves funds is gated by a preview step and an approval token
278
+ by default; "autonomous session" and "autonomous permission group" are the
279
+ two ways a human can explicitly grant the agent standing authority to skip
280
+ that per-transaction gate, bounded (the former) or broad (the latter) —
281
+ always confirm with the user before either one is enabled, and treat any
282
+ operation on mainnet as real, irreversible money movement.
@@ -66,6 +66,8 @@ no-op once the backend is healthy.
66
66
  explicit in-command confirmation before enabling the standing permission.
67
67
  - `/agentlayer-autonomous-revoke` — disable the combined autonomous permission
68
68
  group for Base swaps and supported EVM DeFi tools.
69
+ - `/guide` — walk a new user through what this plugin can do, conversationally
70
+ (see `AGENTLAYER_AGENT_GUIDE.md` for the source material).
69
71
  - `AGENT_WALLET_AUTO_BOOTSTRAP=0` — opt out of the auto-install: the
70
72
  `SessionStart` hook then only reminds you to run `/wallet-setup` instead of
71
73
  installing the backend itself.
@@ -0,0 +1,40 @@
1
+ ---
2
+ description: Walk a new user through what the AgentLayer wallet plugin can do, conversationally.
3
+ allowed-tools: Bash(cat:*)
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ Give the user a plain-language walkthrough of this wallet plugin, the way
8
+ you'd onboard someone who has never used it before.
9
+
10
+ 1. Read the source material:
11
+
12
+ ```
13
+ cat "${CLAUDE_PLUGIN_ROOT}/AGENTLAYER_AGENT_GUIDE.md"
14
+ ```
15
+
16
+ 2. Do not paste or summarize the raw file section-by-section. Retell it as a
17
+ conversational walkthrough, addressed directly to the user ("you"), in
18
+ the language they've been using. Cover, roughly in this order:
19
+
20
+ - **What it is** — a direct line to their own local AgentLayer wallet
21
+ (Solana, an EVM chain, Bitcoin), not a generic crypto-data tool; every
22
+ write moves real money unless it's an explicit preview.
23
+ - **What they can do** — the "What You Can Do" list: Solana (transfers,
24
+ Jupiter swaps, staking, Kamino, Bags launches), EVM (transfers, swaps,
25
+ Aave/Lido/Morpho/Uniswap LP), cross-chain bridging, x402 payments.
26
+ - **How a session works** — the agent checks which backend/network is
27
+ active before doing anything, and can switch between them.
28
+ - **The quick commands** — list the slash commands from the "Quick
29
+ Commands" table by name and one-line purpose only; skip why each one
30
+ is or isn't model-invokable, that's implementation detail.
31
+ - **How money-moving operations work** — preview first, then execute
32
+ only after they confirm; keep this to the outcome (see it, approve it,
33
+ then it happens), not the internal approval-token mechanics.
34
+ - **Autonomous mode** — that it exists as an opt-in way to skip
35
+ per-operation confirmation, with a bounded (scoped) and an unbounded
36
+ (full) version, and that either requires them to explicitly ask for it.
37
+
38
+ 3. Keep the whole thing skimmable — short paragraphs or a few bullets per
39
+ topic, no wall of text. Close by inviting them to ask about any specific
40
+ chain or protocol for the exact tool-level detail.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-wallet",
3
- "version": "0.1.93",
3
+ "version": "0.1.95",
4
4
  "description": "Codex plugin bridge for the AgentLayer wallet runtime.",
5
5
  "author": {
6
6
  "name": "AgentLayer"
@@ -69,6 +69,7 @@ AUTONOMOUS_DEFI_TOOLS = {
69
69
  "manage_evm_lido_withdrawal",
70
70
  "manage_evm_morpho_market_position",
71
71
  "manage_evm_morpho_vault_position",
72
+ "manage_evm_uniswap_liquidity",
72
73
  }
73
74
  APPROVAL_PREVIEW_TOOL_ALIASES = {
74
75
  "x402_pay_request": "x402_preview_request",
@@ -1,5 +1,5 @@
1
1
  name: agent-wallet
2
- version: 0.1.93
2
+ version: 0.1.95
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.93",
3
+ "version": "0.1.95",
4
4
  "description": "Universal AgentLayer wallet installer for OpenClaw, Codex, Claude Code, and Hermes.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wdk-btc-wallet",
3
- "version": "0.1.93",
3
+ "version": "0.1.95",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Separate BTC-only wallet service built on Tether WDK.",
@@ -26,6 +26,9 @@ MORPHO_API_BASE_URL=https://api.morpho.org/graphql
26
26
  # directly (https://trade-api.gateway.uniswap.org/v1) for legacy/offline direct mode.
27
27
  UNISWAP_API_KEY=
28
28
  # UNISWAP_TRADING_API_BASE_URL= # defaults to PROVIDER_GATEWAY_URL/v1/evm/uniswap
29
+ # LP actions use the Liquidity API. Gateway mode is the default; set this only
30
+ # for direct API access (for example https://liquidity.api.uniswap.org).
31
+ # UNISWAP_LIQUIDITY_API_BASE_URL= # defaults to PROVIDER_GATEWAY_URL/v1/evm/uniswap/lp
29
32
  UNISWAP_ROUTER_VERSION=2.0
30
33
  # Optional per-network override; each value must exist in the wallet's reviewed
31
34
  # execution profile and match the provider-gateway's per-chain configuration.
@@ -187,6 +187,7 @@ Environment variables:
187
187
  - `MORPHO_API_BASE_URL`
188
188
  - `UNISWAP_API_KEY`
189
189
  - `UNISWAP_TRADING_API_BASE_URL`
190
+ - `UNISWAP_LIQUIDITY_API_BASE_URL`
190
191
  - `UNISWAP_ROUTER_VERSION`
191
192
  - `UNISWAP_ROUTER_VERSION_BY_NETWORK`
192
193
  - `UNISWAP_DEFAULT_SLIPPAGE_BPS`
@@ -214,6 +215,11 @@ Swap providers:
214
215
  - `UNISWAP_API_KEY` is required for the Uniswap routes; it identifies the
215
216
  integrator (this service), not an end user — swaps are scoped per request by the
216
217
  active wallet address, so a single key never mixes users
218
+ - LP actions (`create`, `increase`, `decrease`, `claim_fees`) are exposed at
219
+ `/v1/evm/uniswap/liquidity/*` and use Uniswap's Liquidity API. The runtime
220
+ accepts transactions only for pinned V3/V4 PositionManager deployments on
221
+ Ethereum, Base, and Robinhood, refreshes the final LP transaction just before
222
+ signing, and executes only API-returned bounded approvals.
217
223
 
218
224
  Gateway mode:
219
225