@agentlayer.tech/wallet 0.1.94 → 0.1.96

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 (35) hide show
  1. package/.openclaw/extensions/agent-wallet/README.md +2 -2
  2. package/.openclaw/extensions/agent-wallet/dist/index.js +70 -14
  3. package/.openclaw/extensions/agent-wallet/index.ts +70 -14
  4. package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +4 -2
  5. package/.openclaw/extensions/agent-wallet/package.json +1 -1
  6. package/VERSION +1 -1
  7. package/agent-wallet/README.md +3 -3
  8. package/agent-wallet/agent_wallet/__init__.py +1 -1
  9. package/agent-wallet/agent_wallet/autonomous_policy.py +2 -1
  10. package/agent-wallet/agent_wallet/config.py +7 -11
  11. package/agent-wallet/agent_wallet/networks.py +25 -0
  12. package/agent-wallet/agent_wallet/openclaw_adapter.py +171 -27
  13. package/agent-wallet/agent_wallet/providers/evm_portfolio.py +9 -2
  14. package/agent-wallet/agent_wallet/wallet_layer/base.py +19 -0
  15. package/agent-wallet/agent_wallet/wallet_layer/wdk_evm.py +61 -1
  16. package/agent-wallet/openclaw.plugin.json +1 -1
  17. package/agent-wallet/pyproject.toml +1 -1
  18. package/agent-wallet/scripts/install_agent_wallet.py +29 -1
  19. package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +1 -1
  20. package/claude-code/plugins/agent-wallet/AGENTLAYER_AGENT_GUIDE.md +282 -0
  21. package/claude-code/plugins/agent-wallet/README.md +2 -0
  22. package/claude-code/plugins/agent-wallet/commands/guide.md +40 -0
  23. package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +1 -1
  24. package/codex/plugins/agent-wallet/server.py +15 -11
  25. package/codex/plugins/agent-wallet/skills/wallet-operator/SKILL.md +1 -1
  26. package/hermes/plugins/agent_wallet/plugin.yaml +1 -1
  27. package/package.json +1 -1
  28. package/wdk-btc-wallet/package.json +1 -1
  29. package/wdk-evm-wallet/.env.example +4 -1
  30. package/wdk-evm-wallet/README.md +18 -2
  31. package/wdk-evm-wallet/package.json +1 -1
  32. package/wdk-evm-wallet/src/config.js +34 -3
  33. package/wdk-evm-wallet/src/network_state.js +8 -2
  34. package/wdk-evm-wallet/src/server.js +12 -0
  35. package/wdk-evm-wallet/src/wdk_evm_wallet.js +132 -2
@@ -646,6 +646,18 @@ async function handleRequest(request, response) {
646
646
  return sendJson(response, 200, { ok: true, data });
647
647
  }
648
648
 
649
+ if (method === "POST" && url.pathname === "/v1/evm/uniswap/liquidity/pools") {
650
+ const body = await withResolvedNetwork(await readJsonBody(request));
651
+ const data = await service.getUniswapLiquidityPools(body);
652
+ return sendJson(response, 200, { ok: true, data });
653
+ }
654
+
655
+ if (method === "POST" && url.pathname === "/v1/evm/uniswap/liquidity/positions") {
656
+ const body = await withResolvedNetwork(await withResolvedSeedOrAddress(await readJsonBody(request)));
657
+ const data = await service.getUniswapLiquidityPositions(body);
658
+ return sendJson(response, 200, { ok: true, data });
659
+ }
660
+
649
661
  if (method === "POST" && url.pathname === "/v1/evm/uniswap/liquidity/send") {
650
662
  const body = await withResolvedNetwork(await withResolvedSeed(await readJsonBody(request)));
651
663
  const data = await service.sendUniswapLiquidity(body);
@@ -45,6 +45,14 @@ const UNISWAP_LIQUIDITY_POSITION_MANAGERS = {
45
45
  const ERC20_APPROVE_INTERFACE = new Interface([
46
46
  "function approve(address spender,uint256 amount) returns (bool)",
47
47
  ]);
48
+ // V3 PositionManager is ERC-721 enumerable, so positions owned by the active
49
+ // wallet can be discovered and then read directly from the canonical contract.
50
+ // V4 deliberately is not enumerable; see getUniswapLiquidityPositions below.
51
+ const UNISWAP_V3_POSITION_MANAGER_INTERFACE = new Interface([
52
+ "function balanceOf(address owner) view returns (uint256)",
53
+ "function tokenOfOwnerByIndex(address owner,uint256 index) view returns (uint256)",
54
+ "function positions(uint256 tokenId) view returns (uint96 nonce,address operator,address token0,address token1,uint24 fee,int24 tickLower,int24 tickUpper,uint128 liquidity,uint256 feeGrowthInside0LastX128,uint256 feeGrowthInside1LastX128,uint128 tokensOwed0,uint128 tokensOwed1)",
55
+ ]);
48
56
  // Every executable path is declared here rather than inferred from a Trading
49
57
  // API response. A new chain/router version therefore requires an explicit,
50
58
  // reviewed allow-list entry before it can receive a signed transaction.
@@ -594,11 +602,17 @@ function assertValidNetwork(network, fieldName = "network") {
594
602
  "base-mainnet": "base",
595
603
  base_sepolia: "base-sepolia",
596
604
  "robinhood-mainnet": "robinhood",
605
+ "goat-mainnet": "goat",
606
+ "goat-testnet3": "goat-testnet",
597
607
  };
598
608
  const effective = aliases[normalized] || normalized;
599
- if (!["ethereum", "sepolia", "base", "base-sepolia", "robinhood"].includes(effective)) {
609
+ if (
610
+ !["ethereum", "sepolia", "base", "base-sepolia", "robinhood", "goat", "goat-testnet"].includes(
611
+ effective
612
+ )
613
+ ) {
600
614
  throw new Error(
601
- `${fieldName} must be one of: ethereum, sepolia, base, base-sepolia, robinhood.`
615
+ `${fieldName} must be one of: ethereum, sepolia, base, base-sepolia, robinhood, goat, goat-testnet.`
602
616
  );
603
617
  }
604
618
  return effective;
@@ -6015,6 +6029,122 @@ export class WdkEvmWalletService {
6015
6029
  };
6016
6030
  }
6017
6031
 
6032
+ async getUniswapLiquidityPools({ protocol, poolParameters, poolReferences, pageSize = 20, currentPage = 1, network }) {
6033
+ const runtimeConfig = this.#resolveRuntimeConfig(network);
6034
+ assertUniswapSupportedNetwork(runtimeConfig.network);
6035
+ const normalizedProtocol = normalizeUniswapLiquidityProtocol(protocol);
6036
+ const hasParameters = poolParameters !== undefined && poolParameters !== null;
6037
+ const hasReferences = poolReferences !== undefined && poolReferences !== null;
6038
+ if (hasParameters === hasReferences) {
6039
+ throw new Error("Provide exactly one of poolParameters or poolReferences.");
6040
+ }
6041
+ const boundedPageSize = Number(pageSize);
6042
+ const normalizedPageSize = Number.isInteger(boundedPageSize) && boundedPageSize > 0
6043
+ ? Math.min(boundedPageSize, 20)
6044
+ : 20;
6045
+ const boundedCurrentPage = Number(currentPage);
6046
+ const normalizedCurrentPage = Number.isInteger(boundedCurrentPage) && boundedCurrentPage > 0
6047
+ ? boundedCurrentPage
6048
+ : 1;
6049
+ const body = {
6050
+ protocol: normalizedProtocol,
6051
+ chainId: runtimeConfig.chainId,
6052
+ pageSize: normalizedPageSize,
6053
+ currentPage: normalizedCurrentPage,
6054
+ };
6055
+ if (hasParameters) {
6056
+ body.poolParameters = assertPlainObject(poolParameters, "poolParameters");
6057
+ } else {
6058
+ if (!Array.isArray(poolReferences) || poolReferences.length === 0 || poolReferences.length > 20) {
6059
+ throw new Error("poolReferences must be an array containing between 1 and 20 references.");
6060
+ }
6061
+ body.poolReferences = poolReferences.map((reference, index) => assertPlainObject(reference, `poolReferences[${index}]`));
6062
+ }
6063
+ const payload = await this.#uniswapLiquidityApiRequest("pool_info", body);
6064
+ return {
6065
+ network: runtimeConfig.network,
6066
+ chainId: runtimeConfig.chainId,
6067
+ protocol: normalizedProtocol,
6068
+ requestId: String(payload?.requestId || "").trim() || null,
6069
+ pools: Array.isArray(payload?.pools) ? payload.pools : [],
6070
+ pageSize: Number(payload?.pageSize ?? normalizedPageSize),
6071
+ currentPage: Number(payload?.currentPage ?? normalizedCurrentPage),
6072
+ source: "uniswap-liquidity-api",
6073
+ };
6074
+ }
6075
+
6076
+ async getUniswapLiquidityPositions({ seedPhrase, address, protocol = "V3", accountIndex = 0, network, limit = 20 }) {
6077
+ return this.#withReadableAccount({ seedPhrase, address, accountIndex, network }, async (account, runtimeConfig) => {
6078
+ assertUniswapSupportedNetwork(runtimeConfig.network);
6079
+ const normalizedProtocol = normalizeUniswapLiquidityProtocol(protocol);
6080
+ if (normalizedProtocol === "V4") {
6081
+ // Uniswap's V4 PositionManager is intentionally not ERC-721 enumerable.
6082
+ // Discovering token IDs requires a chain-specific indexed subgraph, then
6083
+ // on-chain verification. Do not pretend balanceOf/tokenOfOwnerByIndex is
6084
+ // available or ask an RPC provider to scan unbounded transfer history.
6085
+ throw createTaggedError(
6086
+ "Uniswap V4 position discovery requires a configured indexed subgraph; the V4 PositionManager is not ERC-721 enumerable.",
6087
+ "uniswap_v4_position_discovery_unavailable",
6088
+ { network: runtimeConfig.network }
6089
+ );
6090
+ }
6091
+ const owner = await account.getAddress();
6092
+ const positionManager = getUniswapLiquidityPositionManager(runtimeConfig.network, "V3");
6093
+ const rawBalance = await callContract(
6094
+ runtimeConfig.providerUrl,
6095
+ positionManager,
6096
+ UNISWAP_V3_POSITION_MANAGER_INTERFACE,
6097
+ "balanceOf",
6098
+ [owner]
6099
+ );
6100
+ const balance = BigInt(rawBalance[0]);
6101
+ const requestedLimit = Number(limit);
6102
+ const boundedLimit = Number.isInteger(requestedLimit) && requestedLimit > 0 ? Math.min(requestedLimit, 100) : 20;
6103
+ const count = Number(balance > BigInt(boundedLimit) ? BigInt(boundedLimit) : balance);
6104
+ const positions = [];
6105
+ for (let index = 0; index < count; index += 1) {
6106
+ const tokenIdResult = await callContract(
6107
+ runtimeConfig.providerUrl,
6108
+ positionManager,
6109
+ UNISWAP_V3_POSITION_MANAGER_INTERFACE,
6110
+ "tokenOfOwnerByIndex",
6111
+ [owner, index]
6112
+ );
6113
+ const tokenId = BigInt(tokenIdResult[0]);
6114
+ const position = await callContract(
6115
+ runtimeConfig.providerUrl,
6116
+ positionManager,
6117
+ UNISWAP_V3_POSITION_MANAGER_INTERFACE,
6118
+ "positions",
6119
+ [tokenId]
6120
+ );
6121
+ positions.push({
6122
+ tokenId: tokenId.toString(),
6123
+ token0: String(position[2]),
6124
+ token1: String(position[3]),
6125
+ fee: Number(position[4]),
6126
+ tickLower: Number(position[5]),
6127
+ tickUpper: Number(position[6]),
6128
+ liquidity: BigInt(position[7]).toString(),
6129
+ tokensOwed0: BigInt(position[10]).toString(),
6130
+ tokensOwed1: BigInt(position[11]).toString(),
6131
+ });
6132
+ }
6133
+ return {
6134
+ network: runtimeConfig.network,
6135
+ chainId: runtimeConfig.chainId,
6136
+ protocol: "V3",
6137
+ owner,
6138
+ positionManager,
6139
+ totalCount: balance.toString(),
6140
+ returnedCount: positions.length,
6141
+ truncated: balance > BigInt(positions.length),
6142
+ positions,
6143
+ source: "uniswap-v3-position-manager",
6144
+ };
6145
+ });
6146
+ }
6147
+
6018
6148
  async quoteUniswapLiquidity({ seedPhrase, address, action, protocol, request, accountIndex = 0, network }) {
6019
6149
  return this.#withReadableAccount({ seedPhrase, address, accountIndex, network }, async (account, runtimeConfig) => {
6020
6150
  assertUniswapSupportedNetwork(runtimeConfig.network);