├── .example.env ├── .example_agent.env ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── common_checks.yaml │ └── release.yaml ├── .gitignore ├── .gitleaksignore ├── .pylintrc ├── .spelling ├── AUTHORS.md ├── CONTRIBUTING.md ├── DEPLOYMENT.md ├── HISTORY.md ├── LICENSE ├── Makefile ├── README.md ├── SECURITY.md ├── deployment └── Dockerfile ├── docs ├── images │ ├── mech_request_response_flow.png │ ├── mechkit.svg │ └── mechs-logo.png └── index.md ├── healthcheck_service ├── Dockerfile ├── healthcheck.py ├── requirements.txt └── web3 │ └── abi.json ├── make_release.sh ├── mints ├── 01.json ├── 01.png ├── 02.json ├── 02.png ├── 03.json ├── 03.png ├── 04.json ├── 04.png ├── 05.json ├── 05.png ├── 06.json ├── 06.png ├── 07.png ├── 08.json ├── 08.png ├── 09.json ├── 09.png ├── base │ ├── 28.json │ ├── 28.png │ ├── 29.json │ ├── 29.png │ ├── 30.json │ └── 30.png ├── initial │ ├── 01.json │ └── 01.png ├── mapping.txt └── whitelist.txt ├── mkdocs.yml ├── packages ├── __init__.py ├── packages.json └── valory │ ├── agents │ └── mech │ │ └── aea-config.yaml │ ├── connections │ ├── __init__.py │ ├── http_client │ │ ├── README.md │ │ ├── __init__.py │ │ ├── connection.py │ │ ├── connection.yaml │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── test_http_client.py │ └── websocket_client │ │ ├── __init__.py │ │ ├── connection.py │ │ ├── connection.yaml │ │ └── readme.md │ ├── contracts │ ├── __init__.py │ ├── agent_mech │ │ ├── __init__.py │ │ ├── build │ │ │ └── AgentMech.json │ │ ├── contract.py │ │ └── contract.yaml │ ├── agent_registry │ │ ├── __init__.py │ │ ├── build │ │ │ └── AgentRegistry.json │ │ ├── contract.py │ │ ├── contract.yaml │ │ └── tests │ │ │ ├── __init__.py │ │ │ └── test_contract.py │ ├── balance_tracker │ │ ├── __init__.py │ │ ├── build │ │ │ └── BalanceTracker.json │ │ ├── contract.py │ │ └── contract.yaml │ ├── hash_checkpoint │ │ ├── __init__.py │ │ ├── build │ │ │ └── HashCheckpoint.json │ │ ├── contract.py │ │ └── contract.yaml │ └── mech_marketplace │ │ ├── BatchPriorityPassedCheck.sol │ │ ├── __init__.py │ │ ├── build │ │ └── MechMarketplace.json │ │ ├── contract.py │ │ └── contract.yaml │ ├── customs │ └── __init__.py │ ├── protocols │ ├── __init__.py │ ├── acn_data_share │ │ ├── README.md │ │ ├── __init__.py │ │ ├── acn_data_share.proto │ │ ├── acn_data_share_pb2.py │ │ ├── dialogues.py │ │ ├── message.py │ │ ├── protocol.yaml │ │ ├── serialization.py │ │ └── tests │ │ │ ├── test_acn_data_share_dialogues.py │ │ │ └── test_acn_data_share_messages.py │ ├── default │ │ ├── README.md │ │ ├── __init__.py │ │ ├── custom_types.py │ │ ├── default.proto │ │ ├── default_pb2.py │ │ ├── dialogues.py │ │ ├── message.py │ │ ├── protocol.yaml │ │ ├── serialization.py │ │ └── tests │ │ │ ├── test_default_dialogues.py │ │ │ └── test_default_messages.py │ └── websocket_client │ │ ├── README.md │ │ ├── __init__.py │ │ ├── dialogues.py │ │ ├── message.py │ │ ├── protocol.yaml │ │ ├── serialization.py │ │ ├── tests │ │ ├── test_websocket_client_dialogues.py │ │ └── test_websocket_client_messages.py │ │ ├── websocket_client.proto │ │ └── websocket_client_pb2.py │ ├── services │ └── mech │ │ ├── README.md │ │ └── service.yaml │ └── skills │ ├── __init__.py │ ├── contract_subscription │ ├── __init__.py │ ├── behaviours.py │ ├── dialogues.py │ ├── handlers.py │ ├── models.py │ └── skill.yaml │ ├── delivery_rate_abci │ ├── __init__.py │ ├── behaviours.py │ ├── dialogues.py │ ├── fsm_specification.yaml │ ├── handlers.py │ ├── models.py │ ├── payloads.py │ ├── rounds.py │ └── skill.yaml │ ├── mech_abci │ ├── __init__.py │ ├── behaviours.py │ ├── composition.py │ ├── dialogues.py │ ├── fsm_specification.yaml │ ├── handlers.py │ ├── models.py │ └── skill.yaml │ ├── task_execution │ ├── __init__.py │ ├── behaviours.py │ ├── dialogues.py │ ├── handlers.py │ ├── models.py │ ├── skill.yaml │ └── utils │ │ ├── __init__.py │ │ ├── apis.py │ │ ├── benchmarks.py │ │ ├── cost_calculation.py │ │ ├── ipfs.py │ │ └── task.py │ ├── task_submission_abci │ ├── __init__.py │ ├── behaviours.py │ ├── dialogues.py │ ├── fsm_specification.yaml │ ├── handlers.py │ ├── models.py │ ├── payloads.py │ ├── rounds.py │ ├── skill.yaml │ └── tasks.py │ └── websocket_client │ ├── __init__.py │ ├── behaviours.py │ ├── dialogues.py │ ├── handlers.py │ ├── models.py │ └── skill.yaml ├── poetry.lock ├── pyproject.toml ├── run_agent.sh ├── run_service.sh ├── run_tm.sh ├── scripts ├── __init__.py ├── bump.py ├── check_dependencies.py └── check_doc_ipfs_hashes.py ├── setup.cfg └── tox.ini /.example.env: -------------------------------------------------------------------------------- 1 | ON_CHAIN_SERVICE_ID= 2 | NUM_AGENTS= 3 | TOOLS_TO_PACKAGE_HASH= 4 | API_KEYS= 5 | GNOSIS_LEDGER_RPC_0= 6 | GNOSIS_LEDGER_CHAIN_ID= 7 | BASE_LEDGER_RPC_0= 8 | BASE_LEDGER_CHAIN_ID= 9 | DEFAULT_CHAIN_ID= 10 | ALL_PARTICIPANTS= 11 | RESET_PAUSE_DURATION=100 12 | SAFE_CONTRACT_ADDRESS="" 13 | MECH_TO_CONFIG= 14 | MECH_TO_MAX_DELIVERY_RATE= 15 | MECH_MARKETPLACE_ADDRESS= 16 | CHECKPOINT_ADDRESS= 17 | AGENT_REGISTRY_ADDRESS= 18 | -------------------------------------------------------------------------------- /.example_agent.env: -------------------------------------------------------------------------------- 1 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_ON_CHAIN_SERVICE_ID= 2 | SKILL_TASK_EXECUTION_MODELS_PARAMS_ARGS_NUM_AGENTS= 3 | SKILL_TASK_EXECUTION_MODELS_PARAMS_ARGS_TOOLS_TO_PACKAGE_HASH= 4 | SKILL_TASK_EXECUTION_MODELS_PARAMS_ARGS_API_KEYS= 5 | CONNECTION_LEDGER_CONFIG_LEDGER_APIS_GNOSIS_ADDRESS= 6 | CONNECTION_LEDGER_CONFIG_LEDGER_APIS_GNOSIS_CHAIN_ID= 7 | SKILL_TASK_EXECUTION_MODELS_PARAMS_ARGS_DEFAULT_CHAIN_ID= 8 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_DEFAULT_CHAIN_ID= 9 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_SETUP_ALL_PARTICIPANTS= 10 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_RESET_PAUSE_DURATION= 11 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_SETUP_SAFE_CONTRACT_ADDRESS= 12 | SKILL_TASK_EXECUTION_MODELS_PARAMS_ARGS_MECH_TO_CONFIG= 13 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_MECH_TO_CONFIG= 14 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_MECH_TO_MAX_DELIVERY_RATE= 15 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_MECH_MARKETPLACE_ADDRESS= 16 | SKILL_TASK_EXECUTION_MODELS_PARAMS_ARGS_MECH_MARKETPLACE_ADDRESS= 17 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_HASH_CHECKPOINT_ADDRESS= 18 | SKILL_MECH_ABCI_MODELS_PARAMS_ARGS_AGENT_REGISTRY_ADDRESS= 19 | SKILL_MECH_ABCI_MODELS_BENCHMARK_TOOL_ARGS_LOG_DIR= 20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Proposed changes 2 | 3 | Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. 4 | 5 | ## Fixes 6 | 7 | If it fixes a bug or resolves a feature request, be sure to link to that issue. 8 | 9 | ## Types of changes 10 | 11 | What types of changes does your code introduce? (A **breaking change** is a fix or feature that would cause existing functionality and APIs to not work as expected.) 12 | _Put an `x` in the box that applies_ 13 | 14 | - [ ] Non-breaking fix (non-breaking change which fixes an issue) 15 | - [ ] Breaking fix (breaking change which fixes an issue) 16 | - [ ] Non-breaking feature (non-breaking change which adds functionality) 17 | - [ ] Breaking feature (breaking change which adds functionality) 18 | - [ ] Refactor (non-breaking change which changes implementation) 19 | - [ ] Messy (mixture of the above - requires explanation!) 20 | 21 | ## Checklist 22 | 23 | _Put an `x` in the boxes that apply._ 24 | 25 | - [ ] I have read the [CONTRIBUTING](../blob/main/CONTRIBUTING.md) doc 26 | - [ ] I am making a pull request against the `main` branch (left side). Also you should start your branch off our `main`. 27 | - [ ] Lint and unit tests pass locally with my changes 28 | - [ ] I have added tests that prove my fix is effective or that my feature works 29 | 30 | ## Further comments 31 | 32 | If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */keys.json 2 | *private_key.txt 3 | packages/fetchai/ 4 | packages/open_aea/ 5 | packages/valory/connections/abci/ 6 | packages/valory/connections/http_server 7 | packages/valory/connections/ipfs/ 8 | packages/valory/connections/ledger/ 9 | packages/valory/connections/p2p_libp2p_client/ 10 | packages/valory/skills/abstract_abci/ 11 | 12 | packages/valory/contracts/gnosis_safe_proxy_factory/ 13 | packages/valory/contracts/multisend/ 14 | packages/valory/contracts/service_registry/ 15 | packages/valory/contracts/gnosis_safe/ 16 | 17 | packages/valory/protocols/abci 18 | packages/valory/protocols/acn 19 | packages/valory/protocols/contract_api 20 | packages/valory/protocols/http 21 | packages/valory/protocols/ipfs 22 | packages/valory/protocols/ledger_api 23 | packages/valory/protocols/tendermint 24 | /packages/valory/skills/abstract_round_abci 25 | /packages/valory/skills/registration_abci 26 | /packages/valory/skills/reset_pause_abci 27 | /packages/valory/skills/transaction_settlement_abci 28 | 29 | *test_mech.py 30 | 31 | .idea 32 | **/__pycache__/ 33 | *.DS_Store 34 | 35 | .mypy_cache 36 | /.tox/ 37 | 38 | packages/valory/protocols/abci 39 | packages/valory/protocols/acn 40 | packages/valory/protocols/contract_api 41 | packages/valory/protocols/http 42 | packages/valory/protocols/ipfs 43 | packages/valory/protocols/ledger_api 44 | packages/valory/protocols/tendermint 45 | 46 | 47 | .env 48 | .1env 49 | .agentenv 50 | keys.json 51 | leak_report 52 | 53 | agent/ 54 | backup_mech/ 55 | /packages/valory/skills/termination_abci/ 56 | /pip 57 | /tool_test.py 58 | .venv 59 | log 60 | .benchmark-cache 61 | mech/ 62 | mech_service/ 63 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | ignore-patterns=.*_pb2.py,contract_dispatcher.py,test_abci_messages.py,test_tendermint_messages.py 3 | ignore=packages/valory/protocols/abci,packages/valory/connections/abci/gogoproto 4 | 5 | [MESSAGES CONTROL] 6 | disable=C0103,R0801,C0301,C0201,C0204,C0209,W1203,C0302,R1735,R1729,W0511,E0611 7 | 8 | # See here for more options: https://www.codeac.io/documentation/pylint-configuration.html 9 | R1735: use-dict-literal 10 | R1729: use-a-generator 11 | C0103: invalid-name 12 | C0201: consider-iterating-dictionary 13 | W1203: logging-fstring-interpolation 14 | C0204: bad-mcs-classmethod-argument 15 | C0209: consider-using-f-string 16 | C0301: http://pylint-messages.wikidot.com/messages:c0301 > Line too long 17 | C0302: http://pylint-messages.wikidot.com/messages:c0302 > Too many lines in module 18 | R0801: similar lines 19 | E0611: no-name-in-module 20 | 21 | [IMPORTS] 22 | ignored-modules=pandas,numpy,aea_cli_ipfs,compose,multidict,gql,anthropic,tiktoken 23 | 24 | [DESIGN] 25 | # min-public-methods=1 26 | max-public-methods=58 27 | # max-returns=10 28 | # max-bool-expr=7 29 | max-args=6 30 | # max-locals=31 31 | # max-statements=80 32 | max-parents=10 33 | max-branches=36 34 | max-attributes=8 35 | 36 | [REFACTORING] 37 | # max-nested-blocks=6 38 | 39 | [SPELLING] 40 | # uncomment to enable 41 | # spelling-dict=en_US 42 | 43 | # List of comma separated words that should not be checked. 44 | spelling-ignore-words=nocover,pragma,params,noqa,kwargs,str,async,json,boolean,config,pytest,args,url,tx,jsonschema,traceback,api,nosec 45 | 46 | [SIMILARITIES] 47 | 48 | # Minimum lines number of a similarity. 49 | min-similarity-lines=10 50 | 51 | # Ignore comments when computing similarities. 52 | ignore-comments=yes 53 | 54 | # Ignore docstrings when computing similarities. 55 | ignore-docstrings=yes 56 | 57 | # Ignore imports when computing similarities. 58 | ignore-imports=no -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | This is the official list of authors for copyright purposes. 4 | 5 | * 8baller <8ball030@gmail.com> [8ball030](https://github.com/8ball030) 6 | * David Vilela [dvilelaf](https://github.com/dvilelaf) 7 | * David Minarsch [DavidMinarsch](https://github.com/DavidMinarsch) 8 | * Justice Mace [N0xMare](https://github.com/N0xMare) 9 | * Ardian Abazi [0xArdi](https://github.com/0xArdi) 10 | * Jose Moreira Sanchez [jmoreira-valory](https://github.com/jmoreira-valory) 11 | * Adamantios Zaras [Adamantios](https://github.com/Adamantios) 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guide. 2 | 3 | ### Creating A Pull Request 4 | - **Target branch:** double-check the PR is opened against the correct branch before submitting 5 | - **Naming convention:** name of the branch should be in kebab case with not more than two or three words. for example `some-feature` or `feat/some-feature`. 6 | - **Tag relevant ticket/issue:** describe the purpose of the PR properly with relevant ticket/issue. Also attaching a tag such as enhancement/bug/test would help. 7 | - **Include a sensible description:** descriptions help reviewers to understand the purpose and context of the proposed changes. 8 | - **Properly comment non-obvious code** to avoid confusion during the review and enhance maintainability. 9 | - **Code reviews:** two reviewers will be assigned to a PR. 10 | - **Linters:** make sure every linter and checks pass before making a commit. Linters help us maintain a coherent codebase with a common code style, proper API documentation and will help you catch most errors before even running your code. 11 | - **Tests:** the PR needs to contain tests for the newly added code or updated code. (If a commit is made for sole purpose of the review you can add tests later after review is done and PR is ready to merge) 12 | 13 | Also mention potential effects on other branches/code might have from your changes. 14 | 15 | For a clean workflow run checks in following order before making a PR or pushing the code 16 | 17 | - make clean 18 | - make formatters 19 | - make code-checks 20 | - make security 21 | 22 | **Run only if you've modified an AbciApp definition** 23 | - make abci-docstrings 24 | 25 | **Only run following if you have modified a file in `packages/`** 26 | - make generators 27 | - make common-checks-1 28 | 29 | **else run** 30 | - make copyright 31 | 32 | **run this after making a commit** 33 | - make common-checks-2 34 | 35 | 36 | ### Documentation (Docstrings and inline comments) 37 | - Instead of writing just single line of docstring write more informative docstring. If a method is fairly easy to understand one line of docstring will do but if the method has more complex logic it needs be documented properly. 38 | ```python 39 | def some_method(some_arg: Type) -> ReturnType: 40 | """ 41 | This method does something very complex. 42 | 43 | example: 44 | >> a = Type("value") 45 | >> some_method(a) 46 | output 47 | 48 | :param some_arg: describe argument. 49 | :return: value of ReturnType 50 | 51 | optional 52 | - types of exceptions it might raise 53 | """ 54 | ``` 55 | - After editing documentation use `tomte check-spelling` to ensure spelling is correct. 56 | 57 | ### Some more suggestions to help you write better code. 58 | 59 | - Always use guard clauses where possible. This leads to more efficient code that has less nesting and is much easier to read. 60 | 61 | 62 | ### Agent development 63 | 64 | You can find several general recommendations in the **Considerations to Develop FSM Apps** section in our documentation [here](https://docs.autonolas.network/open-autonomy/key_concepts/fsm_app_introduction/). -------------------------------------------------------------------------------- /DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # DEPLOYMENT PROCESS 2 | 3 | use make release command: 4 | it creates tag, pushes to github and makes release that triggers deployment process 5 | release environment determined by suffix format `()` like `release v0.11 (prod)` 6 | 7 | list of environments supported is at release.yaml file 8 | 9 | to use gommand you have to install gh command locally, and login with it 10 | 11 | `./make_release.sh [OPTIONAL DESCRIPTION]` 12 | 13 | example: 14 | `./make_release.sh 0.11 prod 'some description'` 15 | 16 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # Release History - `mech` 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | clean: clean-build clean-pyc clean-test clean-docs 3 | 4 | .PHONY: clean-build 5 | clean-build: 6 | rm -fr build/ 7 | rm -fr dist/ 8 | rm -fr .eggs/ 9 | rm -fr pip-wheel-metadata 10 | find . -name '*.egg-info' -exec rm -fr {} + 11 | find . -name '*.egg' -exec rm -fr {} + 12 | find . -name '*.svn' -exec rm -fr {} + 13 | find . -type d -name __pycache__ -exec rm -rv {} + 14 | rm -fr .idea .history 15 | rm -fr venv 16 | 17 | .PHONY: clean-docs 18 | clean-docs: 19 | rm -fr site/ 20 | 21 | .PHONY: clean-pyc 22 | clean-pyc: 23 | find . -name '*.pyc' -exec rm -f {} + 24 | find . -name '*.pyo' -exec rm -f {} + 25 | find . -name '*~' -exec rm -f {} + 26 | find . -name '__pycache__' -exec rm -fr {} + 27 | find . -name '.DS_Store' -exec rm -fr {} + 28 | 29 | .PHONY: clean-test 30 | clean-test: clean-cache 31 | rm -fr .tox/ 32 | rm -f .coverage 33 | find . -name ".coverage*" -not -name ".coveragerc" -exec rm -fr "{}" \; 34 | rm -fr coverage.xml 35 | rm -fr htmlcov/ 36 | find . -name 'log.txt' -exec rm -fr {} + 37 | find . -name 'log.*.txt' -exec rm -fr {} + 38 | rm -rf leak_report 39 | 40 | # removes various cache files 41 | .PHONY: clean-cache 42 | clean-cache: 43 | find . -type d -name .hypothesis -prune -exec rm -rf {} \; 44 | rm -fr .pytest_cache 45 | rm -fr .mypy_cache/ 46 | 47 | # isort: fix import orders 48 | # black: format files according to the pep standards 49 | .PHONY: format 50 | format: 51 | tomte format-code 52 | 53 | # black-check: check code style 54 | # isort-check: check for import order 55 | # flake8: wrapper around various code checks, https://flake8.pycqa.org/en/latest/user/error-codes.html 56 | # mypy: static type checker 57 | # pylint: code analysis for code smells and refactoring suggestions 58 | # darglint: docstring linter 59 | .PHONY: code-checks 60 | code-checks: 61 | tomte check-code 62 | 63 | # safety: checks dependencies for known security vulnerabilities 64 | # bandit: security linter 65 | # gitleaks: checks for sensitive information 66 | .PHONY: security 67 | security: 68 | tomte check-security 69 | gitleaks detect --report-format json --report-path leak_report 70 | 71 | # generate abci docstrings 72 | # update copyright headers 73 | # generate latest hashes for updated packages 74 | .PHONY: generators 75 | generators: clean-cache fix-abci-app-specs 76 | tox -e abci-docstrings 77 | tomte format-copyright --author valory --exclude-part abci --exclude-part http_client --exclude-part ipfs --exclude-part ledger --exclude-part p2p_libp2p_client --exclude-part gnosis_safe --exclude-part gnosis_safe_proxy_factory --exclude-part multisend --exclude-part service_registry --exclude-part protocols --exclude-part abstract_abci --exclude-part abstract_round_abci --exclude-part registration_abci --exclude-part reset_pause_abci --exclude-part termination_abci --exclude-part transaction_settlement_abci --exclude-part websocket_client --exclude-part contract_subscription 78 | autonomy packages lock 79 | tox -e fix-doc-hashes 80 | 81 | .PHONY: common-checks-1 82 | common-checks-1: 83 | tomte check-copyright --author valory --exclude-part abci --exclude-part http_client --exclude-part ipfs --exclude-part ledger --exclude-part p2p_libp2p_client --exclude-part gnosis_safe --exclude-part gnosis_safe_proxy_factory --exclude-part multisend --exclude-part service_registry --exclude-part protocols --exclude-part abstract_abci --exclude-part abstract_round_abci --exclude-part registration_abci --exclude-part reset_pause_abci --exclude-part termination_abci --exclude-part transaction_settlement_abci --exclude-part websocket_client --exclude-part contract_subscription 84 | tomte check-doc-links 85 | tox -p -e check-hash -e check-packages -e check-doc-hashes -e analyse-service 86 | 87 | .PHONY: common-checks-2 88 | common-checks-2: 89 | tox -e check-abci-docstrings 90 | tox -e check-abciapp-specs 91 | tox -e check-handlers 92 | 93 | .PHONY: all-checks 94 | all-checks: clean format code-checks security generators common-checks-1 common-checks-2 95 | 96 | .PHONY: fix-abci-app-specs 97 | fix-abci-app-specs: 98 | autonomy analyse fsm-specs --update --app-class MechAbciApp --package packages/valory/skills/mech_abci 99 | echo "Successfully validated abcis!" 100 | 101 | protolint_install: 102 | mkdir protolint_install 103 | cd protolint_install && \ 104 | wget https://github.com/yoheimuta/protolint/releases/download/v0.27.0/protolint_0.27.0_Linux_x86_64.tar.gz && \ 105 | tar -xvf protolint_0.27.0_Linux_x86_64.tar.gz && \ 106 | sudo mv protolint /usr/local/bin/protolint 107 | sudo rm -rf protolint_install -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | This document outlines security procedures and general policies for the `mech` project. 4 | 5 | ## Supported Versions 6 | 7 | The following table shows which versions of `mech` are currently being supported with security updates. 8 | 9 | | Version | Supported | 10 | |---------|--------------------| 11 | | `n/a` | :white_check_mark: | 12 | | `n/a` | :x: | 13 | 14 | ## Reporting a Vulnerability 15 | 16 | The `mech` team and community take all security bugs in `mech` seriously. Thank you for improving the security of `mech`. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions. 17 | 18 | Report security bugs by emailing `info@valory.xyz`. 19 | 20 | The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavour to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. 21 | 22 | Report security bugs in third-party modules to the person or team maintaining the module. 23 | 24 | ## Disclosure Policy 25 | 26 | When the security team receives a security bug report, they will assign it to a primary handler. This person will coordinate the fix and release process, involving the following steps: 27 | 28 | - Confirm the problem and determine the affected versions. 29 | - Audit code to find any potential similar problems. 30 | - Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible to PyPI. 31 | 32 | ## Comments on this Policy 33 | 34 | If you have suggestions on how this process could be improved please submit a pull request. 35 | -------------------------------------------------------------------------------- /deployment/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG AUTONOMY_IMAGE_VERSION="latest" 2 | ARG AUTONOMY_IMAGE_NAME="valory/open-autonomy" 3 | FROM ${AUTONOMY_IMAGE_NAME}:${AUTONOMY_IMAGE_VERSION} 4 | 5 | ARG AEA_AGENT 6 | ARG AUTHOR 7 | ARG EXTRA_DEPENDENCIES 8 | 9 | RUN aea init --reset --remote --ipfs --author ${AUTHOR} 10 | 11 | WORKDIR /root 12 | 13 | RUN AEA_AGENT=${AEA_AGENT} EXTRA_DEPENDENCIES=${EXTRA_DEPENDENCIES} bash /root/scripts/install.sh 14 | 15 | RUN pip uninstall -y opencv-python || echo "opencv-python not installed" 16 | RUN pip uninstall opencv-python-headless || echo "opencv-python-headless not installed" 17 | 18 | # re-install headless opencv 19 | RUN pip install opencv-python-headless==4.10.0.84 20 | 21 | CMD ["/root/scripts/start.sh"] 22 | 23 | HEALTHCHECK --interval=3s --timeout=600s --retries=600 CMD netstat -ltn | grep -c 26658 > /dev/null; if [ 0 != $? ]; then exit 1; fi; 24 | -------------------------------------------------------------------------------- /docs/images/mech_request_response_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/docs/images/mech_request_response_flow.png -------------------------------------------------------------------------------- /docs/images/mechkit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/images/mechs-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/docs/images/mechs-logo.png -------------------------------------------------------------------------------- /healthcheck_service/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Python 3.10 image as the base image 2 | FROM python:3.10-slim 3 | 4 | # Set the working directory inside the container 5 | WORKDIR /app 6 | 7 | # Copy the Python script into the container 8 | COPY . /app/ 9 | 10 | RUN pip install -r requirements.txt 11 | 12 | # Expose the port on which the health check server will run 13 | EXPOSE 8080 14 | 15 | # Run the Python script when the container starts 16 | CMD ["python", "healthcheck.py"] 17 | -------------------------------------------------------------------------------- /healthcheck_service/requirements.txt: -------------------------------------------------------------------------------- 1 | web3==6.1.0 2 | -------------------------------------------------------------------------------- /make_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export VERSION=$1 4 | export ENV=$2 5 | export DESCRIPTION=$3 6 | 7 | if [ -z $VERSION ]; then 8 | echo no version 9 | exit 1 10 | fi 11 | 12 | if [ -z $ENV ]; then 13 | echo no env 14 | exit 1 15 | fi 16 | 17 | export TAG_NAME=release_${VERSION}_${ENV} 18 | 19 | echo make tag $TAG_NAME ... 20 | git tag $TAG_NAME 21 | echo push tag $TAG_NAME ... 22 | git push origin $TAG_NAME 23 | echo create release $TAG_NAME ... 24 | 25 | if gh release create $TAG_NAME --title "Release $VERSION ($ENV)" --notes "$DESCRIPTION"; then 26 | echo done 27 | else 28 | echo Error! 29 | fi 30 | -------------------------------------------------------------------------------- /mints/01.json: -------------------------------------------------------------------------------- 1 | {"name":"contract/valory/agent_mech:0.1.0","description":"agent mech contract","code_uri":"ipfs://bafybeidrhnm7xfcbxaxyl26azjvd6ur7xkcr5pdvpbpk5tddpyma7c74xu","image":"ipfs://bafybeid7a6fpnabo5aphu6prjfte4y3tsrhjbce6pdtalu4hu6leoeia64","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/01.png -------------------------------------------------------------------------------- /mints/02.json: -------------------------------------------------------------------------------- 1 | {"name":"skill/valory/contract_subscription:0.1.0","description":"A simple skill to subscribe to events on a particular contract using the websocket connection.","code_uri":"ipfs://bafybeif3hkpgbzuoxsbqxnd752qkvk3onytltrufnyrphnqbi62si4mdhy","image":"ipfs://bafybeifm6f6xrdc2bgaolzxi4wavqby2il3r3loa5bb3iff3vugap7ogum","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/02.png -------------------------------------------------------------------------------- /mints/03.json: -------------------------------------------------------------------------------- 1 | {"name":"skill/valory/multiplexer_abci:0.1.0","description":"An abci skill that implements decision logic for the mech.","code_uri":"ipfs://bafybeiatryharf4xsxouas7dzofcjedxa3sx3ifm5wfzf5z5hgz3jps474","image":"ipfs://bafybeicyxvpxcn2uypvftty6hm6ivvdzcgvmvfls3gp3i72jedlpz26nbi","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/03.png -------------------------------------------------------------------------------- /mints/04.json: -------------------------------------------------------------------------------- 1 | {"name":"skill/valory/task_execution_abci:0.1.0","description":"An abci skill that implements task execution and transaction preparation for the mech.","code_uri":"ipfs://bafybeiagkhgyrm3lbdmiufbb6fe2iuad6yvuavk4ksiy2tiasocv445ala","image":"ipfs://bafybeihvarl2rn7n7izckdtakwqar6moyi7x7ttmgkatgzfejgqsighdpe","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/04.png -------------------------------------------------------------------------------- /mints/05.json: -------------------------------------------------------------------------------- 1 | {"name":"skill/valory/mech_abci:0.1.0","description":"The chained abci skill for the mech.","code_uri":"ipfs://bafybeifmlpw26kjfhpb36arpm242qtriuj63fd2pxvfpsrogytowxnarwa","image":"ipfs://bafybeigq7jtdl7737jevdhhlnnjgbegk5dvsr5eg7ts6l4cxqesqewlmea","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/05.png -------------------------------------------------------------------------------- /mints/06.json: -------------------------------------------------------------------------------- 1 | {"name":"agent/valory/mech:0.1.0","description":"A mech agent","code_uri":"ipfs://bafybeia3ja3njzgxseefhizeypzvi5epoe2467khymqywktcgwid5fljx4","image":"ipfs://bafybeifgj3kackzfoq4fxjiuousm6epgwx7jbc3n2gjwzjgvtbbz7fc3su","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/06.png -------------------------------------------------------------------------------- /mints/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/07.png -------------------------------------------------------------------------------- /mints/08.json: -------------------------------------------------------------------------------- 1 | {"name":"custom/valory/native_transfer_request:0.1.0","description":"A tool to prepare a native transfer request.","code_uri":"ipfs://bafybeihkxzwmsggjgfgfsuy26zwnwxk4wchtljbtwd42arqal7k756zjba","image":"ipfs://bafybeih5xhgdyyyiz2apczfndvv24vf6brojad6qthiri5c5mppz5ql5au","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/08.png -------------------------------------------------------------------------------- /mints/09.json: -------------------------------------------------------------------------------- 1 | {"name":"custom/valory/openai_request:0.1.0","description":"A tool that runs a prompt against the OpenAI API.","code_uri":"ipfs://bafybeicnwhf67ywtrjwjh2dn2ocn57xtkgch4xs6hpmmnlma5vstmjf42i","image":"ipfs://bafybeic7rms6tovxdbcwcoxxor4jtddpdkyrhad5h4czqchngw2b6dxvwm","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/09.png -------------------------------------------------------------------------------- /mints/base/28.json: -------------------------------------------------------------------------------- 1 | {"name":"protocol/valory/default:1.0.0","description":"A protocol for exchanging any bytes message.","code_uri":"ipfs://bafybeiecmut3235aen7wxukllv424f3dysvvlgfmn562kzdunc5hdj3hxu","image":"ipfs://bafybeib3sh5jgymk6duzsz2xiidxqqpl667qx6qzetpisgb3r3rs2zvtnu","attributes":[{"trait_type":"version","value":"1.0.0"}]} -------------------------------------------------------------------------------- /mints/base/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/base/28.png -------------------------------------------------------------------------------- /mints/base/29.json: -------------------------------------------------------------------------------- 1 | {"name":"protocol/valory/acn_data_share:0.1.0","description":"A protocol for sharing raw data using ACN.","code_uri":"ipfs://bafybeieyixetwvz767zekhvg7r6etumyanzys6xbalx2brrfswybinnlhi","image":"ipfs://bafybeieg5uvessvnkfkr4kf4tn3qqk6in7gf4iyhub4kbd34rm6dght7ie","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/base/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/base/29.png -------------------------------------------------------------------------------- /mints/base/30.json: -------------------------------------------------------------------------------- 1 | {"name":"connection/valory/websocket_client:0.1.0","description":"Simple Websocket Client to allow the agent to interact with a Websocket Server.","code_uri":"ipfs://bafybeicz53kzs5uvyiod2azntl76zwgmpgr22ven4wl5fnwt2m546j3wsu","image":"ipfs://bafybeifg6ws4kbq6leelcj3pjpgckr2ioycmuwpfclb42u3rn5kiw7axr4","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/base/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/base/30.png -------------------------------------------------------------------------------- /mints/initial/01.json: -------------------------------------------------------------------------------- 1 | {"name":"service/valory/mech:0.1.0","description":"The mech executes AI tasks requested on-chain and delivers the results to the requester.","code_uri":"ipfs://bafybeidn3pgtofyom7mwusjm73ydy2librqcofrxwqhxajyh2rrdvlyngy","image":"ipfs://bafybeidzpenez565d7vp7jexfrwisa2wijzx6vwcffli57buznyyqkrceq","attributes":[{"trait_type":"version","value":"0.1.0"}]} -------------------------------------------------------------------------------- /mints/initial/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/mints/initial/01.png -------------------------------------------------------------------------------- /mints/mapping.txt: -------------------------------------------------------------------------------- 1 | token_id-"component_id" 2 | 78-"protocol/valory/default/1.0.0" 3 | 79-"protocol/valory/acn_data_share/0.1.0" 4 | 80-"connection/valory/websocket_client/0.1.0" 5 | 81-"contract/valory/agent_mech/0.1.0" 6 | 82-"skill/valory/contract_subscription/0.1.0" 7 | 83-"skill/valory/multiplexer_abci/0.1.0" 8 | 84-"skill/valory/task_execution_abci/0.1.0" 9 | 85-"skill/valory/mech_abci/0.1.0" 10 | 11 | --- 12 | token_id-"agent_id" 13 | 9-"agent/valory/mech/0.1.0" 14 | 26-"agent/valory/mech/0.1.0" 15 | 29-"agent/valory/mech/0.1.0" (mech extension) 16 | --- 17 | token_id-"service_id" (Gnosis) 18 | 1-3-"service/valory/mech/0.1.0" 19 | token_id-"service_id" (Ethereum) 20 | 21-"service/valory/mech/0.1.0" 21 | -------------------------------------------------------------------------------- /mints/whitelist.txt: -------------------------------------------------------------------------------- 1 | contract/valory/agent_registry/0.1.0 -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: product/mechkit #Required format to work with monorepo including a specific route in the address. 2 | site_url: https://docs.autonolas.network/product/mechkit/ 3 | site_description: Autonolas MechKit developer documentation 4 | repo_url: https://github.com/valory-xyz/agent-academy-1 5 | site_author: developer@valory.xyz 6 | edit_uri: "" 7 | copyright: Copyright © 2021 - 2023 Valory AG 8 | 9 | 10 | strict: true 11 | 12 | 13 | theme: 14 | name: 'material' 15 | language: en 16 | favicon: images/favicon.ico 17 | logo: images/logo.svg 18 | icon: 19 | admonition: 20 | abstract: material/book-open-variant 21 | features: 22 | - navigation.indexes 23 | - navigation.top 24 | - navigation.tracking 25 | - navigation.footer 26 | - search.highlight 27 | - search.share 28 | - search.suggest 29 | - content.code.copy 30 | - content.code.annotate 31 | - content.tabs.link 32 | 33 | 34 | extra_css: 35 | - stylesheets/extra.css 36 | 37 | 38 | nav: 39 | - MechKit: 'index.md' 40 | 41 | 42 | plugins: 43 | - macros: 44 | on_error_fail: true 45 | on_undefined: strict 46 | - search 47 | 48 | 49 | markdown_extensions: 50 | - admonition 51 | - attr_list 52 | - pymdownx.details 53 | - pymdownx.keys 54 | - pymdownx.superfences 55 | - pymdownx.tabbed: 56 | alternate_style: true 57 | - pymdownx.highlight 58 | - pymdownx.emoji: 59 | emoji_index: !!python/name:material.extensions.emoji.twemoji 60 | emoji_generator: !!python/name:material.extensions.emoji.to_svg 61 | - pymdownx.arithmatex: 62 | generic: true 63 | - pymdownx.superfences: 64 | custom_fences: 65 | - name: mermaid 66 | class: mermaid 67 | format: !!python/name:pymdownx.superfences.fence_code_format 68 | - def_list 69 | - md_in_html 70 | - toc: 71 | title: On this page 72 | toc_depth: 3 73 | 74 | 75 | extra: 76 | open_aea: '[Open AEA](https://github.com/valory-xyz/open-aea)' 77 | open_aea_doc: '[Open AEA documentation](https://open-aea.docs.autonolas.tech)' 78 | open_aea_api: '[Open AEA API](https://open-aea.docs.autonolas.tech/api)' 79 | fsm_app: 'FSM App' 80 | open_autonomy: '[Open Autonomy](https://github.com/valory-xyz/open-autonomy)' 81 | open_autonomy_api: '[Open Autonomy API](https://docs.autonolas.network)' 82 | open_aea_repository: '[Open AEA repository](https://github.com/valory-xyz/open-aea)' 83 | open_autonomy_repository: '[Open Autonomy repository](https://github.com/valory-xyz/open-autonomy)' 84 | autonolas_whitepaper: '[Autonolas Whitepaper](https://www.autonolas.network/documents/whitepaper/Whitepaper%20v1.0.pdf)' 85 | autonolas_protocol: '[Autonolas Protocol](https://docs.autonolas.network/protocol)' 86 | autonolas_protocol_registry_dapp_link: 'https://registry.olas.network' 87 | autonolas_protocol_registry_dapp: '[Autonolas Protocol web app](https://registry.olas.network)' 88 | autonolas_protocol_tokenomics_dapp: '[Autonolas Tokenomics web app](https://tokenomics.olas.network)' 89 | social: 90 | - icon: fontawesome/brands/twitter 91 | link: https://twitter.com/autonolas 92 | name: Autonolas on Twitter 93 | - icon: fontawesome/brands/discord 94 | link: https://discord.com/invite/z2PT65jKqQ 95 | name: Autonolas on Discord 96 | - icon: fontawesome/brands/github 97 | link: https://github.com/valory-xyz 98 | name: Autonolas on GitHub 99 | 100 | 101 | extra_javascript: 102 | - https://unpkg.com/mermaid@8.10.1/dist/mermaid.min.js 103 | - javascripts/mathjax.js 104 | - https://polyfill.io/v3/polyfill.min.js?features=es6 105 | - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js 106 | -------------------------------------------------------------------------------- /packages/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Valory packages.""" 21 | -------------------------------------------------------------------------------- /packages/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "protocol/valory/acn_data_share/0.1.0": "bafybeih5ydonnvrwvy2ygfqgfabkr47s4yw3uqxztmwyfprulwfsoe7ipq", 4 | "protocol/valory/websocket_client/0.1.0": "bafybeifjk254sy65rna2k32kynzenutujwqndap2r222afvr3zezi27mx4", 5 | "contract/valory/agent_mech/0.1.0": "bafybeibjlxgwwqodubwy3mhstnjqjsyat4ray32xgkkv5adysjwz5mzcau", 6 | "contract/valory/agent_registry/0.1.0": "bafybeiarzhzs2wm2sl47qg37tqoc3qok54enxlcj6vx3hldozg537uslnq", 7 | "contract/valory/hash_checkpoint/0.1.0": "bafybeihyzjja65zrhjdgm5p4oecjm7ijrs6aur2ux2fkmfgfiurautm2da", 8 | "contract/valory/mech_marketplace/0.1.0": "bafybeicx4aw7kbp4zxbdsafshkagzb53ji5m2ak537on2ryrzpnoxs2jkq", 9 | "contract/valory/balance_tracker/0.1.0": "bafybeiceepsgckl7x5ljvkv4ztg7ubc3re6d4xzan6msywuifao3nxyyq4", 10 | "connection/valory/websocket_client/0.1.0": "bafybeic4ag3gqc7kd3k2o3pucddj2odck5yrfbgmwh5veqny7zao5qayli", 11 | "skill/valory/contract_subscription/0.1.0": "bafybeiefuemlp75obgpxrp6iuleb3hn6vcviwh5oetk5djbuprf4xsmgjy", 12 | "skill/valory/mech_abci/0.1.0": "bafybeie2xstvcujzo7frn227a5thsbxv22prngc2nbzxbwms2hwkrhk5ty", 13 | "skill/valory/task_submission_abci/0.1.0": "bafybeib2v5zeeu4cwnxt37avxysdxgqh4gmotcvz6wthepqnvupafbpy7e", 14 | "skill/valory/task_execution/0.1.0": "bafybeigbueebww7nbja5jo3x7o3524e26hhfnmvxrprpbmnvjffcxm7k54", 15 | "skill/valory/websocket_client/0.1.0": "bafybeif7rrvsu6z4evqkhblxj3u6wwv2eqou576hgkyoehxuj7cntw7o2m", 16 | "skill/valory/delivery_rate_abci/0.1.0": "bafybeiakedzpbl2v4ajpovpzrgpigwbzfqlwjyuucvexs2kckhlh7x3mce", 17 | "agent/valory/mech/0.1.0": "bafybeiesbbt467twifwjvoa5kay54y7tiizevvuaybqhmhtgvtjswer2t4", 18 | "service/valory/mech/0.1.0": "bafybeid5ub7tdchcpxpxl3mhf2ded5iwo4k7fo52gtcvu2sm5kdj2arqya" 19 | }, 20 | "third_party": { 21 | "protocol/valory/default/1.0.0": "bafybeifqcqy5hfbnd7fjv4mqdjrtujh2vx3p2xhe33y67zoxa6ph7wdpaq", 22 | "protocol/open_aea/signing/1.0.0": "bafybeig2d36zxy65vd7fwhs7scotuktydcarm74aprmrb5nioiymr3yixm", 23 | "protocol/valory/abci/0.1.0": "bafybeiatodhboj6a3p35x4f4b342lzk6ckxpud23awnqbxwjeon3k5y36u", 24 | "protocol/valory/contract_api/1.0.0": "bafybeid247uig2ekykdumh7ewhp2cdq7rchaeqjj6e7urx35zfpdl5zrn4", 25 | "protocol/valory/http/1.0.0": "bafybeih4azmfwtamdbkhztkm4xitep3gx6tfdnoz6tvllmaqnhu3klejfa", 26 | "protocol/valory/ledger_api/1.0.0": "bafybeihmqzcbj6t7vxz2aehd5726ofnzsfjs5cwlf42ro4tn6i34cbfrc4", 27 | "protocol/valory/acn/1.1.0": "bafybeic6h55ov5lrzbah6fate54c4u6spopcexxspw3abotbmffabfddeu", 28 | "protocol/valory/ipfs/0.1.0": "bafybeifi2nri7sprmkez4rqzwb4lnu6peoy3bax5k6asf6k5ms7kmjpmkq", 29 | "protocol/valory/tendermint/0.1.0": "bafybeigydrbfrlmr4f7shbtqx44kvmbg22im27mxdap2e3m5tkti6t445y", 30 | "contract/valory/service_registry/0.1.0": "bafybeibuq4p66jdpnrq7viz4zylydu3zneteukfy3gwdgp273vptnq3dvi", 31 | "contract/valory/gnosis_safe_proxy_factory/0.1.0": "bafybeihx4j2k4gwst4qswkgqlcsr3zmplroc7zjwuqo3ttngjq3fwyumpu", 32 | "contract/valory/gnosis_safe/0.1.0": "bafybeidw3uxuxyp3lso5mh43nhauzvra4jabnuk34bkqd6mrv4ojz37nui", 33 | "contract/valory/multisend/0.1.0": "bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y", 34 | "connection/valory/http_client/0.23.0": "bafybeid5ffvg76ejjoese7brj5ji3lx66cu7p2ixfwflpo6rgofkypfd7y", 35 | "connection/valory/abci/0.1.0": "bafybeifu42n4vz3bid3nkbr7sea6d3pfmxx7rzctr37ovafmbpyq6vplkm", 36 | "connection/valory/ipfs/0.1.0": "bafybeigjspoceazd5roxo4pcqcgyu3ozixkdoc44domwcaumt2zwoz2x3m", 37 | "connection/valory/ledger/0.19.0": "bafybeibiayfscw4badpr545f47hsvc2r5lgfpgzib5q4h4u6kkosdsytby", 38 | "connection/valory/p2p_libp2p_client/0.1.0": "bafybeic6ayusdwy4dks75njwk32ac7ur7salgllwf4fdc34ue5z2k5iz4q", 39 | "connection/valory/http_server/0.22.0": "bafybeic3jpkum7g6qo6x6vdrmvvhj7vqw7ec2op72uc3yfhmnlp5hn3joy", 40 | "skill/valory/transaction_settlement_abci/0.1.0": "bafybeicvfbyp4lfqcohmvw6ozlvsbp2eugl2wxqxsdpp36ro7bk3waxjky", 41 | "skill/valory/termination_abci/0.1.0": "bafybeig4stz7s6phndruvrgqptbc62ue2filttj4wbnempkur5ybso5edu", 42 | "skill/valory/abstract_round_abci/0.1.0": "bafybeiba3zhx5drsf7ailfboeuvwykocmkffs2j426u4q7d4erig67lyhm", 43 | "skill/valory/reset_pause_abci/0.1.0": "bafybeidhqvc4cl6alvkql5kadiv7snudl7o2ctfqbmhrihtejm3zhkmbby", 44 | "skill/valory/registration_abci/0.1.0": "bafybeigp2g6uhhgjlkqyhjlk4abfjuecmulnwlki6acbpfu45thslqujlu", 45 | "skill/valory/abstract_abci/0.1.0": "bafybeifv2dynqo3o57nr6jntsvdkduytz3f6i52csv2bjwrr4qhi4mkm7i" 46 | } 47 | } -------------------------------------------------------------------------------- /packages/valory/connections/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # ------------------------------------------------------------------------------ 4 | # 5 | # Copyright 2021-2023 Valory AG 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | -------------------------------------------------------------------------------- /packages/valory/connections/http_client/README.md: -------------------------------------------------------------------------------- 1 | # HTTP client connection 2 | 3 | This connection wraps an HTTP client. It consumes messages from the AEA, translates them into HTTP requests, then sends the HTTP response as a message back to the AEA. 4 | 5 | ## Usage 6 | 7 | First, add the connection to your AEA project (`aea add connection valory/http_client:0.23.0`). Then, update the `config` in `connection.yaml` by providing a `host` and `port` of the server. 8 | -------------------------------------------------------------------------------- /packages/valory/connections/http_client/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2021-2022 Valory AG 5 | # Copyright 2018-2020 Fetch.AI Limited 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """Implementation of the HTTP_client connection and channel.""" 22 | -------------------------------------------------------------------------------- /packages/valory/connections/http_client/connection.yaml: -------------------------------------------------------------------------------- 1 | name: http_client 2 | author: valory 3 | version: 0.23.0 4 | type: connection 5 | description: The HTTP_client connection that wraps a web-based client connecting to 6 | a RESTful API specification. 7 | license: Apache-2.0 8 | aea_version: '>=1.0.0, <2.0.0' 9 | fingerprint: 10 | README.md: bafybeigqhgnqpgi22gfxqvsgbmrjdkrklpgu2m4px6zwb7bhvy3gkkyetu 11 | __init__.py: bafybeieh7rjtg22qukaznxzhadreuxhyfeamj3lcluxtcbfiexktue2nim 12 | connection.py: bafybeiephqitgfzzautuegh2fpp5yezglkri4gj646glu3erokbfgsupzu 13 | tests/__init__.py: bafybeiak7fbussk7n5zl2o4trefz7whvc3ae3k2vrryhb6cettb2qskjau 14 | tests/test_http_client.py: bafybeic4k7g6k4y5axh3pgpz25j7drghqxl5gblczux2sxtms54ududepe 15 | fingerprint_ignore_patterns: [] 16 | connections: [] 17 | protocols: 18 | - valory/http:1.0.0:bafybeih4azmfwtamdbkhztkm4xitep3gx6tfdnoz6tvllmaqnhu3klejfa 19 | class_name: HTTPClientConnection 20 | config: 21 | host: 127.0.0.1 22 | port: 8000 23 | timeout: 300 24 | excluded_protocols: [] 25 | restricted_to_protocols: 26 | - valory/http:1.0.0 27 | dependencies: 28 | aiohttp: 29 | version: <4.0.0,>=3.8.5 30 | certifi: {} 31 | multidict: {} 32 | is_abstract: false 33 | -------------------------------------------------------------------------------- /packages/valory/connections/http_client/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2021-2022 Valory AG 5 | # Copyright 2018-2020 Fetch.AI Limited 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """Tests package for valory/http_client connection.""" 22 | -------------------------------------------------------------------------------- /packages/valory/connections/websocket_client/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # Copyright 2023 eightballer 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """Scaffold of a connection.""" 22 | -------------------------------------------------------------------------------- /packages/valory/connections/websocket_client/connection.yaml: -------------------------------------------------------------------------------- 1 | name: websocket_client 2 | author: valory 3 | version: 0.1.0 4 | type: connection 5 | description: Simple Websocket Client to allow the agent to interact with a Websocket 6 | Server. 7 | license: Apache-2.0 8 | aea_version: '>=1.0.0, <2.0.0' 9 | fingerprint: 10 | __init__.py: bafybeicyrebbic2h3ytyxeg776zelg2bpshcepnkm4qc5oypqqqfq3sqmq 11 | connection.py: bafybeiakisvetjqs3qqlpdo5asm45gfygx35lw7cciypaneyqieyf6ul34 12 | readme.md: bafybeihg5yfzgqvg5ngy7r2o5tfeqnelx2ffxw4po5hmheqjfhumpmxpoq 13 | fingerprint_ignore_patterns: [] 14 | connections: [] 15 | protocols: 16 | - valory/websocket_client:0.1.0:bafybeifjk254sy65rna2k32kynzenutujwqndap2r222afvr3zezi27mx4 17 | class_name: WebSocketClient 18 | config: 19 | endpoint: null 20 | target_skill_id: null 21 | excluded_protocols: [] 22 | restricted_to_protocols: [] 23 | dependencies: 24 | websocket_client: 25 | version: <1,>=0.32.0 26 | is_abstract: false 27 | cert_requests: [] 28 | -------------------------------------------------------------------------------- /packages/valory/connections/websocket_client/readme.md: -------------------------------------------------------------------------------- 1 | # Scaffold connection 2 | The scaffold connection acts as a boilerplate for a newly created connection. 3 | 4 | ## Usage 5 | Create a scaffold connection with the `aea scaffold connection {NAME}` command and implement your own connection. 6 | -------------------------------------------------------------------------------- /packages/valory/contracts/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # ------------------------------------------------------------------------------ 4 | # 5 | # Copyright 2021-2023 Valory AG 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | -------------------------------------------------------------------------------- /packages/valory/contracts/agent_mech/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the support resources for the agent mech contract.""" 21 | -------------------------------------------------------------------------------- /packages/valory/contracts/agent_mech/contract.yaml: -------------------------------------------------------------------------------- 1 | name: agent_mech 2 | author: valory 3 | version: 0.1.0 4 | type: contract 5 | description: agent mech contract 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | __init__.py: bafybeigpq5lxfj2aza6ok3fjuywtdafelkbvoqwaits7regfbgu4oynmku 10 | build/AgentMech.json: bafybeigtikt7m5nyhlsxscgfciejkfvot56a7gbwe2og6dziwzvgkvo7hq 11 | contract.py: bafybeigbe2x57etfsqkf5xocgeaejid2tpyoc7xp6zud55mey7odnpn7jy 12 | fingerprint_ignore_patterns: [] 13 | class_name: AgentMechContract 14 | contract_interface_paths: 15 | ethereum: build/AgentMech.json 16 | dependencies: 17 | open-aea-ledger-ethereum: 18 | version: ==1.63.0 19 | web3: 20 | version: <7,>=6.0.0 21 | eth-abi: 22 | version: ==4.0.0 23 | eth-utils: 24 | version: ==2.2.0 25 | hexbytes: {} 26 | eth_typing: {} 27 | contracts: [] 28 | -------------------------------------------------------------------------------- /packages/valory/contracts/agent_registry/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the support resources for the registries manager contract.""" 21 | -------------------------------------------------------------------------------- /packages/valory/contracts/agent_registry/contract.yaml: -------------------------------------------------------------------------------- 1 | name: agent_registry 2 | author: valory 3 | version: 0.1.0 4 | type: contract 5 | description: Agent registry contract 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | __init__.py: bafybeiaaoxkui6cjj52avj3xbriazrwdg6bcfqxmukkw7emwc2q4hbdfdi 10 | build/AgentRegistry.json: bafybeiakiipetr5roi6lld3l72lpxspoq2zssgqrktkrprqvyclfpfql7m 11 | contract.py: bafybeidxosuli2n7kn5schpj5jan7kjq4jvqvpjfg2tr2cbx3upyukoq7y 12 | tests/__init__.py: bafybeig6vb3j7xuemr25f5uapvhyuo4hlk3rbfiq7kfxg4f5gfz6oc6tte 13 | tests/test_contract.py: bafybeichmcfjtqyv3435grfl54ijeelgoe4owoqh3xeutcjodexbjl6f74 14 | fingerprint_ignore_patterns: [] 15 | contracts: [] 16 | class_name: AgentRegistryContract 17 | contract_interface_paths: 18 | ethereum: build/AgentRegistry.json 19 | dependencies: {} 20 | -------------------------------------------------------------------------------- /packages/valory/contracts/agent_registry/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Tests for `valory/agent_registry` contract""" 21 | -------------------------------------------------------------------------------- /packages/valory/contracts/agent_registry/tests/test_contract.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Test for contract module.""" 21 | 22 | from pathlib import Path 23 | 24 | from aea_test_autonomy.base_test_classes.contracts import BaseRegistriesContractsTest 25 | from aea_test_autonomy.docker.base import skip_docker_tests 26 | from aea_test_autonomy.docker.registries import AGENT_REGISTRY 27 | 28 | from packages.valory.contracts.agent_registry.contract import AgentRegistryContract 29 | 30 | 31 | PACKAGE_DIR = Path(__file__).parent.parent 32 | 33 | 34 | @skip_docker_tests 35 | class TestAgentRegistry(BaseRegistriesContractsTest): 36 | """Test agent registry.""" 37 | 38 | contract: AgentRegistryContract 39 | contract_address = AGENT_REGISTRY 40 | contract_directory = PACKAGE_DIR 41 | 42 | def test_get_token_uri(self) -> None: 43 | """Test get token URI method.""" 44 | 45 | token_uri = self.contract.get_token_uri( 46 | ledger_api=self.ledger_api, 47 | contract_address=self.contract_address, 48 | token_id=1, 49 | ) 50 | 51 | assert ( 52 | token_uri 53 | == "https://gateway.autonolas.tech/ipfs/f01701220985b4c36158b51f8a865faceff8141dbc0989c349a1a41ba1e2ac8e5b24536b2" # nosec 54 | ) 55 | -------------------------------------------------------------------------------- /packages/valory/contracts/balance_tracker/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the support resources for the balance tracker mech contract.""" 21 | -------------------------------------------------------------------------------- /packages/valory/contracts/balance_tracker/contract.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the balance_tracker contract definition.""" 21 | 22 | import logging 23 | from typing import Any, cast 24 | 25 | from aea.common import JSONLike 26 | from aea.configurations.base import PublicId 27 | from aea.contracts.base import Contract 28 | from aea.crypto.base import LedgerApi 29 | from aea_ledger_ethereum import EthereumApi 30 | 31 | 32 | PUBLIC_ID = PublicId.from_str("valory/balance_tracker:0.1.0") 33 | 34 | _logger = logging.getLogger( 35 | f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.contract" 36 | ) 37 | 38 | 39 | class BalanceTrackerContract(Contract): 40 | """The scaffold contract class for a smart contract.""" 41 | 42 | contract_id = PublicId.from_str("valory/balance_tracker:0.1.0") 43 | 44 | @classmethod 45 | def get_mech_balance( 46 | cls, ledger_api: LedgerApi, contract_address: str, mech_address: str 47 | ) -> JSONLike: 48 | """Get mech balance""" 49 | contract_instance = cls.get_instance(ledger_api, contract_address) 50 | mech_balance = contract_instance.functions.mapMechBalances(mech_address).call() 51 | return {"mech_balance": mech_balance} 52 | 53 | @classmethod 54 | def simulate_tx( 55 | cls, 56 | ledger_api: EthereumApi, 57 | contract_address: str, 58 | sender_address: str, 59 | data: str, 60 | ) -> JSONLike: 61 | """Simulate the transaction.""" 62 | try: 63 | ledger_api.api.eth.call( 64 | { 65 | "from": ledger_api.api.to_checksum_address(sender_address), 66 | "to": ledger_api.api.to_checksum_address(contract_address), 67 | "data": data, 68 | } 69 | ) 70 | simulation_ok = True 71 | except Exception as e: 72 | _logger.info(f"Simulation failed: {str(e)}") 73 | simulation_ok = False 74 | 75 | return dict(data=simulation_ok) 76 | 77 | @classmethod 78 | def get_process_payment_tx( 79 | cls, 80 | ledger_api: EthereumApi, 81 | contract_address: str, 82 | sender_address: str, 83 | mech_address: str, 84 | ) -> JSONLike: 85 | """Get tx data""" 86 | 87 | contract_instance = cls.get_instance(ledger_api, contract_address) 88 | tx_data = contract_instance.encodeABI( 89 | fn_name="processPaymentByMultisig", 90 | args=[mech_address], 91 | ) 92 | simulation_ok = cls.simulate_tx( 93 | ledger_api, contract_address, sender_address, tx_data 94 | ).pop("data") 95 | return {"data": bytes.fromhex(tx_data[2:]), "simulation_ok": simulation_ok} # type: ignore 96 | -------------------------------------------------------------------------------- /packages/valory/contracts/balance_tracker/contract.yaml: -------------------------------------------------------------------------------- 1 | name: balance_tracker 2 | author: valory 3 | version: 0.1.0 4 | type: contract 5 | description: balance tracker contract 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | __init__.py: bafybeigim3df7lcxmr4gjugo73fyrwfkkpll7jykgjp7nij6ugbkc7igyy 10 | build/BalanceTracker.json: bafybeifnmntoaw2qym5oei2shy3zvy4exhfklrh5sindvi2hqymoina2ny 11 | contract.py: bafybeih7jqmhxehzgluunkx5jla44wtedddsceshvgcd3st2cowprie7h4 12 | fingerprint_ignore_patterns: [] 13 | class_name: BalanceTrackerContract 14 | contract_interface_paths: 15 | ethereum: build/BalanceTracker.json 16 | dependencies: 17 | open-aea-ledger-ethereum: 18 | version: ==1.63.0 19 | web3: 20 | version: <7,>=6.0.0 21 | contracts: [] 22 | -------------------------------------------------------------------------------- /packages/valory/contracts/hash_checkpoint/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the support resources for the agent mech contract.""" 21 | -------------------------------------------------------------------------------- /packages/valory/contracts/hash_checkpoint/contract.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2024 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the hash checkpoint contract definition.""" 21 | from enum import Enum 22 | from typing import Any, Dict, List, cast 23 | 24 | from aea.common import JSONLike 25 | from aea.configurations.base import PublicId 26 | from aea.contracts.base import Contract 27 | from aea.crypto.base import LedgerApi 28 | from aea_ledger_ethereum import EthereumApi 29 | from web3.types import BlockIdentifier, TxReceipt 30 | 31 | 32 | class HashCheckpointContract(Contract): 33 | """The scaffold contract class for a smart contract.""" 34 | 35 | contract_id = PublicId.from_str("valory/hash_checkpoint:0.1.0") 36 | 37 | @classmethod 38 | def get_raw_transaction( 39 | cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any 40 | ) -> JSONLike: 41 | """ 42 | Handler method for the 'GET_RAW_TRANSACTION' requests. 43 | 44 | Implement this method in the sub class if you want 45 | to handle the contract requests manually. 46 | 47 | :param ledger_api: the ledger apis. 48 | :param contract_address: the contract address. 49 | :param kwargs: the keyword arguments. 50 | :return: the tx # noqa: DAR202 51 | """ 52 | raise NotImplementedError 53 | 54 | @classmethod 55 | def get_raw_message( 56 | cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any 57 | ) -> bytes: 58 | """ 59 | Handler method for the 'GET_RAW_MESSAGE' requests. 60 | 61 | Implement this method in the sub class if you want 62 | to handle the contract requests manually. 63 | 64 | :param ledger_api: the ledger apis. 65 | :param contract_address: the contract address. 66 | :param kwargs: the keyword arguments. 67 | :return: the tx # noqa: DAR202 68 | """ 69 | raise NotImplementedError 70 | 71 | @classmethod 72 | def get_state( 73 | cls, ledger_api: LedgerApi, contract_address: str, **kwargs: Any 74 | ) -> JSONLike: 75 | """ 76 | Handler method for the 'GET_STATE' requests. 77 | 78 | Implement this method in the sub class if you want 79 | to handle the contract requests manually. 80 | 81 | :param ledger_api: the ledger apis. 82 | :param contract_address: the contract address. 83 | :param kwargs: the keyword arguments. 84 | :return: the tx # noqa: DAR202 85 | """ 86 | raise NotImplementedError 87 | 88 | @classmethod 89 | def get_checkpoint_data( 90 | cls, ledger_api: LedgerApi, contract_address: str, data: bytes 91 | ) -> JSONLike: 92 | """ 93 | Deliver a response to a request. 94 | 95 | :param ledger_api: LedgerApi object 96 | :param contract_address: the address of the token to be used 97 | :param data: the ipfs hash 98 | :return: the deliver data 99 | """ 100 | ledger_api = cast(EthereumApi, ledger_api) 101 | 102 | if not isinstance(ledger_api, EthereumApi): 103 | raise ValueError(f"Only EthereumApi is supported, got {type(ledger_api)}") 104 | 105 | contract_instance = cls.get_instance(ledger_api, contract_address) 106 | data = contract_instance.encodeABI(fn_name="checkpoint", args=[data]) 107 | return {"data": data} 108 | 109 | @classmethod 110 | def get_latest_hash( 111 | cls, 112 | ledger_api: LedgerApi, 113 | contract_address: str, 114 | sender_address: str, 115 | ) -> JSONLike: 116 | """Get the Request events emitted by the contract.""" 117 | ledger_api = cast(EthereumApi, ledger_api) 118 | 119 | if not isinstance(ledger_api, EthereumApi): 120 | raise ValueError(f"Only EthereumApi is supported, got {type(ledger_api)}") 121 | 122 | contract_instance = cls.get_instance(ledger_api, contract_address) 123 | sender_address = ledger_api.api.to_checksum_address(sender_address) 124 | latest_ipfs_hash = contract_instance.functions.latestHash(sender_address).call() 125 | return {"data": latest_ipfs_hash} 126 | -------------------------------------------------------------------------------- /packages/valory/contracts/hash_checkpoint/contract.yaml: -------------------------------------------------------------------------------- 1 | name: hash_checkpoint 2 | author: valory 3 | version: 0.1.0 4 | type: contract 5 | description: Hash checkpoint contract 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | __init__.py: bafybeigpq5lxfj2aza6ok3fjuywtdafelkbvoqwaits7regfbgu4oynmku 10 | build/HashCheckpoint.json: bafybeicdse6k7xbis3mdurqee7a3ghiba4hzfk4llhc3hk6q4qbfjd5rg4 11 | contract.py: bafybeiggklmnb6p7naanj3ywiwiwzcylluqe34lnhkrfxfndtl3rkzmf3e 12 | fingerprint_ignore_patterns: [] 13 | class_name: HashCheckpointContract 14 | contract_interface_paths: 15 | ethereum: build/HashCheckpoint.json 16 | dependencies: 17 | open-aea-ledger-ethereum: 18 | version: ==1.63.0 19 | web3: 20 | version: <7,>=6.0.0 21 | contracts: [] 22 | -------------------------------------------------------------------------------- /packages/valory/contracts/mech_marketplace/BatchPriorityPassedCheck.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.23; 3 | 4 | 5 | struct MechDelivery { 6 | // Priority mech address 7 | address priorityMech; 8 | // Delivery mech address 9 | address deliveryMech; 10 | // Requester address 11 | address requester; 12 | // Response timeout window 13 | uint32 responseTimeout; 14 | } 15 | 16 | interface IMechMarketplace { 17 | function mapRequestIdDeliveries(uint256) external view returns (MechDelivery memory); 18 | } 19 | 20 | contract BatchPriorityPassedCheck { 21 | constructor(IMechMarketplace _marketplace, uint256[] memory _requestIds) { 22 | // cache requestIds length 23 | uint256 requestIdsLength = _requestIds.length; 24 | 25 | // create temporary array with requestIds length to populate only with requestIds that have passed the priority timeout 26 | uint256[] memory tempRequestIds = new uint256[](requestIdsLength); 27 | 28 | // declare counter to know how many of the request are eligible 29 | uint256 eligibleRequestIdsCount; 30 | 31 | for (uint256 _i; _i < requestIdsLength;) { 32 | MechDelivery memory delivery = _marketplace.mapRequestIdDeliveries(_requestIds[_i]); 33 | if (block.timestamp >= delivery.responseTimeout) { 34 | tempRequestIds[eligibleRequestIdsCount] = _requestIds[_i]; 35 | ++eligibleRequestIdsCount; 36 | } 37 | unchecked {++_i;} 38 | } 39 | 40 | // create a new array with the actual length of the eligible to not corrupt memory with a wrong length 41 | uint256[] memory eligibleRequestIds = new uint256[](eligibleRequestIdsCount); 42 | 43 | // populate the array with the eligible requestIds 44 | for (uint256 _i; _i < eligibleRequestIdsCount;) { 45 | eligibleRequestIds[_i] = tempRequestIds[_i]; 46 | unchecked {++_i;} 47 | } 48 | 49 | // encode eligible referrers to ensure a proper layout in memory 50 | bytes memory data = abi.encode(eligibleRequestIds); 51 | 52 | assembly { 53 | // pointer to the beginning of the data containing the eligible referrers in memory 54 | let _dataStartPointer := add(data, 32) 55 | // return everything from the start of the data to the end of memory 56 | return (_dataStartPointer, sub(msize(), _dataStartPointer)) 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /packages/valory/contracts/mech_marketplace/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2024 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the support resources for the agent mech contract.""" 21 | -------------------------------------------------------------------------------- /packages/valory/contracts/mech_marketplace/contract.yaml: -------------------------------------------------------------------------------- 1 | name: mech_marketplace 2 | author: valory 3 | version: 0.1.0 4 | type: contract 5 | description: Mech Marketplace contract for the AgentMech project. 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | BatchPriorityPassedCheck.sol: bafybeie3hfpyss43sggqh5rjzwsqe7o37td4v4k6f3hlweiosnayyseo4i 10 | __init__.py: bafybeigqedpnruwcvjarngql7yfnpqwozvvgzcei2xcrp7mjf4ccspa62y 11 | build/MechMarketplace.json: bafybeiauqsmm5aqqzqqr7vi46obq7exa7id5vbq57e3e3wxxkzblgqnjoy 12 | contract.py: bafybeihyob46cn2hzogvle4a74uy77bozhubflqupmiwzy5z56jybxctyu 13 | fingerprint_ignore_patterns: [] 14 | class_name: MechMarketplaceContract 15 | contract_interface_paths: 16 | ethereum: build/MechMarketplace.json 17 | dependencies: 18 | open-aea-ledger-ethereum: 19 | version: ==1.63.0 20 | web3: 21 | version: <7,>=6.0.0 22 | eth-abi: 23 | version: ==4.0.0 24 | eth-utils: 25 | version: ==2.2.0 26 | hexbytes: {} 27 | eth_typing: {} 28 | contracts: [] 29 | -------------------------------------------------------------------------------- /packages/valory/customs/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2024 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | -------------------------------------------------------------------------------- /packages/valory/protocols/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/valory-xyz/mech/ae5c7ffe4a0c4efd0b03b8e946a047007d0dbf3a/packages/valory/protocols/__init__.py -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/README.md: -------------------------------------------------------------------------------- 1 | # ACN Data share protocol 2 | 3 | ## Description 4 | 5 | This protocol provides support for sharing raw data using ACN 6 | 7 | ## Specification 8 | 9 | ```yaml 10 | --- 11 | name: acn_data_share 12 | author: valory 13 | version: 0.1.0 14 | description: A protocol for sharing raw data using ACN. 15 | license: Apache-2.0 16 | aea_version: '>=1.0.0, <2.0.0' 17 | protocol_specification_id: valory/acn_data_share:0.1.0 18 | speech_acts: 19 | data: 20 | request_id: pt:str 21 | content: pt:str 22 | ... 23 | --- 24 | initiation: [data] 25 | reply: 26 | data: [] 27 | termination: [data] 28 | roles: {agent,skill} 29 | end_states: [successful, failed] 30 | keep_terminal_state_dialogues: false 31 | ... 32 | ``` 33 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """ 21 | This module contains the support resources for the acn_data_share protocol. 22 | 23 | It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. 24 | """ 25 | 26 | from packages.valory.protocols.acn_data_share.message import AcnDataShareMessage 27 | from packages.valory.protocols.acn_data_share.serialization import ( 28 | AcnDataShareSerializer, 29 | ) 30 | 31 | 32 | AcnDataShareMessage.serializer = AcnDataShareSerializer 33 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/acn_data_share.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package aea.valory.acn_data_share.v0_1_0; 4 | 5 | message AcnDataShareMessage{ 6 | 7 | // Performatives and contents 8 | message Data_Performative{ 9 | string request_id = 1; 10 | string content = 2; 11 | } 12 | 13 | 14 | oneof performative{ 15 | Data_Performative data = 5; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/acn_data_share_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: acn_data_share.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import descriptor_pool as _descriptor_pool 7 | from google.protobuf import symbol_database as _symbol_database 8 | from google.protobuf.internal import builder as _builder 9 | 10 | 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( 17 | b'\n\x14\x61\x63n_data_share.proto\x12 aea.valory.acn_data_share.v0_1_0"\xb8\x01\n\x13\x41\x63nDataShareMessage\x12W\n\x04\x64\x61ta\x18\x05 \x01(\x0b\x32G.aea.valory.acn_data_share.v0_1_0.AcnDataShareMessage.Data_PerformativeH\x00\x1a\x38\n\x11\x44\x61ta_Performative\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\tB\x0e\n\x0cperformativeb\x06proto3' 18 | ) 19 | 20 | _globals = globals() 21 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 22 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "acn_data_share_pb2", _globals) 23 | if _descriptor._USE_C_DESCRIPTORS == False: 24 | DESCRIPTOR._options = None 25 | _globals["_ACNDATASHAREMESSAGE"]._serialized_start = 59 26 | _globals["_ACNDATASHAREMESSAGE"]._serialized_end = 243 27 | _globals["_ACNDATASHAREMESSAGE_DATA_PERFORMATIVE"]._serialized_start = 171 28 | _globals["_ACNDATASHAREMESSAGE_DATA_PERFORMATIVE"]._serialized_end = 227 29 | # @@protoc_insertion_point(module_scope) 30 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """ 21 | This module contains the classes required for acn_data_share dialogue management. 22 | 23 | - AcnDataShareDialogue: The dialogue class maintains state of a dialogue and manages it. 24 | - AcnDataShareDialogues: The dialogues class keeps track of all dialogues. 25 | """ 26 | 27 | from abc import ABC 28 | from typing import Callable, Dict, FrozenSet, Type, cast 29 | 30 | from aea.common import Address 31 | from aea.protocols.base import Message 32 | from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues 33 | 34 | from packages.valory.protocols.acn_data_share.message import AcnDataShareMessage 35 | 36 | 37 | class AcnDataShareDialogue(Dialogue): 38 | """The acn_data_share dialogue class maintains state of a dialogue and manages it.""" 39 | 40 | INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( 41 | {AcnDataShareMessage.Performative.DATA} 42 | ) 43 | TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( 44 | {AcnDataShareMessage.Performative.DATA} 45 | ) 46 | VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { 47 | AcnDataShareMessage.Performative.DATA: frozenset(), 48 | } 49 | 50 | class Role(Dialogue.Role): 51 | """This class defines the agent's role in a acn_data_share dialogue.""" 52 | 53 | AGENT = "agent" 54 | SKILL = "skill" 55 | 56 | class EndState(Dialogue.EndState): 57 | """This class defines the end states of a acn_data_share dialogue.""" 58 | 59 | SUCCESSFUL = 0 60 | FAILED = 1 61 | 62 | def __init__( 63 | self, 64 | dialogue_label: DialogueLabel, 65 | self_address: Address, 66 | role: Dialogue.Role, 67 | message_class: Type[AcnDataShareMessage] = AcnDataShareMessage, 68 | ) -> None: 69 | """ 70 | Initialize a dialogue. 71 | 72 | :param dialogue_label: the identifier of the dialogue 73 | :param self_address: the address of the entity for whom this dialogue is maintained 74 | :param role: the role of the agent this dialogue is maintained for 75 | :param message_class: the message class used 76 | """ 77 | Dialogue.__init__( 78 | self, 79 | dialogue_label=dialogue_label, 80 | message_class=message_class, 81 | self_address=self_address, 82 | role=role, 83 | ) 84 | 85 | 86 | class AcnDataShareDialogues(Dialogues, ABC): 87 | """This class keeps track of all acn_data_share dialogues.""" 88 | 89 | END_STATES = frozenset( 90 | {AcnDataShareDialogue.EndState.SUCCESSFUL, AcnDataShareDialogue.EndState.FAILED} 91 | ) 92 | 93 | _keep_terminal_state_dialogues = False 94 | 95 | def __init__( 96 | self, 97 | self_address: Address, 98 | role_from_first_message: Callable[[Message, Address], Dialogue.Role], 99 | dialogue_class: Type[AcnDataShareDialogue] = AcnDataShareDialogue, 100 | ) -> None: 101 | """ 102 | Initialize dialogues. 103 | 104 | :param self_address: the address of the entity for whom dialogues are maintained 105 | :param dialogue_class: the dialogue class used 106 | :param role_from_first_message: the callable determining role from first message 107 | """ 108 | Dialogues.__init__( 109 | self, 110 | self_address=self_address, 111 | end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), 112 | message_class=AcnDataShareMessage, 113 | dialogue_class=dialogue_class, 114 | role_from_first_message=role_from_first_message, 115 | ) 116 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/protocol.yaml: -------------------------------------------------------------------------------- 1 | name: acn_data_share 2 | author: valory 3 | version: 0.1.0 4 | protocol_specification_id: valory/acn_data_share:0.1.0 5 | type: protocol 6 | description: A protocol for sharing raw data using ACN. 7 | license: Apache-2.0 8 | aea_version: '>=1.0.0, <2.0.0' 9 | fingerprint: 10 | README.md: bafybeiexqywrjzv4ajzesbzaw7bujvmgadsqtxzfnerwqogi7nz6jcvp6u 11 | __init__.py: bafybeif7fohg7vfalh35nyuqchdw5lnjblqtodhxmcnnhycderagqs46du 12 | acn_data_share.proto: bafybeiell3oa6eo2oogbgymu5cupeakbkpkmxkh7gossgy4jdip7lrr7tu 13 | acn_data_share_pb2.py: bafybeifyna3ykdjrh2t5etusxc22hiplfvekh6vjlrnom2tzgcolmhsslu 14 | dialogues.py: bafybeigtnzvicosvctjk67qni5mu3yy77fp5u2xpb2eszwfht7igeaip4m 15 | message.py: bafybeiggjuq6fooopoy423v6huhfk6szyzdlgkxk5ardlyllawj2qykhfq 16 | serialization.py: bafybeihi2cogvek6irdncct5ga2ztdeqho4eai6krtk354yq2ip2d5f3se 17 | tests/test_acn_data_share_dialogues.py: bafybeie5kcwchjl5vozdlrnwhmim4kffa7fr5zsqjy3r27mjzuilaog5su 18 | tests/test_acn_data_share_messages.py: bafybeifap2cnraojc4ohd46rrjgusi6iisjm5tum2bs4sfgdocx5zjsqea 19 | fingerprint_ignore_patterns: [] 20 | dependencies: 21 | protobuf: {} 22 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/serialization.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Serialization module for acn_data_share protocol.""" 21 | 22 | # pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin 23 | from typing import Any, Dict, cast 24 | 25 | from aea.mail.base_pb2 import DialogueMessage # type: ignore 26 | from aea.mail.base_pb2 import Message as ProtobufMessage # type: ignore 27 | from aea.protocols.base import Message # type: ignore 28 | from aea.protocols.base import Serializer # type: ignore 29 | 30 | from packages.valory.protocols.acn_data_share import acn_data_share_pb2 # type: ignore 31 | from packages.valory.protocols.acn_data_share.message import ( # type: ignore 32 | AcnDataShareMessage, 33 | ) 34 | 35 | 36 | class AcnDataShareSerializer(Serializer): 37 | """Serialization for the 'acn_data_share' protocol.""" 38 | 39 | @staticmethod 40 | def encode(msg: Message) -> bytes: 41 | """ 42 | Encode a 'AcnDataShare' message into bytes. 43 | 44 | :param msg: the message object. 45 | :return: the bytes. 46 | """ 47 | msg = cast(AcnDataShareMessage, msg) 48 | message_pb = ProtobufMessage() 49 | dialogue_message_pb = DialogueMessage() 50 | acn_data_share_msg = acn_data_share_pb2.AcnDataShareMessage() # type: ignore 51 | 52 | dialogue_message_pb.message_id = msg.message_id 53 | dialogue_reference = msg.dialogue_reference 54 | dialogue_message_pb.dialogue_starter_reference = dialogue_reference[0] 55 | dialogue_message_pb.dialogue_responder_reference = dialogue_reference[1] 56 | dialogue_message_pb.target = msg.target 57 | 58 | performative_id = msg.performative 59 | if performative_id == AcnDataShareMessage.Performative.DATA: 60 | performative = acn_data_share_pb2.AcnDataShareMessage.Data_Performative() # type: ignore 61 | request_id = msg.request_id 62 | performative.request_id = request_id 63 | content = msg.content 64 | performative.content = content 65 | acn_data_share_msg.data.CopyFrom(performative) 66 | else: 67 | raise ValueError("Performative not valid: {}".format(performative_id)) 68 | 69 | dialogue_message_pb.content = acn_data_share_msg.SerializeToString() 70 | 71 | message_pb.dialogue_message.CopyFrom(dialogue_message_pb) 72 | message_bytes = message_pb.SerializeToString() 73 | return message_bytes 74 | 75 | @staticmethod 76 | def decode(obj: bytes) -> Message: 77 | """ 78 | Decode bytes into a 'AcnDataShare' message. 79 | 80 | :param obj: the bytes object. 81 | :return: the 'AcnDataShare' message. 82 | """ 83 | message_pb = ProtobufMessage() 84 | acn_data_share_pb = acn_data_share_pb2.AcnDataShareMessage() # type: ignore 85 | message_pb.ParseFromString(obj) 86 | message_id = message_pb.dialogue_message.message_id 87 | dialogue_reference = ( 88 | message_pb.dialogue_message.dialogue_starter_reference, 89 | message_pb.dialogue_message.dialogue_responder_reference, 90 | ) 91 | target = message_pb.dialogue_message.target 92 | 93 | acn_data_share_pb.ParseFromString(message_pb.dialogue_message.content) 94 | performative = acn_data_share_pb.WhichOneof("performative") 95 | performative_id = AcnDataShareMessage.Performative(str(performative)) 96 | performative_content = dict() # type: Dict[str, Any] 97 | if performative_id == AcnDataShareMessage.Performative.DATA: 98 | request_id = acn_data_share_pb.data.request_id 99 | performative_content["request_id"] = request_id 100 | content = acn_data_share_pb.data.content 101 | performative_content["content"] = content 102 | else: 103 | raise ValueError("Performative not valid: {}.".format(performative_id)) 104 | 105 | return AcnDataShareMessage( 106 | message_id=message_id, 107 | dialogue_reference=dialogue_reference, 108 | target=target, 109 | performative=performative, 110 | **performative_content 111 | ) 112 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/tests/test_acn_data_share_dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Test dialogues module for acn_data_share protocol.""" 21 | 22 | # pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin 23 | from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase 24 | 25 | from packages.valory.protocols.acn_data_share.dialogues import ( 26 | AcnDataShareDialogue, 27 | AcnDataShareDialogues, 28 | ) 29 | from packages.valory.protocols.acn_data_share.message import AcnDataShareMessage 30 | 31 | 32 | class TestDialoguesAcnDataShare(BaseProtocolDialoguesTestCase): 33 | """Test for the 'acn_data_share' protocol dialogues.""" 34 | 35 | MESSAGE_CLASS = AcnDataShareMessage 36 | 37 | DIALOGUE_CLASS = AcnDataShareDialogue 38 | 39 | DIALOGUES_CLASS = AcnDataShareDialogues 40 | 41 | ROLE_FOR_THE_FIRST_MESSAGE = AcnDataShareDialogue.Role.AGENT # CHECK 42 | 43 | def make_message_content(self) -> dict: 44 | """Make a dict with message contruction content for dialogues.create.""" 45 | return dict( 46 | performative=AcnDataShareMessage.Performative.DATA, 47 | request_id="some str", 48 | content="some str", 49 | ) 50 | -------------------------------------------------------------------------------- /packages/valory/protocols/acn_data_share/tests/test_acn_data_share_messages.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Test messages module for acn_data_share protocol.""" 21 | 22 | # pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin 23 | from typing import List 24 | 25 | from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase 26 | 27 | from packages.valory.protocols.acn_data_share.message import AcnDataShareMessage 28 | 29 | 30 | class TestMessageAcnDataShare(BaseProtocolMessagesTestCase): 31 | """Test for the 'acn_data_share' protocol message.""" 32 | 33 | MESSAGE_CLASS = AcnDataShareMessage 34 | 35 | def build_messages(self) -> List[AcnDataShareMessage]: # type: ignore[override] 36 | """Build the messages to be used for testing.""" 37 | return [ 38 | AcnDataShareMessage( 39 | performative=AcnDataShareMessage.Performative.DATA, 40 | request_id="some str", 41 | content="some str", 42 | ), 43 | ] 44 | 45 | def build_inconsistent(self) -> List[AcnDataShareMessage]: # type: ignore[override] 46 | """Build inconsistent messages to be used for testing.""" 47 | return [ 48 | AcnDataShareMessage( 49 | performative=AcnDataShareMessage.Performative.DATA, 50 | # skip content: request_id 51 | content="some str", 52 | ), 53 | ] 54 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/README.md: -------------------------------------------------------------------------------- 1 | # Default Protocol 2 | 3 | ## Description 4 | 5 | This is a protocol for two agents exchanging any bytes messages. 6 | 7 | ## Specification 8 | 9 | ```yaml 10 | --- 11 | name: default 12 | author: valory 13 | version: 1.0.0 14 | description: A protocol for exchanging any bytes message. 15 | license: Apache-2.0 16 | aea_version: '>=1.0.0, <2.0.0' 17 | protocol_specification_id: valory/default:1.0.0 18 | speech_acts: 19 | bytes: 20 | content: pt:bytes 21 | error: 22 | error_code: ct:ErrorCode 23 | error_msg: pt:str 24 | error_data: pt:dict[pt:str, pt:bytes] 25 | end: {} 26 | ... 27 | --- 28 | ct:ErrorCode: | 29 | enum ErrorCodeEnum { 30 | UNSUPPORTED_PROTOCOL = 0; 31 | DECODING_ERROR = 1; 32 | INVALID_MESSAGE = 2; 33 | UNSUPPORTED_SKILL = 3; 34 | INVALID_DIALOGUE = 4; 35 | } 36 | ErrorCodeEnum error_code = 1; 37 | ... 38 | --- 39 | initiation: [bytes, error] 40 | reply: 41 | bytes: [bytes, error, end] 42 | error: [] 43 | end: [] 44 | termination: [end, error] 45 | roles: {agent} 46 | end_states: [successful, failed] 47 | keep_terminal_state_dialogues: true 48 | ... 49 | ``` 50 | 51 | ## Links -------------------------------------------------------------------------------- /packages/valory/protocols/default/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """ 21 | This module contains the support resources for the default protocol. 22 | 23 | It was created with protocol buffer compiler version `libprotoc 24.3` and aea protocol generator version `1.0.0`. 24 | """ 25 | 26 | from packages.valory.protocols.default.message import DefaultMessage 27 | from packages.valory.protocols.default.serialization import DefaultSerializer 28 | 29 | 30 | DefaultMessage.serializer = DefaultSerializer 31 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/custom_types.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains class representations corresponding to every custom type in the protocol specification.""" 21 | 22 | from enum import Enum 23 | from typing import Any 24 | 25 | 26 | class ErrorCode(Enum): 27 | """This class represents an instance of ErrorCode.""" 28 | 29 | UNSUPPORTED_PROTOCOL = 0 30 | DECODING_ERROR = 1 31 | INVALID_MESSAGE = 2 32 | UNSUPPORTED_SKILL = 3 33 | INVALID_DIALOGUE = 4 34 | 35 | @staticmethod 36 | def encode(error_code_protobuf_object: Any, error_code_object: "ErrorCode") -> None: 37 | """ 38 | Encode an instance of this class into the protocol buffer object. 39 | 40 | The protocol buffer object in the error_code_protobuf_object argument is matched with the instance of this class in the 'error_code_object' argument. 41 | 42 | :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. 43 | :param error_code_object: an instance of this class to be encoded in the protocol buffer object. 44 | """ 45 | error_code_protobuf_object.error_code = error_code_object.value 46 | 47 | @classmethod 48 | def decode(cls, error_code_protobuf_object: Any) -> "ErrorCode": 49 | """ 50 | Decode a protocol buffer object that corresponds with this class into an instance of this class. 51 | 52 | A new instance of this class is created that matches the protocol buffer object in the 'error_code_protobuf_object' argument. 53 | 54 | :param error_code_protobuf_object: the protocol buffer object whose type corresponds with this class. 55 | :return: A new instance of this class that matches the protocol buffer object in the 'error_code_protobuf_object' argument. 56 | """ 57 | enum_value_from_pb2 = error_code_protobuf_object.error_code 58 | return ErrorCode(enum_value_from_pb2) 59 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/default.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package aea.valory.default.v1_0_0; 4 | 5 | message DefaultMessage{ 6 | 7 | // Custom Types 8 | message ErrorCode{ 9 | enum ErrorCodeEnum { 10 | UNSUPPORTED_PROTOCOL = 0; 11 | DECODING_ERROR = 1; 12 | INVALID_MESSAGE = 2; 13 | UNSUPPORTED_SKILL = 3; 14 | INVALID_DIALOGUE = 4; 15 | } 16 | ErrorCodeEnum error_code = 1; 17 | } 18 | 19 | 20 | // Performatives and contents 21 | message Bytes_Performative{ 22 | bytes content = 1; 23 | } 24 | 25 | message Error_Performative{ 26 | ErrorCode error_code = 1; 27 | string error_msg = 2; 28 | map error_data = 3; 29 | } 30 | 31 | message End_Performative{ 32 | } 33 | 34 | 35 | oneof performative{ 36 | Bytes_Performative bytes = 5; 37 | End_Performative end = 6; 38 | Error_Performative error = 7; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/default_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: default.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import descriptor_pool as _descriptor_pool 7 | from google.protobuf import symbol_database as _symbol_database 8 | from google.protobuf.internal import builder as _builder 9 | 10 | 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( 17 | b'\n\rdefault.proto\x12\x19\x61\x65\x61.valory.default.v1_0_0"\xb0\x06\n\x0e\x44\x65\x66\x61ultMessage\x12M\n\x05\x62ytes\x18\x05 \x01(\x0b\x32<.aea.valory.default.v1_0_0.DefaultMessage.Bytes_PerformativeH\x00\x12I\n\x03\x65nd\x18\x06 \x01(\x0b\x32:.aea.valory.default.v1_0_0.DefaultMessage.End_PerformativeH\x00\x12M\n\x05\x65rror\x18\x07 \x01(\x0b\x32<.aea.valory.default.v1_0_0.DefaultMessage.Error_PerformativeH\x00\x1a\xe3\x01\n\tErrorCode\x12U\n\nerror_code\x18\x01 \x01(\x0e\x32\x41.aea.valory.default.v1_0_0.DefaultMessage.ErrorCode.ErrorCodeEnum"\x7f\n\rErrorCodeEnum\x12\x18\n\x14UNSUPPORTED_PROTOCOL\x10\x00\x12\x12\n\x0e\x44\x45\x43ODING_ERROR\x10\x01\x12\x13\n\x0fINVALID_MESSAGE\x10\x02\x12\x15\n\x11UNSUPPORTED_SKILL\x10\x03\x12\x14\n\x10INVALID_DIALOGUE\x10\x04\x1a%\n\x12\x42ytes_Performative\x12\x0f\n\x07\x63ontent\x18\x01 \x01(\x0c\x1a\x83\x02\n\x12\x45rror_Performative\x12G\n\nerror_code\x18\x01 \x01(\x0b\x32\x33.aea.valory.default.v1_0_0.DefaultMessage.ErrorCode\x12\x11\n\terror_msg\x18\x02 \x01(\t\x12_\n\nerror_data\x18\x03 \x03(\x0b\x32K.aea.valory.default.v1_0_0.DefaultMessage.Error_Performative.ErrorDataEntry\x1a\x30\n\x0e\x45rrorDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\x1a\x12\n\x10\x45nd_PerformativeB\x0e\n\x0cperformativeb\x06proto3' 18 | ) 19 | 20 | _globals = globals() 21 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 22 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "default_pb2", _globals) 23 | if _descriptor._USE_C_DESCRIPTORS == False: 24 | DESCRIPTOR._options = None 25 | _DEFAULTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY._options = None 26 | _DEFAULTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY._serialized_options = b"8\001" 27 | _globals["_DEFAULTMESSAGE"]._serialized_start = 45 28 | _globals["_DEFAULTMESSAGE"]._serialized_end = 861 29 | _globals["_DEFAULTMESSAGE_ERRORCODE"]._serialized_start = 297 30 | _globals["_DEFAULTMESSAGE_ERRORCODE"]._serialized_end = 524 31 | _globals["_DEFAULTMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_start = 397 32 | _globals["_DEFAULTMESSAGE_ERRORCODE_ERRORCODEENUM"]._serialized_end = 524 33 | _globals["_DEFAULTMESSAGE_BYTES_PERFORMATIVE"]._serialized_start = 526 34 | _globals["_DEFAULTMESSAGE_BYTES_PERFORMATIVE"]._serialized_end = 563 35 | _globals["_DEFAULTMESSAGE_ERROR_PERFORMATIVE"]._serialized_start = 566 36 | _globals["_DEFAULTMESSAGE_ERROR_PERFORMATIVE"]._serialized_end = 825 37 | _globals[ 38 | "_DEFAULTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY" 39 | ]._serialized_start = 777 40 | _globals["_DEFAULTMESSAGE_ERROR_PERFORMATIVE_ERRORDATAENTRY"]._serialized_end = 825 41 | _globals["_DEFAULTMESSAGE_END_PERFORMATIVE"]._serialized_start = 827 42 | _globals["_DEFAULTMESSAGE_END_PERFORMATIVE"]._serialized_end = 845 43 | # @@protoc_insertion_point(module_scope) 44 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """ 21 | This module contains the classes required for default dialogue management. 22 | 23 | - DefaultDialogue: The dialogue class maintains state of a dialogue and manages it. 24 | - DefaultDialogues: The dialogues class keeps track of all dialogues. 25 | """ 26 | 27 | from abc import ABC 28 | from typing import Callable, Dict, FrozenSet, Type, cast 29 | 30 | from aea.common import Address 31 | from aea.protocols.base import Message 32 | from aea.protocols.dialogue.base import Dialogue, DialogueLabel, Dialogues 33 | 34 | from packages.valory.protocols.default.message import DefaultMessage 35 | 36 | 37 | class DefaultDialogue(Dialogue): 38 | """The default dialogue class maintains state of a dialogue and manages it.""" 39 | 40 | INITIAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( 41 | {DefaultMessage.Performative.BYTES, DefaultMessage.Performative.ERROR} 42 | ) 43 | TERMINAL_PERFORMATIVES: FrozenSet[Message.Performative] = frozenset( 44 | {DefaultMessage.Performative.END, DefaultMessage.Performative.ERROR} 45 | ) 46 | VALID_REPLIES: Dict[Message.Performative, FrozenSet[Message.Performative]] = { 47 | DefaultMessage.Performative.BYTES: frozenset( 48 | { 49 | DefaultMessage.Performative.BYTES, 50 | DefaultMessage.Performative.ERROR, 51 | DefaultMessage.Performative.END, 52 | } 53 | ), 54 | DefaultMessage.Performative.END: frozenset(), 55 | DefaultMessage.Performative.ERROR: frozenset(), 56 | } 57 | 58 | class Role(Dialogue.Role): 59 | """This class defines the agent's role in a default dialogue.""" 60 | 61 | AGENT = "agent" 62 | 63 | class EndState(Dialogue.EndState): 64 | """This class defines the end states of a default dialogue.""" 65 | 66 | SUCCESSFUL = 0 67 | FAILED = 1 68 | 69 | def __init__( 70 | self, 71 | dialogue_label: DialogueLabel, 72 | self_address: Address, 73 | role: Dialogue.Role, 74 | message_class: Type[DefaultMessage] = DefaultMessage, 75 | ) -> None: 76 | """ 77 | Initialize a dialogue. 78 | 79 | :param dialogue_label: the identifier of the dialogue 80 | :param self_address: the address of the entity for whom this dialogue is maintained 81 | :param role: the role of the agent this dialogue is maintained for 82 | :param message_class: the message class used 83 | """ 84 | Dialogue.__init__( 85 | self, 86 | dialogue_label=dialogue_label, 87 | message_class=message_class, 88 | self_address=self_address, 89 | role=role, 90 | ) 91 | 92 | 93 | class DefaultDialogues(Dialogues, ABC): 94 | """This class keeps track of all default dialogues.""" 95 | 96 | END_STATES = frozenset( 97 | {DefaultDialogue.EndState.SUCCESSFUL, DefaultDialogue.EndState.FAILED} 98 | ) 99 | 100 | _keep_terminal_state_dialogues = True 101 | 102 | def __init__( 103 | self, 104 | self_address: Address, 105 | role_from_first_message: Callable[[Message, Address], Dialogue.Role], 106 | dialogue_class: Type[DefaultDialogue] = DefaultDialogue, 107 | ) -> None: 108 | """ 109 | Initialize dialogues. 110 | 111 | :param self_address: the address of the entity for whom dialogues are maintained 112 | :param dialogue_class: the dialogue class used 113 | :param role_from_first_message: the callable determining role from first message 114 | """ 115 | Dialogues.__init__( 116 | self, 117 | self_address=self_address, 118 | end_states=cast(FrozenSet[Dialogue.EndState], self.END_STATES), 119 | message_class=DefaultMessage, 120 | dialogue_class=dialogue_class, 121 | role_from_first_message=role_from_first_message, 122 | ) 123 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/protocol.yaml: -------------------------------------------------------------------------------- 1 | name: default 2 | author: valory 3 | version: 1.0.0 4 | protocol_specification_id: valory/default:1.0.0 5 | type: protocol 6 | description: A protocol for exchanging any bytes message. 7 | license: Apache-2.0 8 | aea_version: '>=1.0.0, <2.0.0' 9 | fingerprint: 10 | README.md: bafybeignmf6cibowaii3h7vhdwctj67upzu3nhlsgc4zvqawf7zqyebt6m 11 | __init__.py: bafybeieg6vsjgnfshtsn77qe6j5t7q5uofpp4xgtnktp7ktkd5aaet6ybu 12 | custom_types.py: bafybeibrbholfmbipktfhl336v6xhaa3zypb4yoqlcfddjfka4qcodfwni 13 | default.proto: bafybeibrzpusdjc5gvinf2iok7xm7mexre4ucxjqjvvt5tmxi5o3f3p5c4 14 | default_pb2.py: bafybeigpidaesu5wflqfy7xoqqhct7nauqucsb3ta5o2e755b2l6oxrsoi 15 | dialogues.py: bafybeibpxuq6eqn53xwtbjnqjaeme5pbeuvteefpq54w7qbdhjvhick53q 16 | message.py: bafybeihupv2fba722psun4xvjbk4gvmilnmc74kxobkz2kpcb7rodeyuzm 17 | serialization.py: bafybeidvybyzhuhwl3o5l4hc7w6ekmyco4jgh6qcp2cvcpvsl36iks3fva 18 | tests/test_default_dialogues.py: bafybeib4u3jf724x3fozrinusj4oxwzhzzbqufsy2zwiiv2fjxzmjgq23q 19 | tests/test_default_messages.py: bafybeif45s7gyfve4owf6de6n6j6fa7fdg6ysny3bjfgvyikcyedzucr4a 20 | fingerprint_ignore_patterns: [] 21 | dependencies: 22 | protobuf: {} 23 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/tests/test_default_dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Test dialogues module for default protocol.""" 21 | 22 | # pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin 23 | from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase 24 | 25 | from packages.valory.protocols.default.dialogues import ( 26 | DefaultDialogue, 27 | DefaultDialogues, 28 | ) 29 | from packages.valory.protocols.default.message import DefaultMessage 30 | 31 | 32 | class TestDialoguesDefault(BaseProtocolDialoguesTestCase): 33 | """Test for the 'default' protocol dialogues.""" 34 | 35 | MESSAGE_CLASS = DefaultMessage 36 | 37 | DIALOGUE_CLASS = DefaultDialogue 38 | 39 | DIALOGUES_CLASS = DefaultDialogues 40 | 41 | ROLE_FOR_THE_FIRST_MESSAGE = DefaultDialogue.Role.AGENT # CHECK 42 | 43 | def make_message_content(self) -> dict: 44 | """Make a dict with message contruction content for dialogues.create.""" 45 | return dict( 46 | performative=DefaultMessage.Performative.BYTES, 47 | content=b"some_bytes", 48 | ) 49 | -------------------------------------------------------------------------------- /packages/valory/protocols/default/tests/test_default_messages.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Test messages module for default protocol.""" 21 | 22 | # pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin 23 | from typing import List 24 | 25 | from aea.test_tools.test_protocol import BaseProtocolMessagesTestCase 26 | 27 | from packages.valory.protocols.default.custom_types import ErrorCode 28 | from packages.valory.protocols.default.message import DefaultMessage 29 | 30 | 31 | class TestMessageDefault(BaseProtocolMessagesTestCase): 32 | """Test for the 'default' protocol message.""" 33 | 34 | MESSAGE_CLASS = DefaultMessage 35 | 36 | def build_messages(self) -> List[DefaultMessage]: # type: ignore[override] 37 | """Build the messages to be used for testing.""" 38 | return [ 39 | DefaultMessage( 40 | performative=DefaultMessage.Performative.BYTES, 41 | content=b"some_bytes", 42 | ), 43 | DefaultMessage( 44 | performative=DefaultMessage.Performative.ERROR, 45 | error_code=ErrorCode.DECODING_ERROR, # check it please! 46 | error_msg="some str", 47 | error_data={"some str": b"some_bytes"}, 48 | ), 49 | DefaultMessage( 50 | performative=DefaultMessage.Performative.END, 51 | ), 52 | ] 53 | 54 | def build_inconsistent(self) -> List[DefaultMessage]: # type: ignore[override] 55 | """Build inconsistent messages to be used for testing.""" 56 | return [ 57 | DefaultMessage( 58 | performative=DefaultMessage.Performative.BYTES, 59 | # skip content: content 60 | ), 61 | DefaultMessage( 62 | performative=DefaultMessage.Performative.ERROR, 63 | # skip content: error_code 64 | error_msg="some str", 65 | error_data={"some str": b"some_bytes"}, 66 | ), 67 | ] 68 | -------------------------------------------------------------------------------- /packages/valory/protocols/websocket_client/README.md: -------------------------------------------------------------------------------- 1 | # Websocket Client Protocol 2 | 3 | ## Description 4 | 5 | This is a protocol for communicating with websocket servers. 6 | 7 | ## Specification 8 | 9 | ```yaml 10 | --- 11 | name: websocket_client 12 | author: valory 13 | version: 0.1.0 14 | description: A protocol for websocket client. 15 | license: Apache-2.0 16 | aea_version: '>=1.0.0, <2.0.0' 17 | protocol_specification_id: valory/websocket_client:1.0.0 18 | speech_acts: 19 | subscribe: 20 | url: pt:str 21 | subscription_id: pt:str 22 | subscription_payload: pt:optional[pt:str] 23 | subscription: 24 | alive: pt:bool 25 | subscription_id: pt:str 26 | check_subscription: 27 | alive: pt:bool 28 | subscription_id: pt:str 29 | send: 30 | payload: pt:str 31 | subscription_id: pt:str 32 | send_success: 33 | send_length: pt:int 34 | subscription_id: pt:str 35 | recv: 36 | data: pt:str 37 | subscription_id: pt:str 38 | error: 39 | alive: pt:bool 40 | message: pt:str 41 | subscription_id: pt:str 42 | ... 43 | --- 44 | initiation: [subscribe,check_subscription,send] 45 | reply: 46 | subscribe: [subscription, recv, error] 47 | subscription: [] 48 | check_subscription: [subscription, error] 49 | send: [send_success, recv, error] 50 | send_success: [] 51 | recv: [] 52 | error: [] 53 | termination: [recv,send_success,subscription,error] 54 | roles: {skill, connection} 55 | end_states: [successful] 56 | keep_terminal_state_dialogues: false 57 | ... 58 | ``` 59 | 60 | ## Links 61 | 62 | -------------------------------------------------------------------------------- /packages/valory/protocols/websocket_client/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """ 21 | This module contains the support resources for the websocket_client protocol. 22 | 23 | It was created with protocol buffer compiler version `libprotoc 3.19.4` and aea protocol generator version `1.0.0`. 24 | """ 25 | 26 | from packages.valory.protocols.websocket_client.message import WebsocketClientMessage 27 | from packages.valory.protocols.websocket_client.serialization import ( 28 | WebsocketClientSerializer, 29 | ) 30 | 31 | 32 | WebsocketClientMessage.serializer = WebsocketClientSerializer 33 | -------------------------------------------------------------------------------- /packages/valory/protocols/websocket_client/protocol.yaml: -------------------------------------------------------------------------------- 1 | name: websocket_client 2 | author: valory 3 | version: 0.1.0 4 | protocol_specification_id: valory/websocket_client:1.0.0 5 | type: protocol 6 | description: A protocol for websocket client. 7 | license: Apache-2.0 8 | aea_version: '>=1.0.0, <2.0.0' 9 | fingerprint: 10 | README.md: bafybeieot47xhqlvc3dwl2hc4yq3f6wcva7xf5dx5wz5n4ir6woknyqrsi 11 | __init__.py: bafybeifhhqtcfac5lcrjxrcdpsrs3kyyxt7uf2qv2a4ivllyyt3c62q4aq 12 | dialogues.py: bafybeienrjdbwqsx4dikqo3wjfgner5pz5qtbwfb2qtzsukn6iog6e4iyi 13 | message.py: bafybeigpuhz4fw5ng3qay7duci7qhb4rj336wb2qwiyszddkjmnjebf72e 14 | serialization.py: bafybeiar6guqw2qgofycbjuyhy7puxill5wcy6hsyrqmbkzcjzitxuws5i 15 | tests/test_websocket_client_dialogues.py: bafybeig7cd7mllqmk6w4oaz7wqwubueaa4hpofgplhzeivqtwihalhpnne 16 | tests/test_websocket_client_messages.py: bafybeibboz4j4itkwjh5ahza53v4d4dew3qxqq6fsbzragz76wnjin254u 17 | websocket_client.proto: bafybeifqkmkqzbepxkj56o45ljysxujmoftjlm6pkllj7t4tbryqt42ql4 18 | websocket_client_pb2.py: bafybeicov77amgzltypi7ncgy32pigh7zwlluzcbrbwjtr6q4jpvqgowg4 19 | fingerprint_ignore_patterns: [] 20 | dependencies: 21 | protobuf: {} 22 | -------------------------------------------------------------------------------- /packages/valory/protocols/websocket_client/tests/test_websocket_client_dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 valory 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Test dialogues module for websocket_client protocol.""" 21 | 22 | # pylint: disable=too-many-statements,too-many-locals,no-member,too-few-public-methods,redefined-builtin 23 | from aea.test_tools.test_protocol import BaseProtocolDialoguesTestCase 24 | 25 | from packages.valory.protocols.websocket_client.dialogues import ( 26 | WebsocketClientDialogue, 27 | WebsocketClientDialogues, 28 | ) 29 | from packages.valory.protocols.websocket_client.message import WebsocketClientMessage 30 | 31 | 32 | class TestDialoguesWebsocketClient(BaseProtocolDialoguesTestCase): 33 | """Test for the 'websocket_client' protocol dialogues.""" 34 | 35 | MESSAGE_CLASS = WebsocketClientMessage 36 | 37 | DIALOGUE_CLASS = WebsocketClientDialogue 38 | 39 | DIALOGUES_CLASS = WebsocketClientDialogues 40 | 41 | ROLE_FOR_THE_FIRST_MESSAGE = WebsocketClientDialogue.Role.CONNECTION # CHECK 42 | 43 | def make_message_content(self) -> dict: 44 | """Make a dict with message contruction content for dialogues.create.""" 45 | return dict( 46 | performative=WebsocketClientMessage.Performative.SUBSCRIBE, 47 | url="some str", 48 | subscription_id="some str", 49 | subscription_payload="some str", 50 | ) 51 | -------------------------------------------------------------------------------- /packages/valory/protocols/websocket_client/websocket_client.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package aea.valory.websocket_client.v1_0_0; 4 | 5 | message WebsocketClientMessage{ 6 | 7 | // Performatives and contents 8 | message Subscribe_Performative{ 9 | string url = 1; 10 | string subscription_id = 2; 11 | string subscription_payload = 3; 12 | bool subscription_payload_is_set = 4; 13 | } 14 | 15 | message Subscription_Performative{ 16 | bool alive = 1; 17 | string subscription_id = 2; 18 | } 19 | 20 | message Check_Subscription_Performative{ 21 | bool alive = 1; 22 | string subscription_id = 2; 23 | } 24 | 25 | message Send_Performative{ 26 | string payload = 1; 27 | string subscription_id = 2; 28 | } 29 | 30 | message Send_Success_Performative{ 31 | int32 send_length = 1; 32 | string subscription_id = 2; 33 | } 34 | 35 | message Recv_Performative{ 36 | string data = 1; 37 | string subscription_id = 2; 38 | } 39 | 40 | message Error_Performative{ 41 | bool alive = 1; 42 | string message = 2; 43 | string subscription_id = 3; 44 | } 45 | 46 | 47 | oneof performative{ 48 | Check_Subscription_Performative check_subscription = 5; 49 | Error_Performative error = 6; 50 | Recv_Performative recv = 7; 51 | Send_Performative send = 8; 52 | Send_Success_Performative send_success = 9; 53 | Subscribe_Performative subscribe = 10; 54 | Subscription_Performative subscription = 11; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/valory/services/mech/README.md: -------------------------------------------------------------------------------- 1 | ## Mech Service 2 | -------------------------------------------------------------------------------- /packages/valory/skills/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the skills packages authored by Valory AG.""" 21 | -------------------------------------------------------------------------------- /packages/valory/skills/contract_subscription/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # Copyright 2023 eightballer 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """This module contains the implementation of the default skill.""" 22 | 23 | from aea.configurations.base import PublicId 24 | 25 | 26 | PUBLIC_ID = PublicId.from_str("valory/contract_subscription:0.1.0") 27 | -------------------------------------------------------------------------------- /packages/valory/skills/contract_subscription/behaviours.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # Copyright 2023 eightballer 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """This package contains a scaffold of a behaviour.""" 22 | 23 | import json 24 | from typing import Any, cast 25 | 26 | from packages.valory.connections.websocket_client.connection import WebSocketClient 27 | from packages.valory.skills.contract_subscription.handlers import DISCONNECTION_POINT 28 | from packages.valory.skills.contract_subscription.models import Params 29 | from packages.valory.skills.websocket_client.behaviours import ( 30 | SubscriptionBehaviour as BaseSubscriptionBehaviour, 31 | ) 32 | from packages.valory.skills.websocket_client.handlers import ( 33 | SubscriptionStatus, 34 | WEBSOCKET_SUBSCRIPTION_STATUS, 35 | ) 36 | 37 | 38 | DEFAULT_ENCODING = "utf-8" 39 | WEBSOCKET_CLIENT_CONNECTION_NAME = "websocket_client" 40 | 41 | 42 | class ContractSubscriptionBehaviour(BaseSubscriptionBehaviour): 43 | """This class scaffolds a behaviour.""" 44 | 45 | def __init__(self, **kwargs: Any) -> None: 46 | """Initialise the agent.""" 47 | super().__init__(**kwargs) 48 | 49 | @property 50 | def params(self) -> Params: 51 | """Return params model.""" 52 | 53 | return cast(Params, self.context.params) 54 | 55 | def setup(self) -> None: 56 | """Implement the setup.""" 57 | self._last_subscription_check = None 58 | 59 | # if we are using polling, then we don't set up an contract subscription 60 | if self.params.use_polling: 61 | return 62 | 63 | for connection in self.context.outbox._multiplexer.connections: 64 | if connection.component_id.name == WEBSOCKET_CLIENT_CONNECTION_NAME: 65 | self._ws_client_connection = cast(WebSocketClient, connection) 66 | 67 | def create_contract_subscription_payload(self) -> str: 68 | """Create subscription payload.""" 69 | return json.dumps( 70 | { 71 | "jsonrpc": "2.0", 72 | "id": 1, 73 | "method": "eth_subscribe", 74 | "params": ["logs", {"address": self.params.contract_address}], 75 | } 76 | ) 77 | 78 | def create_contract_filter_payload(self, disconnection_point: int) -> str: 79 | """Create subscription payload.""" 80 | return json.dumps( 81 | { 82 | "jsonrpc": "2.0", 83 | "id": 1, 84 | "method": "eth_newFilter", 85 | "params": [ 86 | { 87 | "fromBlock": disconnection_point, 88 | "address": self.params.contract_address, 89 | } 90 | ], 91 | } 92 | ) 93 | 94 | def act(self) -> None: 95 | """Perform subcription.""" 96 | 97 | if self.params.use_polling: 98 | # do nothing if we are polling 99 | return 100 | 101 | if self.subscribing or self.checking_subscription: 102 | return 103 | 104 | disconnection_point = self.context.shared_state.get(DISCONNECTION_POINT, None) 105 | if self.subscribed and disconnection_point is not None: 106 | self.context.logger.info( 107 | f"Requesting block filter for {disconnection_point}" 108 | ) 109 | self._ws_send( 110 | payload=self.create_contract_filter_payload( 111 | disconnection_point=disconnection_point 112 | ), 113 | subscription_id=self.params.subscription_id, 114 | ) 115 | self.context.shared_state[DISCONNECTION_POINT] = None 116 | 117 | if self.subscribed: 118 | self.check_subscription() 119 | return 120 | 121 | if self.unsubscribed: 122 | self._create_subscription( 123 | provider=self.params.websocket_provider, 124 | subscription_id=self.params.subscription_id, 125 | subscription_payload=self.create_contract_subscription_payload(), 126 | ) 127 | self.context.shared_state[WEBSOCKET_SUBSCRIPTION_STATUS][ 128 | self.params.subscription_id 129 | ] = SubscriptionStatus.SUBSCRIBING 130 | return 131 | -------------------------------------------------------------------------------- /packages/valory/skills/contract_subscription/dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # Copyright 2023 eightballer 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | 22 | """Dialogues""" 23 | 24 | from typing import Any 25 | 26 | from aea.common import Address 27 | from aea.protocols.base import Message 28 | from aea.protocols.dialogue.base import Dialogue as BaseDialogue 29 | from aea.skills.base import Model 30 | 31 | from packages.valory.protocols.websocket_client.dialogues import ( 32 | WebsocketClientDialogue as BaseWebsocketClientDialogue, 33 | ) 34 | from packages.valory.protocols.websocket_client.dialogues import ( 35 | WebsocketClientDialogues as BaseWebsocketClientDialogues, 36 | ) 37 | 38 | 39 | WebsocketClientDialogue = BaseWebsocketClientDialogue 40 | 41 | 42 | class WebsocketClientDialogues(Model, BaseWebsocketClientDialogues): 43 | """The dialogues class keeps track of all dialogues.""" 44 | 45 | def __init__(self, **kwargs: Any) -> None: 46 | """ 47 | Initialize dialogues. 48 | 49 | :param kwargs: keyword arguments 50 | """ 51 | Model.__init__(self, **kwargs) 52 | 53 | def role_from_first_message( # pylint: disable=unused-argument 54 | message: Message, receiver_address: Address 55 | ) -> BaseDialogue.Role: 56 | """Infer the role of the agent from an incoming/outgoing first message 57 | 58 | :param message: an incoming/outgoing first message 59 | :param receiver_address: the address of the receiving agent 60 | :return: The role of the agent 61 | """ 62 | return WebsocketClientDialogue.Role.SKILL 63 | 64 | BaseWebsocketClientDialogues.__init__( 65 | self, 66 | self_address=str(self.skill_id), 67 | role_from_first_message=role_from_first_message, 68 | ) 69 | -------------------------------------------------------------------------------- /packages/valory/skills/contract_subscription/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the shared state for the abci skill of Mech.""" 21 | from typing import Any 22 | 23 | from packages.valory.skills.websocket_client.models import Params as BaseParams 24 | 25 | 26 | DEFAULT_WEBSOCKET_PROVIDER = "ws://localhost:8001" 27 | DEFAULT_CONTRACT_ADDRESS = "0xFf82123dFB52ab75C417195c5fDB87630145ae81" 28 | 29 | 30 | class Params(BaseParams): 31 | """A model to represent params for multiple abci apps.""" 32 | 33 | def __init__(self, *args: Any, **kwargs: Any) -> None: 34 | """Initialize the parameters object.""" 35 | super().__init__(*args, **kwargs) 36 | 37 | self.use_polling = kwargs.get("use_polling", False) 38 | self.contract_address = kwargs.get("contract_address", DEFAULT_CONTRACT_ADDRESS) 39 | -------------------------------------------------------------------------------- /packages/valory/skills/contract_subscription/skill.yaml: -------------------------------------------------------------------------------- 1 | name: contract_subscription 2 | author: valory 3 | version: 0.1.0 4 | type: skill 5 | description: A simple skill to subscribe to events on a particular contract using 6 | the websocket connection. 7 | license: Apache-2.0 8 | aea_version: '>=1.0.0, <2.0.0' 9 | fingerprint: 10 | __init__.py: bafybeihmbiavlq5ekiat57xuekfuxjkoniizurn77hivqwtsaqydv32owu 11 | behaviours.py: bafybeihhhfpan6i5vzxaoggmnj5jw556wnxz75ufcmiucq3yygrbmlsdpm 12 | dialogues.py: bafybeigxlbj6mte72ko7osykjfilg4udfmnrnhxtoib5k4xcxde6qi3niu 13 | handlers.py: bafybeiasnq4qlq5qys4ugktetmaeqnreaswvaqyi7zvjjlifmhbylucasu 14 | models.py: bafybeiafdc32u7yjph4kb4tvsdsaz4tpzo25m3gmthssc62newpgvrros4 15 | fingerprint_ignore_patterns: [] 16 | connections: 17 | - valory/websocket_client:0.1.0:bafybeic4ag3gqc7kd3k2o3pucddj2odck5yrfbgmwh5veqny7zao5qayli 18 | contracts: [] 19 | protocols: 20 | - valory/websocket_client:0.1.0:bafybeifjk254sy65rna2k32kynzenutujwqndap2r222afvr3zezi27mx4 21 | skills: 22 | - valory/websocket_client:0.1.0:bafybeif7rrvsu6z4evqkhblxj3u6wwv2eqou576hgkyoehxuj7cntw7o2m 23 | behaviours: 24 | contract_subscriptions: 25 | args: {} 26 | class_name: ContractSubscriptionBehaviour 27 | handlers: 28 | new_event: 29 | args: 30 | contract_to_monitor: '0xFf82123dFB52ab75C417195c5fDB87630145ae81' 31 | websocket_provider: https://rpc.gnosischain.com 32 | class_name: WebSocketHandler 33 | models: 34 | websocket_client_dialogues: 35 | args: {} 36 | class_name: WebsocketClientDialogues 37 | params: 38 | args: 39 | use_polling: false 40 | websocket_provider: ws://localhost:8001 41 | contract_address: '0xFf82123dFB52ab75C417195c5fDB87630145ae81' 42 | subscription_id: mech-contract-subscription 43 | class_name: Params 44 | dependencies: 45 | web3: 46 | version: <7,>=6.0.0 47 | is_abstract: false 48 | -------------------------------------------------------------------------------- /packages/valory/skills/delivery_rate_abci/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the implementation of the update delivery rates skill.""" 21 | 22 | from aea.configurations.base import PublicId 23 | 24 | 25 | PUBLIC_ID = PublicId.from_str("valory/delivery_rate_abci:0.1.0") 26 | -------------------------------------------------------------------------------- /packages/valory/skills/delivery_rate_abci/dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the dialogues of the UpdateDeliveryRateAbciApp.""" 21 | 22 | from typing import Any 23 | 24 | from aea.common import Address 25 | from aea.protocols.base import Message 26 | from aea.protocols.dialogue.base import Dialogue as BaseDialogue 27 | from aea.skills.base import Model 28 | 29 | from packages.valory.protocols.acn_data_share.dialogues import ( 30 | AcnDataShareDialogue as BaseAcnDataShareDialogue, 31 | ) 32 | from packages.valory.protocols.acn_data_share.dialogues import ( 33 | AcnDataShareDialogues as BaseAcnDataShareDialogues, 34 | ) 35 | from packages.valory.skills.abstract_round_abci.dialogues import ( 36 | AbciDialogue as BaseAbciDialogue, 37 | ) 38 | from packages.valory.skills.abstract_round_abci.dialogues import ( 39 | AbciDialogues as BaseAbciDialogues, 40 | ) 41 | from packages.valory.skills.abstract_round_abci.dialogues import ( 42 | ContractApiDialogue as BaseContractApiDialogue, 43 | ) 44 | from packages.valory.skills.abstract_round_abci.dialogues import ( 45 | ContractApiDialogues as BaseContractApiDialogues, 46 | ) 47 | from packages.valory.skills.abstract_round_abci.dialogues import ( 48 | HttpDialogue as BaseHttpDialogue, 49 | ) 50 | from packages.valory.skills.abstract_round_abci.dialogues import ( 51 | HttpDialogues as BaseHttpDialogues, 52 | ) 53 | from packages.valory.skills.abstract_round_abci.dialogues import ( 54 | IpfsDialogue as BaseIpfsDialogue, 55 | ) 56 | from packages.valory.skills.abstract_round_abci.dialogues import ( 57 | IpfsDialogues as BaseIpfsDialogues, 58 | ) 59 | from packages.valory.skills.abstract_round_abci.dialogues import ( 60 | LedgerApiDialogue as BaseLedgerApiDialogue, 61 | ) 62 | from packages.valory.skills.abstract_round_abci.dialogues import ( 63 | LedgerApiDialogues as BaseLedgerApiDialogues, 64 | ) 65 | from packages.valory.skills.abstract_round_abci.dialogues import ( 66 | SigningDialogue as BaseSigningDialogue, 67 | ) 68 | from packages.valory.skills.abstract_round_abci.dialogues import ( 69 | SigningDialogues as BaseSigningDialogues, 70 | ) 71 | from packages.valory.skills.abstract_round_abci.dialogues import ( 72 | TendermintDialogue as BaseTendermintDialogue, 73 | ) 74 | from packages.valory.skills.abstract_round_abci.dialogues import ( 75 | TendermintDialogues as BaseTendermintDialogues, 76 | ) 77 | 78 | 79 | AbciDialogue = BaseAbciDialogue 80 | AbciDialogues = BaseAbciDialogues 81 | 82 | 83 | HttpDialogue = BaseHttpDialogue 84 | HttpDialogues = BaseHttpDialogues 85 | 86 | 87 | SigningDialogue = BaseSigningDialogue 88 | SigningDialogues = BaseSigningDialogues 89 | 90 | 91 | LedgerApiDialogue = BaseLedgerApiDialogue 92 | LedgerApiDialogues = BaseLedgerApiDialogues 93 | 94 | 95 | ContractApiDialogue = BaseContractApiDialogue 96 | ContractApiDialogues = BaseContractApiDialogues 97 | 98 | 99 | TendermintDialogue = BaseTendermintDialogue 100 | TendermintDialogues = BaseTendermintDialogues 101 | 102 | 103 | IpfsDialogue = BaseIpfsDialogue 104 | IpfsDialogues = BaseIpfsDialogues 105 | 106 | 107 | AcnDataShareDialogue = BaseAcnDataShareDialogue 108 | 109 | 110 | class AcnDataShareDialogues(Model, BaseAcnDataShareDialogues): 111 | """The dialogues class keeps track of all dialogues.""" 112 | 113 | def __init__(self, **kwargs: Any) -> None: 114 | """ 115 | Initialize dialogues. 116 | 117 | :param kwargs: keyword arguments 118 | """ 119 | Model.__init__(self, **kwargs) 120 | 121 | def role_from_first_message( # pylint: disable=unused-argument 122 | message: Message, receiver_address: Address 123 | ) -> BaseDialogue.Role: 124 | """Infer the role of the agent from an incoming/outgoing first message 125 | 126 | :param message: an incoming/outgoing first message 127 | :param receiver_address: the address of the receiving agent 128 | :return: The role of the agent 129 | """ 130 | return AcnDataShareDialogue.Role.AGENT 131 | 132 | BaseAcnDataShareDialogues.__init__( 133 | self, 134 | self_address=str(self.context.agent_address), 135 | role_from_first_message=role_from_first_message, 136 | ) 137 | -------------------------------------------------------------------------------- /packages/valory/skills/delivery_rate_abci/fsm_specification.yaml: -------------------------------------------------------------------------------- 1 | alphabet_in: 2 | - DONE 3 | - ERROR 4 | - NO_MAJORITY 5 | - NO_TX 6 | default_start_state: UpdateDeliveryRateRound 7 | final_states: 8 | - FinishedWithTxRound 9 | - FinishedWithoutTxRound 10 | label: DeliveryRateUpdateAbciApp 11 | start_states: 12 | - UpdateDeliveryRateRound 13 | states: 14 | - FinishedWithTxRound 15 | - FinishedWithoutTxRound 16 | - UpdateDeliveryRateRound 17 | transition_func: 18 | (UpdateDeliveryRateRound, DONE): FinishedWithTxRound 19 | (UpdateDeliveryRateRound, ERROR): UpdateDeliveryRateRound 20 | (UpdateDeliveryRateRound, NO_MAJORITY): UpdateDeliveryRateRound 21 | (UpdateDeliveryRateRound, NO_TX): FinishedWithoutTxRound 22 | -------------------------------------------------------------------------------- /packages/valory/skills/delivery_rate_abci/handlers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the handlers for the skill of UpdateDeliveryRateAbciApp.""" 21 | 22 | 23 | from packages.valory.skills.abstract_round_abci.handlers import ( 24 | ABCIRoundHandler as BaseABCIRoundHandler, 25 | ) 26 | from packages.valory.skills.abstract_round_abci.handlers import ( 27 | ContractApiHandler as BaseContractApiHandler, 28 | ) 29 | from packages.valory.skills.abstract_round_abci.handlers import ( 30 | HttpHandler as BaseHttpHandler, 31 | ) 32 | from packages.valory.skills.abstract_round_abci.handlers import ( 33 | IpfsHandler as BaseIpfsHandler, 34 | ) 35 | from packages.valory.skills.abstract_round_abci.handlers import ( 36 | LedgerApiHandler as BaseLedgerApiHandler, 37 | ) 38 | from packages.valory.skills.abstract_round_abci.handlers import ( 39 | SigningHandler as BaseSigningHandler, 40 | ) 41 | from packages.valory.skills.abstract_round_abci.handlers import ( 42 | TendermintHandler as BaseTendermintHandler, 43 | ) 44 | 45 | 46 | ABCIHandler = BaseABCIRoundHandler 47 | HttpHandler = BaseHttpHandler 48 | SigningHandler = BaseSigningHandler 49 | LedgerApiHandler = BaseLedgerApiHandler 50 | ContractApiHandler = BaseContractApiHandler 51 | TendermintHandler = BaseTendermintHandler 52 | IpfsHandler = BaseIpfsHandler 53 | -------------------------------------------------------------------------------- /packages/valory/skills/delivery_rate_abci/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the shared state for the abci skill of UpdateDeliveryRateAbciApp.""" 21 | from dataclasses import dataclass 22 | from typing import Any, Optional, Type, Dict, List 23 | 24 | from aea.exceptions import enforce 25 | 26 | from packages.valory.skills.abstract_round_abci.base import AbciApp 27 | from packages.valory.skills.abstract_round_abci.models import BaseParams 28 | from packages.valory.skills.abstract_round_abci.models import ( 29 | BenchmarkTool as BaseBenchmarkTool, 30 | ) 31 | from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests 32 | from packages.valory.skills.abstract_round_abci.models import ( 33 | SharedState as BaseSharedState, 34 | ) 35 | from packages.valory.skills.abstract_round_abci.models import TypeCheckMixin 36 | from packages.valory.skills.abstract_round_abci.utils import check_type 37 | from packages.valory.skills.delivery_rate_abci.rounds import DeliveryRateUpdateAbciApp 38 | 39 | 40 | class SharedState(BaseSharedState): 41 | """Keep the current shared state of the skill.""" 42 | 43 | abci_app_cls: Type[AbciApp] = DeliveryRateUpdateAbciApp 44 | 45 | 46 | @dataclass 47 | class MutableParams(TypeCheckMixin): 48 | """Collection for the mutable parameters.""" 49 | 50 | latest_metadata_hash: Optional[bytes] = None 51 | 52 | 53 | class Params(BaseParams): 54 | """Parameters.""" 55 | 56 | def __init__(self, *args: Any, **kwargs: Any) -> None: 57 | """Initialize the parameters object.""" 58 | 59 | self.mech_to_max_delivery_rate: Dict[str, int] = self._ensure_get( 60 | "mech_to_max_delivery_rate", kwargs, Dict[str, int] 61 | ) 62 | self.manual_gas_limit = self._ensure_get("manual_gas_limit", kwargs, int) 63 | self.multisend_address = self._ensure_get("multisend_address", kwargs, str) 64 | super().__init__(*args, **kwargs) 65 | 66 | @classmethod 67 | def _ensure_get(cls, key: str, kwargs: Dict, type_: Any) -> Any: 68 | """Ensure that the parameters are set, and return them without popping the key.""" 69 | enforce("skill_context" in kwargs, "Only use on models!") 70 | skill_id = kwargs["skill_context"].skill_id 71 | enforce( 72 | key in kwargs, 73 | f"'{key}' of type '{type_}' required, but it is not set in `models.params.args` of `skill.yaml` of `{skill_id}`", 74 | ) 75 | value = kwargs.get(key, None) 76 | try: 77 | check_type(key, value, type_) 78 | except TypeError: # pragma: nocover 79 | enforce( 80 | False, 81 | f"'{key}' must be a {type_}, but type {type(value)} was found in `models.params.args` of `skill.yaml` of `{skill_id}`", 82 | ) 83 | return value 84 | 85 | 86 | Requests = BaseRequests 87 | BenchmarkTool = BaseBenchmarkTool 88 | -------------------------------------------------------------------------------- /packages/valory/skills/delivery_rate_abci/payloads.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the transaction payloads of the UpdateDeliveryRateAbciApp.""" 21 | 22 | from dataclasses import dataclass 23 | 24 | from packages.valory.skills.abstract_round_abci.base import BaseTxPayload 25 | 26 | 27 | @dataclass(frozen=True) 28 | class UpdateDeliveryRatePayload(BaseTxPayload): 29 | """Represent a transaction payload for the UpdateDeliveryRateRound.""" 30 | 31 | content: str 32 | -------------------------------------------------------------------------------- /packages/valory/skills/mech_abci/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the implementation of the mech_abci skill.""" 21 | 22 | from aea.configurations.base import PublicId 23 | 24 | 25 | PUBLIC_ID = PublicId.from_str("valory/mech_abci:0.1.0") 26 | -------------------------------------------------------------------------------- /packages/valory/skills/mech_abci/behaviours.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This package contains round behaviours of Mech.""" 21 | 22 | from typing import Set, Type 23 | 24 | from packages.valory.skills.abstract_round_abci.behaviours import ( 25 | AbstractRoundBehaviour, 26 | BaseBehaviour, 27 | ) 28 | from packages.valory.skills.delivery_rate_abci.behaviours import ( 29 | UpdateDeliveryRateRoundBehaviour, 30 | ) 31 | from packages.valory.skills.mech_abci.composition import MechAbciApp 32 | from packages.valory.skills.registration_abci.behaviours import ( 33 | AgentRegistrationRoundBehaviour, 34 | RegistrationStartupBehaviour, 35 | ) 36 | from packages.valory.skills.reset_pause_abci.behaviours import ( 37 | ResetPauseABCIConsensusBehaviour, 38 | ) 39 | from packages.valory.skills.task_submission_abci.behaviours import ( 40 | TaskSubmissionRoundBehaviour, 41 | ) 42 | from packages.valory.skills.termination_abci.behaviours import ( 43 | BackgroundBehaviour, 44 | TerminationAbciBehaviours, 45 | ) 46 | from packages.valory.skills.transaction_settlement_abci.behaviours import ( 47 | TransactionSettlementRoundBehaviour, 48 | ) 49 | 50 | 51 | class MechConsensusBehaviour(AbstractRoundBehaviour): 52 | """Class to define the behaviours this AbciApp has.""" 53 | 54 | initial_behaviour_cls = RegistrationStartupBehaviour 55 | abci_app_cls = MechAbciApp 56 | behaviours: Set[Type[BaseBehaviour]] = { 57 | *TaskSubmissionRoundBehaviour.behaviours, 58 | *AgentRegistrationRoundBehaviour.behaviours, 59 | *ResetPauseABCIConsensusBehaviour.behaviours, 60 | *TransactionSettlementRoundBehaviour.behaviours, 61 | *TerminationAbciBehaviours.behaviours, 62 | *UpdateDeliveryRateRoundBehaviour.behaviours, 63 | } 64 | background_behaviours_cls = {BackgroundBehaviour} # type: ignore 65 | -------------------------------------------------------------------------------- /packages/valory/skills/mech_abci/composition.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This package contains round behaviours of MechAbciApp.""" 21 | 22 | import packages.valory.skills.delivery_rate_abci.rounds as DeliveryRateUpdateAbciApp 23 | import packages.valory.skills.registration_abci.rounds as RegistrationAbci 24 | import packages.valory.skills.reset_pause_abci.rounds as ResetAndPauseAbci 25 | import packages.valory.skills.task_submission_abci.rounds as TaskSubmissionAbciApp 26 | import packages.valory.skills.transaction_settlement_abci.rounds as TransactionSubmissionAbciApp 27 | from packages.valory.skills.abstract_round_abci.abci_app_chain import ( 28 | AbciAppTransitionMapping, 29 | chain, 30 | ) 31 | from packages.valory.skills.abstract_round_abci.base import BackgroundAppConfig 32 | from packages.valory.skills.termination_abci.rounds import ( 33 | BackgroundRound, 34 | Event, 35 | TerminationAbciApp, 36 | ) 37 | 38 | 39 | # Here we define how the transition between the FSMs should happen 40 | # more information here: https://docs.autonolas.network/fsm_app_introduction/#composition-of-fsm-apps 41 | abci_app_transition_mapping: AbciAppTransitionMapping = { 42 | RegistrationAbci.FinishedRegistrationRound: DeliveryRateUpdateAbciApp.UpdateDeliveryRateRound, 43 | DeliveryRateUpdateAbciApp.FinishedWithoutTxRound: TaskSubmissionAbciApp.TaskPoolingRound, 44 | DeliveryRateUpdateAbciApp.FinishedWithTxRound: TransactionSubmissionAbciApp.RandomnessTransactionSubmissionRound, # pylint: disable=C0301 45 | TaskSubmissionAbciApp.FinishedTaskPoolingRound: TransactionSubmissionAbciApp.RandomnessTransactionSubmissionRound, # pylint: disable=C0301 46 | TaskSubmissionAbciApp.FinishedTaskExecutionWithErrorRound: ResetAndPauseAbci.ResetAndPauseRound, 47 | TaskSubmissionAbciApp.FinishedWithoutTasksRound: ResetAndPauseAbci.ResetAndPauseRound, 48 | TransactionSubmissionAbciApp.FinishedTransactionSubmissionRound: ResetAndPauseAbci.ResetAndPauseRound, 49 | TransactionSubmissionAbciApp.FailedRound: ResetAndPauseAbci.ResetAndPauseRound, 50 | ResetAndPauseAbci.FinishedResetAndPauseRound: TaskSubmissionAbciApp.TaskPoolingRound, 51 | ResetAndPauseAbci.FinishedResetAndPauseErrorRound: RegistrationAbci.RegistrationRound, 52 | } 53 | 54 | termination_config = BackgroundAppConfig( 55 | round_cls=BackgroundRound, 56 | start_event=Event.TERMINATE, 57 | abci_app=TerminationAbciApp, 58 | ) 59 | 60 | MechAbciApp = chain( 61 | ( 62 | RegistrationAbci.AgentRegistrationAbciApp, 63 | TaskSubmissionAbciApp.TaskSubmissionAbciApp, 64 | ResetAndPauseAbci.ResetPauseAbciApp, 65 | TransactionSubmissionAbciApp.TransactionSubmissionAbciApp, 66 | DeliveryRateUpdateAbciApp.DeliveryRateUpdateAbciApp, 67 | ), 68 | abci_app_transition_mapping, 69 | ).add_background_app(termination_config) 70 | -------------------------------------------------------------------------------- /packages/valory/skills/mech_abci/dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the classes required for dialogue management.""" 21 | 22 | from packages.valory.skills.abstract_round_abci.dialogues import ( 23 | AbciDialogue as BaseAbciDialogue, 24 | ) 25 | from packages.valory.skills.abstract_round_abci.dialogues import ( 26 | AbciDialogues as BaseAbciDialogues, 27 | ) 28 | from packages.valory.skills.abstract_round_abci.dialogues import ( 29 | ContractApiDialogue as BaseContractApiDialogue, 30 | ) 31 | from packages.valory.skills.abstract_round_abci.dialogues import ( 32 | ContractApiDialogues as BaseContractApiDialogues, 33 | ) 34 | from packages.valory.skills.abstract_round_abci.dialogues import ( 35 | HttpDialogue as BaseHttpDialogue, 36 | ) 37 | from packages.valory.skills.abstract_round_abci.dialogues import ( 38 | HttpDialogues as BaseHttpDialogues, 39 | ) 40 | from packages.valory.skills.abstract_round_abci.dialogues import ( 41 | IpfsDialogue as BaseIpfsDialogue, 42 | ) 43 | from packages.valory.skills.abstract_round_abci.dialogues import ( 44 | IpfsDialogues as BaseIpfsDialogues, 45 | ) 46 | from packages.valory.skills.abstract_round_abci.dialogues import ( 47 | LedgerApiDialogue as BaseLedgerApiDialogue, 48 | ) 49 | from packages.valory.skills.abstract_round_abci.dialogues import ( 50 | LedgerApiDialogues as BaseLedgerApiDialogues, 51 | ) 52 | from packages.valory.skills.abstract_round_abci.dialogues import ( 53 | SigningDialogue as BaseSigningDialogue, 54 | ) 55 | from packages.valory.skills.abstract_round_abci.dialogues import ( 56 | SigningDialogues as BaseSigningDialogues, 57 | ) 58 | from packages.valory.skills.abstract_round_abci.dialogues import ( 59 | TendermintDialogue as BaseTendermintDialogue, 60 | ) 61 | from packages.valory.skills.abstract_round_abci.dialogues import ( 62 | TendermintDialogues as BaseTendermintDialogues, 63 | ) 64 | from packages.valory.skills.task_submission_abci.dialogues import ( 65 | AcnDataShareDialogue as BaseAcnDataShareDialogue, 66 | ) 67 | from packages.valory.skills.task_submission_abci.dialogues import ( 68 | AcnDataShareDialogues as BaseAcnDataShareDialogues, 69 | ) 70 | 71 | 72 | AbciDialogue = BaseAbciDialogue 73 | AbciDialogues = BaseAbciDialogues 74 | 75 | 76 | HttpDialogue = BaseHttpDialogue 77 | HttpDialogues = BaseHttpDialogues 78 | 79 | 80 | SigningDialogue = BaseSigningDialogue 81 | SigningDialogues = BaseSigningDialogues 82 | 83 | 84 | LedgerApiDialogue = BaseLedgerApiDialogue 85 | LedgerApiDialogues = BaseLedgerApiDialogues 86 | 87 | 88 | ContractApiDialogue = BaseContractApiDialogue 89 | ContractApiDialogues = BaseContractApiDialogues 90 | 91 | 92 | TendermintDialogue = BaseTendermintDialogue 93 | TendermintDialogues = BaseTendermintDialogues 94 | 95 | 96 | IpfsDialogue = BaseIpfsDialogue 97 | IpfsDialogues = BaseIpfsDialogues 98 | 99 | AcnDataShareDialogue = BaseAcnDataShareDialogue 100 | AcnDataShareDialogues = BaseAcnDataShareDialogues 101 | -------------------------------------------------------------------------------- /packages/valory/skills/mech_abci/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the shared state for the abci skill of Mech.""" 21 | from typing import Any 22 | 23 | from packages.valory.skills.abstract_round_abci.models import ApiSpecs 24 | from packages.valory.skills.abstract_round_abci.models import ( 25 | BenchmarkTool as BaseBenchmarkTool, 26 | ) 27 | from packages.valory.skills.abstract_round_abci.models import Requests as BaseRequests 28 | from packages.valory.skills.delivery_rate_abci.models import ( 29 | Params as SubscriptionParams, 30 | ) 31 | from packages.valory.skills.mech_abci.composition import MechAbciApp 32 | from packages.valory.skills.reset_pause_abci.rounds import Event as ResetPauseEvent 33 | from packages.valory.skills.task_submission_abci.models import ( 34 | Params as TaskExecutionAbciParams, 35 | ) 36 | from packages.valory.skills.task_submission_abci.models import ( 37 | SharedState as TaskExecSharedState, 38 | ) 39 | from packages.valory.skills.task_submission_abci.rounds import ( 40 | Event as TaskExecutionEvent, 41 | ) 42 | from packages.valory.skills.termination_abci.models import TerminationParams 43 | from packages.valory.skills.transaction_settlement_abci.rounds import ( 44 | Event as TransactionSettlementEvent, 45 | ) 46 | 47 | 48 | TaskExecutionParams = TaskExecutionAbciParams 49 | 50 | 51 | Requests = BaseRequests 52 | BenchmarkTool = BaseBenchmarkTool 53 | 54 | 55 | class RandomnessApi(ApiSpecs): 56 | """A model that wraps ApiSpecs for randomness api specifications.""" 57 | 58 | 59 | MARGIN = 5 60 | 61 | 62 | class SharedState(TaskExecSharedState): 63 | """Keep the current shared state of the skill.""" 64 | 65 | abci_app_cls = MechAbciApp 66 | 67 | def __init__(self, *args: Any, **kwargs: Any) -> None: 68 | """Initialize the shared state.""" 69 | self.last_processed_request_block_number: int = 0 70 | super().__init__(*args, **kwargs) 71 | 72 | def setup(self) -> None: 73 | """Set up.""" 74 | super().setup() 75 | 76 | MechAbciApp.event_to_timeout[ 77 | TaskExecutionEvent.ROUND_TIMEOUT 78 | ] = self.context.params.round_timeout_seconds 79 | 80 | MechAbciApp.event_to_timeout[ 81 | TaskExecutionEvent.TASK_EXECUTION_ROUND_TIMEOUT 82 | ] = self.context.params.round_timeout_seconds 83 | 84 | MechAbciApp.event_to_timeout[ 85 | ResetPauseEvent.ROUND_TIMEOUT 86 | ] = self.context.params.round_timeout_seconds 87 | 88 | MechAbciApp.event_to_timeout[ 89 | TransactionSettlementEvent.ROUND_TIMEOUT 90 | ] = self.context.params.round_timeout_seconds 91 | 92 | MechAbciApp.event_to_timeout[ 93 | TransactionSettlementEvent.VALIDATE_TIMEOUT 94 | ] = self.context.params.validate_timeout 95 | 96 | MechAbciApp.event_to_timeout[ 97 | TransactionSettlementEvent.FINALIZE_TIMEOUT 98 | ] = self.context.params.finalize_timeout 99 | 100 | MechAbciApp.event_to_timeout[ResetPauseEvent.RESET_AND_PAUSE_TIMEOUT] = ( 101 | self.context.params.reset_pause_duration + MARGIN 102 | ) 103 | 104 | 105 | class Params(TaskExecutionParams, SubscriptionParams, TerminationParams): # type: ignore 106 | """A model to represent params for multiple abci apps.""" 107 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the implementation of the task execution skill.""" 21 | 22 | from aea.configurations.base import PublicId 23 | 24 | 25 | PUBLIC_ID = PublicId.from_str("valory/task_execution:0.1.0") 26 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/skill.yaml: -------------------------------------------------------------------------------- 1 | name: task_execution 2 | author: valory 3 | version: 0.1.0 4 | type: skill 5 | description: A skill used for monitoring and executing tasks. 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | __init__.py: bafybeidqhvvlnthkbnmrdkdeyjyx2f2ab6z4xdgmagh7welqnh2v6wczx4 10 | behaviours.py: bafybeidps7mfbiog4k35ow6weq363n2qwc3p4yqzlwnoljacvvnhf2op24 11 | dialogues.py: bafybeib6xkxutxwctbegngexys3smael4rzkrkdlbwi7f5lgcvmag3siqm 12 | handlers.py: bafybeifcagftjvcgkva76iisq7ymfuvwna43jsyrgl24tu5v6qzaa6aoje 13 | models.py: bafybeiedvetvbvd3hd455kfg7ms476r5qigji4dns4m4wdnipac726dus4 14 | utils/__init__.py: bafybeiccdijaigu6e5p2iruwo5mkk224o7ywedc7nr6xeu5fpmhjqgk24e 15 | utils/apis.py: bafybeigu73lfz3g3mc6iupisrvlsp3fyl4du3oqlyajgdpfvtqypddh3w4 16 | utils/benchmarks.py: bafybeib5xjfeu2jezcj4ofl36qnznhbrjad6hqiwavebg5cidkl2pwlhz4 17 | utils/cost_calculation.py: bafybeighafxied73w3mcmgziwfp3u2x6t4qlztw4kyekyq2ddgyhdge74q 18 | utils/ipfs.py: bafybeiev3mtt5ubsiykigmsxxyf4abevi7qsektcrxbgrirvidc36zjlve 19 | utils/task.py: bafybeicb6nqd475ul6mz4hcexpva33ivkn4fygicgmlb4clu5cuzr34diy 20 | fingerprint_ignore_patterns: [] 21 | connections: 22 | - valory/ledger:0.19.0:bafybeibiayfscw4badpr545f47hsvc2r5lgfpgzib5q4h4u6kkosdsytby 23 | - valory/ipfs:0.1.0:bafybeigjspoceazd5roxo4pcqcgyu3ozixkdoc44domwcaumt2zwoz2x3m 24 | - valory/p2p_libp2p_client:0.1.0:bafybeic6ayusdwy4dks75njwk32ac7ur7salgllwf4fdc34ue5z2k5iz4q 25 | contracts: 26 | - valory/agent_mech:0.1.0:bafybeibjlxgwwqodubwy3mhstnjqjsyat4ray32xgkkv5adysjwz5mzcau 27 | protocols: 28 | - valory/acn_data_share:0.1.0:bafybeih5ydonnvrwvy2ygfqgfabkr47s4yw3uqxztmwyfprulwfsoe7ipq 29 | - valory/contract_api:1.0.0:bafybeid247uig2ekykdumh7ewhp2cdq7rchaeqjj6e7urx35zfpdl5zrn4 30 | - valory/ledger_api:1.0.0:bafybeihmqzcbj6t7vxz2aehd5726ofnzsfjs5cwlf42ro4tn6i34cbfrc4 31 | - valory/default:1.0.0:bafybeifqcqy5hfbnd7fjv4mqdjrtujh2vx3p2xhe33y67zoxa6ph7wdpaq 32 | - valory/ipfs:0.1.0:bafybeifi2nri7sprmkez4rqzwb4lnu6peoy3bax5k6asf6k5ms7kmjpmkq 33 | - valory/http:1.0.0:bafybeih4azmfwtamdbkhztkm4xitep3gx6tfdnoz6tvllmaqnhu3klejfa 34 | skills: 35 | - valory/abstract_round_abci:0.1.0:bafybeiba3zhx5drsf7ailfboeuvwykocmkffs2j426u4q7d4erig67lyhm 36 | behaviours: 37 | task_execution: 38 | args: {} 39 | class_name: TaskExecutionBehaviour 40 | handlers: 41 | acn_data_share_handler: 42 | args: {} 43 | class_name: AcnHandler 44 | contract_handler: 45 | args: {} 46 | class_name: ContractHandler 47 | ipfs_handler: 48 | args: {} 49 | class_name: IpfsHandler 50 | ledger_handler: 51 | args: {} 52 | class_name: LedgerHandler 53 | mech_http_handler: 54 | args: {} 55 | class_name: MechHttpHandler 56 | models: 57 | acn_data_share_dialogues: 58 | args: {} 59 | class_name: AcnDataShareDialogues 60 | contract_dialogues: 61 | args: {} 62 | class_name: ContractDialogues 63 | default_dialogues: 64 | args: {} 65 | class_name: DefaultDialogues 66 | ipfs_dialogues: 67 | args: {} 68 | class_name: IpfsDialogues 69 | ledger_dialogues: 70 | args: {} 71 | class_name: LedgerDialogues 72 | mech_http_dialogues: 73 | args: {} 74 | class_name: MechHttpDialogues 75 | params: 76 | args: 77 | agent_index: 0 78 | api_keys: {} 79 | tools_to_package_hash: {} 80 | from_block_range: 50000 81 | num_agents: 4 82 | mech_to_config: {} 83 | polling_interval: 30.0 84 | task_deadline: 240.0 85 | max_block_window: 500 86 | use_slashing: false 87 | timeout_limit: 3 88 | slash_cooldown_hours: 3 89 | slash_threshold_amount: 10000000000000000 90 | light_slash_unit_amount: 5000000000000000 91 | serious_slash_unit_amount: 8000000000000000 92 | mech_marketplace_address: '0x0000000000000000000000000000000000000000' 93 | default_chain_id: gnosis 94 | class_name: Params 95 | dependencies: 96 | py-multibase: 97 | version: ==1.0.3 98 | py-multicodec: 99 | version: ==0.2.1 100 | eth-abi: 101 | version: ==4.0.0 102 | PyYAML: 103 | version: ==6.0.1 104 | is_abstract: false 105 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | """This module contains helper classes.""" 20 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/utils/apis.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2024 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | """Utils for API integrations.""" 20 | from typing import Dict, List 21 | 22 | 23 | class KeyChain: 24 | """Class for managing API keys.""" 25 | 26 | def __init__(self, services: Dict[str, List[str]]) -> None: 27 | """Initialize the KeyChain with a dictionary of service names and corresponding lists of API keys.""" 28 | if not isinstance(services, dict): 29 | raise ValueError( 30 | "Services must be a dictionary with service names as keys and lists of API keys as values." 31 | ) 32 | 33 | self.services = services 34 | self.current_index = { 35 | service: 0 for service in services 36 | } # Start with the first key for each service 37 | 38 | def max_retries(self) -> Dict[str, int]: 39 | """Get the maximum number of retries for a given service.""" 40 | return {service: len(keys) for service, keys in self.services.items()} 41 | 42 | def rotate(self, service_name: str) -> None: 43 | """Rotate the current API key for a given service to the next one.""" 44 | if service_name not in self.services: 45 | raise KeyError(f"Service '{service_name!r}' not found in KeyChain.") 46 | 47 | # Increment the current index, looping back if at the end of the list 48 | self.current_index[service_name] += 1 49 | if self.current_index[service_name] >= len(self.services[service_name]): 50 | self.current_index[service_name] = 0 # Reset to the start 51 | 52 | def get(self, service_name: str, default_value: str) -> str: 53 | """Get the current API key for a given service.""" 54 | if service_name not in self.services: 55 | return default_value 56 | 57 | return self.__getitem__(service_name) 58 | 59 | def __getitem__(self, service_name: str) -> str: 60 | """Get the current API key for a given service.""" 61 | if service_name not in self.services: 62 | raise KeyError(f"Service '{service_name!r}' not found in KeyChain.") 63 | 64 | index = self.current_index[service_name] 65 | return self.services[service_name][index] 66 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/utils/benchmarks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2024-2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | """Benchmarking for tools.""" 20 | 21 | import logging 22 | from typing import Any, Callable, Dict, Union 23 | 24 | 25 | PRICE_NUM_TOKENS = 1000 26 | 27 | 28 | class TokenCounterCallback: 29 | """Callback to count the number of tokens used in a generation.""" 30 | 31 | TOKEN_PRICES = { 32 | "gpt-3.5-turbo": {"input": 0.0005, "output": 0.0015}, 33 | "gpt-3.5-turbo-0125": {"input": 0.0005, "output": 0.0015}, 34 | "gpt-3.5-turbo-1106": {"input": 0.001, "output": 0.002}, 35 | "gpt-4": {"input": 0.03, "output": 0.06}, 36 | "gpt-4-turbo-preview": {"input": 0.01, "output": 0.03}, 37 | "gpt-4-0125-preview": {"input": 0.01, "output": 0.03}, 38 | "gpt-4-1106-preview": {"input": 0.01, "output": 0.03}, 39 | "gpt-4o-2024-08-06": {"input": 0.01, "output": 0.03}, 40 | "claude-2": {"input": 0.008, "output": 0.024}, 41 | "claude-3-haiku-20240307": {"input": 0.00025, "output": 0.00125}, 42 | "claude-3-5-sonnet-20240620": {"input": 0.003, "output": 0.015}, 43 | "claude-3-opus-20240229": {"input": 0.015, "output": 0.075}, 44 | "cohere/command-r-plus": {"input": 0.003, "output": 0.015}, 45 | "databricks/dbrx-instruct:nitro": {"input": 0.0009, "output": 0.0009}, 46 | "nousresearch/nous-hermes-2-mixtral-8x7b-sft": { 47 | "input": 0.00054, 48 | "output": 0.00054, 49 | }, 50 | } 51 | 52 | def __init__(self) -> None: 53 | """Initialize the callback.""" 54 | self.cost_dict: Dict[str, Union[int, float]] = { 55 | "input_tokens": 0, 56 | "output_tokens": 0, 57 | "total_tokens": 0, 58 | "input_cost": 0, 59 | "output_cost": 0, 60 | "total_cost": 0, 61 | } 62 | 63 | @staticmethod 64 | def token_to_cost(tokens: int, model: str, tokens_type: str) -> float: 65 | """Converts a number of tokens to a cost in dollars.""" 66 | return ( 67 | tokens 68 | / PRICE_NUM_TOKENS 69 | * TokenCounterCallback.TOKEN_PRICES[model][tokens_type] 70 | ) 71 | 72 | def calculate_cost( 73 | self, tokens_type: str, model: str, token_counter: Callable, **kwargs: Any 74 | ) -> None: 75 | """Calculate the cost of a generation.""" 76 | # Check if it its prompt or tokens are passed in 77 | prompt_key = f"{tokens_type}_prompt" 78 | token_key = f"{tokens_type}_tokens" 79 | if prompt_key in kwargs: 80 | tokens = token_counter(kwargs[prompt_key], model) 81 | elif token_key in kwargs: 82 | tokens = kwargs[token_key] 83 | else: 84 | logging.warning(f"No {token_key}_tokens or {tokens_type}_prompt found.") 85 | cost = self.token_to_cost(tokens, model, tokens_type) 86 | self.cost_dict[token_key] += tokens 87 | self.cost_dict[f"{tokens_type}_cost"] += cost 88 | 89 | def __call__(self, model: str, token_counter: Callable, **kwargs: Any) -> None: 90 | """Callback to count the number of tokens used in a generation.""" 91 | if model not in list(TokenCounterCallback.TOKEN_PRICES.keys()): 92 | raise ValueError(f"Model {model} not supported.") 93 | try: 94 | self.calculate_cost("input", model, token_counter, **kwargs) 95 | self.calculate_cost("output", model, token_counter, **kwargs) 96 | self.cost_dict["total_tokens"] = ( 97 | self.cost_dict["input_tokens"] + self.cost_dict["output_tokens"] 98 | ) 99 | self.cost_dict["total_cost"] = ( 100 | self.cost_dict["input_cost"] + self.cost_dict["output_cost"] 101 | ) 102 | except Exception as e: 103 | logging.error(f"Error in TokenCounterCallback: {e}") 104 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/utils/cost_calculation.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2024 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | """Calculate the cost for tools.""" 20 | import logging 21 | import math 22 | from typing import Any, Dict, cast 23 | 24 | from packages.valory.skills.task_execution import PUBLIC_ID 25 | 26 | 27 | _logger = logging.getLogger( 28 | f"aea.packages.{PUBLIC_ID.author}.contracts.{PUBLIC_ID.name}.utils.cost_calculation" 29 | ) 30 | 31 | DEFAULT_PRICE = 1 32 | 33 | 34 | def get_cost_for_done_task( 35 | done_task: Dict[str, Any], fallback_price: int = DEFAULT_PRICE 36 | ) -> int: 37 | """Get the cost for a done task.""" 38 | cost_dict = done_task.get("cost_dict", {}) 39 | if cost_dict == {}: 40 | _logger.warning(f"Cost dict not found in done task {done_task['request_id']}.") 41 | return fallback_price 42 | total_cost = cost_dict.get("total_cost", None) 43 | if total_cost is None: 44 | _logger.warning( 45 | f"Total cost not found in cost dict {cost_dict} for {done_task['request_id']}." 46 | ) 47 | return fallback_price 48 | 49 | total_cost = cast(float, total_cost) 50 | # 0.01 token (ex. xDAI/USDC) -> 1 NFT credit 51 | cost_in_credits = math.ceil(total_cost * 100) 52 | return cost_in_credits 53 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/utils/ipfs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2025 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | """This module contains helpers for IPFS interaction.""" 20 | 21 | from typing import Any, Dict, Tuple 22 | 23 | import yaml 24 | from aea.helpers.cid import CID 25 | from multibase import multibase 26 | from multicodec import multicodec 27 | 28 | 29 | CID_PREFIX = "f01701220" 30 | 31 | 32 | def get_ipfs_file_hash(data: bytes) -> str: 33 | """Get hash from bytes""" 34 | try: 35 | return str(CID.from_string(data.decode())) 36 | except Exception: # noqa 37 | # if something goes wrong, fallback to sha256 38 | file_hash = data.hex() 39 | file_hash = CID_PREFIX + file_hash 40 | file_hash = str(CID.from_string(file_hash)) 41 | return file_hash 42 | 43 | 44 | def to_multihash(hash_string: str) -> str: 45 | """To multihash string.""" 46 | # Decode the Base32 CID to bytes 47 | cid_bytes = multibase.decode(hash_string) 48 | # Remove the multicodec prefix (0x01) from the bytes 49 | multihash_bytes = multicodec.remove_prefix(cid_bytes) 50 | # Convert the multihash bytes to a hexadecimal string 51 | hex_multihash = multihash_bytes.hex() 52 | return hex_multihash[6:] 53 | 54 | 55 | class ComponentPackageLoader: 56 | """Component package loader.""" 57 | 58 | @staticmethod 59 | def load(serialized_objects: Dict[str, str]) -> Tuple[Dict[str, Any], str, str]: 60 | """ 61 | Load a custom component package. 62 | 63 | :param serialized_objects: the serialized objects. 64 | :return: the component.yaml, entry_point.py and callable as tuple. 65 | """ 66 | # the package MUST contain a component.yaml file 67 | if "component.yaml" not in serialized_objects: 68 | raise ValueError( 69 | "Invalid component package. " 70 | "The package MUST contain a component.yaml." 71 | ) 72 | 73 | # load the component.yaml file 74 | component_yaml = yaml.safe_load(serialized_objects["component.yaml"]) 75 | if "entry_point" not in component_yaml or "callable" not in component_yaml: 76 | raise ValueError( 77 | "Invalid component package. " 78 | "The component.yaml file MUST contain the 'entry_point' and 'callable' keys." 79 | ) 80 | 81 | # the name of the script that needs to be executed 82 | entry_point_name = component_yaml["entry_point"] 83 | 84 | # load the script 85 | if entry_point_name not in serialized_objects: 86 | raise ValueError( 87 | f"Invalid component package. " 88 | f"{entry_point_name} is not present in the component package." 89 | ) 90 | entry_point = serialized_objects[entry_point_name] 91 | 92 | # the method that needs to be called 93 | callable_method = component_yaml["callable"] 94 | 95 | return component_yaml, entry_point, callable_method 96 | -------------------------------------------------------------------------------- /packages/valory/skills/task_execution/utils/task.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023-2024 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This package contains a custom Loader for the ipfs connection.""" 21 | 22 | from typing import Any 23 | 24 | 25 | class AnyToolAsTask: 26 | """AnyToolAsTask""" 27 | 28 | def execute(self, *args: Any, **kwargs: Any) -> Any: 29 | """Execute the task.""" 30 | tool_py = kwargs.pop("tool_py") 31 | callable_method = kwargs.pop("callable_method") 32 | local_namespace: Any = {} 33 | exec(tool_py, local_namespace) # pylint: disable=W0122 # nosec 34 | method = local_namespace[callable_method] 35 | return method(*args, **kwargs) 36 | -------------------------------------------------------------------------------- /packages/valory/skills/task_submission_abci/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the implementation of the task submission skill.""" 21 | 22 | from aea.configurations.base import PublicId 23 | 24 | 25 | PUBLIC_ID = PublicId.from_str("valory/task_submission_abci:0.1.0") 26 | -------------------------------------------------------------------------------- /packages/valory/skills/task_submission_abci/dialogues.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the dialogues of the TaskExecutionAbciApp.""" 21 | 22 | from typing import Any 23 | 24 | from aea.common import Address 25 | from aea.protocols.base import Message 26 | from aea.protocols.dialogue.base import Dialogue as BaseDialogue 27 | from aea.skills.base import Model 28 | 29 | from packages.valory.protocols.acn_data_share.dialogues import ( 30 | AcnDataShareDialogue as BaseAcnDataShareDialogue, 31 | ) 32 | from packages.valory.protocols.acn_data_share.dialogues import ( 33 | AcnDataShareDialogues as BaseAcnDataShareDialogues, 34 | ) 35 | from packages.valory.skills.abstract_round_abci.dialogues import ( 36 | AbciDialogue as BaseAbciDialogue, 37 | ) 38 | from packages.valory.skills.abstract_round_abci.dialogues import ( 39 | AbciDialogues as BaseAbciDialogues, 40 | ) 41 | from packages.valory.skills.abstract_round_abci.dialogues import ( 42 | ContractApiDialogue as BaseContractApiDialogue, 43 | ) 44 | from packages.valory.skills.abstract_round_abci.dialogues import ( 45 | ContractApiDialogues as BaseContractApiDialogues, 46 | ) 47 | from packages.valory.skills.abstract_round_abci.dialogues import ( 48 | HttpDialogue as BaseHttpDialogue, 49 | ) 50 | from packages.valory.skills.abstract_round_abci.dialogues import ( 51 | HttpDialogues as BaseHttpDialogues, 52 | ) 53 | from packages.valory.skills.abstract_round_abci.dialogues import ( 54 | IpfsDialogue as BaseIpfsDialogue, 55 | ) 56 | from packages.valory.skills.abstract_round_abci.dialogues import ( 57 | IpfsDialogues as BaseIpfsDialogues, 58 | ) 59 | from packages.valory.skills.abstract_round_abci.dialogues import ( 60 | LedgerApiDialogue as BaseLedgerApiDialogue, 61 | ) 62 | from packages.valory.skills.abstract_round_abci.dialogues import ( 63 | LedgerApiDialogues as BaseLedgerApiDialogues, 64 | ) 65 | from packages.valory.skills.abstract_round_abci.dialogues import ( 66 | SigningDialogue as BaseSigningDialogue, 67 | ) 68 | from packages.valory.skills.abstract_round_abci.dialogues import ( 69 | SigningDialogues as BaseSigningDialogues, 70 | ) 71 | from packages.valory.skills.abstract_round_abci.dialogues import ( 72 | TendermintDialogue as BaseTendermintDialogue, 73 | ) 74 | from packages.valory.skills.abstract_round_abci.dialogues import ( 75 | TendermintDialogues as BaseTendermintDialogues, 76 | ) 77 | 78 | 79 | AbciDialogue = BaseAbciDialogue 80 | AbciDialogues = BaseAbciDialogues 81 | 82 | 83 | HttpDialogue = BaseHttpDialogue 84 | HttpDialogues = BaseHttpDialogues 85 | 86 | 87 | SigningDialogue = BaseSigningDialogue 88 | SigningDialogues = BaseSigningDialogues 89 | 90 | 91 | LedgerApiDialogue = BaseLedgerApiDialogue 92 | LedgerApiDialogues = BaseLedgerApiDialogues 93 | 94 | 95 | ContractApiDialogue = BaseContractApiDialogue 96 | ContractApiDialogues = BaseContractApiDialogues 97 | 98 | 99 | TendermintDialogue = BaseTendermintDialogue 100 | TendermintDialogues = BaseTendermintDialogues 101 | 102 | 103 | IpfsDialogue = BaseIpfsDialogue 104 | IpfsDialogues = BaseIpfsDialogues 105 | 106 | 107 | AcnDataShareDialogue = BaseAcnDataShareDialogue 108 | 109 | 110 | class AcnDataShareDialogues(Model, BaseAcnDataShareDialogues): 111 | """The dialogues class keeps track of all dialogues.""" 112 | 113 | def __init__(self, **kwargs: Any) -> None: 114 | """ 115 | Initialize dialogues. 116 | 117 | :param kwargs: keyword arguments 118 | """ 119 | Model.__init__(self, **kwargs) 120 | 121 | def role_from_first_message( # pylint: disable=unused-argument 122 | message: Message, receiver_address: Address 123 | ) -> BaseDialogue.Role: 124 | """Infer the role of the agent from an incoming/outgoing first message 125 | 126 | :param message: an incoming/outgoing first message 127 | :param receiver_address: the address of the receiving agent 128 | :return: The role of the agent 129 | """ 130 | return AcnDataShareDialogue.Role.AGENT 131 | 132 | BaseAcnDataShareDialogues.__init__( 133 | self, 134 | self_address=str(self.context.agent_address), 135 | role_from_first_message=role_from_first_message, 136 | ) 137 | -------------------------------------------------------------------------------- /packages/valory/skills/task_submission_abci/fsm_specification.yaml: -------------------------------------------------------------------------------- 1 | alphabet_in: 2 | - DONE 3 | - ERROR 4 | - NO_MAJORITY 5 | - NO_TASKS 6 | - ROUND_TIMEOUT 7 | - TASK_EXECUTION_ROUND_TIMEOUT 8 | default_start_state: TaskPoolingRound 9 | final_states: 10 | - FinishedTaskExecutionWithErrorRound 11 | - FinishedTaskPoolingRound 12 | - FinishedWithoutTasksRound 13 | label: TaskSubmissionAbciApp 14 | start_states: 15 | - TaskPoolingRound 16 | states: 17 | - FinishedTaskExecutionWithErrorRound 18 | - FinishedTaskPoolingRound 19 | - FinishedWithoutTasksRound 20 | - TaskPoolingRound 21 | - TransactionPreparationRound 22 | transition_func: 23 | (TaskPoolingRound, DONE): TransactionPreparationRound 24 | (TaskPoolingRound, NO_TASKS): FinishedWithoutTasksRound 25 | (TaskPoolingRound, ROUND_TIMEOUT): TaskPoolingRound 26 | (TransactionPreparationRound, DONE): FinishedTaskPoolingRound 27 | (TransactionPreparationRound, ERROR): FinishedTaskExecutionWithErrorRound 28 | (TransactionPreparationRound, NO_MAJORITY): FinishedTaskExecutionWithErrorRound 29 | (TransactionPreparationRound, TASK_EXECUTION_ROUND_TIMEOUT): TransactionPreparationRound 30 | -------------------------------------------------------------------------------- /packages/valory/skills/task_submission_abci/handlers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the handlers for the skill of TaskExecutionAbciApp.""" 21 | 22 | 23 | from packages.valory.skills.abstract_round_abci.handlers import ( 24 | ABCIRoundHandler as BaseABCIRoundHandler, 25 | ) 26 | from packages.valory.skills.abstract_round_abci.handlers import ( 27 | ContractApiHandler as BaseContractApiHandler, 28 | ) 29 | from packages.valory.skills.abstract_round_abci.handlers import ( 30 | HttpHandler as BaseHttpHandler, 31 | ) 32 | from packages.valory.skills.abstract_round_abci.handlers import ( 33 | IpfsHandler as BaseIpfsHandler, 34 | ) 35 | from packages.valory.skills.abstract_round_abci.handlers import ( 36 | LedgerApiHandler as BaseLedgerApiHandler, 37 | ) 38 | from packages.valory.skills.abstract_round_abci.handlers import ( 39 | SigningHandler as BaseSigningHandler, 40 | ) 41 | from packages.valory.skills.abstract_round_abci.handlers import ( 42 | TendermintHandler as BaseTendermintHandler, 43 | ) 44 | 45 | 46 | ABCIHandler = BaseABCIRoundHandler 47 | HttpHandler = BaseHttpHandler 48 | SigningHandler = BaseSigningHandler 49 | LedgerApiHandler = BaseLedgerApiHandler 50 | ContractApiHandler = BaseContractApiHandler 51 | TendermintHandler = BaseTendermintHandler 52 | IpfsHandler = BaseIpfsHandler 53 | -------------------------------------------------------------------------------- /packages/valory/skills/task_submission_abci/payloads.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the transaction payloads of the TaskExecutionAbciApp.""" 21 | 22 | from dataclasses import dataclass 23 | 24 | from packages.valory.skills.abstract_round_abci.base import BaseTxPayload 25 | 26 | 27 | @dataclass(frozen=True) 28 | class TaskPoolingPayload(BaseTxPayload): 29 | """Represent a transaction payload for the TaskPoolingRound.""" 30 | 31 | content: str 32 | 33 | 34 | @dataclass(frozen=True) 35 | class TransactionPayload(BaseTxPayload): 36 | """Represent a transaction payload for the TransactionPreparationRound.""" 37 | 38 | content: str 39 | -------------------------------------------------------------------------------- /packages/valory/skills/task_submission_abci/tasks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """Contains the background tasks of the APY estimation skill.""" 21 | 22 | from typing import Any 23 | 24 | from aea.skills.tasks import Task 25 | 26 | 27 | class AnyToolAsTask(Task): 28 | """AnyToolAsTask""" 29 | 30 | def execute(self, *args: Any, **kwargs: Any) -> Any: 31 | """Execute the task.""" 32 | method = kwargs.pop("method") 33 | return method(*args, **kwargs) 34 | -------------------------------------------------------------------------------- /packages/valory/skills/websocket_client/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # Copyright 2023 eightballer 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """This module contains the implementation of the default skill.""" 22 | 23 | from aea.configurations.base import PublicId 24 | 25 | PUBLIC_ID = PublicId.from_str("valory/websocket_client:0.1.0") 26 | -------------------------------------------------------------------------------- /packages/valory/skills/websocket_client/dialogues.py: -------------------------------------------------------------------------------- 1 | """ 2 | Dialogues 3 | """ 4 | 5 | from typing import Any 6 | 7 | from aea.common import Address 8 | from aea.protocols.base import Message 9 | from aea.protocols.dialogue.base import Dialogue as BaseDialogue 10 | from aea.skills.base import Model 11 | 12 | from packages.valory.protocols.websocket_client.dialogues import ( 13 | WebsocketClientDialogue as BaseWebsocketClientDialogue, 14 | ) 15 | from packages.valory.protocols.websocket_client.dialogues import ( 16 | WebsocketClientDialogues as BaseWebsocketClientDialogues, 17 | ) 18 | 19 | WebsocketClientDialogue = BaseWebsocketClientDialogue 20 | 21 | 22 | class WebsocketClientDialogues(Model, BaseWebsocketClientDialogues): 23 | """The dialogues class keeps track of all dialogues.""" 24 | 25 | def __init__(self, **kwargs: Any) -> None: 26 | """ 27 | Initialize dialogues. 28 | 29 | :param kwargs: keyword arguments 30 | """ 31 | Model.__init__(self, **kwargs) 32 | 33 | def role_from_first_message( # pylint: disable=unused-argument 34 | message: Message, receiver_address: Address 35 | ) -> BaseDialogue.Role: 36 | """Infer the role of the agent from an incoming/outgoing first message 37 | 38 | :param message: an incoming/outgoing first message 39 | :param receiver_address: the address of the receiving agent 40 | :return: The role of the agent 41 | """ 42 | return WebsocketClientDialogue.Role.SKILL 43 | 44 | BaseWebsocketClientDialogues.__init__( 45 | self, 46 | self_address=str(self.skill_id), 47 | role_from_first_message=role_from_first_message, 48 | ) 49 | -------------------------------------------------------------------------------- /packages/valory/skills/websocket_client/handlers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # Copyright 2023 eightballer 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ------------------------------------------------------------------------------ 20 | 21 | """This package contains a scaffold of a handler.""" 22 | 23 | import json 24 | import time 25 | 26 | from aea.protocols.base import Message 27 | from aea.skills.base import Handler 28 | from web3 import Web3 29 | from web3.types import TxReceipt 30 | from typing import Callable, cast 31 | from packages.valory.protocols.websocket_client.message import WebsocketClientMessage 32 | from enum import Enum 33 | 34 | JOB_QUEUE = "pending_tasks" 35 | SUBSCRIPTION_ID = "subscription_id" 36 | WEBSOCKET_SUBSCRIPTION_STATUS = "websocket_subscription_status" 37 | WEBSOCKET_SUBSCRIPTIONS = "websocket_subscriptions" 38 | 39 | 40 | class SubscriptionStatus(Enum): 41 | """Subscription status.""" 42 | 43 | UNSUBSCRIBED = "unsubscribed" 44 | SUBSCRIBING = "subscribing" 45 | CHECKING_SUBSCRIPTION = "checking_subscription" 46 | SUBSCRIBED = "subscribed" 47 | 48 | 49 | class WebSocketHandler(Handler): 50 | """This class scaffolds a handler.""" 51 | 52 | SUPPORTED_PROTOCOL = WebsocketClientMessage.protocol_id 53 | 54 | def setup(self) -> None: 55 | """Implement the setup.""" 56 | if WEBSOCKET_SUBSCRIPTION_STATUS not in self.context.shared_state: 57 | self.context.shared_state[WEBSOCKET_SUBSCRIPTION_STATUS] = {} 58 | 59 | if WEBSOCKET_SUBSCRIPTIONS not in self.context.shared_state: 60 | self.context.shared_state[WEBSOCKET_SUBSCRIPTIONS] = {} 61 | 62 | self._count = 0 63 | 64 | def handle(self, message: WebsocketClientMessage) -> None: 65 | """ 66 | Implement the reaction to an envelope. 67 | 68 | :param message: the message 69 | """ 70 | self.context.logger.info(f"Received message: {message}") 71 | handler = cast( 72 | Callable[[WebsocketClientMessage], None], 73 | getattr(self, f"handle_{message.performative.value}"), 74 | ) 75 | handler(message) 76 | 77 | def handle_subscription(self, message: WebsocketClientMessage) -> None: 78 | """Handler `WebsocketClientMessage.Performative.SUBSCRIPTION` response""" 79 | self.context.shared_state[WEBSOCKET_SUBSCRIPTION_STATUS][ 80 | message.subscription_id 81 | ] = ( 82 | SubscriptionStatus.SUBSCRIBED 83 | if message.alive 84 | else SubscriptionStatus.UNSUBSCRIBED 85 | ) 86 | 87 | def handle_send_success(self, message: WebsocketClientMessage) -> None: 88 | """Handler `WebsocketClientMessage.Performative.SEND_SUCCESS` response""" 89 | self.context.logger.info( 90 | f"Sent data to the websocket with id {message.subscription_id}; send_length: {message.send_length}" 91 | ) 92 | 93 | def handle_recv(self, message: WebsocketClientMessage) -> None: 94 | """Handler `WebsocketClientMessage.Performative.RECV` response""" 95 | self.context.logger.info( 96 | f"Received {message.data} from subscription {message.subscription_id}" 97 | ) 98 | subscription_id = message.subscription_id 99 | if subscription_id not in self.context.shared_state[WEBSOCKET_SUBSCRIPTIONS]: 100 | self.context.shared_state[WEBSOCKET_SUBSCRIPTIONS][subscription_id] = [] 101 | 102 | self.context.shared_state[WEBSOCKET_SUBSCRIPTIONS][subscription_id].append( 103 | message.data 104 | ) 105 | 106 | def handle_error(self, message: WebsocketClientMessage) -> None: 107 | """Handler `WebsocketClientMessage.Performative.ERROR` response""" 108 | self.context.logger.info( 109 | f"Error occured on the websocket with id {message.subscription_id}; Error: {message.message}" 110 | ) 111 | self.context.shared_state[WEBSOCKET_SUBSCRIPTION_STATUS][ 112 | message.subscription_id 113 | ] = ( 114 | SubscriptionStatus.SUBSCRIBED 115 | if message.alive 116 | else SubscriptionStatus.UNSUBSCRIBED 117 | ) 118 | 119 | def teardown(self) -> None: 120 | """Implement the handler teardown.""" 121 | -------------------------------------------------------------------------------- /packages/valory/skills/websocket_client/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This module contains the shared state for the abci skill of Mech.""" 21 | from typing import Any 22 | 23 | from aea.skills.base import Model 24 | 25 | DEFAULT_WEBSOCKET_PROVIDER = "ws://localhost:8001" 26 | DEFAULT_SUBSCRIPTION_ID = "websocket-subscription" 27 | 28 | 29 | class Params(Model): 30 | """A model to represent params for multiple abci apps.""" 31 | 32 | def __init__(self, *args: Any, **kwargs: Any) -> None: 33 | """Initialize the parameters object.""" 34 | 35 | self.websocket_provider = kwargs.get( 36 | "websocket_provider", DEFAULT_WEBSOCKET_PROVIDER 37 | ) 38 | self.subscription_id = kwargs.get("subscription_id", DEFAULT_SUBSCRIPTION_ID) 39 | super().__init__(*args, **kwargs) 40 | -------------------------------------------------------------------------------- /packages/valory/skills/websocket_client/skill.yaml: -------------------------------------------------------------------------------- 1 | name: websocket_client 2 | author: valory 3 | version: 0.1.0 4 | type: skill 5 | description: Websocket client. 6 | license: Apache-2.0 7 | aea_version: '>=1.0.0, <2.0.0' 8 | fingerprint: 9 | __init__.py: bafybeibgl4hnpsd3vokfs6cfkg4elgqu7nm4yhs6sh373j6erwvgpjdqeu 10 | behaviours.py: bafybeiawcxlvtzr7757s6ury6xwvuv4ydz6yzec2vhxft77gqihvmncowy 11 | dialogues.py: bafybeicc26sbiipnfublma3ywvh54elbx5y5sj7xckq3xyqyfmmoamiouy 12 | handlers.py: bafybeibqfinswattz7gu4pijjxvixp5gtrgfz5idsz3uzlgrjw2vanjiu4 13 | models.py: bafybeicuei7xoozvgr6kyp6cp7b6gqonlkmlgkvhhff37iecnjqzhkvbgi 14 | fingerprint_ignore_patterns: [] 15 | connections: 16 | - valory/websocket_client:0.1.0:bafybeic4ag3gqc7kd3k2o3pucddj2odck5yrfbgmwh5veqny7zao5qayli 17 | contracts: [] 18 | protocols: 19 | - valory/websocket_client:0.1.0:bafybeifjk254sy65rna2k32kynzenutujwqndap2r222afvr3zezi27mx4 20 | skills: [] 21 | behaviours: 22 | websocket_subscription: 23 | args: {} 24 | class_name: SubscriptionBehaviour 25 | handlers: 26 | new_event: 27 | args: {} 28 | class_name: WebSocketHandler 29 | models: 30 | websocket_client_dialogues: 31 | args: {} 32 | class_name: WebsocketClientDialogues 33 | params: 34 | args: 35 | websocket_provider: ws://localhost:8001 36 | subscription_id: websocket-subscription 37 | class_name: Params 38 | dependencies: 39 | web3: 40 | version: <7,>=6.0.0 41 | is_abstract: true 42 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ "poetry-core>=1.0.0",] 3 | build-backend = "poetry.core.masonry.api" 4 | 5 | [tool.poetry] 6 | name = "mech" 7 | version = "0.1.0" 8 | description = "" 9 | authors = [ "8baller <8ball030@gmail.com>", "David Vilela ", "David Minarsch ", "Justice Mace ", "Ardian Abazi ", "Jose Moreira Sanchez ", "Adamantios Zaras ",] 10 | readme = "README.md" 11 | repository = "https://github.com/valory-xyz/mech" 12 | keywords = [ "mech", "autonomy", "autonomous", "autonolas", "service", "multi", "agent",] 13 | classifiers = [ "Environment :: Console", "Environment :: Web Environment", "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Operating System :: MacOS", "Operating System :: Microsoft", "Operating System :: Unix", "Programming Language :: Python :: 3.10", "Topic :: Communications", "Topic :: Internet", "Topic :: Scientific/Engineering", "Topic :: Software Development", "Topic :: System",] 14 | [[tool.poetry.packages]] 15 | include = "packages" 16 | 17 | [tool.poetry.dependencies] 18 | python = ">=3.10,<3.12" 19 | open-autonomy = "==0.19.2" 20 | openai = "==1.30.2" 21 | requests = "==2.28.2" 22 | py-multibase = "==1.0.3" 23 | py-multicodec = "==0.2.1" 24 | grpcio = "==1.53.0" 25 | asn1crypto = "<1.5.0,>=1.4.0" 26 | open-aea-ledger-ethereum = "==1.63.0" 27 | open-aea-ledger-cosmos = "==1.63.0" 28 | protobuf = "<4.25.0,>=4.21.6" 29 | hypothesis = "==6.21.6" 30 | open-aea-test-autonomy = "==0.19.2" 31 | web3 = "<7,>=6.0.0" 32 | ipfshttpclient = "==0.8.0a2" 33 | open-aea-cli-ipfs = "==1.63.0" 34 | pytest-asyncio = "*" 35 | aiohttp = "<4.0.0,>=3.8.5" 36 | certifi = "*" 37 | multidict = "*" 38 | ecdsa = ">=0.15" 39 | eth_typing = "*" 40 | hexbytes = "*" 41 | packaging = "*" 42 | py-ecc = "==6.0.0" 43 | pytz = "==2022.2.1" 44 | typing_extensions = ">=3.10.0.2" 45 | websocket_client = "<1,>=0.32.0" 46 | toml = "==0.10.2" 47 | eth-abi = "==4.0.0" 48 | pytest = "==7.2.1" 49 | eth-utils = "==2.2.0" 50 | pycryptodome = "==3.18.0" 51 | openapi-core = "==0.15.0" 52 | openapi-spec-validator = "<0.5.0,>=0.4.0" 53 | 54 | [tool.poetry.group.dev.dependencies] 55 | setuptools = "^78.0.1" 56 | 57 | [tool.poetry.group.dev.dependencies.tomte] 58 | version = ">=0.2.15" 59 | extras = [ "cli", "tests",] 60 | -------------------------------------------------------------------------------- /run_agent.sh: -------------------------------------------------------------------------------- 1 | cleanup() { 2 | echo "Terminating tendermint..." 3 | if kill -0 "$tm_subprocess_pid" 2>/dev/null; then 4 | kill "$tm_subprocess_pid" 5 | wait "$tm_subprocess_pid" 2>/dev/null 6 | fi 7 | echo "Tendermint terminated" 8 | } 9 | 10 | # Link cleanup to the exit signal 11 | trap cleanup EXIT 12 | 13 | # Remove previous agent if exists 14 | if test -d agent; then 15 | echo "Removing previous agent build" 16 | sudo rm -r agent 17 | fi 18 | 19 | # Remove empty directories to avoid wrong hashes 20 | find . -empty -type d -delete 21 | make clean 22 | 23 | # Ensure hashes are updated 24 | autonomy packages lock 25 | 26 | # Fetch the agent 27 | autonomy fetch --local --agent valory/mech --alias agent 28 | 29 | # Copy and add the keys, env and issue certificates 30 | cd agent 31 | cp $PWD/../.agentenv . 32 | cp $PWD/../ethereum_private_key.txt . 33 | autonomy add-key ethereum ethereum_private_key.txt 34 | autonomy issue-certificates 35 | 36 | # Run tendermint 37 | rm -r ~/.tendermint 38 | tendermint init > /dev/null 2>&1 39 | echo "Starting Tendermint..." 40 | tendermint node --proxy_app=tcp://127.0.0.1:26658 --rpc.laddr=tcp://127.0.0.1:26657 --p2p.laddr=tcp://0.0.0.0:26656 --p2p.seeds= --consensus.create_empty_blocks=true > /dev/null 2>&1 & 41 | tm_subprocess_pid=$! 42 | 43 | # Run the agent 44 | aea -s run --env .agentenv 45 | -------------------------------------------------------------------------------- /run_service.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rm -r mech 4 | 5 | # Load env vars 6 | set -o allexport; source .1env; set +o allexport 7 | 8 | # Remove previous builds 9 | # if [ -d "mech" ]; then 10 | # echo $PASSWORD | sudo -S sudo rm -Rf mech; 11 | # fi 12 | 13 | # Push packages and fetch service 14 | # make formatters 15 | # make generators 16 | make clean 17 | 18 | autonomy push-all 19 | 20 | autonomy fetch --local --service valory/mech && cd mech 21 | 22 | # Build the image 23 | autonomy build-image 24 | 25 | # Copy keys and build the deployment 26 | cp $PWD/../keys.json . 27 | 28 | autonomy deploy build -ltm --n ${NUM_AGENTS:-4} 29 | 30 | # Run the deployment 31 | autonomy deploy run --build-dir abci_build/ 32 | -------------------------------------------------------------------------------- /run_tm.sh: -------------------------------------------------------------------------------- 1 | rm -r ~/.tendermint 2 | tendermint init 3 | tendermint node --proxy_app=tcp://127.0.0.1:26658 --rpc.laddr=tcp://127.0.0.1:26657 --p2p.laddr=tcp://0.0.0.0:26656 --p2p.seeds= --consensus.create_empty_blocks=true -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # ------------------------------------------------------------------------------ 3 | # 4 | # Copyright 2021-2023 Valory AG 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ------------------------------------------------------------------------------ 19 | 20 | """This directory contains scripts for workflow automation and project maintenance.""" 21 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [isort] 2 | # for black compatibility 3 | multi_line_output=3 4 | include_trailing_comma=True 5 | force_grid_wrap=0 6 | use_parentheses=True 7 | ensure_newline_before_comments = True 8 | line_length=88 9 | # custom configurations 10 | order_by_type=False 11 | case_sensitive=True 12 | lines_after_imports=2 13 | skip=packages/valory/skills/abstract_round_abci/test_tools/integration.py,packages/valory/skills/transaction_settlement_abci/test_tools/integration.py, 14 | skip_glob = 15 | known_first_party=autonomy 16 | known_packages=packages 17 | known_local_folder=tests 18 | sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,PACKAGES,LOCALFOLDER 19 | --------------------------------------------------------------------------------