Skip to content

Commit

Permalink
Merge pull request #2273 from OjusWiZard/fix/fetch
Browse files Browse the repository at this point in the history
Refactor (Fetch): Allow fetching from TokenID
  • Loading branch information
Adamantios authored Oct 22, 2024
2 parents 0eb9c1b + f050e6b commit dc4a095
Show file tree
Hide file tree
Showing 12 changed files with 313 additions and 41 deletions.
7 changes: 6 additions & 1 deletion autonomy/chain/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from autonomy.chain.constants import SERVICE_MANAGER_TOKEN_COMPATIBLE_CHAINS
from autonomy.chain.exceptions import DependencyError, FailedToRetrieveComponentMetadata
from autonomy.chain.metadata import IPFS_URI_PREFIX
from autonomy.constants import OLAS_DOCS_URL


def get_ipfs_hash_from_uri(uri: str) -> str:
Expand Down Expand Up @@ -61,7 +62,11 @@ def resolve_component_id(
token_id=token_id,
)
except RequestConnectionError as e:
raise FailedToRetrieveComponentMetadata("Error connecting to the RPC") from e
raise FailedToRetrieveComponentMetadata(
"Error connecting to the RPC. Please make sure that "
"you have set the chain RPC environment variable correctly. "
f"You can read more about the configurations on {OLAS_DOCS_URL}/open-autonomy/advanced_reference/commands/autonomy_service/#options."
) from e

try:
return r_get(url=metadata_uri).json()
Expand Down
6 changes: 6 additions & 0 deletions autonomy/cli/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,12 @@ def run_deployment_from_token( # pylint: disable=too-many-arguments, too-many-l
"use `OPEN_AUTONOMY_PRIVATE_KEY_PASSWORD` to export the password value"
)

click.echo(
"DEPRECATION WARNING: `autonomy deploy from-token` is being deprecated.\n"
"Please use `autonomy fetch <token_id>` instead to fetch the service, "
"followed by `build-image`, `deploy build`, and `deploy run` as usual."
)

ctx = cast(Context, click_context.obj)
ctx.registry_type = REGISTRY_REMOTE
keys_file = Path(keys_file or DEFAULT_KEYS_FILE).absolute()
Expand Down
32 changes: 26 additions & 6 deletions autonomy/cli/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@
# ------------------------------------------------------------------------------
"""Implementation of the 'autonomy fetch' subcommand."""

from typing import cast
from typing import Union, cast

import click
from aea.cli.fetch import NotAnAgentPackage, do_fetch
from aea.cli.utils.click_utils import PublicIdParameter, registry_flag
from aea.cli.utils.click_utils import registry_flag
from aea.cli.utils.context import Context
from aea.configurations.base import PublicId
from aea.configurations.constants import AGENT, SERVICE

from autonomy.cli.helpers.registry import fetch_service
from autonomy.chain.config import ChainType
from autonomy.cli.helpers.deployment import _resolve_on_chain_token_id
from autonomy.cli.helpers.registry import fetch_service, fetch_service_ipfs
from autonomy.cli.utils.click_utils import PublicIdOrHashOrTokenId, chain_selection_flag


@click.command(name="fetch")
Expand All @@ -51,21 +54,38 @@
help="Specify the package type as service.",
flag_value=SERVICE,
)
@click.argument("public-id", type=PublicIdParameter(), required=True)
@click.argument("public-id", type=PublicIdOrHashOrTokenId(), required=True)
@chain_selection_flag(help_string_format="Use {} chain to resolve the token id.")
@click.pass_context
def fetch(
click_context: click.Context,
public_id: PublicId,
public_id: Union[PublicId, int],
alias: str,
package_type: str,
registry: str,
chain_type: str,
) -> None:
"""Fetch an agent from the registry."""
ctx = cast(Context, click_context.obj)
ctx.registry_type = registry

try:
if package_type == AGENT:
if isinstance(public_id, int):
(
service_metadata,
*_,
) = _resolve_on_chain_token_id(
token_id=public_id,
chain_type=ChainType(chain_type),
)

click.echo("Service name: " + service_metadata["name"])
*_, service_hash = service_metadata["code_uri"].split("//")
public_id = PublicId(
author="valory", name="service", package_hash=service_hash
)
fetch_service_ipfs(public_id)
elif package_type == AGENT:
do_fetch(ctx, public_id, alias)
else:
fetch_service(ctx, public_id, alias)
Expand Down
5 changes: 4 additions & 1 deletion autonomy/cli/helpers/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,10 @@ def _resolve_on_chain_token_id(

try:
metadata = resolve_component_id(
ledger_api=ledger_api, contract_address=contract_address, token_id=token_id
ledger_api=ledger_api,
contract_address=contract_address,
token_id=token_id,
is_service=True,
)
info = get_agent_instances(
ledger_api=ledger_api, chain_type=chain_type, token_id=token_id
Expand Down
18 changes: 18 additions & 0 deletions autonomy/cli/utils/click_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
from typing import Any, Callable, Generator, Optional, Union, cast

import click
from aea.cli.utils.click_utils import PublicIdParameter
from aea.cli.utils.config import get_default_author_from_cli_config
from aea.configurations.data_types import PublicId
from aea.helpers.base import IPFSHash, SimpleId

from autonomy.analyse.abci.app_spec import FSMSpecificationLoader
Expand Down Expand Up @@ -158,3 +160,19 @@ def _validate(_ctx, _param, value): # type: ignore
default=None,
callback=_validate,
)(fn)


class PublicIdOrHashOrTokenId(PublicIdParameter):
"""A click parameter that can be a public id, an IPFS hash or a token id."""

def get_metavar(self, param: Any) -> str:
"""Return the metavar default for this param if it provides one."""
return "PUBLIC_ID_OR_HASH_OR_TOKEN_ID"

def convert(self, value: str, param: Any, ctx: Optional[click.Context]) -> PublicId:
"""Returns integer token id if value is numeric, else try to parse public id or hash."""

if value.isnumeric():
return int(value)

return super().convert(value, param, ctx)
1 change: 1 addition & 0 deletions autonomy/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,4 @@
DEFAULT_DOCKER_IMAGE_AUTHOR = "valory"
OAR_IMAGE = "{image_author}/oar-{agent}:{version}"
ABSTRACT_ROUND_ABCI_SKILL_WITH_HASH = "valory/abstract_round_abci:0.1.0:bafybeigax5gzud6ytq3wypajqwzlfwhpuegcma7q5b7m534kgu7vfmfaaq"
OLAS_DOCS_URL = "https://docs.autonolas.network"
3 changes: 3 additions & 0 deletions docs/advanced_reference/commands/autonomy_deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ autonomy deploy run --build-dir ./abci_build_hAsH

## `autonomy deploy from-token`

!!! warning "Deprecation Warning"
This command will be deprecated in the future. Please use `autonomy fetch` instead.

Run a service deployment minted on-chain protocol.

This command allows to deploy services directly without having the need to explicitly fetch them locally (also known as "one-click deployment"). The command requires the `TOKEN_ID` which can be checked in the {{ autonolas_protocol_registry_dapp }}. See the [mint a service on-chain](../../guides/publish_mint_packages.md) guide for more information.
Expand Down
102 changes: 82 additions & 20 deletions docs/advanced_reference/commands/autonomy_fetch.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,98 @@
Fetch an agent or agent service from a registry.
Fetch an agent or agent service from a registry using its public ID, hash, or token ID.

## Usage
```bash
autonomy fetch [OPTIONS] PUBLIC_ID_OR_HASH
autonomy fetch [OPTIONS] PUBLIC_ID_OR_HASH_OR_TOKEN_ID
```

## Options
```
--remote
```

`--remote`
: To use a remote registry.

```
--local
```
`--local`
: To use a local registry.

```
--alias TEXT
```
`--alias` TEXT
: Provide a local alias for the agent or service.

```
--agent
```
`--agent`
: Specify the package type as agent (default).

```
--service
```
`--service`
: Specify the package type as service.

```
--help
```
`--help`
: Show the help message and exit.

`--use-celo` 
: Use the `Celo` chain profile to find the token with the given token ID.

`--use-base-sepolia` 
: Use the `Base Sepolia` profile to find the token with the given token ID.

`--use-base` 
: Use the `Base` chain profile to find the token with the given token ID.

`--use-optimistic-sepolia` 
: Use the `Optimistic Sepolia` chain profile to find the token with the given token ID.

`--use-optimistic` 
: Use the `Optimistic` chain profile to find the token with the given token ID.

`--use-arbitrum-sepolia` 
: Use the `Arbitrum Sepolia` chain profile to find the token with the given token ID.

`--use-arbitrum-one` 
: Use the `Arbitrum One` chain profile to find the token with the given token ID.

`--use-chiado` 
: Use the `Chiado` chain profile to find the token with the given token ID.

`--use-gnosis` 
: Use the `Gnosis` chain profile to find the token with the given token ID.

`--use-polygon-mumbai` 
: Use the `Polygon Mumbai` chain profile to find the token with the given token ID.

`--use-polygon` 
: Use the `Polygon` chain profile to find the token with the given token ID.

`--use-ethereum`
: Use the `Ethereum` chain profile to find the token with the given token ID.

To use these chain profile, you will have to export an environment variable for RPC in `<CHAIN_NAME>_CHAIN_RPC` format. For example if you want to use `ethereum`, you will have to export `ETHEREUM_CHAIN_RPC` and for `polygon-mumbai` it would be `POLYGON_MUMBAI_CHAIN_RPC`

`--use-custom-chain`
: Use the custom-chain profile to find the token with the given token ID. This profile requires that you define some parameters and [contract addresses](../on_chain_addresses.md) as environment variables (see also the {{ autonolas_protocol }} documentation for more information):

- `CUSTOM_CHAIN_RPC` : RPC endpoint for the custom chain.
- `CUSTOM_CHAIN_ID` : chain ID.
- `CUSTOM_COMPONENT_REGISTRY_ADDRESS` : Custom Component Registry contract address.
- `CUSTOM_AGENT_REGISTRY_ADDRESS` : Custom Agent Registry contract address.
- `CUSTOM_REGISTRIES_MANAGER_ADDRESS` : Custom Registries Manager contract address.
- `CUSTOM_SERVICE_MANAGER_ADDRESS` : Custom Service Manager contract address.
- `CUSTOM_SERVICE_REGISTRY_ADDRESS` : Custom Service Registry contract address.
- `CUSTOM_GNOSIS_SAFE_PROXY_FACTORY_ADDRESS` : Custom Gnosis Safe multisig contract address.
- `CUSTOM_GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_ADDRESS` : Custom Gnosis Safe Same Address Multisig address.
- `CUSTOM_SERVICE_REGISTRY_TOKEN_UTILITY_ADDRESS` : Custom Service Registry Token Utility address.
- `CUSTOM_MULTISEND_ADDRESS` : Custom Multisend address.

!!! note
For L2 chains you are only required to set
- `CUSTOM_SERVICE_MANAGER_ADDRESS`,
- `CUSTOM_SERVICE_REGISTRY_ADDRESS`,
- `CUSTOM_GNOSIS_SAFE_PROXY_FACTORY_ADDRESS`,
- `CUSTOM_GNOSIS_SAFE_SAME_ADDRESS_MULTISIG_ADDRESS` and
- `CUSTOM_MULTISEND_ADDRESS`.

`--use-local`
: Use the local chain profile to find the token with the given token ID. This option requires that you have a local Hardhat node with the required contracts deployed.

!!! note

The chain profile flags are mutually exclusive.


## Examples
Fetch the agent `hello_world` from the local registry and assign the alias `my_hello_world_agent`:
Expand All @@ -57,3 +114,8 @@ Fetch the agent service `hello_world` from a remote registry ([IPFS](https://ipf
```bash
autonomy fetch valory/hello_world:0.1.0:bafybeihl6j7ihkytk4t4ca2ffhctpzydwi6r4a354ubjasttuv2pw4oaci --service --remote
```

Fetch the agent service with the token ID `123` on Gnosis chain:
```bash
autonomy fetch 123 --use-gnosis
```
9 changes: 6 additions & 3 deletions docs/api/cli/fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ Implementation of the 'autonomy fetch' subcommand.
help="Specify the package type as service.",
flag_value=SERVICE,
)
@click.argument("public-id", type=PublicIdParameter(), required=True)
@click.argument("public-id", type=PublicIdOrHashOrTokenId(), required=True)
@chain_selection_flag(
help_string_format="Use {} chain to resolve the token id.")
@click.pass_context
def fetch(click_context: click.Context, public_id: PublicId, alias: str,
package_type: str, registry: str) -> None
def fetch(click_context: click.Context, public_id: Union[PublicId,
int], alias: str,
package_type: str, registry: str, chain_type: str) -> None
```

Fetch an agent from the registry.
Expand Down
30 changes: 30 additions & 0 deletions docs/api/cli/utils/click_utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,33 @@ def image_author_option(fn: Callable) -> Callable

Wrap function with clik option for image-author

<a id="autonomy.cli.utils.click_utils.PublicIdOrHashOrTokenId"></a>

## PublicIdOrHashOrTokenId Objects

```python
class PublicIdOrHashOrTokenId(PublicIdParameter)
```

A click parameter that can be a public id, an IPFS hash or a token id.

<a id="autonomy.cli.utils.click_utils.PublicIdOrHashOrTokenId.get_metavar"></a>

#### get`_`metavar

```python
def get_metavar(param: Any) -> str
```

Return the metavar default for this param if it provides one.

<a id="autonomy.cli.utils.click_utils.PublicIdOrHashOrTokenId.convert"></a>

#### convert

```python
def convert(value: str, param: Any, ctx: Optional[click.Context]) -> PublicId
```

Returns integer token id if value is numeric, else try to parse public id or hash.

Loading

0 comments on commit dc4a095

Please sign in to comment.