@agentlayer.tech/wallet 0.1.76 → 0.1.77

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/README.md +4 -4
  2. package/.openclaw/extensions/agent-wallet/dist/index.js +57 -19
  3. package/.openclaw/extensions/agent-wallet/index.ts +57 -19
  4. package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +1 -1
  5. package/.openclaw/extensions/agent-wallet/package.json +1 -1
  6. package/CHANGELOG.md +19 -0
  7. package/VERSION +1 -1
  8. package/agent-wallet/agent_wallet/__init__.py +1 -1
  9. package/agent-wallet/agent_wallet/autonomous_permissions.py +2 -2
  10. package/agent-wallet/agent_wallet/autonomous_policy.py +1 -1
  11. package/agent-wallet/agent_wallet/config.py +3 -3
  12. package/agent-wallet/agent_wallet/openclaw_adapter.py +24 -24
  13. package/agent-wallet/agent_wallet/providers/evm_portfolio.py +2 -2
  14. package/agent-wallet/agent_wallet/wallet_layer/wdk_evm.py +2 -2
  15. package/agent-wallet/openclaw.plugin.json +1 -1
  16. package/agent-wallet/pyproject.toml +1 -1
  17. package/agent-wallet/skills/wallet-operator/SKILL.md +4 -1
  18. package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +1 -1
  19. package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +1 -1
  20. package/codex/plugins/agent-wallet/server.py +13 -10
  21. package/codex/plugins/agent-wallet/skills/wallet-operator/SKILL.md +1 -1
  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 -2
  26. package/wdk-evm-wallet/package.json +5 -2
  27. package/wdk-evm-wallet/src/config.js +16 -2
  28. package/wdk-evm-wallet/src/network_state.js +5 -2
  29. package/wdk-evm-wallet/src/wdk_evm_wallet.js +10 -4
@@ -14,7 +14,7 @@ It is designed so the OpenClaw agent sees a small operational wallet surface ins
14
14
  In practice this means the agent works through explicit tools for:
15
15
 
16
16
  - BTC balance, fee-rate, max-spendable, history, and transfer flows through the local `wdk-btc-wallet` backend
17
- - EVM native balance, ERC-20 balance/metadata, fee-rate, receipt, Velora swap quote/execute, Aave V3 account/reserve/position flows, and transfer flows through the local `wdk-evm-wallet` backend
17
+ - EVM native balance, ERC-20 balance/metadata, fee-rate, receipt, Velora and Uniswap swap quote/execute, Aave V3 account/reserve/position flows, and transfer flows through the local `wdk-evm-wallet` backend
18
18
  - wallet address, balances, and portfolio reads
19
19
  - native SOL and SPL token transfers
20
20
  - Jupiter swap and price lookup, including Solana swap intent execution that refreshes quotes inside user-approved limits
@@ -94,11 +94,11 @@ Important:
94
94
  - When the BTC service URL is local, that bootstrap script can also auto-start `wdk-btc-wallet` before patching OpenClaw config.
95
95
  - The EVM flow also only supports local service URLs (`127.0.0.1` / `localhost` / `::1`) and uses a bearer token loaded from `~/.openclaw/wdk-evm-wallet/local-auth-token`.
96
96
  - The installer now provisions a sealed local EVM vault password under `sealed_keys.json` by default, and host-side EVM setup helpers refresh that sealed value whenever the operator enters a new password.
97
- - The EVM tool surface is intentionally narrow: Velora swap quote/execute, Aave V3 account/reserve/position flows, native transfers, ERC-20 transfers, fee quotes, and receipt lookup only. No arbitrary calldata, standalone approvals, or generic contract execution are exposed to the agent.
97
+ - The EVM tool surface is intentionally narrow: Velora and Uniswap swap quote/execute, Aave V3 account/reserve/position flows, native transfers, ERC-20 transfers, fee quotes, and receipt lookup only. No arbitrary calldata, standalone approvals, or generic contract execution are exposed to the agent.
98
98
  - Velora swap and Aave V3 support are currently limited to `ethereum` and `base`. Test carefully because the upstream WDK protocol packages are still beta.
99
99
  - Agents can call `set_wallet_backend` to switch the active wallet for the current OpenClaw plugin session between Solana, EVM, and Bitcoin. This does not edit `openclaw.json`; plugin config remains the startup default.
100
- - EVM read and write tools accept an optional per-call `network` override for `ethereum` or `base`.
101
- - Agents can also call `set_evm_network` to select the active EVM network for the current OpenClaw plugin session. After that, EVM tools default to the selected network unless a specific call passes its own `network` value. Do not edit code, plugin config, or environment variables just to switch between Base and Ethereum.
100
+ - EVM core read and transfer tools accept an optional per-call `network` override for `ethereum`, `base`, or `robinhood`; Velora/Aave remain limited to Ethereum/Base, while Uniswap supports all three.
101
+ - Agents can also call `set_evm_network` to select the active EVM network for the current OpenClaw plugin session. After that, EVM tools default to the selected network unless a specific call passes its own `network` value. Do not edit code, plugin config, or environment variables just to switch between Base, Ethereum, and Robinhood.
102
102
  - `get_wallet_balance` returns an enriched wallet overview for Solana and EVM: native balance, discovered token balances, per-asset USD values when pricing is available, and `total_value_usd`.
103
103
  - Solana wallet overview uses Solana RPC only for balance and token-account discovery. Token prices come from Jupiter, not RPC, and internal transfer/staking checks continue to use native-only balance reads.
104
104
  - If the user needs to recover the mnemonic later, host-side reveal stays outside the agent tool surface via `agent-wallet/scripts/manage_openclaw_btc_wallet.py reveal-seed`.
@@ -18,6 +18,7 @@ const PREVIEW_BOUND_SWAP_TOOLS = new Set([
18
18
  "flash_trade_open_position",
19
19
  "flash_trade_close_position",
20
20
  ]);
21
+ const EVM_CORE_NETWORKS = ["ethereum", "base", "robinhood"];
21
22
  const AUTONOMOUS_BASE_SWAP_TOOLS = new Set([
22
23
  "swap_evm_tokens",
23
24
  "swap_evm_uniswap_tokens",
@@ -202,6 +203,7 @@ function normalizeWalletBackend(value) {
202
203
  ethereum: "wdk_evm_local",
203
204
  eth: "wdk_evm_local",
204
205
  base: "wdk_evm_local",
206
+ robinhood: "wdk_evm_local",
205
207
  wdk_evm_local: "wdk_evm_local",
206
208
  "wdk-evm-local": "wdk_evm_local",
207
209
  evm_local: "wdk_evm_local",
@@ -215,7 +217,7 @@ function normalizeWalletBackend(value) {
215
217
  };
216
218
  const backend = aliases[normalized] || normalized;
217
219
  if (!["solana_local", "wdk_evm_local", "wdk_btc_local"].includes(backend)) {
218
- throw new Error("Wallet backend must be solana, evm, base, ethereum, btc, or bitcoin.");
220
+ throw new Error("Wallet backend must be solana, evm, ethereum, base, robinhood, btc, or bitcoin.");
219
221
  }
220
222
  return backend;
221
223
  }
@@ -240,10 +242,10 @@ function normalizeEvmNetwork(value) {
240
242
  function normalizeSelectableEvmNetwork(value) {
241
243
  const network = normalizeEvmNetwork(value);
242
244
  if (["sepolia", "base-sepolia", "base_sepolia"].includes(network)) {
243
- throw new Error("EVM testnets are no longer supported. Use ethereum or base.");
245
+ throw new Error("EVM testnets are no longer supported. Use ethereum, base, or robinhood.");
244
246
  }
245
- if (!["ethereum", "base"].includes(network)) {
246
- throw new Error("EVM network must be 'ethereum' or 'base'.");
247
+ if (!EVM_CORE_NETWORKS.includes(network)) {
248
+ throw new Error("EVM network must be 'ethereum', 'base', or 'robinhood'.");
247
249
  }
248
250
  return network;
249
251
  }
@@ -289,7 +291,7 @@ function normalizeBtcNetwork(value) {
289
291
  function defaultSelectableEvmNetwork(api) {
290
292
  const config = resolvePluginConfig(api);
291
293
  const configured = normalizeEvmNetwork(config.network || process.env.WDK_EVM_NETWORK);
292
- return ["ethereum", "base"].includes(configured) ? configured : null;
294
+ return EVM_CORE_NETWORKS.includes(configured) ? configured : null;
293
295
  }
294
296
 
295
297
  function defaultSolanaNetwork(api) {
@@ -841,12 +843,12 @@ const walletSessionToolDefinitions = [
841
843
  properties: {
842
844
  backend: {
843
845
  type: "string",
844
- enum: ["solana", "sol", "evm", "ethereum", "base", "bitcoin", "btc"],
846
+ enum: ["solana", "sol", "evm", "ethereum", "base", "robinhood", "bitcoin", "btc"],
845
847
  description: "Wallet backend or common alias to make active.",
846
848
  },
847
849
  network: {
848
850
  type: "string",
849
- description: "Optional network for the selected wallet. Examples: mainnet, ethereum, base, bitcoin.",
851
+ description: "Optional network for the selected wallet. Examples: mainnet, ethereum, base, robinhood, bitcoin.",
850
852
  },
851
853
  },
852
854
  required: ["backend"],
@@ -1537,7 +1539,7 @@ const evmToolDefinitions = [
1537
1539
  properties: {
1538
1540
  network: {
1539
1541
  type: "string",
1540
- enum: ["ethereum", "base"],
1542
+ enum: EVM_CORE_NETWORKS,
1541
1543
  description: "Optional EVM network override for this request.",
1542
1544
  },
1543
1545
  },
@@ -1552,7 +1554,7 @@ const evmToolDefinitions = [
1552
1554
  properties: {
1553
1555
  network: {
1554
1556
  type: "string",
1555
- enum: ["ethereum", "base"],
1557
+ enum: EVM_CORE_NETWORKS,
1556
1558
  description: "Optional EVM network override for this request.",
1557
1559
  },
1558
1560
  },
@@ -1571,7 +1573,7 @@ const evmToolDefinitions = [
1571
1573
  },
1572
1574
  network: {
1573
1575
  type: "string",
1574
- enum: ["ethereum", "base"],
1576
+ enum: EVM_CORE_NETWORKS,
1575
1577
  description: "Optional EVM network override for this request.",
1576
1578
  },
1577
1579
  },
@@ -1628,7 +1630,7 @@ const evmToolDefinitions = [
1628
1630
  properties: {
1629
1631
  network: {
1630
1632
  type: "string",
1631
- enum: ["ethereum", "base"],
1633
+ enum: EVM_CORE_NETWORKS,
1632
1634
  },
1633
1635
  },
1634
1636
  additionalProperties: false,
@@ -1637,13 +1639,13 @@ const evmToolDefinitions = [
1637
1639
  {
1638
1640
  name: "set_evm_network",
1639
1641
  description:
1640
- "Select the active EVM network for subsequent wallet tool calls in this OpenClaw plugin session. Use this to switch between ethereum and base instead of editing code or plugin configuration.",
1642
+ "Select the active EVM network for subsequent wallet tool calls in this OpenClaw plugin session. Use this to switch between ethereum, base, and robinhood instead of editing code or plugin configuration.",
1641
1643
  parameters: {
1642
1644
  type: "object",
1643
1645
  properties: {
1644
1646
  network: {
1645
1647
  type: "string",
1646
- enum: ["ethereum", "base"],
1648
+ enum: EVM_CORE_NETWORKS,
1647
1649
  description: "EVM network to make active for subsequent calls.",
1648
1650
  },
1649
1651
  },
@@ -1658,7 +1660,7 @@ const evmToolDefinitions = [
1658
1660
  type: "object",
1659
1661
  properties: {
1660
1662
  token_address: { type: "string" },
1661
- network: { type: "string", enum: ["ethereum", "base"] },
1663
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1662
1664
  },
1663
1665
  required: ["token_address"],
1664
1666
  additionalProperties: false,
@@ -1671,7 +1673,7 @@ const evmToolDefinitions = [
1671
1673
  type: "object",
1672
1674
  properties: {
1673
1675
  token_address: { type: "string" },
1674
- network: { type: "string", enum: ["ethereum", "base"] },
1676
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1675
1677
  },
1676
1678
  required: ["token_address"],
1677
1679
  additionalProperties: false,
@@ -1683,7 +1685,7 @@ const evmToolDefinitions = [
1683
1685
  parameters: {
1684
1686
  type: "object",
1685
1687
  properties: {
1686
- network: { type: "string", enum: ["ethereum", "base"] },
1688
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1687
1689
  },
1688
1690
  additionalProperties: false,
1689
1691
  },
@@ -1695,7 +1697,7 @@ const evmToolDefinitions = [
1695
1697
  type: "object",
1696
1698
  properties: {
1697
1699
  tx_hash: { type: "string" },
1698
- network: { type: "string", enum: ["ethereum", "base"] },
1700
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1699
1701
  },
1700
1702
  required: ["tx_hash"],
1701
1703
  additionalProperties: false,
@@ -1959,6 +1961,42 @@ const evmToolDefinitions = [
1959
1961
  additionalProperties: false,
1960
1962
  },
1961
1963
  },
1964
+ {
1965
+ name: "get_uniswap_swap_quote",
1966
+ description: "Get a read-only Uniswap Trading API quote (CLASSIC routing) for an ERC-20 or native ETH swap on ethereum, base, or robinhood. This does not approve, sign, or execute a swap.",
1967
+ parameters: {
1968
+ type: "object",
1969
+ properties: {
1970
+ token_in: { type: "string" },
1971
+ token_out: { type: "string" },
1972
+ amount_in_raw: { type: "string" },
1973
+ slippage_bps: { type: "integer" },
1974
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1975
+ },
1976
+ required: ["token_in", "token_out", "amount_in_raw"],
1977
+ additionalProperties: false,
1978
+ },
1979
+ },
1980
+ {
1981
+ name: "swap_evm_uniswap_tokens",
1982
+ description: "Preview, prepare, or execute an ERC-20 or native ETH swap through the Uniswap Trading API (CLASSIC routing) on ethereum, base, or robinhood. ERC-20 inputs use Permit2 EIP-712 signing automatically. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1983
+ optional: true,
1984
+ parameters: {
1985
+ type: "object",
1986
+ properties: {
1987
+ token_in: { type: "string" },
1988
+ token_out: { type: "string" },
1989
+ amount_in_raw: { type: "string" },
1990
+ slippage_bps: { type: "integer" },
1991
+ mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1992
+ purpose: { type: "string" },
1993
+ user_intent: { type: "boolean" },
1994
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1995
+ },
1996
+ required: ["token_in", "token_out", "amount_in_raw", "mode", "purpose"],
1997
+ additionalProperties: false,
1998
+ },
1999
+ },
1962
2000
  {
1963
2001
  name: "swap_evm_lifi_cross_chain_tokens",
1964
2002
  description: "Preview, prepare, or execute an EVM-origin cross-chain swap through LI.FI. This currently supports ethereum/base as the source network and ethereum/base/solana as the destination chain. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
@@ -2004,7 +2042,7 @@ const evmToolDefinitions = [
2004
2042
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2005
2043
  purpose: { type: "string" },
2006
2044
  user_intent: { type: "boolean" },
2007
- network: { type: "string", enum: ["ethereum", "base"] },
2045
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
2008
2046
  },
2009
2047
  required: ["recipient", "amount_wei", "mode", "purpose"],
2010
2048
  additionalProperties: false,
@@ -2023,7 +2061,7 @@ const evmToolDefinitions = [
2023
2061
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2024
2062
  purpose: { type: "string" },
2025
2063
  user_intent: { type: "boolean" },
2026
- network: { type: "string", enum: ["ethereum", "base"] },
2064
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
2027
2065
  },
2028
2066
  required: ["token_address", "recipient", "amount_raw", "mode", "purpose"],
2029
2067
  additionalProperties: false,
@@ -18,6 +18,7 @@ const PREVIEW_BOUND_SWAP_TOOLS = new Set([
18
18
  "flash_trade_open_position",
19
19
  "flash_trade_close_position",
20
20
  ]);
21
+ const EVM_CORE_NETWORKS = ["ethereum", "base", "robinhood"];
21
22
  const AUTONOMOUS_BASE_SWAP_TOOLS = new Set([
22
23
  "swap_evm_tokens",
23
24
  "swap_evm_uniswap_tokens",
@@ -202,6 +203,7 @@ function normalizeWalletBackend(value) {
202
203
  ethereum: "wdk_evm_local",
203
204
  eth: "wdk_evm_local",
204
205
  base: "wdk_evm_local",
206
+ robinhood: "wdk_evm_local",
205
207
  wdk_evm_local: "wdk_evm_local",
206
208
  "wdk-evm-local": "wdk_evm_local",
207
209
  evm_local: "wdk_evm_local",
@@ -215,7 +217,7 @@ function normalizeWalletBackend(value) {
215
217
  };
216
218
  const backend = aliases[normalized] || normalized;
217
219
  if (!["solana_local", "wdk_evm_local", "wdk_btc_local"].includes(backend)) {
218
- throw new Error("Wallet backend must be solana, evm, base, ethereum, btc, or bitcoin.");
220
+ throw new Error("Wallet backend must be solana, evm, ethereum, base, robinhood, btc, or bitcoin.");
219
221
  }
220
222
  return backend;
221
223
  }
@@ -240,10 +242,10 @@ function normalizeEvmNetwork(value) {
240
242
  function normalizeSelectableEvmNetwork(value) {
241
243
  const network = normalizeEvmNetwork(value);
242
244
  if (["sepolia", "base-sepolia", "base_sepolia"].includes(network)) {
243
- throw new Error("EVM testnets are no longer supported. Use ethereum or base.");
245
+ throw new Error("EVM testnets are no longer supported. Use ethereum, base, or robinhood.");
244
246
  }
245
- if (!["ethereum", "base"].includes(network)) {
246
- throw new Error("EVM network must be 'ethereum' or 'base'.");
247
+ if (!EVM_CORE_NETWORKS.includes(network)) {
248
+ throw new Error("EVM network must be 'ethereum', 'base', or 'robinhood'.");
247
249
  }
248
250
  return network;
249
251
  }
@@ -289,7 +291,7 @@ function normalizeBtcNetwork(value) {
289
291
  function defaultSelectableEvmNetwork(api) {
290
292
  const config = resolvePluginConfig(api);
291
293
  const configured = normalizeEvmNetwork(config.network || process.env.WDK_EVM_NETWORK);
292
- return ["ethereum", "base"].includes(configured) ? configured : null;
294
+ return EVM_CORE_NETWORKS.includes(configured) ? configured : null;
293
295
  }
294
296
 
295
297
  function defaultSolanaNetwork(api) {
@@ -841,12 +843,12 @@ const walletSessionToolDefinitions = [
841
843
  properties: {
842
844
  backend: {
843
845
  type: "string",
844
- enum: ["solana", "sol", "evm", "ethereum", "base", "bitcoin", "btc"],
846
+ enum: ["solana", "sol", "evm", "ethereum", "base", "robinhood", "bitcoin", "btc"],
845
847
  description: "Wallet backend or common alias to make active.",
846
848
  },
847
849
  network: {
848
850
  type: "string",
849
- description: "Optional network for the selected wallet. Examples: mainnet, ethereum, base, bitcoin.",
851
+ description: "Optional network for the selected wallet. Examples: mainnet, ethereum, base, robinhood, bitcoin.",
850
852
  },
851
853
  },
852
854
  required: ["backend"],
@@ -1537,7 +1539,7 @@ const evmToolDefinitions = [
1537
1539
  properties: {
1538
1540
  network: {
1539
1541
  type: "string",
1540
- enum: ["ethereum", "base"],
1542
+ enum: EVM_CORE_NETWORKS,
1541
1543
  description: "Optional EVM network override for this request.",
1542
1544
  },
1543
1545
  },
@@ -1552,7 +1554,7 @@ const evmToolDefinitions = [
1552
1554
  properties: {
1553
1555
  network: {
1554
1556
  type: "string",
1555
- enum: ["ethereum", "base"],
1557
+ enum: EVM_CORE_NETWORKS,
1556
1558
  description: "Optional EVM network override for this request.",
1557
1559
  },
1558
1560
  },
@@ -1571,7 +1573,7 @@ const evmToolDefinitions = [
1571
1573
  },
1572
1574
  network: {
1573
1575
  type: "string",
1574
- enum: ["ethereum", "base"],
1576
+ enum: EVM_CORE_NETWORKS,
1575
1577
  description: "Optional EVM network override for this request.",
1576
1578
  },
1577
1579
  },
@@ -1628,7 +1630,7 @@ const evmToolDefinitions = [
1628
1630
  properties: {
1629
1631
  network: {
1630
1632
  type: "string",
1631
- enum: ["ethereum", "base"],
1633
+ enum: EVM_CORE_NETWORKS,
1632
1634
  },
1633
1635
  },
1634
1636
  additionalProperties: false,
@@ -1637,13 +1639,13 @@ const evmToolDefinitions = [
1637
1639
  {
1638
1640
  name: "set_evm_network",
1639
1641
  description:
1640
- "Select the active EVM network for subsequent wallet tool calls in this OpenClaw plugin session. Use this to switch between ethereum and base instead of editing code or plugin configuration.",
1642
+ "Select the active EVM network for subsequent wallet tool calls in this OpenClaw plugin session. Use this to switch between ethereum, base, and robinhood instead of editing code or plugin configuration.",
1641
1643
  parameters: {
1642
1644
  type: "object",
1643
1645
  properties: {
1644
1646
  network: {
1645
1647
  type: "string",
1646
- enum: ["ethereum", "base"],
1648
+ enum: EVM_CORE_NETWORKS,
1647
1649
  description: "EVM network to make active for subsequent calls.",
1648
1650
  },
1649
1651
  },
@@ -1658,7 +1660,7 @@ const evmToolDefinitions = [
1658
1660
  type: "object",
1659
1661
  properties: {
1660
1662
  token_address: { type: "string" },
1661
- network: { type: "string", enum: ["ethereum", "base"] },
1663
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1662
1664
  },
1663
1665
  required: ["token_address"],
1664
1666
  additionalProperties: false,
@@ -1671,7 +1673,7 @@ const evmToolDefinitions = [
1671
1673
  type: "object",
1672
1674
  properties: {
1673
1675
  token_address: { type: "string" },
1674
- network: { type: "string", enum: ["ethereum", "base"] },
1676
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1675
1677
  },
1676
1678
  required: ["token_address"],
1677
1679
  additionalProperties: false,
@@ -1683,7 +1685,7 @@ const evmToolDefinitions = [
1683
1685
  parameters: {
1684
1686
  type: "object",
1685
1687
  properties: {
1686
- network: { type: "string", enum: ["ethereum", "base"] },
1688
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1687
1689
  },
1688
1690
  additionalProperties: false,
1689
1691
  },
@@ -1695,7 +1697,7 @@ const evmToolDefinitions = [
1695
1697
  type: "object",
1696
1698
  properties: {
1697
1699
  tx_hash: { type: "string" },
1698
- network: { type: "string", enum: ["ethereum", "base"] },
1700
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1699
1701
  },
1700
1702
  required: ["tx_hash"],
1701
1703
  additionalProperties: false,
@@ -1959,6 +1961,42 @@ const evmToolDefinitions = [
1959
1961
  additionalProperties: false,
1960
1962
  },
1961
1963
  },
1964
+ {
1965
+ name: "get_uniswap_swap_quote",
1966
+ description: "Get a read-only Uniswap Trading API quote (CLASSIC routing) for an ERC-20 or native ETH swap on ethereum, base, or robinhood. This does not approve, sign, or execute a swap.",
1967
+ parameters: {
1968
+ type: "object",
1969
+ properties: {
1970
+ token_in: { type: "string" },
1971
+ token_out: { type: "string" },
1972
+ amount_in_raw: { type: "string" },
1973
+ slippage_bps: { type: "integer" },
1974
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1975
+ },
1976
+ required: ["token_in", "token_out", "amount_in_raw"],
1977
+ additionalProperties: false,
1978
+ },
1979
+ },
1980
+ {
1981
+ name: "swap_evm_uniswap_tokens",
1982
+ description: "Preview, prepare, or execute an ERC-20 or native ETH swap through the Uniswap Trading API (CLASSIC routing) on ethereum, base, or robinhood. ERC-20 inputs use Permit2 EIP-712 signing automatically. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
1983
+ optional: true,
1984
+ parameters: {
1985
+ type: "object",
1986
+ properties: {
1987
+ token_in: { type: "string" },
1988
+ token_out: { type: "string" },
1989
+ amount_in_raw: { type: "string" },
1990
+ slippage_bps: { type: "integer" },
1991
+ mode: { type: "string", enum: ["preview", "prepare", "execute"] },
1992
+ purpose: { type: "string" },
1993
+ user_intent: { type: "boolean" },
1994
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
1995
+ },
1996
+ required: ["token_in", "token_out", "amount_in_raw", "mode", "purpose"],
1997
+ additionalProperties: false,
1998
+ },
1999
+ },
1962
2000
  {
1963
2001
  name: "swap_evm_lifi_cross_chain_tokens",
1964
2002
  description: "Preview, prepare, or execute an EVM-origin cross-chain swap through LI.FI. This currently supports ethereum/base as the source network and ethereum/base/solana as the destination chain. Preview or prepare first. After the user explicitly confirms the shown summary in chat, call execute; the OpenClaw plugin handles the internal execution authorization automatically.",
@@ -2004,7 +2042,7 @@ const evmToolDefinitions = [
2004
2042
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2005
2043
  purpose: { type: "string" },
2006
2044
  user_intent: { type: "boolean" },
2007
- network: { type: "string", enum: ["ethereum", "base"] },
2045
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
2008
2046
  },
2009
2047
  required: ["recipient", "amount_wei", "mode", "purpose"],
2010
2048
  additionalProperties: false,
@@ -2023,7 +2061,7 @@ const evmToolDefinitions = [
2023
2061
  mode: { type: "string", enum: ["preview", "prepare", "execute"] },
2024
2062
  purpose: { type: "string" },
2025
2063
  user_intent: { type: "boolean" },
2026
- network: { type: "string", enum: ["ethereum", "base"] },
2064
+ network: { type: "string", enum: EVM_CORE_NETWORKS },
2027
2065
  },
2028
2066
  required: ["token_address", "recipient", "amount_raw", "mode", "purpose"],
2029
2067
  additionalProperties: false,
@@ -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.76",
5
+ "version": "0.1.77",
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.76",
3
+ "version": "0.1.77",
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,25 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v0.1.77 - 2026-07-13
6
+
7
+ - Added Robinhood Chain mainnet (`chainId` 4663) to the local EVM wallet,
8
+ provider gateway, OpenClaw extension, and Codex bridge. The existing EVM
9
+ wallet address can now be selected with `set_evm_network=robinhood` or the
10
+ `robinhood` wallet alias.
11
+
12
+ - Added Robinhood support to native/ERC-20 balance reads, fee estimates,
13
+ transfers, receipts, portfolio token discovery through the gateway, and
14
+ mainnet confirmation safeguards.
15
+
16
+ - Added Uniswap Trading API CLASSIC quote and swap support on Robinhood,
17
+ including the Robinhood Universal Router allow-list and cross-network router
18
+ rejection coverage.
19
+
20
+ - Kept unsupported Robinhood protocol surfaces intentionally unavailable:
21
+ LI.FI routes, Velora, Aave, Morpho, and Lido remain limited to their
22
+ previously supported networks.
23
+
5
24
  ## v0.1.75 - 2026-07-11
6
25
 
7
26
  - Added a persistent, non-secret ownership registry for OpenClaw, Hermes,
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.76
1
+ 0.1.77
@@ -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.76"
5
+ __version__ = "0.1.77"
6
6
 
7
7
  __all__ = [
8
8
  "config",
@@ -23,7 +23,7 @@ BASE_SWAP_NETWORK = "base"
23
23
  BASE_SWAP_TOOLS = frozenset({"swap_evm_tokens", "swap_evm_uniswap_tokens"})
24
24
  BASE_SWAP_ISSUER = "autonomous-permission:base-swaps"
25
25
  DEFI_TOOLS_SCOPE = "defi_tools"
26
- DEFI_TOOLS_NETWORKS = frozenset({"base", "ethereum"})
26
+ DEFI_TOOLS_NETWORKS = frozenset({"base", "ethereum", "robinhood"})
27
27
  DEFI_TOOLS = frozenset(
28
28
  {
29
29
  "manage_evm_aave_position",
@@ -219,7 +219,7 @@ def authorize_defi_tool(*, tool_name: str, network: str, summary: dict[str, Any]
219
219
  if str(tool_name) not in DEFI_TOOLS:
220
220
  raise WalletBackendError("Autonomous DeFi permission only covers supported EVM DeFi tools.")
221
221
  if normalized_network not in DEFI_TOOLS_NETWORKS:
222
- raise WalletBackendError("Autonomous DeFi permission only applies on ethereum or base.")
222
+ raise WalletBackendError("Autonomous DeFi permission only applies on ethereum, base, or robinhood.")
223
223
  if not is_defi_tools_approved():
224
224
  raise WalletBackendError(
225
225
  "Autonomous execution is not enabled. Ask the user to run "
@@ -46,7 +46,7 @@ AUTONOMOUS_ISSUER = "autonomous-policy"
46
46
 
47
47
  #: Networks treated as "real money" and therefore gated behind
48
48
  #: ``allow_mainnet`` regardless of the per-tool allow-list.
49
- MAINNET_NETWORKS = frozenset({"mainnet", "mainnet-beta", "ethereum", "base", "arbitrum", "optimism", "polygon"})
49
+ MAINNET_NETWORKS = frozenset({"mainnet", "mainnet-beta", "ethereum", "base", "robinhood", "arbitrum", "optimism", "polygon"})
50
50
 
51
51
  TokenIssuer = Callable[..., str]
52
52
 
@@ -123,13 +123,13 @@ def normalize_evm_network(network: str | None) -> str:
123
123
  from agent_wallet.wallet_layer.base import WalletBackendError
124
124
 
125
125
  raise WalletBackendError(
126
- "EVM testnets are no longer supported by agent-wallet. Use ethereum or base."
126
+ "EVM testnets are no longer supported by agent-wallet. Use ethereum, base, or robinhood."
127
127
  )
128
- if normalized not in {"ethereum", "base"}:
128
+ if normalized not in {"ethereum", "base", "robinhood"}:
129
129
  from agent_wallet.wallet_layer.base import WalletBackendError
130
130
 
131
131
  raise WalletBackendError(
132
- f"Unsupported EVM network: {normalized}. Use ethereum or base."
132
+ f"Unsupported EVM network: {normalized}. Use ethereum, base, or robinhood."
133
133
  )
134
134
  return normalized
135
135
 
@@ -39,7 +39,7 @@ If the preview result includes a confirmation_summary or mainnet_warning, surfac
39
39
  Never bypass the approval token requirement for wallet writes.
40
40
  In OpenClaw, switch between Solana, EVM, and Bitcoin wallets with set_wallet_backend.
41
41
  The plugin config is the startup default, not something to edit during a normal conversation.
42
- For EVM wallets, switch between Ethereum and Base with set_evm_network or by passing the
42
+ For EVM wallets, switch between Ethereum, Base, and Robinhood with set_evm_network or by passing the
43
43
  network argument to EVM tools. Do not edit code, plugin config, or environment variables
44
44
  just to switch the active EVM network.
45
45
  """.strip()
@@ -74,7 +74,7 @@ class OpenClawWalletAdapter:
74
74
  if chain == "bitcoin":
75
75
  return normalized == "bitcoin"
76
76
  if chain == "evm":
77
- return normalized in {"ethereum", "base", "eip155:1", "eip155:8453"}
77
+ return normalized in {"ethereum", "base", "robinhood", "eip155:1", "eip155:8453", "eip155:4663"}
78
78
  if chain == "solana":
79
79
  return normalized in {"mainnet", "solana:5eykt4usfv8p8njdtrepy1vzkqzkvdp"}
80
80
  return normalized == "mainnet"
@@ -101,9 +101,9 @@ class OpenClawWalletAdapter:
101
101
  }
102
102
  network = aliases.get(network, network)
103
103
  if network in {"sepolia", "base-sepolia", "base_sepolia"}:
104
- raise WalletBackendError("EVM testnets are no longer supported. Use ethereum or base.")
105
- if network not in {"ethereum", "base"}:
106
- raise WalletBackendError("EVM network must be 'ethereum' or 'base'.")
104
+ raise WalletBackendError("EVM testnets are no longer supported. Use ethereum, base, or robinhood.")
105
+ if network not in {"ethereum", "base", "robinhood"}:
106
+ raise WalletBackendError("EVM network must be 'ethereum', 'base', or 'robinhood'.")
107
107
  return network
108
108
 
109
109
  def _resolve_backend_for_args(self, args: dict[str, Any]) -> AgentWalletBackend:
@@ -386,7 +386,7 @@ class OpenClawWalletAdapter:
386
386
  elif scope == autonomous_permissions.DEFI_TOOLS_SCOPE:
387
387
  if network not in autonomous_permissions.DEFI_TOOLS_NETWORKS:
388
388
  raise WalletBackendError(
389
- "Autonomous DeFi permission only applies on ethereum or base. "
389
+ "Autonomous DeFi permission only applies on ethereum, base, or robinhood. "
390
390
  "Use set_evm_network or the network parameter to select a supported network."
391
391
  )
392
392
  if not autonomous_permissions.is_defi_tools_approved():
@@ -1178,7 +1178,7 @@ class OpenClawWalletAdapter:
1178
1178
  "properties": {
1179
1179
  "network": {
1180
1180
  "type": "string",
1181
- "enum": ["ethereum", "base"],
1181
+ "enum": ["ethereum", "base", "robinhood"],
1182
1182
  "description": "Optional EVM network override for this request.",
1183
1183
  },
1184
1184
  },
@@ -1195,7 +1195,7 @@ class OpenClawWalletAdapter:
1195
1195
  "properties": {
1196
1196
  "network": {
1197
1197
  "type": "string",
1198
- "enum": ["ethereum", "base"],
1198
+ "enum": ["ethereum", "base", "robinhood"],
1199
1199
  "description": "Optional EVM network override for this request.",
1200
1200
  },
1201
1201
  },
@@ -1220,7 +1220,7 @@ class OpenClawWalletAdapter:
1220
1220
  },
1221
1221
  "network": {
1222
1222
  "type": "string",
1223
- "enum": ["ethereum", "base"],
1223
+ "enum": ["ethereum", "base", "robinhood"],
1224
1224
  "description": "Optional EVM network override for this request.",
1225
1225
  },
1226
1226
  },
@@ -1301,7 +1301,7 @@ class OpenClawWalletAdapter:
1301
1301
  "properties": {
1302
1302
  "network": {
1303
1303
  "type": "string",
1304
- "enum": ["ethereum", "base"],
1304
+ "enum": ["ethereum", "base", "robinhood"],
1305
1305
  "description": "Optional EVM network override for this request.",
1306
1306
  },
1307
1307
  },
@@ -1314,7 +1314,7 @@ class OpenClawWalletAdapter:
1314
1314
  name="set_evm_network",
1315
1315
  description=(
1316
1316
  "Select the active EVM network for subsequent wallet tool calls in this "
1317
- "runtime session. Use this to switch between ethereum and base instead "
1317
+ "runtime session. Use this to switch between ethereum, base, and robinhood instead "
1318
1318
  "of editing code or plugin configuration."
1319
1319
  ),
1320
1320
  input_schema={
@@ -1322,7 +1322,7 @@ class OpenClawWalletAdapter:
1322
1322
  "properties": {
1323
1323
  "network": {
1324
1324
  "type": "string",
1325
- "enum": ["ethereum", "base"],
1325
+ "enum": ["ethereum", "base", "robinhood"],
1326
1326
  "description": "EVM network to make active for subsequent calls.",
1327
1327
  },
1328
1328
  },
@@ -1344,7 +1344,7 @@ class OpenClawWalletAdapter:
1344
1344
  },
1345
1345
  "network": {
1346
1346
  "type": "string",
1347
- "enum": ["ethereum", "base"],
1347
+ "enum": ["ethereum", "base", "robinhood"],
1348
1348
  "description": "Optional EVM network override for this request.",
1349
1349
  },
1350
1350
  },
@@ -1366,7 +1366,7 @@ class OpenClawWalletAdapter:
1366
1366
  },
1367
1367
  "network": {
1368
1368
  "type": "string",
1369
- "enum": ["ethereum", "base"],
1369
+ "enum": ["ethereum", "base", "robinhood"],
1370
1370
  "description": "Optional EVM network override for this request.",
1371
1371
  },
1372
1372
  },
@@ -1384,7 +1384,7 @@ class OpenClawWalletAdapter:
1384
1384
  "properties": {
1385
1385
  "network": {
1386
1386
  "type": "string",
1387
- "enum": ["ethereum", "base"],
1387
+ "enum": ["ethereum", "base", "robinhood"],
1388
1388
  "description": "Optional EVM network override for this request.",
1389
1389
  },
1390
1390
  },
@@ -1405,7 +1405,7 @@ class OpenClawWalletAdapter:
1405
1405
  },
1406
1406
  "network": {
1407
1407
  "type": "string",
1408
- "enum": ["ethereum", "base"],
1408
+ "enum": ["ethereum", "base", "robinhood"],
1409
1409
  "description": "Optional EVM network override for this request.",
1410
1410
  },
1411
1411
  },
@@ -1438,7 +1438,7 @@ class OpenClawWalletAdapter:
1438
1438
  "approval_token": {"type": "string"},
1439
1439
  "network": {
1440
1440
  "type": "string",
1441
- "enum": ["ethereum", "base"],
1441
+ "enum": ["ethereum", "base", "robinhood"],
1442
1442
  "description": "Optional EVM network override for this request.",
1443
1443
  },
1444
1444
  },
@@ -1473,7 +1473,7 @@ class OpenClawWalletAdapter:
1473
1473
  "approval_token": {"type": "string"},
1474
1474
  "network": {
1475
1475
  "type": "string",
1476
- "enum": ["ethereum", "base"],
1476
+ "enum": ["ethereum", "base", "robinhood"],
1477
1477
  "description": "Optional EVM network override for this request.",
1478
1478
  },
1479
1479
  },
@@ -2175,7 +2175,7 @@ class OpenClawWalletAdapter:
2175
2175
  name="get_uniswap_swap_quote",
2176
2176
  description=(
2177
2177
  "Get a read-only Uniswap Trading API quote (CLASSIC routing) for an ERC-20 or native ETH swap "
2178
- "on ethereum or base. Supports full EIP-712 Permit2 path for ERC-20 inputs. "
2178
+ "on ethereum, base, or robinhood. Supports full EIP-712 Permit2 path for ERC-20 inputs. "
2179
2179
  "This does not approve, sign, or execute a swap."
2180
2180
  ),
2181
2181
  input_schema={
@@ -2199,8 +2199,8 @@ class OpenClawWalletAdapter:
2199
2199
  },
2200
2200
  "network": {
2201
2201
  "type": "string",
2202
- "enum": ["ethereum", "base"],
2203
- "description": "EVM network. Uniswap Trading API supports ethereum and base only.",
2202
+ "enum": ["ethereum", "base", "robinhood"],
2203
+ "description": "EVM network. Uniswap Trading API supports ethereum, base, and robinhood.",
2204
2204
  },
2205
2205
  },
2206
2206
  "required": ["token_in", "token_out", "amount_in_raw"],
@@ -2216,7 +2216,7 @@ class OpenClawWalletAdapter:
2216
2216
  name="swap_evm_uniswap_tokens",
2217
2217
  description=(
2218
2218
  "Preview, prepare, or execute an ERC-20 or native ETH swap through the Uniswap Trading API "
2219
- "(CLASSIC routing) on ethereum or base. ERC-20 inputs use Permit2 EIP-712 signing automatically. "
2219
+ "(CLASSIC routing) on ethereum, base, or robinhood. ERC-20 inputs use Permit2 EIP-712 signing automatically. "
2220
2220
  "Prepare returns an execution plan only. Execute requires a host-issued approval token bound to the previewed operation "
2221
2221
  "unless the high-trust autonomous permission group is enabled."
2222
2222
  ),
@@ -2248,8 +2248,8 @@ class OpenClawWalletAdapter:
2248
2248
  "approval_token": {"type": "string"},
2249
2249
  "network": {
2250
2250
  "type": "string",
2251
- "enum": ["ethereum", "base"],
2252
- "description": "EVM network. Uniswap Trading API supports ethereum and base only.",
2251
+ "enum": ["ethereum", "base", "robinhood"],
2252
+ "description": "EVM network. Uniswap Trading API supports ethereum, base, and robinhood.",
2253
2253
  },
2254
2254
  },
2255
2255
  "required": ["token_in", "token_out", "amount_in_raw", "mode", "purpose"],
@@ -142,7 +142,7 @@ _PRICE_CACHE: dict[str, tuple[float, float]] = {}
142
142
 
143
143
  def _normalize_network(network: str) -> str:
144
144
  normalized = str(network or "").strip().lower()
145
- if normalized not in {"ethereum", "base"}:
145
+ if normalized not in {"ethereum", "base", "robinhood"}:
146
146
  raise ProviderError("evm-portfolio", f"Unsupported EVM portfolio network: {network}")
147
147
  return normalized
148
148
 
@@ -207,7 +207,7 @@ async def _gateway_rpc_call(network: str, method: str, params: list[Any]) -> dic
207
207
  if not gateway_url:
208
208
  raise ProviderError(
209
209
  "evm-portfolio",
210
- "Provider gateway URL is required for EVM portfolio lookup on ethereum/base.",
210
+ "Provider gateway URL is required for EVM portfolio lookup on ethereum/base/robinhood.",
211
211
  )
212
212
  try:
213
213
  response = await client.post(
@@ -668,8 +668,8 @@ class WdkEvmLocalWalletBackend(AgentWalletBackend):
668
668
  "configured_network": self.network,
669
669
  "service_active_network": str(data.get("activeNetwork") or "").strip() or None,
670
670
  "available_networks": sorted(str(key) for key in profiles.keys()),
671
- "agent_selectable_networks": ["ethereum", "base"],
672
- "swap_supported_networks": ["ethereum", "base"],
671
+ "agent_selectable_networks": ["ethereum", "base", "robinhood"],
672
+ "swap_supported_networks": ["ethereum", "base", "robinhood"],
673
673
  "network_profiles": {
674
674
  str(network): {
675
675
  **dict(profile),
@@ -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.76",
5
+ "version": "0.1.77",
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.76"
7
+ version = "0.1.77"
8
8
  description = "Plugin-friendly wallet backend for OpenClaw agents"
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -23,7 +23,7 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
23
23
  ## Provider Map
24
24
 
25
25
  - Solana same-chain swap: `swap_solana_tokens` via Jupiter.
26
- - EVM same-chain swap: `swap_evm_tokens` via Velora, ERC-20 to ERC-20 on `ethereum` or `base`.
26
+ - EVM same-chain swap: `swap_evm_tokens` via Velora, ERC-20 to ERC-20 on `ethereum` or `base`; `swap_evm_uniswap_tokens` via Uniswap Trading API on `ethereum`, `base`, or `robinhood`.
27
27
  - Cross-chain Solana -> EVM: `swap_solana_lifi_cross_chain_tokens` via LI.FI.
28
28
  - Cross-chain EVM -> EVM/Solana: `swap_evm_lifi_cross_chain_tokens` via LI.FI.
29
29
  - SOL/SPL transfers: `transfer_sol`, `transfer_spl_token`.
@@ -97,6 +97,9 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
97
97
  - EVM same-chain Velora swap: `swap_evm_tokens`
98
98
  - Params: `token_in`, `token_out`, `amount_in_raw` base-unit string, `mode`, `purpose`, optional `network`.
99
99
  - Current intended path is ERC-20 to ERC-20 on `ethereum` or `base`.
100
+ - EVM same-chain Uniswap swap: `swap_evm_uniswap_tokens`
101
+ - Params: `token_in`, `token_out`, `amount_in_raw` base-unit string, `mode`, `purpose`, optional `network`.
102
+ - Current intended path supports `ethereum`, `base`, and `robinhood` with CLASSIC routing.
100
103
  - EVM swap quote only: `get_evm_swap_quote`
101
104
  - Params: `token_in`, `token_out`, `amount_in_raw`, optional `network`.
102
105
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-wallet",
3
3
  "displayName": "Agent Wallet",
4
- "version": "0.1.76",
4
+ "version": "0.1.77",
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.76",
3
+ "version": "0.1.77",
4
4
  "description": "Codex plugin bridge for the AgentLayer wallet runtime.",
5
5
  "author": {
6
6
  "name": "AgentLayer"
@@ -370,6 +370,7 @@ def _normalize_wallet_backend(value: Any) -> str:
370
370
  "ethereum": "wdk_evm_local",
371
371
  "eth": "wdk_evm_local",
372
372
  "base": "wdk_evm_local",
373
+ "robinhood": "wdk_evm_local",
373
374
  "wdk_evm_local": "wdk_evm_local",
374
375
  "wdk-evm-local": "wdk_evm_local",
375
376
  "evm_local": "wdk_evm_local",
@@ -383,7 +384,7 @@ def _normalize_wallet_backend(value: Any) -> str:
383
384
  }
384
385
  backend = aliases.get(normalized, normalized)
385
386
  if backend not in BACKENDS:
386
- raise RuntimeError("Wallet backend must be solana, evm, base, ethereum, btc, or bitcoin.")
387
+ raise RuntimeError("Wallet backend must be solana, evm, ethereum, base, robinhood, btc, or bitcoin.")
387
388
  return backend
388
389
 
389
390
 
@@ -409,9 +410,9 @@ def _normalize_evm_network(value: Any) -> str:
409
410
  def _normalize_selectable_evm_network(value: Any) -> str:
410
411
  network = _normalize_evm_network(value)
411
412
  if network in {"sepolia", "base-sepolia", "base_sepolia"}:
412
- raise RuntimeError("EVM testnets are no longer supported. Use ethereum or base.")
413
- if network not in {"ethereum", "base"}:
414
- raise RuntimeError("EVM network must be 'ethereum' or 'base'.")
413
+ raise RuntimeError("EVM testnets are no longer supported. Use ethereum, base, or robinhood.")
414
+ if network not in {"ethereum", "base", "robinhood"}:
415
+ raise RuntimeError("EVM network must be 'ethereum', 'base', or 'robinhood'.")
415
416
  return network
416
417
 
417
418
 
@@ -419,6 +420,8 @@ def _implied_evm_network_from_backend_alias(value: Any) -> str | None:
419
420
  normalized = str(value or "").strip().lower()
420
421
  if normalized in {"base", "base-mainnet"}:
421
422
  return "base"
423
+ if normalized == "robinhood":
424
+ return "robinhood"
422
425
  if normalized in {"ethereum", "eth", "mainnet", "eth-mainnet"}:
423
426
  return "ethereum"
424
427
  return None
@@ -471,7 +474,7 @@ def _default_backend() -> str:
471
474
 
472
475
  def _default_evm_network() -> str | None:
473
476
  configured = _normalize_evm_network(os.getenv("WDK_EVM_NETWORK"))
474
- if configured in {"ethereum", "base"}:
477
+ if configured in {"ethereum", "base", "robinhood"}:
475
478
  return configured
476
479
  return _configured_network_for_backend("wdk_evm_local")
477
480
 
@@ -1205,11 +1208,11 @@ def _manual_tool_definitions() -> list[dict[str, Any]]:
1205
1208
  "properties": {
1206
1209
  "backend": {
1207
1210
  "type": "string",
1208
- "description": "solana, evm, base, ethereum, btc, or bitcoin.",
1211
+ "description": "solana, evm, ethereum, base, robinhood, btc, or bitcoin.",
1209
1212
  },
1210
1213
  "network": {
1211
1214
  "type": "string",
1212
- "description": "Optional network override. Use base or ethereum for EVM.",
1215
+ "description": "Optional network override. Use ethereum, base, or robinhood for EVM.",
1213
1216
  },
1214
1217
  "address": {
1215
1218
  "type": "string",
@@ -1244,7 +1247,7 @@ def _manual_tool_definitions() -> list[dict[str, Any]]:
1244
1247
  "properties": {
1245
1248
  "backend": {
1246
1249
  "type": "string",
1247
- "description": "solana, evm, base, ethereum, btc, or bitcoin.",
1250
+ "description": "solana, evm, ethereum, base, robinhood, btc, or bitcoin.",
1248
1251
  },
1249
1252
  "wallet": {
1250
1253
  "type": "string",
@@ -1262,14 +1265,14 @@ def _manual_tool_definitions() -> list[dict[str, Any]]:
1262
1265
  {
1263
1266
  "name": "set_evm_network",
1264
1267
  "description": (
1265
- "Set the active EVM network for this Codex MCP session to ethereum or base."
1268
+ "Set the active EVM network for this Codex MCP session to ethereum, base, or robinhood."
1266
1269
  ),
1267
1270
  "input_schema": {
1268
1271
  "type": "object",
1269
1272
  "properties": {
1270
1273
  "network": {
1271
1274
  "type": "string",
1272
- "description": "ethereum or base.",
1275
+ "description": "ethereum, base, or robinhood.",
1273
1276
  }
1274
1277
  },
1275
1278
  "required": ["network"],
@@ -16,4 +16,4 @@ Rules:
16
16
  - On mainnet, restate the network, asset, amount, and destination before execute.
17
17
  - Do not ask the user for `approval_token`. The bridge manages approval binding internally.
18
18
  - If approval context is missing or stale, repeat preview instead of improvising.
19
- - Use `set_wallet_backend` to switch between Solana, EVM, and Bitcoin wallets within a session, and `set_evm_network` to pick ethereum or base.
19
+ - Use `set_wallet_backend` to switch between Solana, EVM, and Bitcoin wallets within a session, and `set_evm_network` to pick ethereum, base, or robinhood.
@@ -1,5 +1,5 @@
1
1
  name: agent-wallet
2
- version: 0.1.76
2
+ version: 0.1.77
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.76",
3
+ "version": "0.1.77",
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.76",
3
+ "version": "0.1.77",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Separate BTC-only wallet service built on Tether WDK.",
@@ -10,14 +10,15 @@ WDK_EVM_RPC_PROVIDER_MODE=gateway
10
10
  WDK_EVM_RPC_GATEWAY_PROVIDER=alchemy
11
11
  PROVIDER_GATEWAY_URL=https://agent-layer-production.up.railway.app
12
12
  PROVIDER_GATEWAY_BEARER_TOKEN=
13
- # Mainnet ethereum/base are forced through provider-gateway -> Alchemy.
13
+ # Mainnet ethereum/base/robinhood are forced through provider-gateway -> Alchemy.
14
14
  # Direct per-network URLs below are only relevant for testnet-style paths.
15
15
  WDK_EVM_ETHEREUM_RPC_URL=
16
16
  WDK_EVM_SEPOLIA_RPC_URL=https://sepolia.drpc.org
17
17
  WDK_EVM_BASE_RPC_URL=
18
18
  WDK_EVM_BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
19
+ WDK_EVM_ROBINHOOD_RPC_URL=
19
20
  MORPHO_API_BASE_URL=https://api.morpho.org/graphql
20
- # Uniswap Trading API swap provider (ethereum/base, CLASSIC routing).
21
+ # Uniswap Trading API swap provider (ethereum/base/robinhood, CLASSIC routing).
21
22
  # Uniswap Trading API. By default the daemon routes quotes/swaps through the
22
23
  # provider gateway (PROVIDER_GATEWAY_URL/v1/evm/uniswap), which holds the Uniswap
23
24
  # key and authenticates via the gateway bearer — so no UNISWAP_API_KEY is needed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wdk-evm-wallet",
3
- "version": "0.1.76",
3
+ "version": "0.1.77",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Separate EVM wallet service built on Tether WDK.",
@@ -15,7 +15,10 @@
15
15
  "test:lido-runtime": "node --test --test-concurrency=1 tests/smoke_lido_runtime.mjs",
16
16
  "test:uniswap-runtime": "node --test --test-concurrency=1 tests/smoke_uniswap_runtime.mjs",
17
17
  "test:unit": "node --test tests/unit_uniswap_helpers.mjs",
18
- "test:identity": "node --test tests/unit_instance_identity.mjs"
18
+ "test:identity": "node --test tests/unit_instance_identity.mjs",
19
+ "test:network-config": "node --test tests/unit_network_config.mjs",
20
+ "test:network-state": "node --test tests/unit_network_state.mjs",
21
+ "test:wallet-network": "node --test tests/unit_wdk_wallet_network.mjs"
19
22
  },
20
23
  "dependencies": {
21
24
  "@morpho-org/morpho-sdk": "^3.2.0",
@@ -27,7 +27,7 @@ function readPackageVersion() {
27
27
 
28
28
  const PACKAGE_VERSION = readPackageVersion();
29
29
  const DEFAULT_PROVIDER_GATEWAY_URL = "https://agent-layer-production.up.railway.app";
30
- const ENFORCED_GATEWAY_MAINNETS = new Set(["ethereum", "base"]);
30
+ const ENFORCED_GATEWAY_MAINNETS = new Set(["ethereum", "base", "robinhood"]);
31
31
 
32
32
  const DEFAULT_NETWORK_PROFILES = {
33
33
  ethereum: {
@@ -50,6 +50,11 @@ const DEFAULT_NETWORK_PROFILES = {
50
50
  providerUrl: "https://sepolia.base.org",
51
51
  nativeSymbol: "ETH",
52
52
  },
53
+ robinhood: {
54
+ chainId: 4663,
55
+ providerUrl: "https://rpc.mainnet.chain.robinhood.com",
56
+ nativeSymbol: "ETH",
57
+ },
53
58
  };
54
59
 
55
60
  const SUPPORTED_GATEWAY_PROVIDERS = new Set(["auto", "shared", "alchemy"]);
@@ -179,6 +184,7 @@ function normalizeNetworkKey(value) {
179
184
  "eth-mainnet": "ethereum",
180
185
  "base-mainnet": "base",
181
186
  base_sepolia: "base-sepolia",
187
+ "robinhood-mainnet": "robinhood",
182
188
  };
183
189
  return aliases[normalized] || normalized;
184
190
  }
@@ -211,7 +217,7 @@ export function loadConfig(env = process.env) {
211
217
  const network = normalizeNetworkKey(env.WDK_EVM_NETWORK ?? DEFAULTS.network) || DEFAULTS.network;
212
218
  if (!Object.hasOwn(DEFAULT_NETWORK_PROFILES, network)) {
213
219
  throw new Error(
214
- "WDK_EVM_NETWORK must be one of: ethereum, sepolia, base, base-sepolia."
220
+ "WDK_EVM_NETWORK must be one of: ethereum, sepolia, base, base-sepolia, robinhood."
215
221
  );
216
222
  }
217
223
 
@@ -295,6 +301,14 @@ export function loadConfig(env = process.env) {
295
301
  DEFAULT_NETWORK_PROFILES["base-sepolia"].providerUrl
296
302
  ),
297
303
  },
304
+ robinhood: {
305
+ ...DEFAULT_NETWORK_PROFILES.robinhood,
306
+ providerUrl: resolveProviderUrl(
307
+ "robinhood",
308
+ env.WDK_EVM_ROBINHOOD_RPC_URL,
309
+ DEFAULT_NETWORK_PROFILES.robinhood.providerUrl
310
+ ),
311
+ },
298
312
  };
299
313
 
300
314
  // Route Uniswap Trading API calls through the provider-gateway by default so the
@@ -11,10 +11,13 @@ function assertValidNetwork(network, fieldName = "network") {
11
11
  "eth-mainnet": "ethereum",
12
12
  "base-mainnet": "base",
13
13
  base_sepolia: "base-sepolia",
14
+ "robinhood-mainnet": "robinhood",
14
15
  };
15
16
  const effective = aliases[normalized] || normalized;
16
- if (!["ethereum", "sepolia", "base", "base-sepolia"].includes(effective)) {
17
- throw new Error(`${fieldName} must be one of: ethereum, sepolia, base, base-sepolia.`);
17
+ if (!["ethereum", "sepolia", "base", "base-sepolia", "robinhood"].includes(effective)) {
18
+ throw new Error(
19
+ `${fieldName} must be one of: ethereum, sepolia, base, base-sepolia, robinhood.`
20
+ );
18
21
  }
19
22
  return effective;
20
23
  }
@@ -22,11 +22,12 @@ const DEFAULT_SWAP_SLIPPAGE_BPS = 100;
22
22
  const DEFAULT_LIFI_SLIPPAGE = 0.005;
23
23
  const ALWAYS_DENIED_LIFI_BRIDGES = ["mayan"];
24
24
  const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
25
- const UNISWAP_SUPPORTED_CHAIN_IDS = { ethereum: 1, base: 8453 };
25
+ const UNISWAP_SUPPORTED_CHAIN_IDS = { ethereum: 1, base: 8453, robinhood: 4663 };
26
26
  // Universal Router v2.0 allow-list (defense-in-depth: /swap response `to` must match).
27
27
  const UNISWAP_UNIVERSAL_ROUTER_BY_NETWORK = {
28
28
  ethereum: "0x66a9893cc07d91d95644aedd05d03f95e1dba8af",
29
29
  base: "0x6ff5693b99212da76ad316178a184ab56d299b43",
30
+ robinhood: "0x8876789976decbfcbbbe364623c63652db8c0904",
30
31
  };
31
32
  const AAVE_RAY = 10n ** 27n;
32
33
  const LIDO_STETH_DECIMALS = 18;
@@ -502,10 +503,13 @@ function assertValidNetwork(network, fieldName = "network") {
502
503
  eth: "ethereum",
503
504
  "base-mainnet": "base",
504
505
  base_sepolia: "base-sepolia",
506
+ "robinhood-mainnet": "robinhood",
505
507
  };
506
508
  const effective = aliases[normalized] || normalized;
507
- if (!["ethereum", "sepolia", "base", "base-sepolia"].includes(effective)) {
508
- throw new Error(`${fieldName} must be one of: ethereum, sepolia, base, base-sepolia.`);
509
+ if (!["ethereum", "sepolia", "base", "base-sepolia", "robinhood"].includes(effective)) {
510
+ throw new Error(
511
+ `${fieldName} must be one of: ethereum, sepolia, base, base-sepolia, robinhood.`
512
+ );
509
513
  }
510
514
  return effective;
511
515
  }
@@ -847,7 +851,7 @@ function assertUniswapSupportedNetwork(network) {
847
851
  const chainId = UNISWAP_SUPPORTED_CHAIN_IDS[network];
848
852
  if (!chainId) {
849
853
  throw new Error(
850
- "Uniswap Trading API swaps are currently supported only on ethereum and base mainnet."
854
+ "Uniswap Trading API swaps are currently supported only on ethereum, base, and robinhood mainnet."
851
855
  );
852
856
  }
853
857
  return chainId;
@@ -7558,8 +7562,10 @@ export class WdkEvmWalletService {
7558
7562
  export const __testables = {
7559
7563
  PERMIT2_ADDRESS,
7560
7564
  UNISWAP_SUPPORTED_CHAIN_IDS,
7565
+ UNISWAP_UNIVERSAL_ROUTER_BY_NETWORK,
7561
7566
  normalizeUniswapTokenAddress,
7562
7567
  assertUniswapSupportedNetwork,
7568
+ assertValidNetwork,
7563
7569
  uniswapSlippagePercentFromBps,
7564
7570
  normalizeUniswapPermitData,
7565
7571
  };