diff --git a/examples/08-local-network-interaction/agent1.py b/examples/08-local-network-interaction/agent1.py index 2dfef5c9..157cb34f 100644 --- a/examples/08-local-network-interaction/agent1.py +++ b/examples/08-local-network-interaction/agent1.py @@ -1,5 +1,4 @@ from uagents.setup import fund_agent_if_low -from uagents.resolver import get_agent_address from uagents import Agent, Context, Model @@ -11,21 +10,15 @@ class Message(Model): bob = Agent( - name="agent bob", + name="bob", port=8001, - seed="agent bob secret phrase", + seed="bob secret phrase", endpoint=["http://127.0.0.1:8001/submit"], ) fund_agent_if_low(bob.wallet.address()) -@bob.on_event("startup") -async def register_name(ctx: Context): - await bob.register_name() - print("agent bob registered address: ", get_agent_address(ctx.name)) - - @bob.on_message(model=Message) async def message_handler(ctx: Context, sender: str, msg: Message): ctx.logger.info(f"Received message from {sender}: {msg.message}") diff --git a/examples/08-local-network-interaction/agent2.py b/examples/08-local-network-interaction/agent2.py index b7f251b3..149bb27b 100644 --- a/examples/08-local-network-interaction/agent2.py +++ b/examples/08-local-network-interaction/agent2.py @@ -6,6 +6,8 @@ class Message(Model): message: str +RECIPIENT_ADDRESS = "agent1q2kxet3vh0scsf0sm7y2erzz33cve6tv5uk63x64upw5g68kr0chkv7hw50" + alice = Agent( name="alice", port=8000, @@ -18,7 +20,7 @@ class Message(Model): @alice.on_interval(period=2.0) async def send_message(ctx: Context): - await ctx.send("agent bob", Message(message="Hello there bob.")) + await ctx.send(RECIPIENT_ADDRESS, Message(message="Hello there bob.")) @alice.on_message(model=Message) diff --git a/examples/13-agent-name-service/agent1.py b/examples/13-agent-name-service/agent1.py new file mode 100644 index 00000000..b70295fb --- /dev/null +++ b/examples/13-agent-name-service/agent1.py @@ -0,0 +1,44 @@ +from cosmpy.aerial.wallet import LocalWallet + +from uagents.network import get_ledger, get_name_service_contract +from uagents.setup import fund_agent_if_low +from uagents import Agent, Context, Model + + +# NOTE: Run agent1.py before running agent2.py + + +class Message(Model): + message: str + + +bob = Agent( + name="bob-0", + seed="agent bob-0 secret phrase", + port=8001, + endpoint=["http://localhost:8001/submit"], +) + +ledger = get_ledger() +my_wallet = LocalWallet.from_unsafe_seed("registration test wallet") +name_service_contract = get_name_service_contract() +DOMAIN = "agent" + +for wallet in [my_wallet, bob.wallet]: + fund_agent_if_low(wallet.address()) + + +@bob.on_event("startup") +async def register_agent_name(ctx: Context): + await name_service_contract.register( + ledger, my_wallet, ctx.address, ctx.name, DOMAIN + ) + + +@bob.on_message(model=Message) +async def message_handler(ctx: Context, sender: str, msg: Message): + ctx.logger.info(f"Received message from {sender}: {msg.message}") + + +if __name__ == "__main__": + bob.run() diff --git a/examples/13-agent-name-service/agent2.py b/examples/13-agent-name-service/agent2.py new file mode 100644 index 00000000..10709f46 --- /dev/null +++ b/examples/13-agent-name-service/agent2.py @@ -0,0 +1,28 @@ +from uagents.setup import fund_agent_if_low +from uagents import Agent, Context, Model + + +class Message(Model): + message: str + + +alice = Agent( + name="alice-0", + seed="agent alice-0 secret phrase", + port=8000, + endpoint=["http://localhost:8000/submit"], +) + + +fund_agent_if_low(alice.wallet.address()) + + +@alice.on_interval(period=5) +async def alice_interval_handler(ctx: Context): + bob_name = "bob-0.agent" + ctx.logger.info(f"Sending message to {bob_name}...") + await ctx.send(bob_name, Message(message="Hello there bob.")) + + +if __name__ == "__main__": + alice.run() diff --git a/src/uagents/agent.py b/src/uagents/agent.py index d1e67381..9a58e174 100644 --- a/src/uagents/agent.py +++ b/src/uagents/agent.py @@ -1,15 +1,11 @@ import asyncio import functools -from typing import Dict, List, Optional, Set, Union, Type, Tuple, Any +from typing import Dict, List, Optional, Set, Union, Type, Tuple, Any, Coroutine import uuid import requests from cosmpy.aerial.wallet import LocalWallet, PrivateKey from cosmpy.crypto.address import Address -from cosmpy.aerial.contract.cosmwasm import create_cosmwasm_execute_msg -from cosmpy.aerial.client import prepare_and_broadcast_basic_transaction -from cosmpy.aerial.tx import Transaction - from uagents.asgi import ASGIServer from uagents.context import ( @@ -28,14 +24,10 @@ from uagents.network import ( get_ledger, get_almanac_contract, - get_service_contract, - wait_for_tx_to_complete, ) from uagents.mailbox import MailboxClient from uagents.config import ( - CONTRACT_ALMANAC, REGISTRATION_FEE, - REGISTRATION_DENOM, MIN_REGISTRATION_TIME, LEDGER_PREFIX, parse_endpoint_config, @@ -56,6 +48,11 @@ async def _run_interval(func: IntervalCallback, ctx: Context, period: float): await asyncio.sleep(period) +async def _delay(coroutine: Coroutine, delay_seconds: float): + await asyncio.sleep(delay_seconds) + await coroutine + + async def _handle_error(ctx: Context, destination: str, msg: ErrorMessage): await ctx.send(destination, msg) @@ -114,7 +111,6 @@ def __init__( self._ledger = get_ledger() self._almanac_contract = get_almanac_contract() - self._service_contract = get_service_contract() self._storage = KeyValueStore(self.address[0:16]) self._interval_handlers: List[Tuple[IntervalCallback, float]] = [] self._interval_messages: Set[str] = set() @@ -234,69 +230,56 @@ def update_loop(self, loop): def update_queries(self, queries): self._queries = queries - async def _register(self, ctx: Context): - agent_balance = ctx.ledger.query_bank_balance(Address(ctx.wallet.address())) - - if agent_balance < REGISTRATION_FEE: + async def register(self): + if self._endpoints is None: self._logger.warning( - f"I do not have enough funds to register on Almanac contract\ - \nFund using wallet address: {self.wallet.address()}" + "I have no endpoint and cannot receive external messages" ) return - signature = self.sign_registration() - - self._logger.info("Registering on almanac contract...") - - transaction = Transaction() - - almanac_msg = self._almanac_contract.get_registration_msg( - self.protocols, self._endpoints, signature, self.address - ) + # register if not yet registered or registration is about to expire + # or anything has changed from the last registration + if ( + not self._almanac_contract.is_registered(self.address) + or self._schedule_registration() < MIN_REGISTRATION_TIME + or self._endpoints != self._almanac_contract.get_endpoints(self.address) + or list(self.protocols.keys()) + != self._almanac_contract.get_protocols(self.address) + ): + agent_balance = self._ledger.query_bank_balance( + Address(self.wallet.address()) + ) - transaction.add_message( - create_cosmwasm_execute_msg( - ctx.wallet.address(), - CONTRACT_ALMANAC, - almanac_msg, - funds=f"{REGISTRATION_FEE}{REGISTRATION_DENOM}", + if agent_balance < REGISTRATION_FEE: + self._logger.warning( + f"I do not have enough funds to register on Almanac contract\ + \nFund using wallet address: {self.wallet.address()}" + ) + return + self._logger.info("Registering on almanac contract...") + signature = self.sign_registration() + await self._almanac_contract.register( + self._ledger, + self.wallet, + self.address, + list(self.protocols.keys()), + self._endpoints, + signature, ) - ) + self._logger.info("Registering on almanac contract...complete") + else: + self._logger.info("Almanac registration is up to date!") - transaction = prepare_and_broadcast_basic_transaction( - ctx.ledger, transaction, ctx.wallet + async def _registration_loop(self): + await self.register() + # schedule the next registration + self._loop.create_task( + _delay(self._registration_loop(), self._schedule_registration()) ) - await wait_for_tx_to_complete(transaction.tx_hash) - self._logger.info("Registering on almanac contract...complete") def _schedule_registration(self): return self._almanac_contract.get_expiry(self.address) - async def register_name(self): - self._logger.info("Registering name...") - - if not self._almanac_contract.is_registered(self.address): - self._logger.warning( - f"Agent {self.name} needs to be registered in almanac contract to register its name" - ) - return - - transaction = self._service_contract.get_registration_tx( - self.name, str(self.wallet.address()), self.address - ) - - if transaction is None: - self._logger.error( - f"Please select another name, {self.name} is owned by another address" - ) - - return - transaction = prepare_and_broadcast_basic_transaction( - self._ledger, transaction, self.wallet - ) - await wait_for_tx_to_complete(transaction.tx_hash) - self._logger.info("Registering name...complete") - def on_interval( self, period: float, @@ -397,6 +380,7 @@ async def handle_message( await self._message_queue.put((schema_digest, sender, message, session)) async def _startup(self): + await self._registration_loop() for handler in self._on_startup: await handler(self._ctx) @@ -426,25 +410,6 @@ def start_background_tasks(self): self._background_tasks.add(task) task.add_done_callback(self._background_tasks.discard) - # start the contract registration update loop - if self._endpoints is not None: - if ( - not self._almanac_contract.is_registered(self.address) - or self._schedule_registration() < MIN_REGISTRATION_TIME - or self._endpoints != self._almanac_contract.get_endpoints(self.address) - ): - self._loop.create_task( - _run_interval( - self._register, self._ctx, self._schedule_registration() - ) - ) - else: - self._logger.info("Registration up to date!") - else: - self._logger.warning( - "I have no endpoint and won't be able to receive external messages" - ) - def run(self): self.setup() try: @@ -516,7 +481,7 @@ def __init__( endpoint: Optional[Union[str, List[str], Dict[str, dict]]] = None, ): self._loop = asyncio.get_event_loop_policy().get_event_loop() - self._agents = [] + self._agents: List[Agent] = [] self._endpoints = parse_endpoint_config(endpoint) self._port = port or 8000 self._queries: Dict[str, asyncio.Future] = {} @@ -527,7 +492,7 @@ def __init__( def add(self, agent: Agent): agent.update_loop(self._loop) agent.update_queries(self._queries) - if agent.mailbox is not None: + if agent.agentverse["use_mailbox"]: self._use_mailbox = True else: agent.update_endpoints(self._endpoints) @@ -537,7 +502,7 @@ def run(self): tasks = [] for agent in self._agents: agent.setup() - if agent.mailbox is not None: + if agent.agentverse["use_mailbox"]: tasks.append( self._loop.create_task( agent.mailbox_client.process_deletion_queue() diff --git a/src/uagents/network.py b/src/uagents/network.py index 4268161b..f9488a97 100644 --- a/src/uagents/network.py +++ b/src/uagents/network.py @@ -1,6 +1,6 @@ import asyncio from datetime import datetime, timedelta -from typing import Optional, Dict, List, Union +from typing import Any, Optional, Dict, List from cosmpy.aerial.contract import LedgerContract from cosmpy.aerial.client import ( @@ -8,12 +8,14 @@ NetworkConfig, DEFAULT_QUERY_INTERVAL_SECS, DEFAULT_QUERY_TIMEOUT_SECS, + prepare_and_broadcast_basic_transaction, ) from cosmpy.aerial.exceptions import NotFoundError, QueryTimeoutError from cosmpy.aerial.contract.cosmwasm import create_cosmwasm_execute_msg from cosmpy.aerial.faucet import FaucetApi from cosmpy.aerial.tx_helpers import TxResponse from cosmpy.aerial.tx import Transaction +from cosmpy.aerial.wallet import LocalWallet from uagents.config import ( AgentNetwork, @@ -21,9 +23,54 @@ CONTRACT_NAME_SERVICE, AGENT_NETWORK, BLOCK_INTERVAL, + REGISTRATION_FEE, + REGISTRATION_DENOM, + get_logger, ) +logger = get_logger("network") + +if AGENT_NETWORK == AgentNetwork.FETCHAI_TESTNET: + _ledger = LedgerClient(NetworkConfig.fetchai_stable_testnet()) + _faucet_api = FaucetApi(NetworkConfig.fetchai_stable_testnet()) +elif AGENT_NETWORK == AgentNetwork.FETCHAI_MAINNET: + _ledger = LedgerClient(NetworkConfig.fetchai_mainnet()) +else: + raise NotImplementedError + + +def get_ledger() -> LedgerClient: + return _ledger + + +def get_faucet() -> FaucetApi: + return _faucet_api + + +async def wait_for_tx_to_complete( + tx_hash: str, + timeout: Optional[timedelta] = None, + poll_period: Optional[timedelta] = None, +) -> TxResponse: + if timeout is None: + timeout = timedelta(seconds=DEFAULT_QUERY_TIMEOUT_SECS) + if poll_period is None: + poll_period = timedelta(seconds=DEFAULT_QUERY_INTERVAL_SECS) + start = datetime.now() + while True: + try: + return _ledger.query_tx(tx_hash) + except NotFoundError: + pass + + delta = datetime.now() - start + if delta >= timeout: + raise QueryTimeoutError() + + await asyncio.sleep(poll_period.total_seconds()) + + class AlmanacContract(LedgerContract): def is_registered(self, address: str) -> bool: query_msg = {"query_records": {"agent_address": address}} @@ -52,30 +99,56 @@ def get_endpoints(self, address: str): response = self.query(query_msg) if not response["record"]: - return 0 + return None return response.get("record")[0]["record"]["service"]["endpoints"] - def get_registration_msg( + def get_protocols(self, address: str): + query_msg = {"query_records": {"agent_address": address}} + response = self.query(query_msg) + + if not response["record"]: + return None + return response.get("record")[0]["record"]["service"]["protocols"] + + async def register( self, - protocols: Dict, - endpoints: Optional[Union[List[str], Dict[str, dict]]], + ledger: LedgerClient, + wallet: LocalWallet, + agent_address: str, + protocols: List[str], + endpoints: List[Dict[str, Any]], signature: str, - address: str, - ) -> dict: - return { + ): + transaction = Transaction() + + almanac_msg = { "register": { "record": { "service": { - "protocols": list(map(lambda x: x.digest, protocols.values())), + "protocols": protocols, "endpoints": endpoints, } }, "signature": signature, - "sequence": self.get_sequence(address), - "agent_address": address, + "sequence": self.get_sequence(agent_address), + "agent_address": agent_address, } } + transaction.add_message( + create_cosmwasm_execute_msg( + wallet.address(), + self.address, + almanac_msg, + funds=f"{REGISTRATION_FEE}{REGISTRATION_DENOM}", + ) + ) + + transaction = prepare_and_broadcast_basic_transaction( + ledger, transaction, wallet + ) + await wait_for_tx_to_complete(transaction.tx_hash) + def get_sequence(self, address: str) -> int: query_msg = {"query_sequence": {"agent_address": address}} sequence = self.query(query_msg)["sequence"] @@ -83,37 +156,48 @@ def get_sequence(self, address: str) -> int: return sequence +_almanac_contract = AlmanacContract(None, _ledger, CONTRACT_ALMANAC) + + +def get_almanac_contract() -> AlmanacContract: + return _almanac_contract + + class NameServiceContract(LedgerContract): - def is_name_available(self, name: str): - query_msg = {"domain_record": {"domain": f"{name}.agent"}} + def is_name_available(self, name: str, domain: str): + query_msg = {"domain_record": {"domain": f"{name}.{domain}"}} return self.query(query_msg)["is_available"] - def is_owner(self, name: str, wallet_address: str): + def is_owner(self, name: str, domain: str, wallet_address: str): query_msg = { "permissions": { - "domain": f"{name}.agent", + "domain": f"{name}.{domain}", "owner": {"address": {"address": wallet_address}}, } } permission = self.query(query_msg)["permissions"] return permission == "admin" - def _get_registration_msg(self, name: str, address: str): - return { + def is_domain_public(self, domain: str): + res = self.query({"domain_record": {"domain": f".{domain}"}}) + return res["is_public"] + + def get_registration_tx( + self, name: str, wallet_address: str, agent_address: str, domain: str + ): + if not self.is_name_available(name, domain) and not self.is_owner( + name, domain, wallet_address + ): + return None + + registration_msg = { "register": { - "domain": f"{name}.agent", - "agent_address": address, + "domain": f"{name}.{domain}", + "agent_address": agent_address, } } - def get_registration_tx(self, name: str, wallet_address: str, agent_address: str): - if not self.is_name_available(name) and not self.is_owner(name, wallet_address): - return None - transaction = Transaction() - - registration_msg = self._get_registration_msg(name, agent_address) - transaction.add_message( create_cosmwasm_execute_msg( wallet_address, CONTRACT_NAME_SERVICE, registration_msg @@ -122,54 +206,46 @@ def get_registration_tx(self, name: str, wallet_address: str, agent_address: str return transaction + async def register( + self, + ledger: LedgerClient, + wallet: LocalWallet, + agent_address: str, + name: str, + domain: str, + ): + logger.info("Registering name...") + + if not get_almanac_contract().is_registered(agent_address): + logger.warning( + f"Agent {name} needs to be registered in almanac contract to register its name" + ) + return -if AGENT_NETWORK == AgentNetwork.FETCHAI_TESTNET: - _ledger = LedgerClient(NetworkConfig.fetchai_stable_testnet()) - _faucet_api = FaucetApi(NetworkConfig.fetchai_stable_testnet()) -elif AGENT_NETWORK == AgentNetwork.FETCHAI_MAINNET: - _ledger = LedgerClient(NetworkConfig.fetchai_mainnet()) -else: - raise NotImplementedError - - -_almanac_contract = AlmanacContract(None, _ledger, CONTRACT_ALMANAC) -_name_service_contract = NameServiceContract(None, _ledger, CONTRACT_NAME_SERVICE) - - -def get_ledger() -> LedgerClient: - return _ledger + if not self.is_domain_public(domain): + logger.warning( + f"Domain {domain} is not public, please select a public domain" + ) + return + transaction = self.get_registration_tx( + name, str(wallet.address()), agent_address, domain + ) -def get_faucet() -> FaucetApi: - return _faucet_api + if transaction is None: + logger.error( + f"Please select another name, {name} is owned by another address" + ) + return + transaction = prepare_and_broadcast_basic_transaction( + ledger, transaction, wallet + ) + await wait_for_tx_to_complete(transaction.tx_hash) + logger.info("Registering name...complete") -def get_almanac_contract() -> LedgerContract: - return _almanac_contract +_name_service_contract = NameServiceContract(None, _ledger, CONTRACT_NAME_SERVICE) -def get_service_contract() -> LedgerContract: +def get_name_service_contract() -> NameServiceContract: return _name_service_contract - - -async def wait_for_tx_to_complete( - tx_hash: str, - timeout: Optional[timedelta] = None, - poll_period: Optional[timedelta] = None, -) -> TxResponse: - if timeout is None: - timeout = timedelta(seconds=DEFAULT_QUERY_TIMEOUT_SECS) - if poll_period is None: - poll_period = timedelta(seconds=DEFAULT_QUERY_INTERVAL_SECS) - start = datetime.now() - while True: - try: - return _ledger.query_tx(tx_hash) - except NotFoundError: - pass - - delta = datetime.now() - start - if delta >= timeout: - raise QueryTimeoutError() - - await asyncio.sleep(poll_period.total_seconds()) diff --git a/src/uagents/resolver.py b/src/uagents/resolver.py index cb1791ec..7190851c 100644 --- a/src/uagents/resolver.py +++ b/src/uagents/resolver.py @@ -2,7 +2,7 @@ from typing import Dict, Optional import random -from uagents.network import get_almanac_contract, get_service_contract +from uagents.network import get_almanac_contract, get_name_service_contract def query_record(agent_address: str, service: str) -> dict: @@ -15,8 +15,8 @@ def query_record(agent_address: str, service: str) -> dict: def get_agent_address(name: str) -> str: - query_msg = {"domain_record": {"domain": f"{name}.agent"}} - result = get_service_contract().query(query_msg) + query_msg = {"domain_record": {"domain": f"{name}"}} + result = get_name_service_contract().query(query_msg) if result["record"] is not None: registered_address = result["record"]["records"][0]["agent_address"]["records"] if len(registered_address) > 0: diff --git a/src/uagents/setup.py b/src/uagents/setup.py index a2815739..607060ee 100644 --- a/src/uagents/setup.py +++ b/src/uagents/setup.py @@ -8,16 +8,16 @@ LOGGER = get_logger("setup") -def fund_agent_if_low(agent_address: str): +def fund_agent_if_low(wallet_address: str): ledger = get_ledger() faucet = get_faucet() - agent_balance = ledger.query_bank_balance(Address(agent_address)) + agent_balance = ledger.query_bank_balance(Address(wallet_address)) if agent_balance < REGISTRATION_FEE: # Add tokens to agent's wallet LOGGER.info("Adding funds to agent...") - faucet.get_wealth(agent_address) + faucet.get_wealth(wallet_address) LOGGER.info("Adding funds to agent...complete") diff --git a/tests/test_agent_registration.py b/tests/test_agent_registration.py index b450d877..90675a51 100644 --- a/tests/test_agent_registration.py +++ b/tests/test_agent_registration.py @@ -4,34 +4,16 @@ from uagents import Agent from uagents.setup import fund_agent_if_low from uagents.resolver import get_agent_address -from uagents.config import ( - REGISTRATION_FEE, - REGISTRATION_DENOM, -) +from uagents.network import get_name_service_contract -class TestRegistration(unittest.TestCase): - def test_alamanc_registration(self): - agent = Agent() - - reg_fee = f"{REGISTRATION_FEE}{REGISTRATION_DENOM}" +class TestRegistration(unittest.IsolatedAsyncioTestCase): + async def test_almanac_registration(self): + agent = Agent(endpoint=["http://localhost:8000/submit"]) fund_agent_if_low(agent.wallet.address()) - sequence = agent._almanac_contract.get_sequence(agent.address) - - signature = agent._identity.sign_registration( - agent._almanac_contract.address, sequence - ) - - almanac_msg = agent._almanac_contract.get_registration_msg( - {}, [], signature, agent.address - ) - - transaction = agent._almanac_contract.execute( - almanac_msg, agent.wallet, funds=reg_fee - ) - transaction.wait_to_complete() + await agent.register() self.assertEqual( agent._almanac_contract.is_registered(agent.address), @@ -39,44 +21,36 @@ def test_alamanc_registration(self): "Almanac registration failed", ) - def test_alamanc_failed_registration(self): + def test_almanac_failed_registration(self): agent = Agent() self.assertEqual( agent._almanac_contract.is_registered(agent.address), False, - "Shouldn't be registered on alamanac", + "Shouldn't be registered on almanac", ) def test_name_service_failed_ownership(self): agent = Agent() - is_owner = agent._service_contract.is_owner( - agent.name, str(agent.wallet.address()) + domain = "agent" + + name_service_contract = get_name_service_contract() + + is_owner = name_service_contract.is_owner( + agent.name, domain, str(agent.wallet.address()) ) self.assertEqual(is_owner, False, "Agent shouldn't own any domain") - def test_registration(self): - agent = Agent() + async def test_name_service_registration(self): + agent = Agent(endpoint=["http://localhost:8000/submit"]) - reg_fee = f"{REGISTRATION_FEE}{REGISTRATION_DENOM}" + domain = "agent" fund_agent_if_low(agent.wallet.address()) - sequence = agent._almanac_contract.get_sequence(agent.address) - - signature = agent._identity.sign_registration( - agent._almanac_contract.address, sequence - ) - - almanac_msg = agent._almanac_contract.get_registration_msg( - {}, [], signature, agent.address - ) - - agent._almanac_contract.execute( - almanac_msg, agent.wallet, funds=reg_fee - ).wait_to_complete() + await agent.register() self.assertEqual( agent._almanac_contract.is_registered(agent.address), @@ -84,31 +58,29 @@ def test_registration(self): "Almanac registration failed", ) - is_name_available = agent._service_contract.is_name_available(agent.name) + name_service_contract = get_name_service_contract() + + is_name_available = name_service_contract.is_name_available(agent.name, domain) self.assertEqual(is_name_available, True, "Agent name should be available") - is_owner = agent._service_contract.is_owner( - agent.name, str(agent.wallet.address()) + is_owner = name_service_contract.is_owner( + agent.name, domain, str(agent.wallet.address()) ) self.assertEqual(is_owner, False) - registration_msg = agent._service_contract._get_registration_msg( - agent.name, agent.address + await name_service_contract.register( + agent._ledger, agent.wallet, agent.address, agent.name, domain=domain ) - agent._service_contract.execute( - registration_msg, agent.wallet - ).wait_to_complete() - - is_name_available = agent._service_contract.is_name_available(agent.name) + is_name_available = name_service_contract.is_name_available(agent.name, domain) self.assertEqual(is_name_available, False, "Agent name shouldn't be available") - is_owner = agent._service_contract.is_owner( - agent.name, str(agent.wallet.address()) + is_owner = name_service_contract.is_owner( + agent.name, domain, str(agent.wallet.address()) ) self.assertEqual(is_owner, True, "Domain ownership failed") - query_address = get_agent_address(agent.name) + query_address = get_agent_address(agent.name + "." + domain) self.assertEqual( query_address == agent.address, True, "Service contract registration failed"