Skip to content
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

Refactor (Fetch): Allow fetching from TokenID #2273

Merged
merged 4 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading