Skip to content

Commit

Permalink
feat: api specs call
Browse files Browse the repository at this point in the history
  • Loading branch information
dvilelaf committed Oct 7, 2024
1 parent c8c6b47 commit 529b142
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 68 deletions.
8 changes: 4 additions & 4 deletions packages/packages.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"dev": {
"contract/valory/erc20/0.1.0": "bafybeiel24epwfr5nsk5xt2dfdimrzhrqchjxdeeh6wpm6nz35w6po6osa",
"skill/valory/learning_abci/0.1.0": "bafybeiddwdmznotlmqpdpz4jfjaxrls466mwwvodbvthijuo3dvkbvjvmq",
"skill/valory/learning_chained_abci/0.1.0": "bafybeifgnpc5ffvhgjehufna25t2zss4yjmzvjza6l667burz2ukmrr5uq",
"agent/valory/learning_agent/0.1.0": "bafybeidek5ctvxoxxoyf3uvgyoe6es5strfpbb2h6r2eqktumyoihgmj4m",
"service/valory/learning_service/0.1.0": "bafybeia54zy6nolxzrgybes7ljxt2chwi7vkcrweg6hfz2le5gpehvdb6y"
"skill/valory/learning_abci/0.1.0": "bafybeibepvsm2qzi7udwx4lrp2zugdpjpfbtw3xlvm77znhb3ii63w6rdy",
"skill/valory/learning_chained_abci/0.1.0": "bafybeig75qz4mpmoliqrzubyp7oesi63yjx3ucdaseyohm57zhevfzw54q",
"agent/valory/learning_agent/0.1.0": "bafybeidx4wzetzdpma4sxixt7fbxri6q2zj3jfixr6wd7cuo3i2blgjvxu",
"service/valory/learning_service/0.1.0": "bafybeieemuy6f66i4svedvpshtzaxwgltlevwxol7kfghodpufvorrdgsy"
},
"third_party": {
"protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi",
Expand Down
20 changes: 17 additions & 3 deletions packages/valory/agents/learning_agent/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ protocols:
skills:
- valory/abstract_abci:0.1.0:bafybeihu2bcgjk2tqjiq2zhk3uogtfszqn4osvdt7ho3fubdpdj4jgdfjm
- valory/abstract_round_abci:0.1.0:bafybeibovsktd3uxur45nrcomq5shcn46cgxd5idmhxbmjhg32c5abyqim
- valory/learning_abci:0.1.0:bafybeiddwdmznotlmqpdpz4jfjaxrls466mwwvodbvthijuo3dvkbvjvmq
- valory/learning_chained_abci:0.1.0:bafybeifgnpc5ffvhgjehufna25t2zss4yjmzvjza6l667burz2ukmrr5uq
- valory/learning_abci:0.1.0:bafybeibepvsm2qzi7udwx4lrp2zugdpjpfbtw3xlvm77znhb3ii63w6rdy
- valory/learning_chained_abci:0.1.0:bafybeig75qz4mpmoliqrzubyp7oesi63yjx3ucdaseyohm57zhevfzw54q
- valory/registration_abci:0.1.0:bafybeicnth5q4httefsusywx3zrrq4al47owvge72dqf2fziruicq6hqta
- valory/reset_pause_abci:0.1.0:bafybeievjciqdvxhqxfjd4whqs27h6qbxqzrae7wwj7fpvxlvmtw3x35im
- valory/termination_abci:0.1.0:bafybeid54buqxipiuduw7b6nnliiwsxajnltseuroad53wukfonpxca2om
Expand Down Expand Up @@ -99,7 +99,7 @@ public_id: valory/p2p_libp2p_client:0.1.0
type: connection
config:
nodes:
- uri: ${str:acn.staging.autonolas.tech:9005}
- uri: ${str:acn.autonolas.tech:9005}
public_key: ${str:02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77}
cert_requests:
- identifier: acn
Expand Down Expand Up @@ -190,3 +190,17 @@ models:
termination_from_block: ${int:34088325}
transfer_target_address: ${str:0x615d3278680337e2D39C3bc5042D959C7938B917}
olas_token_address: ${str:0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f}
coingecko_specs:
args:
api_id: coingecko
headers:
Accepr: application/json
method: GET
parameters:
ids: autonolas
vs_currencies: usd
x_cg_demo_api_key: ${str:null}
response_key: autonolas
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price?
60 changes: 58 additions & 2 deletions packages/valory/services/learning_service/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license: Apache-2.0
fingerprint:
README.md: bafybeid42pdrf6qrohedylj4ijrss236ai6geqgf3he44huowiuf7pl464
fingerprint_ignore_patterns: []
agent: valory/learning_agent:0.1.0:bafybeidek5ctvxoxxoyf3uvgyoe6es5strfpbb2h6r2eqktumyoihgmj4m
agent: valory/learning_agent:0.1.0:bafybeidx4wzetzdpma4sxixt7fbxri6q2zj3jfixr6wd7cuo3i2blgjvxu
number_of_agents: 4
deployment:
agent:
Expand Down Expand Up @@ -94,6 +94,20 @@ extra:
coingecko_api_key: ${COINGECKO_API_KEY:str:null}
transfer_target_address: ${TRANSFER_TARGET_ADDRESS:str:0x615d3278680337e2D39C3bc5042D959C7938B917}
olas_token_address: ${OLAS_TOKEN_ADDRESS:str:0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f}
coingecko_specs:
args:
api_id: coingecko
headers:
Accepr: application/json
method: GET
parameters:
ids: autonolas
vs_currencies: usd
x_cg_demo_api_key: ${COINGECKO_API_KEY:str:null}
response_key: autonolas
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price?
1:
models:
benchmark_tool:
Expand Down Expand Up @@ -141,6 +155,20 @@ extra:
coingecko_api_key: ${COINGECKO_API_KEY:str:null}
transfer_target_address: ${TRANSFER_TARGET_ADDRESS:str:0x615d3278680337e2D39C3bc5042D959C7938B917}
olas_token_address: ${OLAS_TOKEN_ADDRESS:str:0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f}
coingecko_specs:
args:
api_id: coingecko
headers:
Accepr: application/json
method: GET
parameters:
ids: autonolas
vs_currencies: usd
x_cg_demo_api_key: ${COINGECKO_API_KEY:str:null}
response_key: autonolas
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price?
2:
models:
benchmark_tool:
Expand Down Expand Up @@ -188,6 +216,20 @@ extra:
coingecko_api_key: ${COINGECKO_API_KEY:str:null}
transfer_target_address: ${TRANSFER_TARGET_ADDRESS:str:0x615d3278680337e2D39C3bc5042D959C7938B917}
olas_token_address: ${OLAS_TOKEN_ADDRESS:str:0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f}
coingecko_specs:
args:
api_id: coingecko
headers:
Accepr: application/json
method: GET
parameters:
ids: autonolas
vs_currencies: usd
x_cg_demo_api_key: ${COINGECKO_API_KEY:str:null}
response_key: autonolas
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price?
3:
models:
benchmark_tool:
Expand Down Expand Up @@ -235,6 +277,20 @@ extra:
coingecko_api_key: ${COINGECKO_API_KEY:str:null}
transfer_target_address: ${TRANSFER_TARGET_ADDRESS:str:0x615d3278680337e2D39C3bc5042D959C7938B917}
olas_token_address: ${OLAS_TOKEN_ADDRESS:str:0xcE11e14225575945b8E6Dc0D4F2dD4C570f79d9f}
coingecko_specs:
args:
api_id: coingecko
headers:
Accepr: application/json
method: GET
parameters:
ids: autonolas
vs_currencies: usd
x_cg_demo_api_key: ${COINGECKO_API_KEY:str:null}
response_key: autonolas
response_type: dict
retries: 5
url: https://api.coingecko.com/api/v3/simple/price?
---
public_id: valory/ledger:0.19.0
type: connection
Expand All @@ -255,7 +311,7 @@ public_id: valory/p2p_libp2p_client:0.1.0
type: connection
config:
nodes:
- uri: ${ACN_URI:str:acn.staging.autonolas.tech:9005}
- uri: ${ACN_URI:str:acn.autonolas.tech:9005}
public_key: ${ACN_NODE_PUBLIC_KEY:str:02d3a830c9d6ea1ae91936951430dee11f4662f33118b02190693be835359a9d77}
cert_requests:
- identifier: acn
Expand Down
58 changes: 39 additions & 19 deletions packages/valory/skills/learning_abci/behaviours.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@
AbstractRoundBehaviour,
BaseBehaviour,
)
from packages.valory.skills.learning_abci.models import Params, SharedState
from packages.valory.skills.learning_abci.models import (
CoingeckoSpecs,
Params,
SharedState,
)
from packages.valory.skills.learning_abci.payloads import (
APICheckPayload,
DataPullPayload,
DecisionMakingPayload,
TxPreparationPayload,
)
from packages.valory.skills.learning_abci.rounds import (
APICheckRound,
DataPullRound,
DecisionMakingRound,
Event,
LearningAbciApp,
Expand All @@ -52,6 +56,7 @@
from packages.valory.skills.transaction_settlement_abci.rounds import TX_HASH_LENGTH


# Define constants
HTTP_OK = 200
GNOSIS_CHAIN_ID = "gnosis"
TX_DATA = b"0x"
Expand All @@ -61,45 +66,51 @@


class LearningBaseBehaviour(BaseBehaviour, ABC): # pylint: disable=too-many-ancestors
"""Base behaviour for the learning_abci skill."""

@property
def synchronized_data(self) -> SynchronizedData:
"""Return the synchronized data."""
return cast(SynchronizedData, super().synchronized_data)
"""Base behaviour for the learning_abci behaviours."""

@property
def params(self) -> Params:
"""Return the params."""
"""Return the params. Configs go here"""
return cast(Params, super().params)

@property
def synchronized_data(self) -> SynchronizedData:
"""Return the synchronized data. This data is common to all agents"""
return cast(SynchronizedData, super().synchronized_data)

@property
def local_state(self) -> SharedState:
"""Return the state."""
"""Return the state of this particular agent."""
return cast(SharedState, self.context.state)

@property
def coingecko_specs(self) -> CoingeckoSpecs:
"""Get the Coingecko api specs."""
return self.context.coingecko_specs


class APICheckBehaviour(LearningBaseBehaviour): # pylint: disable=too-many-ancestors
"""APICheckBehaviour"""
class DataPullBehaviour(LearningBaseBehaviour): # pylint: disable=too-many-ancestors
"""This behaviours pulls token prices from API endpoints and reads the native balance of an account"""

matching_round: Type[AbstractRound] = APICheckRound
matching_round: Type[AbstractRound] = DataPullRound

def async_act(self) -> Generator:
"""Do the act, supporting asynchronous execution."""

with self.context.benchmark_tool.measure(self.behaviour_id).local():
sender = self.context.agent_address
price = yield from self.get_token_price()
price = yield from self.get_token_price_simple()
price = yield from self.get_token_price_specs()
balance = yield from self.get_token_balance()
payload = APICheckPayload(sender=sender, price=price, balance=balance)
payload = DataPullPayload(sender=sender, price=price, balance=balance)

with self.context.benchmark_tool.measure(self.behaviour_id).consensus():
yield from self.send_a2a_transaction(payload)
yield from self.wait_until_round_end()

self.set_done()

def get_token_price(self) -> Generator[None, None, Optional[float]]:
def get_token_price_simple(self) -> Generator[None, None, Optional[float]]:
"""Get token price"""

url_template = self.params.coingecko_price_template
Expand All @@ -125,6 +136,15 @@ def get_token_price(self) -> Generator[None, None, Optional[float]]:

return price

def get_token_price_specs(self) -> Generator[None, None, Optional[float]]:
"""Get token price"""
specs = self.coingecko_specs.get_spec()
raw_response = yield from self.get_http_response(**specs)
response = self.coingecko_specs.process_response(raw_response)
price = response.get("usd", None)
self.context.logger.info(f"Got token price from Coingecko: {price}")
return price

def get_token_balance(self) -> Generator[None, None, Optional[float]]:
"""Get balance"""
self.context.logger.info(
Expand Down Expand Up @@ -342,10 +362,10 @@ def _build_safe_tx_hash(
class LearningRoundBehaviour(AbstractRoundBehaviour):
"""LearningRoundBehaviour"""

initial_behaviour_cls = APICheckBehaviour
initial_behaviour_cls = DataPullBehaviour
abci_app_cls = LearningAbciApp # type: ignore
behaviours: Set[Type[BaseBehaviour]] = [ # type: ignore
APICheckBehaviour,
DataPullBehaviour,
DecisionMakingBehaviour,
TxPreparationBehaviour,
]
12 changes: 6 additions & 6 deletions packages/valory/skills/learning_abci/fsm_specification.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ alphabet_in:
- NO_MAJORITY
- ROUND_TIMEOUT
- TRANSACT
default_start_state: APICheckRound
default_start_state: DataPullRound
final_states:
- FinishedDecisionMakingRound
- FinishedTxPreparationRound
label: LearningAbciApp
start_states:
- APICheckRound
- DataPullRound
states:
- APICheckRound
- DataPullRound
- DecisionMakingRound
- FinishedDecisionMakingRound
- FinishedTxPreparationRound
- TxPreparationRound
transition_func:
(APICheckRound, DONE): DecisionMakingRound
(APICheckRound, NO_MAJORITY): APICheckRound
(APICheckRound, ROUND_TIMEOUT): APICheckRound
(DataPullRound, DONE): DecisionMakingRound
(DataPullRound, NO_MAJORITY): DataPullRound
(DataPullRound, ROUND_TIMEOUT): DataPullRound
(DecisionMakingRound, DONE): FinishedDecisionMakingRound
(DecisionMakingRound, ERROR): FinishedDecisionMakingRound
(DecisionMakingRound, NO_MAJORITY): DecisionMakingRound
Expand Down
6 changes: 5 additions & 1 deletion packages/valory/skills/learning_abci/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from typing import Any

from packages.valory.skills.abstract_round_abci.models import BaseParams
from packages.valory.skills.abstract_round_abci.models import ApiSpecs, BaseParams
from packages.valory.skills.abstract_round_abci.models import (
BenchmarkTool as BaseBenchmarkTool,
)
Expand Down Expand Up @@ -56,3 +56,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
)
self.olas_token_address = self._ensure("olas_token_address", kwargs, str)
super().__init__(*args, **kwargs)


class CoingeckoSpecs(ApiSpecs):
"""A model that wraps ApiSpecs for Coingecko API."""
4 changes: 2 additions & 2 deletions packages/valory/skills/learning_abci/payloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@


@dataclass(frozen=True)
class APICheckPayload(BaseTxPayload):
"""Represent a transaction payload for the APICheckRound."""
class DataPullPayload(BaseTxPayload):
"""Represent a transaction payload for the DataPullRound."""

price: Optional[float]
balance: Optional[float]
Expand Down
20 changes: 10 additions & 10 deletions packages/valory/skills/learning_abci/rounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
get_name,
)
from packages.valory.skills.learning_abci.payloads import (
APICheckPayload,
DataPullPayload,
DecisionMakingPayload,
TxPreparationPayload,
)
Expand Down Expand Up @@ -94,10 +94,10 @@ def tx_submitter(self) -> str:
return str(self.db.get_strict("tx_submitter"))


class APICheckRound(CollectSameUntilThresholdRound):
"""APICheckRound"""
class DataPullRound(CollectSameUntilThresholdRound):
"""DataPullRound"""

payload_class = APICheckPayload
payload_class = DataPullPayload
synchronized_data_class = SynchronizedData
done_event = Event.DONE
no_majority_event = Event.NO_MAJORITY
Expand Down Expand Up @@ -160,14 +160,14 @@ class FinishedTxPreparationRound(DegenerateRound):
class LearningAbciApp(AbciApp[Event]):
"""LearningAbciApp"""

initial_round_cls: AppState = APICheckRound
initial_round_cls: AppState = DataPullRound
initial_states: Set[AppState] = {
APICheckRound,
DataPullRound,
}
transition_function: AbciAppTransitionFunction = {
APICheckRound: {
Event.NO_MAJORITY: APICheckRound,
Event.ROUND_TIMEOUT: APICheckRound,
DataPullRound: {
Event.NO_MAJORITY: DataPullRound,
Event.ROUND_TIMEOUT: DataPullRound,
Event.DONE: DecisionMakingRound,
},
DecisionMakingRound: {
Expand All @@ -192,7 +192,7 @@ class LearningAbciApp(AbciApp[Event]):
event_to_timeout: EventToTimeout = {}
cross_period_persisted_keys: FrozenSet[str] = frozenset()
db_pre_conditions: Dict[AppState, Set[str]] = {
APICheckRound: set(),
DataPullRound: set(),
}
db_post_conditions: Dict[AppState, Set[str]] = {
FinishedDecisionMakingRound: set(),
Expand Down
Loading

0 comments on commit 529b142

Please sign in to comment.