diff --git a/cdp-agentkit-core/cdp_agentkit_core/actions/__init__.py b/cdp-agentkit-core/cdp_agentkit_core/actions/__init__.py index ef1fb59d3..9a5cbf53b 100644 --- a/cdp-agentkit-core/cdp_agentkit_core/actions/__init__.py +++ b/cdp-agentkit-core/cdp_agentkit_core/actions/__init__.py @@ -1,8 +1,3 @@ -from cdp_agentkit_core.actions.create_pool import ( - CREATE_POOL_PROMPT, - CreatePoolInput, - create_pool, -) from cdp_agentkit_core.actions.deploy_nft import ( DEPLOY_NFT_PROMPT, DeployNftInput, @@ -48,11 +43,16 @@ TransferInput, transfer, ) +from cdp_agentkit_core.actions.uniswap_v3.create_pool import ( + UNISWAP_V3_CREATE_POOL_PROMPT, + UniswapV3CreatePoolInput, + uniswap_v3_create_pool, +) __all__ = [ - "CREATE_POOL_PROMPT", - "CreatePoolInput", - "create_pool", + "UNISWAP_V3_CREATE_POOL_PROMPT", + "UniswapV3CreatePoolInput", + "uniswap_v3_create_pool", "DEPLOY_NFT_PROMPT", "DeployNftInput", "deploy_nft", diff --git a/cdp-agentkit-core/cdp_agentkit_core/actions/create_pool.py b/cdp-agentkit-core/cdp_agentkit_core/actions/create_pool.py index 11f923759..634701be6 100644 --- a/cdp-agentkit-core/cdp_agentkit_core/actions/create_pool.py +++ b/cdp-agentkit-core/cdp_agentkit_core/actions/create_pool.py @@ -1,7 +1,7 @@ from cdp import Wallet from pydantic import BaseModel, Field -from cdp_agentkit_core.constants import UNISWAP_V3_FACTORY_ABI +from cdp_agentkit_core.actions.uniswap_v3.constants import UNISWAP_V3_FACTORY_ABI CREATE_POOL_PROMPT = """ This tool will create a Uniswap v3 pool for trading 2 tokens, one of which can be the native gas token. For native gas token, use the address 0x4200000000000000000000000000000000000006. This tool takes the address of the first token, address of the second token, and the fee to charge for trades as inputs. The fee is denominated in hundredths of a bip (i.e. 1e-6) and must be passed a string. Acceptable fee values are 100, 500, 3000, and 10000.""" diff --git a/cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/__init__.py b/cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cdp-agentkit-core/cdp_agentkit_core/constants.py b/cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/constants.py similarity index 100% rename from cdp-agentkit-core/cdp_agentkit_core/constants.py rename to cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/constants.py diff --git a/cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/create_pool.py b/cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/create_pool.py new file mode 100644 index 000000000..85b2aa786 --- /dev/null +++ b/cdp-agentkit-core/cdp_agentkit_core/actions/uniswap_v3/create_pool.py @@ -0,0 +1,50 @@ +from cdp import Wallet +from pydantic import BaseModel, Field + +from cdp_agentkit_core.actions.uniswap_v3.constants import UNISWAP_V3_FACTORY_ABI + +UNISWAP_V3_CREATE_POOL_PROMPT = """ +This tool will create a Uniswap v3 pool for trading 2 tokens, one of which can be the native gas token. For native gas token, use the address 0x4200000000000000000000000000000000000006, and for ERC20 token, use its contract address. This tool takes the address of the first token, address of the second token, and the fee to charge for trades as inputs. The fee is denominated in hundredths of a bip (i.e. 1e-6) and must be passed a string. Acceptable fee values are 100, 500, 3000, and 10000. Supported networks are Base Sepolia, Base Mainnet, Ethereum Mainnet, Polygon Mainnet, and Arbitrum Mainnet.""" + + +class UniswapV3CreatePoolInput(BaseModel): + """Input argument schema for create pool action.""" + + token_a: str = Field( + ..., + description="The address of the first token to trade, e.g. 0x4200000000000000000000000000000000000006 for native gas token", + ) + token_b: str = Field( + ..., + description="The address of the second token to trade, e.g. 0x1234567890123456789012345678901234567890 for ERC20 token", + ) + fee: str = Field( + ..., + description="The fee to charge for trades, denominated in hundredths of a bip (i.e. 1e-6). Acceptable fee values are 100, 500, 3000, and 10000.", + ) + + +def uniswap_v3_create_pool(wallet: Wallet, token_a: str, token_b: str, fee: str) -> str: + """Create a Uniswap v3 pool for trading 2 tokens, one of which can be the native gas token. + + Args: + wallet (Wallet): The wallet to create the pool from. + token_a (str): The address of the first token to trade. + token_b (str): The address of the second token to trade. + fee (str): The fee to charge for trades, denominated in hundredths of a bip (i.e. 1e-6). + + Returns: + str: A message containing the pool creation details. + + """ + pool = wallet.invoke_contract( + contract_address="0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24", # TODO - set this based on network id + method="createPool", + abi=UNISWAP_V3_FACTORY_ABI, + args={ + "tokenA": token_a, + "tokenB": token_b, + "fee": fee, + }, + ).wait() + return f"Created pool for {token_a} and {token_b} with fee {fee} on network {wallet.network_id}.\nTransaction hash for the pool creation: {pool.transaction.transaction_hash}\nTransaction link for the pool creation: {pool.transaction.transaction_link}" diff --git a/cdp-agentkit-core/tests/actions/uniswap_v3/__init__.py b/cdp-agentkit-core/tests/actions/uniswap_v3/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cdp-agentkit-core/tests/actions/test_create_pool.py b/cdp-agentkit-core/tests/actions/uniswap_v3/test_create_pool.py similarity index 84% rename from cdp-agentkit-core/tests/actions/test_create_pool.py rename to cdp-agentkit-core/tests/actions/uniswap_v3/test_create_pool.py index 5e3a8b926..d57f0c1f2 100644 --- a/cdp-agentkit-core/tests/actions/test_create_pool.py +++ b/cdp-agentkit-core/tests/actions/uniswap_v3/test_create_pool.py @@ -2,11 +2,11 @@ import pytest -from cdp_agentkit_core.actions.create_pool import ( - CreatePoolInput, - create_pool, +from cdp_agentkit_core.actions.uniswap_v3.constants import UNISWAP_V3_FACTORY_ABI +from cdp_agentkit_core.actions.uniswap_v3.create_pool import ( + UniswapV3CreatePoolInput, + uniswap_v3_create_pool, ) -from cdp_agentkit_core.constants import UNISWAP_V3_FACTORY_ABI MOCK_TOKEN_A = "0x4200000000000000000000000000000000000006" MOCK_TOKEN_B = "0x1234567890123456789012345678901234567890" @@ -15,7 +15,7 @@ def test_create_pool_input_model_valid(): """Test that CreatePoolInput accepts valid parameters.""" - input_model = CreatePoolInput( + input_model = UniswapV3CreatePoolInput( token_a=MOCK_TOKEN_A, token_b=MOCK_TOKEN_B, fee=MOCK_FEE, @@ -29,7 +29,7 @@ def test_create_pool_input_model_valid(): def test_create_pool_input_model_missing_params(): """Test that CreatePoolInput raises error when params are missing.""" with pytest.raises(ValueError): - CreatePoolInput() + UniswapV3CreatePoolInput() def test_create_pool_success(wallet_factory, contract_invocation_factory): @@ -45,7 +45,7 @@ def test_create_pool_success(wallet_factory, contract_invocation_factory): mock_contract_instance, "wait", return_value=mock_contract_instance ) as mock_contract_wait, ): - action_response = create_pool(mock_wallet, MOCK_TOKEN_A, MOCK_TOKEN_B, MOCK_FEE) + action_response = uniswap_v3_create_pool(mock_wallet, MOCK_TOKEN_A, MOCK_TOKEN_B, MOCK_FEE) expected_response = f"Created pool for {MOCK_TOKEN_A} and {MOCK_TOKEN_B} with fee {MOCK_FEE} on network {mock_wallet.network_id}.\nTransaction hash for the pool creation: {mock_contract_instance.transaction.transaction_hash}\nTransaction link for the pool creation: {mock_contract_instance.transaction.transaction_link}" assert action_response == expected_response @@ -71,7 +71,7 @@ def test_create_pool_api_error(wallet_factory): mock_wallet, "invoke_contract", side_effect=Exception("API error") ) as mock_invoke: with pytest.raises(Exception, match="API error"): - create_pool(mock_wallet, MOCK_TOKEN_A, MOCK_TOKEN_B, MOCK_FEE) + uniswap_v3_create_pool(mock_wallet, MOCK_TOKEN_A, MOCK_TOKEN_B, MOCK_FEE) mock_invoke.assert_called_once_with( contract_address="0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24", diff --git a/cdp-langchain/cdp_langchain/agent_toolkits/cdp_toolkit.py b/cdp-langchain/cdp_langchain/agent_toolkits/cdp_toolkit.py index 3efe599a2..85c3a6fd0 100644 --- a/cdp-langchain/cdp_langchain/agent_toolkits/cdp_toolkit.py +++ b/cdp-langchain/cdp_langchain/agent_toolkits/cdp_toolkit.py @@ -4,7 +4,6 @@ from langchain_core.tools.base import BaseToolkit from cdp_agentkit_core.actions import ( - CREATE_POOL_PROMPT, DEPLOY_NFT_PROMPT, DEPLOY_TOKEN_PROMPT, GET_BALANCE_PROMPT, @@ -14,7 +13,7 @@ REQUEST_FAUCET_FUNDS_PROMPT, TRADE_PROMPT, TRANSFER_PROMPT, - CreatePoolInput, + UNISWAP_V3_CREATE_POOL_PROMPT, DeployNftInput, DeployTokenInput, GetBalanceInput, @@ -24,6 +23,7 @@ RequestFaucetFundsInput, TradeInput, TransferInput, + UniswapV3CreatePoolInput, ) from cdp_langchain.tools import CdpAction from cdp_langchain.utils import CdpAgentkitWrapper @@ -81,6 +81,7 @@ class CdpToolkit(BaseToolkit): mint_nft deploy_nft register_basename + uniswap_v3_create_pool Use within an agent: .. code-block:: python @@ -144,10 +145,10 @@ def from_cdp_agentkit_wrapper(cls, cdp_agentkit_wrapper: CdpAgentkitWrapper) -> """ actions: list[dict] = [ { - "mode": "create_pool", - "name": "create_pool", - "description": CREATE_POOL_PROMPT, - "args_schema": CreatePoolInput, + "mode": "uniswap_v3_create_pool", + "name": "uniswap_v3_create_pool", + "description": UNISWAP_V3_CREATE_POOL_PROMPT, + "args_schema": UniswapV3CreatePoolInput, }, { "mode": "get_wallet_details", diff --git a/cdp-langchain/cdp_langchain/utils/cdp_agentkit_wrapper.py b/cdp-langchain/cdp_langchain/utils/cdp_agentkit_wrapper.py index 8f9b85c51..4a805f1d3 100644 --- a/cdp-langchain/cdp_langchain/utils/cdp_agentkit_wrapper.py +++ b/cdp-langchain/cdp_langchain/utils/cdp_agentkit_wrapper.py @@ -7,7 +7,6 @@ from pydantic import BaseModel, model_validator from cdp_agentkit_core.actions import ( - create_pool, deploy_nft, deploy_token, get_balance, @@ -17,6 +16,7 @@ request_faucet_funds, trade, transfer, + uniswap_v3_create_pool, ) @@ -83,7 +83,7 @@ def create_pool_wrapper(self, token_a: str, token_b: str, fee: str) -> str: str: A message containing the pool details. """ - return create_pool(wallet=self.wallet, token_a=token_a, token_b=token_b, fee=fee) + return uniswap_v3_create_pool(wallet=self.wallet, token_a=token_a, token_b=token_b, fee=fee) def get_wallet_details_wrapper(self) -> str: """Get details about the MPC Wallet by wrapping call to CDP Agentkit Core."""