-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NFT functions for general agent #582
Changes from 6 commits
c1b2ac9
5fe2710
00e17f8
deac15f
9be0f9d
5dd2795
b1822dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
from microchain import Function | ||
from prediction_market_agent_tooling.loggers import logger | ||
from prediction_market_agent_tooling.tools.contract import ( | ||
ContractOwnableERC721OnGnosisChain, | ||
) | ||
from web3 import Web3 | ||
|
||
from prediction_market_agent.agents.microchain_agent.microchain_agent_keys import ( | ||
MicrochainAgentKeys, | ||
) | ||
|
||
|
||
class BalanceOfNFT(Function): | ||
@property | ||
def description(self) -> str: | ||
return "Returns the number of given NFT owned by the specified address." | ||
|
||
@property | ||
def example_args(self) -> list[str]: | ||
return [ | ||
"0xNFTAddress", | ||
"0xOwnerddress", | ||
] | ||
|
||
def __call__( | ||
self, | ||
nft_address: str, | ||
owner_address: str, | ||
) -> int: | ||
contract = ContractOwnableERC721OnGnosisChain( | ||
address=Web3.to_checksum_address(nft_address) | ||
) | ||
balance: int = contract.balanceOf(Web3.to_checksum_address(owner_address)) | ||
return balance | ||
|
||
|
||
class OwnerOfNFT(Function): | ||
@property | ||
def description(self) -> str: | ||
return "Returns the owner address of the specified NFT token ID." | ||
|
||
@property | ||
def example_args(self) -> list[str]: | ||
return ["0xNFTAddress", "1"] | ||
|
||
def __call__( | ||
self, | ||
nft_address: str, | ||
token_id: int, | ||
) -> str: | ||
contract = ContractOwnableERC721OnGnosisChain( | ||
address=Web3.to_checksum_address(nft_address) | ||
) | ||
owner_address = contract.ownerOf(token_id) | ||
return owner_address | ||
Comment on lines
+51
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add Exception Handling for Smart Contract Calls Similar to the def __call__(
self,
nft_address: str,
token_id: int,
) -> str:
try:
contract = ContractOwnableERC721OnGnosisChain(
address=Web3.to_checksum_address(nft_address)
)
owner_address = contract.ownerOf(token_id)
return owner_address
except Exception as e:
logger.error(f"Error fetching NFT owner: {e}")
raise ValueError("Failed to retrieve NFT owner.") |
||
|
||
|
||
class SafeTransferFromNFT(Function): | ||
@property | ||
def description(self) -> str: | ||
return "Transfers the specified NFT token ID from one address to another." | ||
|
||
@property | ||
def example_args(self) -> list[str]: | ||
return [ | ||
"0xNFTAddress", | ||
"0xRecipientAddress", | ||
"1", | ||
] | ||
|
||
def __call__( | ||
self, | ||
nft_address: str, | ||
to_address: str, | ||
token_id: int, | ||
) -> str: | ||
keys = MicrochainAgentKeys() | ||
contract = ContractOwnableERC721OnGnosisChain( | ||
address=Web3.to_checksum_address(nft_address) | ||
) | ||
if keys.ENABLE_NFT_TRANSFER: | ||
contract.safeTransferFrom( | ||
api_keys=keys, | ||
from_address=keys.bet_from_address, | ||
to_address=Web3.to_checksum_address(to_address), | ||
tokenId=token_id, | ||
) | ||
else: | ||
logger.warning("NFT transfer is disabled in the environment.") | ||
return "Token transferred successfully." | ||
Comment on lines
+77
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return Appropriate Message Based on Transfer Outcome Currently, the method returns Adjust the return statements to reflect the actual outcome: def __call__(
self,
nft_address: str,
to_address: str,
token_id: int,
) -> str:
keys = MicrochainAgentKeys()
contract = ContractOwnableERC721OnGnosisChain(
address=Web3.to_checksum_address(nft_address)
)
if keys.ENABLE_NFT_TRANSFER:
contract.safeTransferFrom(
api_keys=keys,
from_address=keys.bet_from_address,
to_address=Web3.to_checksum_address(to_address),
tokenId=token_id,
)
return "Token transferred successfully."
else:
logger.warning("NFT transfer is disabled in the environment.")
return "NFT transfer is disabled." |
||
|
||
Comment on lines
+77
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Handle Exceptions During NFT Transfer When performing the NFT transfer, exceptions may occur due to issues like insufficient permissions or network errors. Add exception handling to manage potential errors: def __call__(
self,
nft_address: str,
to_address: str,
token_id: int,
) -> str:
keys = MicrochainAgentKeys()
contract = ContractOwnableERC721OnGnosisChain(
address=Web3.to_checksum_address(nft_address)
)
if keys.ENABLE_NFT_TRANSFER:
try:
contract.safeTransferFrom(
api_keys=keys,
from_address=keys.bet_from_address,
to_address=Web3.to_checksum_address(to_address),
tokenId=token_id,
)
return "Token transferred successfully."
except Exception as e:
logger.error(f"Error transferring NFT: {e}")
raise ValueError("Failed to transfer NFT.")
else:
logger.warning("NFT transfer is disabled in the environment.")
return "NFT transfer is disabled." |
||
|
||
NFT_FUNCTIONS: list[type[Function]] = [ | ||
BalanceOfNFT, | ||
OwnerOfNFT, | ||
SafeTransferFromNFT, | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,6 +136,7 @@ class FunctionsConfig(BaseModel): | |
include_sending_functions: bool | ||
include_twitter_functions: bool | ||
include_messages_functions: bool | ||
include_nft_functions: bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Set Default Value for In the Assign a default value to ensure proper instantiation: class FunctionsConfig(BaseModel):
# ...
include_messages_functions: bool
include_nft_functions: bool = False |
||
|
||
@staticmethod | ||
def from_system_prompt_choice( | ||
|
@@ -149,6 +150,7 @@ def from_system_prompt_choice( | |
include_sending_functions = False | ||
include_twitter_functions = False | ||
include_messages_functions = False | ||
include_nft_functions = False | ||
|
||
if system_prompt_choice == SystemPromptChoice.JUST_BORN: | ||
include_learning_functions = True | ||
|
@@ -171,6 +173,7 @@ def from_system_prompt_choice( | |
|
||
elif system_prompt_choice == SystemPromptChoice.DARE_YOU_GET_MY_RESOURCES_AGENT: | ||
include_messages_functions = True | ||
include_nft_functions = True | ||
|
||
return FunctionsConfig( | ||
include_trading_functions=include_trading_functions, | ||
|
@@ -181,6 +184,7 @@ def from_system_prompt_choice( | |
include_sending_functions=include_sending_functions, | ||
include_twitter_functions=include_twitter_functions, | ||
include_messages_functions=include_messages_functions, | ||
include_nft_functions=include_nft_functions, | ||
) | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add Input Validation and Exception Handling
When interacting with smart contracts, it's important to validate inputs and handle potential exceptions to prevent unexpected failures.
Consider adding input validation and exception handling: