@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.
- package/.openclaw/extensions/agent-wallet/README.md +2 -2
- package/.openclaw/extensions/agent-wallet/dist/index.js +70 -14
- package/.openclaw/extensions/agent-wallet/index.ts +70 -14
- package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +4 -2
- package/.openclaw/extensions/agent-wallet/package.json +1 -1
- package/VERSION +1 -1
- package/agent-wallet/README.md +3 -3
- package/agent-wallet/agent_wallet/__init__.py +1 -1
- package/agent-wallet/agent_wallet/autonomous_policy.py +2 -1
- package/agent-wallet/agent_wallet/config.py +7 -11
- package/agent-wallet/agent_wallet/networks.py +25 -0
- package/agent-wallet/agent_wallet/openclaw_adapter.py +171 -27
- package/agent-wallet/agent_wallet/providers/evm_portfolio.py +9 -2
- package/agent-wallet/agent_wallet/wallet_layer/base.py +19 -0
- package/agent-wallet/agent_wallet/wallet_layer/wdk_evm.py +61 -1
- package/agent-wallet/openclaw.plugin.json +1 -1
- package/agent-wallet/pyproject.toml +1 -1
- package/agent-wallet/scripts/install_agent_wallet.py +29 -1
- package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +1 -1
- package/claude-code/plugins/agent-wallet/AGENTLAYER_AGENT_GUIDE.md +282 -0
- package/claude-code/plugins/agent-wallet/README.md +2 -0
- package/claude-code/plugins/agent-wallet/commands/guide.md +40 -0
- package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +1 -1
- package/codex/plugins/agent-wallet/server.py +15 -11
- package/codex/plugins/agent-wallet/skills/wallet-operator/SKILL.md +1 -1
- package/hermes/plugins/agent_wallet/plugin.yaml +1 -1
- package/package.json +1 -1
- package/wdk-btc-wallet/package.json +1 -1
- package/wdk-evm-wallet/.env.example +4 -1
- package/wdk-evm-wallet/README.md +18 -2
- package/wdk-evm-wallet/package.json +1 -1
- package/wdk-evm-wallet/src/config.js +34 -3
- package/wdk-evm-wallet/src/network_state.js +8 -2
- package/wdk-evm-wallet/src/server.js +12 -0
- 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 (
|
|
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);
|