From 4891cae89998852a7c63d3a443c7a0f6521c7cfe Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Mon, 16 Dec 2024 20:27:15 +0100 Subject: [PATCH 1/6] Tweaks to the NFT agents --- .../microchain_agent/microchain_agent.py | 4 ++-- .../microchain_agent/microchain_agent_keys.py | 4 ++-- .../app_nft_treasury_game.py | 22 +++++++++++++------ .../deploy_nft_treasury_game.py | 14 ++++++++---- .../messages_functions.py | 14 +++++------- .../microchain/test_messages_functions.py | 2 +- 6 files changed, 36 insertions(+), 24 deletions(-) rename prediction_market_agent/agents/microchain_agent/{ => nft_treasury_game}/messages_functions.py (86%) diff --git a/prediction_market_agent/agents/microchain_agent/microchain_agent.py b/prediction_market_agent/agents/microchain_agent/microchain_agent.py index 8891803e..7413d62f 100644 --- a/prediction_market_agent/agents/microchain_agent/microchain_agent.py +++ b/prediction_market_agent/agents/microchain_agent/microchain_agent.py @@ -44,10 +44,10 @@ from prediction_market_agent.agents.microchain_agent.memory_functions import ( LookAtPastActions, ) -from prediction_market_agent.agents.microchain_agent.messages_functions import ( +from prediction_market_agent.agents.microchain_agent.nft_functions import NFT_FUNCTIONS +from prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions import ( MESSAGES_FUNCTIONS, ) -from prediction_market_agent.agents.microchain_agent.nft_functions import NFT_FUNCTIONS from prediction_market_agent.agents.microchain_agent.omen_functions import ( OMEN_FUNCTIONS, ) diff --git a/prediction_market_agent/agents/microchain_agent/microchain_agent_keys.py b/prediction_market_agent/agents/microchain_agent/microchain_agent_keys.py index c649d788..54e580ce 100644 --- a/prediction_market_agent/agents/microchain_agent/microchain_agent_keys.py +++ b/prediction_market_agent/agents/microchain_agent/microchain_agent_keys.py @@ -1,4 +1,4 @@ -from prediction_market_agent_tooling.gtypes import xDai +from prediction_market_agent_tooling.gtypes import xDai, xdai_type from prediction_market_agent_tooling.loggers import logger from prediction_market_agent_tooling.markets.omen.omen import OMEN_TINY_BET_AMOUNT @@ -9,7 +9,7 @@ class MicrochainAgentKeys(APIKeys): # Double check to make sure you want to actually post on public social media. ENABLE_SOCIAL_MEDIA: bool = False # Double check to not spend big money during testing. - SENDING_XDAI_CAP: float | None = OMEN_TINY_BET_AMOUNT + SENDING_XDAI_CAP: xDai | None = xdai_type(0.1) # Double check to not transfer NFTs during testing. ENABLE_NFT_TRANSFER: bool = False RECEIVER_MINIMUM_AMOUNT: xDai = OMEN_TINY_BET_AMOUNT diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py index f9aef18f..65c5d050 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py @@ -16,17 +16,20 @@ from streamlit_extras.stylable_container import stylable_container from prediction_market_agent.agents.identifiers import AgentIdentifier -from prediction_market_agent.agents.microchain_agent.messages_functions import ( - BroadcastPublicMessageToHumans, - ReceiveMessage, - SendPaidMessageToAnotherAgent, -) +from prediction_market_agent.agents.microchain_agent.nft_functions import BalanceOfNFT from prediction_market_agent.agents.microchain_agent.nft_treasury_game.constants_nft_treasury_game import ( + NFT_TOKEN_FACTORY, TREASURY_SAFE_ADDRESS, ) from prediction_market_agent.agents.microchain_agent.nft_treasury_game.deploy_nft_treasury_game import ( DEPLOYED_NFT_AGENTS, DeployableAgentNFTGameAbstract, + MicrochainAgentKeys, +) +from prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions import ( + BroadcastPublicMessageToHumans, + ReceiveMessage, + SendPaidMessageToAnotherAgent, ) from prediction_market_agent.db.blockchain_transaction_fetcher import ( BlockchainTransactionFetcher, @@ -66,10 +69,14 @@ def prompt_table_handler(identifier: AgentIdentifier) -> PromptTableHandler: def send_message_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> None: message = st.text_area("Write a message to the agent") + default_value = MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT + value = st.number_input( + "Value in xDai", min_value=default_value, max_value=0.1, value=default_value + ) if st.button("Send message", disabled=not message): # TODO: Don't do this manually with deployment private key, use the user's wallet! - SendPaidMessageToAnotherAgent()(nft_agent.wallet_address, message) + SendPaidMessageToAnotherAgent()(nft_agent.wallet_address, message, value) st.success("Message sent and will be processed soon!") @@ -189,10 +196,11 @@ def show_about_agent_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> No else nft_agent.get_initial_system_prompt() ) xdai_balance = get_balances(nft_agent.wallet_address).xdai + n_nft = BalanceOfNFT()(NFT_TOKEN_FACTORY, nft_agent.wallet_address) st.markdown( f"""### {nft_agent.name} -Currently holds {xdai_balance:.2f} xDAI. +Currently holds {xdai_balance:.2f} xDAI and still holds {n_nft} NFT keys. --- """, diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py index 1eeb2f0a..4a374814 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py @@ -11,6 +11,7 @@ MicrochainAgentKeys, ) from prediction_market_agent.agents.microchain_agent.nft_treasury_game.constants_nft_treasury_game import ( + NFT_TOKEN_FACTORY, TREASURY_SAFE_ADDRESS, ) @@ -182,6 +183,7 @@ def get_initial_system_prompt(cls) -> str: def nft_treasury_game_base_prompt(wallet_address: ChecksumAddress) -> str: + keys = MicrochainAgentKeys() other_agents_keys_formatted = ", ".join( x.wallet_address for x in DEPLOYED_NFT_AGENTS @@ -191,14 +193,18 @@ def nft_treasury_game_base_prompt(wallet_address: ChecksumAddress) -> str: - You participate in the securing of the NFT key to a treasury. - Your wallet address is {wallet_address}. -- Other agents participating and probably still holding keys are {other_agents_keys_formatted}. -- Address of the NFT treasury is {TREASURY_SAFE_ADDRESS}. +- Other agents participating and maybe still holding keys are {other_agents_keys_formatted}. +- Address of the treasury, wallet holding the treasury's Xdai, is {TREASURY_SAFE_ADDRESS}. +- Address of the NFT contract is {NFT_TOKEN_FACTORY}, there are 5 keys, with token_id 0, 1, 2, 3, 4. + - You can own multiple NFT keys. + - You can use the NFT functions to interact with the NFT keys, for example figuring out how many keys you own or who owns what key. - The agent or person who gets enough of keys, can transfer the resources from the treasury. - The agents can communicate with each other using the messages functions by sending a message to their wallet address. - Sending a message costs you a fee. -- Receiving messages will pay you a fee. -- If you have unseen incoming messages, always process them first. +- Receiving messages will pay you a fee, but part of that fee goes to the treasury, which is good for you. +- If you have unseen incoming messages, always process them first, unless you are processing some message at the moment. - Regularly check balances of your wallet and the treasury. +- Keep in mind that you are able to send, and others agents are able to send at max {keys.SENDING_XDAI_CAP} xDai. """ diff --git a/prediction_market_agent/agents/microchain_agent/messages_functions.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/messages_functions.py similarity index 86% rename from prediction_market_agent/agents/microchain_agent/messages_functions.py rename to prediction_market_agent/agents/microchain_agent/nft_treasury_game/messages_functions.py index ef91bda7..21661543 100644 --- a/prediction_market_agent/agents/microchain_agent/messages_functions.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/messages_functions.py @@ -1,5 +1,5 @@ from microchain import Function -from prediction_market_agent_tooling.gtypes import wei_type +from prediction_market_agent_tooling.gtypes import wei_type, xdai_type from prediction_market_agent_tooling.loggers import logger from prediction_market_agent_tooling.tools.contract import ContractOnGnosisChain from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes @@ -39,21 +39,19 @@ class SendPaidMessageToAnotherAgent(Function): @property def description(self) -> str: return f"""Use {SendPaidMessageToAnotherAgent.__name__} to send a message to an another agent, given his wallet address. -Fee for sending the message is {MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT} xDai.""" +You need to send a fee of at least {MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT} xDai for other agent to read the message.""" @property def example_args(self) -> list[str]: - return ["0x123", "Hello!"] + return ["0x123", "Hello!", f"{MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT}"] - def __call__(self, address: str, message: str) -> str: + def __call__(self, address: str, message: str, fee: float) -> str: keys = MicrochainAgentKeys() send_xdai_to( web3=ContractOnGnosisChain.get_web3(), from_private_key=keys.bet_from_private_key, to_address=Web3.to_checksum_address(address), - value=xdai_to_wei( - keys.cap_sending_xdai(MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT) - ), + value=xdai_to_wei(keys.cap_sending_xdai(xdai_type(fee))), data_text=compress_message(message), ) return self.OUTPUT_TEXT @@ -72,7 +70,7 @@ def get_count_unseen_messages() -> int: @property def description(self) -> str: count_unseen_messages = self.get_count_unseen_messages() - return f"Use {ReceiveMessage.__name__} to receive last {count_unseen_messages} unseen messages from the users." + return f"Use {ReceiveMessage.__name__} to receive last unseen message from the users or other agents. Currently, you have {count_unseen_messages} unseen messages." @property def example_args(self) -> list[str]: diff --git a/tests/agents/microchain/test_messages_functions.py b/tests/agents/microchain/test_messages_functions.py index 71b91d72..45818685 100644 --- a/tests/agents/microchain/test_messages_functions.py +++ b/tests/agents/microchain/test_messages_functions.py @@ -9,7 +9,7 @@ from pydantic import SecretStr from web3 import Web3 -from prediction_market_agent.agents.microchain_agent.messages_functions import ( +from prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions import ( ReceiveMessage, ) from prediction_market_agent.db.blockchain_message_table_handler import ( From 0c13ce2411ebdae1a3412f276c8b5e0cbad1b513 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Mon, 16 Dec 2024 20:39:18 +0100 Subject: [PATCH 2/6] fix tests --- tests/agents/microchain/test_messages_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/agents/microchain/test_messages_functions.py b/tests/agents/microchain/test_messages_functions.py index 45818685..ef91bcae 100644 --- a/tests/agents/microchain/test_messages_functions.py +++ b/tests/agents/microchain/test_messages_functions.py @@ -80,7 +80,7 @@ def patch_spice() -> Generator[PropertyMock, None, None]: def patch_send_xdai() -> Generator[PropertyMock, None, None]: # Note that we patch where the function is called (see https://docs.python.org/3/library/unittest.mock.html#where-to-patch). with patch( - "prediction_market_agent.agents.microchain_agent.messages_functions.send_xdai_to", + "prediction_market_agent.agents.microchain_agent.nft_treasury_game.messages_functions.send_xdai_to", return_value={"transactionHash": HexBytes(MOCK_HASH_1)}, ) as mock_send_xdai: yield mock_send_xdai From 822ff25bfc0806d94ee0055cbbf977a0048181c1 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Mon, 16 Dec 2024 20:43:57 +0100 Subject: [PATCH 3/6] fix formatting --- .../nft_treasury_game/app_nft_treasury_game.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py index 65c5d050..9b1e57f5 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py @@ -71,7 +71,11 @@ def send_message_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> None: message = st.text_area("Write a message to the agent") default_value = MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT value = st.number_input( - "Value in xDai", min_value=default_value, max_value=0.1, value=default_value + "Value in xDai", + min_value=default_value, + max_value=0.1, + value=default_value, + format="%.5f", ) if st.button("Send message", disabled=not message): From d300fee2187edbb025e9db05a22bae0785c7ed3c Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Mon, 16 Dec 2024 20:44:48 +0100 Subject: [PATCH 4/6] add cap --- .../nft_treasury_game/app_nft_treasury_game.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py index 9b1e57f5..c6d0ce1b 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py @@ -69,11 +69,12 @@ def prompt_table_handler(identifier: AgentIdentifier) -> PromptTableHandler: def send_message_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> None: message = st.text_area("Write a message to the agent") - default_value = MicrochainAgentKeys().RECEIVER_MINIMUM_AMOUNT + keys = MicrochainAgentKeys() + default_value = keys.RECEIVER_MINIMUM_AMOUNT value = st.number_input( "Value in xDai", min_value=default_value, - max_value=0.1, + max_value=keys.SENDING_XDAI_CAP, value=default_value, format="%.5f", ) From c3c0ceda4f154fdec6f1a8413b69d4cb9e6291d5 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Tue, 17 Dec 2024 08:09:28 +0100 Subject: [PATCH 5/6] tweak the nft message --- .../nft_treasury_game/app_nft_treasury_game.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py index c6d0ce1b..dbb0a2c2 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py @@ -202,10 +202,15 @@ def show_about_agent_part(nft_agent: type[DeployableAgentNFTGameAbstract]) -> No ) xdai_balance = get_balances(nft_agent.wallet_address).xdai n_nft = BalanceOfNFT()(NFT_TOKEN_FACTORY, nft_agent.wallet_address) + nft_keys_message = ( + "and does not hold any NFT keys anymore" + if n_nft == 0 + else f"and {n_nft} NFT key{'s' if n_nft > 1 else ''}" + ) st.markdown( f"""### {nft_agent.name} -Currently holds {xdai_balance:.2f} xDAI and still holds {n_nft} NFT keys. +Currently holds {xdai_balance:.2f} xDAI {nft_keys_message}. --- """, From cc795934131653375a8bc33a56896b7e167c2084 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Tue, 17 Dec 2024 08:35:17 +0100 Subject: [PATCH 6/6] more tweaks --- .../app_nft_treasury_game.py | 5 +++- .../contracts_nft_treasury_game.py | 24 +++++++++++++++++++ .../deploy_nft_treasury_game.py | 8 +++++-- 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 prediction_market_agent/agents/microchain_agent/nft_treasury_game/contracts_nft_treasury_game.py diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py index dbb0a2c2..4ae8d208 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/app_nft_treasury_game.py @@ -21,6 +21,9 @@ NFT_TOKEN_FACTORY, TREASURY_SAFE_ADDRESS, ) +from prediction_market_agent.agents.microchain_agent.nft_treasury_game.contracts_nft_treasury_game import ( + get_nft_token_factory_max_supply, +) from prediction_market_agent.agents.microchain_agent.nft_treasury_game.deploy_nft_treasury_game import ( DEPLOYED_NFT_AGENTS, DeployableAgentNFTGameAbstract, @@ -246,7 +249,7 @@ def show_treasury_part() -> None: treasury_xdai_balance = get_balances(TREASURY_SAFE_ADDRESS).xdai st.markdown( f"""### Treasury -Currently holds {treasury_xdai_balance:.2f} xDAI.""", +Currently holds {treasury_xdai_balance:.2f} xDAI. There are {get_nft_token_factory_max_supply()} NFT keys.""", unsafe_allow_html=True, ) diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/contracts_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/contracts_nft_treasury_game.py new file mode 100644 index 00000000..ca3d3480 --- /dev/null +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/contracts_nft_treasury_game.py @@ -0,0 +1,24 @@ +from functools import cache + +from prediction_market_agent_tooling.gtypes import ChecksumAddress +from prediction_market_agent_tooling.tools.contract import ( + ContractOwnableERC721OnGnosisChain, +) +from web3 import Web3 + +from prediction_market_agent.agents.microchain_agent.nft_treasury_game.constants_nft_treasury_game import ( + NFT_TOKEN_FACTORY, +) + + +class ContractNFTFactoryOnGnosisChain(ContractOwnableERC721OnGnosisChain): + address: ChecksumAddress = NFT_TOKEN_FACTORY + + def max_supply(self, web3: Web3 | None = None) -> int: + n_tokens: int = self.call("MAX_SUPPLY", web3=web3) + return n_tokens + + +@cache +def get_nft_token_factory_max_supply() -> int: + return ContractNFTFactoryOnGnosisChain().max_supply() diff --git a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py index 4a374814..85bc02cb 100644 --- a/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py +++ b/prediction_market_agent/agents/microchain_agent/nft_treasury_game/deploy_nft_treasury_game.py @@ -14,6 +14,9 @@ NFT_TOKEN_FACTORY, TREASURY_SAFE_ADDRESS, ) +from prediction_market_agent.agents.microchain_agent.nft_treasury_game.contracts_nft_treasury_game import ( + get_nft_token_factory_max_supply, +) class DeployableAgentNFTGameAbstract(DeployableMicrochainAgentAbstract): @@ -184,6 +187,7 @@ def get_initial_system_prompt(cls) -> str: def nft_treasury_game_base_prompt(wallet_address: ChecksumAddress) -> str: keys = MicrochainAgentKeys() + n_nft_keys = get_nft_token_factory_max_supply() other_agents_keys_formatted = ", ".join( x.wallet_address for x in DEPLOYED_NFT_AGENTS @@ -194,8 +198,8 @@ def nft_treasury_game_base_prompt(wallet_address: ChecksumAddress) -> str: - You participate in the securing of the NFT key to a treasury. - Your wallet address is {wallet_address}. - Other agents participating and maybe still holding keys are {other_agents_keys_formatted}. -- Address of the treasury, wallet holding the treasury's Xdai, is {TREASURY_SAFE_ADDRESS}. -- Address of the NFT contract is {NFT_TOKEN_FACTORY}, there are 5 keys, with token_id 0, 1, 2, 3, 4. +- Address of the treasury, wallet holding the treasury's xDai, is {TREASURY_SAFE_ADDRESS}. +- Address of the NFT contract is {NFT_TOKEN_FACTORY}, there are {n_nft_keys} keys, with token_id {list(range(n_nft_keys))}. - You can own multiple NFT keys. - You can use the NFT functions to interact with the NFT keys, for example figuring out how many keys you own or who owns what key. - The agent or person who gets enough of keys, can transfer the resources from the treasury.