@agentlayer.tech/wallet 0.1.30 → 0.1.33

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 (40) hide show
  1. package/.openclaw/extensions/agent-wallet/README.md +1 -2
  2. package/.openclaw/extensions/agent-wallet/dist/index.js +6 -340
  3. package/.openclaw/extensions/agent-wallet/index.ts +6 -340
  4. package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +0 -43
  5. package/.openclaw/extensions/agent-wallet/package.json +1 -1
  6. package/.openclaw/extensions/agent-wallet/skills/wallet-operator/SKILL.md +1 -3
  7. package/CHANGELOG.md +60 -0
  8. package/README.md +0 -5
  9. package/agent-wallet/.env.example +0 -12
  10. package/agent-wallet/README.md +0 -35
  11. package/agent-wallet/agent_wallet/btc_user_wallets.py +32 -1
  12. package/agent-wallet/agent_wallet/config.py +11 -7
  13. package/agent-wallet/agent_wallet/evm_user_wallets.py +2 -0
  14. package/agent-wallet/agent_wallet/openclaw_adapter.py +1 -655
  15. package/agent-wallet/agent_wallet/openclaw_cli.py +0 -7
  16. package/agent-wallet/agent_wallet/providers/evm_portfolio.py +18 -42
  17. package/agent-wallet/agent_wallet/providers/jupiter.py +1 -307
  18. package/agent-wallet/agent_wallet/providers/wdk_btc_local.py +31 -3
  19. package/agent-wallet/agent_wallet/providers/wdk_evm_local.py +37 -3
  20. package/agent-wallet/agent_wallet/transaction_policy.py +0 -262
  21. package/agent-wallet/agent_wallet/wallet_layer/base.py +0 -100
  22. package/agent-wallet/agent_wallet/wallet_layer/solana.py +1 -1118
  23. package/agent-wallet/openclaw.plugin.json +0 -4
  24. package/agent-wallet/pyproject.toml +1 -1
  25. package/agent-wallet/scripts/install_agent_wallet.py +113 -6
  26. package/agent-wallet/scripts/install_openclaw_local_config.py +7 -5
  27. package/agent-wallet/skills/wallet-operator/SKILL.md +1 -5
  28. package/bin/openclaw-agent-wallet.mjs +434 -68
  29. package/claude-code/plugins/agent-wallet/scripts/run_mcp.sh +21 -3
  30. package/codex/plugins/agent-wallet/scripts/run_mcp.sh +18 -0
  31. package/codex/plugins/agent-wallet/server.py +2 -118
  32. package/hermes/plugins/agent_wallet/tools.py +1 -1
  33. package/package.json +1 -1
  34. package/wdk-btc-wallet/src/local_vault.js +45 -68
  35. package/wdk-btc-wallet/src/server.js +1 -0
  36. package/wdk-evm-wallet/README.md +4 -3
  37. package/wdk-evm-wallet/src/config.js +15 -0
  38. package/wdk-evm-wallet/src/local_vault.js +45 -68
  39. package/wdk-evm-wallet/src/server.js +1 -0
  40. package/agent-wallet/agent_wallet/providers/houdini.py +0 -539
@@ -117,10 +117,6 @@
117
117
  "type": "string",
118
118
  "description": "Optional Jupiter Portfolio API base URL for Jupiter-specific positions and staking data."
119
119
  },
120
- "jupiterLendBaseUrl": {
121
- "type": "string",
122
- "description": "Optional Jupiter Lend API base URL for Earn read and deposit/withdraw flows."
123
- },
124
120
  "jupiterApiKey": {
125
121
  "type": "string",
126
122
  "description": "Optional Jupiter API key if your deployment uses a keyed endpoint."
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "openclaw-agent-wallet"
7
- version = "0.1.30"
7
+ version = "0.1.33"
8
8
  description = "Plugin-friendly wallet backend for OpenClaw agents"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -182,6 +182,7 @@ def build_parser() -> argparse.ArgumentParser:
182
182
  parser.add_argument("--extension-path", default=str(_extension_path()))
183
183
  parser.add_argument("--wdk-btc-root", default=str(_default_wdk_btc_root()))
184
184
  parser.add_argument("--wdk-evm-root", default=str(_default_wdk_evm_root()))
185
+ parser.add_argument("--wdk-evm-service-url", default=EVM_DEFAULT_SERVICE_URL)
185
186
  parser.add_argument("--runtime-root", default=str(_default_runtime_root()))
186
187
  parser.add_argument("--npm-bin", default=_default_npm_bin())
187
188
  parser.add_argument("--plugin-id", default="agent-wallet")
@@ -665,6 +666,9 @@ def _build_next_steps(
665
666
  command.extend(["--extension-path", str(effective_extension_path)])
666
667
  command.extend(["--package-root", str(effective_package_root)])
667
668
  command.extend(["--python-bin", str(python_bin)])
669
+ if _is_evm_backend(args.backend):
670
+ service_url = str(getattr(args, "wdk_evm_service_url", "") or EVM_DEFAULT_SERVICE_URL).strip()
671
+ command.extend(["--wdk-evm-service-url", service_url or EVM_DEFAULT_SERVICE_URL])
668
672
  return command
669
673
 
670
674
 
@@ -672,18 +676,51 @@ def _is_solana_backend(backend: str) -> bool:
672
676
  return backend.strip().lower() in {"solana", "solana_local", "solana-local"}
673
677
 
674
678
 
679
+ def _is_evm_backend(backend: str) -> bool:
680
+ return backend.strip().lower() in {
681
+ "wdk_evm_local",
682
+ "wdk-evm-local",
683
+ "evm_local",
684
+ "evm-local",
685
+ }
686
+
687
+
688
+ EVM_DEFAULT_SERVICE_URL = "http://127.0.0.1:8081"
689
+
690
+
691
+ def _build_evm_onboard_config(args: argparse.Namespace) -> dict[str, object]:
692
+ # The EVM wallet is provisioned on every install (best-effort). Seed creation
693
+ # with a valid EVM network; ensure_user_evm_wallet_ready binds BOTH base and
694
+ # ethereum (one address), so the active --network only matters when EVM is the
695
+ # active backend.
696
+ network = args.network.strip().lower() if _is_evm_backend(args.backend) else "base"
697
+ if network not in {"base", "ethereum"}:
698
+ network = "base"
699
+ service_url = str(getattr(args, "wdk_evm_service_url", "") or EVM_DEFAULT_SERVICE_URL).strip()
700
+ return {
701
+ "backend": "wdk_evm_local",
702
+ "network": network,
703
+ "signOnly": bool(args.sign_only),
704
+ "wdkEvmServiceUrl": service_url or EVM_DEFAULT_SERVICE_URL,
705
+ }
706
+
707
+
675
708
  def _build_solana_onboard_config(args: argparse.Namespace) -> dict[str, object]:
709
+ # Solana is provisioned on every install (both wallets are created), so force
710
+ # the Solana backend/network here -- this must work even when the active
711
+ # backend chosen by the user is EVM or BTC.
712
+ solana_active = _is_solana_backend(args.backend)
676
713
  config: dict[str, object] = {
677
- "backend": args.backend,
678
- "network": args.network,
714
+ "backend": "solana_local",
715
+ "network": "mainnet",
679
716
  "signOnly": bool(args.sign_only),
680
717
  "encryptUserWallets": True,
681
718
  "migratePlaintextUserWallets": True,
682
719
  "refuseMainnetWalletRecreation": True,
683
720
  }
684
- if args.rpc_url.strip():
721
+ if solana_active and args.rpc_url.strip():
685
722
  config["rpcUrl"] = args.rpc_url.strip()
686
- if args.rpc_urls.strip():
723
+ if solana_active and args.rpc_urls.strip():
687
724
  config["rpcUrls"] = [item.strip() for item in args.rpc_urls.split(",") if item.strip()]
688
725
  return config
689
726
 
@@ -708,8 +745,6 @@ def _bootstrap_solana_wallet(
708
745
  package_root: Path,
709
746
  args: argparse.Namespace,
710
747
  ) -> dict[str, object] | None:
711
- if not _is_solana_backend(args.backend):
712
- return None
713
748
  result = subprocess.run(
714
749
  [
715
750
  str(python_bin),
@@ -741,6 +776,60 @@ def _bootstrap_solana_wallet(
741
776
  }
742
777
 
743
778
 
779
+ def _bootstrap_evm_wallet(
780
+ python_bin: Path,
781
+ package_root: Path,
782
+ args: argparse.Namespace,
783
+ wdk_evm_root: Path,
784
+ ) -> dict[str, object]:
785
+ """Provision the local EVM wallet (best-effort).
786
+
787
+ Mirrors _bootstrap_solana_wallet but for wdk_evm_local. Runs the onboard CLI,
788
+ which calls ensure_user_evm_wallet_ready: auto-starts the local Node service,
789
+ creates and seals the wallet password, and binds both base and ethereum.
790
+ Failures here never abort the install -- the lazy runtime path (ensure_ready on
791
+ first EVM use) remains the safety net.
792
+ """
793
+ env = _runtime_env_for_onboard(package_root)
794
+ env["OPENCLAW_EVM_WDK_WALLET_ROOT"] = str(wdk_evm_root)
795
+ try:
796
+ result = subprocess.run(
797
+ [
798
+ str(python_bin),
799
+ "-m",
800
+ "agent_wallet.openclaw_cli",
801
+ "onboard",
802
+ "--user-id",
803
+ args.user_id,
804
+ "--config-json",
805
+ json.dumps(_build_evm_onboard_config(args)),
806
+ ],
807
+ cwd=package_root,
808
+ capture_output=True,
809
+ text=True,
810
+ check=True,
811
+ env=env,
812
+ )
813
+ except subprocess.CalledProcessError as exc:
814
+ detail = (exc.stderr or exc.stdout or str(exc)).strip()
815
+ return {"ok": False, "error": detail[-2000:]}
816
+ try:
817
+ payload = json.loads(result.stdout)
818
+ except json.JSONDecodeError:
819
+ return {"ok": False, "error": "EVM onboard returned non-JSON output."}
820
+ session = dict(payload.get("session") or {})
821
+ wallet_path = str(session.get("wallet_path") or "")
822
+ wallet_id = wallet_path.split("walletId=", 1)[-1] if "walletId=" in wallet_path else None
823
+ return {
824
+ "ok": True,
825
+ "user_id": session.get("user_id") or args.user_id,
826
+ "address": session.get("address"),
827
+ "wallet_id": wallet_id,
828
+ "networks": ["base", "ethereum"],
829
+ "backend": session.get("backend"),
830
+ }
831
+
832
+
744
833
  def main() -> None:
745
834
  args = build_parser().parse_args()
746
835
  source_package_root = Path(args.package_root).expanduser().resolve()
@@ -873,6 +962,7 @@ def main() -> None:
873
962
  configured = False
874
963
  configure_stdout = ""
875
964
  solana_onboard_result: dict[str, object] | None = None
965
+ evm_onboard_result: dict[str, object] | None = None
876
966
  if backend_enabled and not pending_env and not args.dry_run:
877
967
  result = subprocess.run(
878
968
  _build_next_steps(
@@ -893,6 +983,22 @@ def main() -> None:
893
983
  package_root,
894
984
  args,
895
985
  )
986
+ # Both wallets are provisioned on every install. EVM provisioning is
987
+ # best-effort: a failure here must not abort the install, since the lazy
988
+ # runtime path will create the wallet on first EVM use.
989
+ evm_onboard_result = _bootstrap_evm_wallet(
990
+ python_bin,
991
+ package_root,
992
+ args,
993
+ wdk_evm_root,
994
+ )
995
+ if isinstance(evm_onboard_result, dict) and not evm_onboard_result.get("ok"):
996
+ print(
997
+ "warning: the EVM wallet was not provisioned during install; it will "
998
+ "be created automatically on first EVM use. Details: "
999
+ + str(evm_onboard_result.get("error") or "unknown"),
1000
+ file=sys.stderr,
1001
+ )
896
1002
 
897
1003
  print(
898
1004
  json.dumps(
@@ -918,6 +1024,7 @@ def main() -> None:
918
1024
  "configured": configured,
919
1025
  "pending_env": pending_env,
920
1026
  "solana_wallet": solana_onboard_result,
1027
+ "evm_wallet": evm_onboard_result,
921
1028
  "next_configure_command": _build_next_steps(
922
1029
  python_bin,
923
1030
  install_config_script,
@@ -13,7 +13,11 @@ from pathlib import Path
13
13
  sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
14
14
 
15
15
  from agent_wallet.file_ops import atomic_write_text, chmod_if_exists
16
- from agent_wallet.config import normalize_btc_network, normalize_solana_network
16
+ from agent_wallet.config import (
17
+ normalize_btc_network,
18
+ normalize_evm_network,
19
+ normalize_solana_network,
20
+ )
17
21
  from agent_wallet.sealed_keys import resolve_sealed_keys_path, seal_keys, unseal_keys
18
22
  from security_utils import write_redacted_backup
19
23
 
@@ -25,10 +29,6 @@ LEGACY_ALLOWLIST_TOOLS = [
25
29
  "set_wallet_backend",
26
30
  "get_wallet_portfolio",
27
31
  "get_solana_token_prices",
28
- "swap_solana_privately",
29
- "continue_solana_private_swap",
30
- "list_pending_solana_private_swaps",
31
- "get_solana_private_swap_status",
32
32
  "get_kamino_lend_markets",
33
33
  "get_kamino_lend_market_reserves",
34
34
  "get_kamino_lend_user_obligations",
@@ -182,6 +182,8 @@ def _normalize_network(backend: str, network: str) -> str:
182
182
  normalized = network.strip().lower()
183
183
  if backend_name in {"wdk_btc_local", "wdk-btc-local", "btc_local", "btc-local"}:
184
184
  return normalize_btc_network(normalized or "bitcoin")
185
+ if backend_name in {"wdk_evm_local", "wdk-evm-local", "evm_local", "evm-local"}:
186
+ return normalize_evm_network(normalized or "ethereum")
185
187
  return normalize_solana_network(normalized or "mainnet")
186
188
 
187
189
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wallet-operator
3
- description: Use when operating OpenClaw wallet tools: balances, transfers, swaps, LI.FI cross-chain swaps, Jupiter swaps, Velora EVM swaps, BTC transfers, staking, Jupiter Earn, Kamino lending, Bags claims/launches, and wallet execution safety.
3
+ description: Use when operating OpenClaw wallet tools: balances, transfers, swaps, LI.FI cross-chain swaps, Jupiter swaps, Velora EVM swaps, BTC transfers, staking, Kamino lending, Bags claims/launches, and wallet execution safety.
4
4
  ---
5
5
 
6
6
  # Wallet Operator
@@ -29,7 +29,6 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
29
29
  - EVM transfers: `transfer_evm_native`, `transfer_evm_token`.
30
30
  - BTC transfer: `transfer_btc`.
31
31
  - Solana staking: `stake_sol_native`, `deactivate_solana_stake`, `withdraw_solana_stake`.
32
- - Jupiter Earn: `jupiter_earn_deposit`, `jupiter_earn_withdraw`.
33
32
  - Kamino: `kamino_lend_deposit`, `kamino_lend_withdraw`, `kamino_lend_borrow`, `kamino_lend_repay`.
34
33
  - Bags: `claim_bags_fees`, `launch_bags_token`.
35
34
 
@@ -107,9 +106,6 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
107
106
  - `stake_sol_native`: `vote_account`, `amount` in SOL, `mode`, `purpose`.
108
107
  - `deactivate_solana_stake`: `stake_account`, `mode`, `purpose`.
109
108
  - `withdraw_solana_stake`: `stake_account`, `amount` in SOL, optional `recipient`, `mode`, `purpose`.
110
- - Before Jupiter Earn writes, use `get_jupiter_earn_tokens`, `get_jupiter_earn_positions`, and `get_jupiter_earn_earnings`.
111
- - `jupiter_earn_deposit`: `asset` mint, `amount_raw`, `mode`, `purpose`.
112
- - `jupiter_earn_withdraw`: `asset` mint, `amount_raw`, `mode`, `purpose`.
113
109
  - Before Kamino writes, use `get_kamino_lend_markets`, `get_kamino_lend_market_reserves`, `get_kamino_lend_user_obligations`, and `get_kamino_lend_user_rewards`.
114
110
  - Kamino write params: `market`, `reserve`, `amount_ui` decimal string, `mode`, `purpose`.
115
111
  - Bags reads: `get_bags_claimable_positions`, `get_bags_fee_analytics`.