Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/prometheus endpoint #369

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions packages/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
"contract/valory/mech_activity/0.1.0": "bafybeibmqmle5fnal3gxlpdmcos2kogzra4q3pr3o5nh7shplxuilji3t4",
"contract/valory/staking_token/0.1.0": "bafybeiep4r6qyilbfgzdvx6t7zvpgaioxqktmxm7puwtnbpb2ftlib43gy",
"contract/valory/relayer/0.1.0": "bafybeicawmds6czx7db2lcktvexwrp245jpekgulndtos5s5zdid3ilvq4",
"skill/valory/market_manager_abci/0.1.0": "bafybeiaru2d32wpmcgqs64eepxud4idgubc3vmsbdwbia7gygipql2mmqi",
"skill/valory/decision_maker_abci/0.1.0": "bafybeiddnmcquiuznts67ridhpnaqw2y3rrt4nfau5kjm74zhk5lhjxi2q",
"skill/valory/trader_abci/0.1.0": "bafybeiemjz3ca7la7jkeqdr7hxo7fa77xe2fkfadzb53gdkji7abpl2eiu",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeietwknem7iiood6pwkfup322ywwjmdrmdapllrcms6jpeev5w2qfe",
"skill/valory/market_manager_abci/0.1.0": "bafybeigi2pohxoh4nv2ku6wlhizipfsj2ijvl4pbwx223qdnel264zqrhq",
"skill/valory/decision_maker_abci/0.1.0": "bafybeiemevk3urrvzf5jvr33pncyhiuo2gqiuescg6vgan4yvhhomdkkm4",
"skill/valory/trader_abci/0.1.0": "bafybeiecarxwf3clvnfnpwyspaxcw4iqyuol4nctripb6g6kvbgetesj4a",
"skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeidchhmoaxcyhnohl5rwywicqyr234kf5ojc46mdsbw6dulr4l2zsu",
"skill/valory/staking_abci/0.1.0": "bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq",
"skill/valory/check_stop_trading_abci/0.1.0": "bafybeieduekpd4zbvjztyxyooppqnmjvup6jfp74uo6hhupvtvzzscdzkq",
"agent/valory/trader/0.1.0": "bafybeihq257kwjybsvrpzhjx4wbretrsurodpckjqdhv3idlnbu4mqvfnq",
"service/valory/trader/0.1.0": "bafybeihr6m4lec5r6kuf2zikusgyqilqwhwlpyehufyndjuziylr73dlqe",
"service/valory/trader_pearl/0.1.0": "bafybeibfqhsrtekx6nvwpz2nbbjyobljcahe6wz6jikyebt7opzxlal45u"
"skill/valory/check_stop_trading_abci/0.1.0": "bafybeidnt3irw5lrbi2n567acdksm4tfdz4gswfcicyja664qiktdobrwy",
"agent/valory/trader/0.1.0": "bafybeicu5kvhhtgstsw2im355l4qjptlcjdkblk5xkszdqmiibvzqrapde",
"service/valory/trader/0.1.0": "bafybeigr6c4qaeze6iqpxbe2yatwnfqydqclf65z5wrrqxnpuhvevlq6uy",
"service/valory/trader_pearl/0.1.0": "bafybeib52clx2k4xhvhgj53lxsy4jbbfm4j6wjx5oqa73gjr4myvgrnjzy"
},
"third_party": {
"protocol/open_aea/signing/1.0.0": "bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi",
Expand Down
11 changes: 6 additions & 5 deletions packages/valory/agents/trader/aea-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ contracts:
- valory/service_staking_token:0.1.0:bafybeihhcs3ewwzhy7yto4y36uqmice3pdvyl54fvxxv6jsxonesie4dxu
- valory/transfer_nft_condition:0.1.0:bafybeid6z2tf7nc4rhwggktxk5f62bowxdczykrxc3y76sbt2ttlw5hmtq
- valory/erc20:0.1.0:bafybeid2p2jyvjjlcsqugnawksdzsca6ljghpqbp2kfi3cxuxoy2233dbi
- valory/relayer:0.1.0:bafybeicawmds6czx7db2lcktvexwrp245jpekgulndtos5s5zdid3ilvq4
protocols:
- open_aea/signing:1.0.0:bafybeihv62fim3wl2bayavfcg3u5e5cxu3b7brtu4cn5xoxd6lqwachasi
- valory/abci:0.1.0:bafybeiaqmp7kocbfdboksayeqhkbrynvlfzsx4uy4x6nohywnmaig4an7u
Expand All @@ -45,12 +46,12 @@ skills:
- valory/reset_pause_abci:0.1.0:bafybeigrdlxed3xlsnxtjhnsbl3cojruihxcqx4jxhgivkd5i2fkjncgba
- valory/termination_abci:0.1.0:bafybeib5l7jhew5ic6iq24dd23nidcoimzqkrk556gqywhoziatj33zvwm
- valory/transaction_settlement_abci:0.1.0:bafybeic7q7recyka272udwcupblwbkc3jkodgp74fvcdxb7urametg5dae
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeietwknem7iiood6pwkfup322ywwjmdrmdapllrcms6jpeev5w2qfe
- valory/market_manager_abci:0.1.0:bafybeiaru2d32wpmcgqs64eepxud4idgubc3vmsbdwbia7gygipql2mmqi
- valory/decision_maker_abci:0.1.0:bafybeiddnmcquiuznts67ridhpnaqw2y3rrt4nfau5kjm74zhk5lhjxi2q
- valory/trader_abci:0.1.0:bafybeiemjz3ca7la7jkeqdr7hxo7fa77xe2fkfadzb53gdkji7abpl2eiu
- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeidchhmoaxcyhnohl5rwywicqyr234kf5ojc46mdsbw6dulr4l2zsu
- valory/market_manager_abci:0.1.0:bafybeigi2pohxoh4nv2ku6wlhizipfsj2ijvl4pbwx223qdnel264zqrhq
- valory/decision_maker_abci:0.1.0:bafybeiemevk3urrvzf5jvr33pncyhiuo2gqiuescg6vgan4yvhhomdkkm4
- valory/trader_abci:0.1.0:bafybeiecarxwf3clvnfnpwyspaxcw4iqyuol4nctripb6g6kvbgetesj4a
- valory/staking_abci:0.1.0:bafybeicupccurmrg7qesivonlyt3nryarsmk5qf5yh6auno64wn45bybvq
- valory/check_stop_trading_abci:0.1.0:bafybeieduekpd4zbvjztyxyooppqnmjvup6jfp74uo6hhupvtvzzscdzkq
- valory/check_stop_trading_abci:0.1.0:bafybeidnt3irw5lrbi2n567acdksm4tfdz4gswfcicyja664qiktdobrwy
- valory/mech_interact_abci:0.1.0:bafybeid6m3i5ofq7vuogqapdnoshhq7mswmudhvfcr2craw25fdwtoe3lm
customs:
- valory/mike_strat:0.1.0:bafybeihjiol7f4ch4piwfikurdtfwzsh6qydkbsztpbwbwb2yrqdqf726m
Expand Down
2 changes: 1 addition & 1 deletion packages/valory/services/trader/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: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq
fingerprint_ignore_patterns: []
agent: valory/trader:0.1.0:bafybeihq257kwjybsvrpzhjx4wbretrsurodpckjqdhv3idlnbu4mqvfnq
agent: valory/trader:0.1.0:bafybeicu5kvhhtgstsw2im355l4qjptlcjdkblk5xkszdqmiibvzqrapde
number_of_agents: 4
deployment:
agent:
Expand Down
2 changes: 1 addition & 1 deletion packages/valory/services/trader_pearl/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license: Apache-2.0
fingerprint:
README.md: bafybeibg7bdqpioh4lmvknw3ygnllfku32oca4eq5pqtvdrdsgw6buko7e
fingerprint_ignore_patterns: []
agent: valory/trader:0.1.0:bafybeihq257kwjybsvrpzhjx4wbretrsurodpckjqdhv3idlnbu4mqvfnq
agent: valory/trader:0.1.0:bafybeicu5kvhhtgstsw2im355l4qjptlcjdkblk5xkszdqmiibvzqrapde
number_of_agents: 1
deployment:
agent:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def async_act(self) -> Generator:
with self.context.benchmark_tool.measure(self.behaviour_id).local():
stop_trading = yield from self._compute_stop_trading()
self.context.logger.info(f"Computed {stop_trading=}")
payload = CheckStopTradingPayload(self.context.agent_address, stop_trading)
payload = CheckStopTradingPayload(self.context.agent_address, stop_trading, self.mech_request_count)

with self.context.benchmark_tool.measure(self.behaviour_id).consensus():
yield from self.send_a2a_transaction(payload)
Expand Down
2 changes: 2 additions & 0 deletions packages/valory/skills/check_stop_trading_abci/payloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"""This module contains the transaction payloads for the check stop trading abci."""

from dataclasses import dataclass
from typing import Optional

from packages.valory.skills.abstract_round_abci.base import BaseTxPayload

Expand All @@ -29,3 +30,4 @@ class CheckStopTradingPayload(BaseTxPayload):
"""A transaction payload for the check stop trading abci."""

vote: bool
mech_request_count: Optional[int]
22 changes: 21 additions & 1 deletion packages/valory/skills/check_stop_trading_abci/rounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,16 @@ def _get_deserialized(self, key: str) -> DeserializedCollection:
serialized = self.db.get_strict(key)
return CollectionRound.deserialize_collection(serialized)

@property
def is_staking_kpi_met(self) -> bool:
"""Get the status of the staking kpi."""
return bool(self.db.get("is_staking_kpi_met", False))

@property
def n_mech_requests(self) -> int:
"""Get the number of mech requests."""
return int(self.db.get("n_mech_requests", 0))


class CheckStopTradingRound(VotingRound):
"""A round for checking stop trading conditions."""
Expand All @@ -77,6 +83,15 @@ class CheckStopTradingRound(VotingRound):
no_majority_event = Event.NO_MAJORITY
collection_key = get_name(SynchronizedData.participant_to_votes)

@property
def mech_request_count(self) -> int:
"""Get the mech request count from the payload."""
payload = self.payloads[0]

if not hasattr(payload, "mech_request_count"):
return 0
return payload.mech_request_count

def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]:
"""Process the end of the block."""
res = super().end_block()
Expand All @@ -85,7 +100,12 @@ def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]:
return None

is_staking_kpi_met = self.positive_vote_threshold_reached
self.synchronized_data.update(is_staking_kpi_met=is_staking_kpi_met)
n_mech_requests = self.mech_request_count

self.synchronized_data.update(
is_staking_kpi_met=is_staking_kpi_met,
n_mech_requests=n_mech_requests
)

return res

Expand Down
6 changes: 3 additions & 3 deletions packages/valory/skills/check_stop_trading_abci/skill.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
README.md: bafybeif2pq7fg5upl6vmfgfzpiwsh4nbk4zaeyz6upyucqi5tasrxgq4ee
__init__.py: bafybeifc23rlw2hzhplp3wfceixnmwq5ztnixhh7jp4dd5av3crwp3x22a
behaviours.py: bafybeie5mkpxsd6z3vjsoacvswin6zz4q4um5gqp6jhwtn65fepx2kma3m
behaviours.py: bafybeibj2sckgorqe4zugak6typbqwev6ot6e6thwelebrzm44gpqxi54i
dialogues.py: bafybeictrrnwcijiejczy23dfvbx5kujgef3dulzqhs3etl2juvz5spm2e
fsm_specification.yaml: bafybeihhau35a5xclncjpxh5lg7qiw34xs4d5qlez7dnjpkf45d3gc57ai
handlers.py: bafybeiard64fwxib3rtyp67ymhf222uongcyqhfhdyttpsyqkmyh5ajipu
models.py: bafybeigwdhgianx5rizlb7ebmm6pdtkixh4uehbvu5c24ysvyvojs74dfq
payloads.py: bafybeidh5bqywun4chrbsci2xbcrnnzuys5sswxwbxq3yl2ksawi3xsi5q
rounds.py: bafybeift7b2afck4e5so2cpgyoywa76t6el6d4qwfoitvfdjw6kgf4fwie
payloads.py: bafybeigyuhfflh45oovhlwij3zgay4xjrrj2mt2pbhtxtughlimzn2jvgq
rounds.py: bafybeif3e23wbnb3niz6czhjo2xxat6mpqw3zt32dee7qnzwwsnhx43yue
tests/__init__.py: bafybeihv2cjk4va5bc5ncqtppqg2xmmxcro34bma36trtvk32gtmhdycxu
tests/test_dialogues.py: bafybeia5ac27w7ijx2nyx5dqyrnv4troo4572gjq7nrcxdncexoxucnqti
tests/test_handlers.py: bafybeigpmtx2hyunzn6nxk2x4bvvybek7jvuhbk34fqlj7fgfsszcoqhxy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,15 @@ def async_act(self) -> Generator:
tx_submitter = self.matching_round.auto_round_id()
betting_tx_hex = yield from self._prepare_safe_tx()
wallet_balance = self.wallet_balance
token_balance = self.token_balance

payload = BetPlacementPayload(
agent,
tx_submitter,
betting_tx_hex,
mocking_mode,
wallet_balance,
token_balance
)

yield from self.finish_behaviour(payload)
127 changes: 112 additions & 15 deletions packages/valory/skills/decision_maker_abci/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,25 @@
"""This module contains the handler for the 'decision_maker_abci' skill."""

import json
import prometheus_client
import re
from datetime import datetime
from enum import Enum
from typing import Callable, Dict, Optional, Tuple, cast
from urllib.parse import urlparse

import requests

from aea.protocols.base import Message
from aea_ledger_ethereum import EthereumApi
from prometheus_client import MetricsHandler, Gauge, generate_latest

from packages.valory.connections.http_server.connection import (
PUBLIC_ID as HTTP_SERVER_PUBLIC_ID,
)
from packages.valory.protocols.http.message import HttpMessage
from packages.valory.protocols.ipfs import IpfsMessage
from packages.valory.skills.abstract_round_abci.base import LEDGER_API_ADDRESS
from packages.valory.skills.abstract_round_abci.handlers import (
ABCIRoundHandler as BaseABCIRoundHandler,
)
Expand All @@ -59,7 +65,6 @@
from packages.valory.skills.decision_maker_abci.models import SharedState
from packages.valory.skills.decision_maker_abci.rounds import SynchronizedData


ABCIHandler = BaseABCIRoundHandler
SigningHandler = BaseSigningHandler
LedgerApiHandler = BaseLedgerApiHandler
Expand Down Expand Up @@ -133,11 +138,13 @@ def setup(self) -> None:
hostname_regex = rf".*({config_uri_base_hostname}|{propel_uri_base_hostname}|{local_ip_regex}|localhost|127.0.0.1|0.0.0.0)(:\d+)?"
self.handler_url_regex = rf"{hostname_regex}\/.*"
health_url_regex = rf"{hostname_regex}\/healthcheck"
metrics_url_regex = rf"{hostname_regex}\/metrics"

# Routes
self.routes = {
(HttpMethod.GET.value, HttpMethod.HEAD.value): [
(health_url_regex, self._handle_get_health),
(metrics_url_regex, self._handle_get_metrics)
],
}

Expand Down Expand Up @@ -194,8 +201,8 @@ def handle(self, message: Message) -> None:

# Check if this is a request sent from the http_server skill
if (
http_msg.performative != HttpMessage.Performative.REQUEST
or message.sender != str(HTTP_SERVER_PUBLIC_ID.without_hash())
http_msg.performative != HttpMessage.Performative.REQUEST
or message.sender != str(HTTP_SERVER_PUBLIC_ID.without_hash())
):
super().handle(message)
return
Expand Down Expand Up @@ -230,7 +237,7 @@ def handle(self, message: Message) -> None:
handler(http_msg, http_dialogue, **kwargs)

def _handle_bad_request(
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
) -> None:
"""
Handle a Http bad request.
Expand All @@ -253,7 +260,7 @@ def _handle_bad_request(
self.context.outbox.put_message(message=http_response)

def _handle_get_health(
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
) -> None:
"""
Handle a Http request of verb GET.
Expand Down Expand Up @@ -284,9 +291,9 @@ def _handle_get_health(
)

is_transitioning_fast = (
not is_tm_unhealthy
and seconds_since_last_transition
< 2 * self.context.params.reset_pause_duration
not is_tm_unhealthy
and seconds_since_last_transition
< 2 * self.context.params.reset_pause_duration
)

if round_sequence._abci_app:
Expand Down Expand Up @@ -314,7 +321,7 @@ def _handle_get_health(
self._send_ok_response(http_msg, http_dialogue, data)

def _send_ok_response(
self, http_msg: HttpMessage, http_dialogue: HttpDialogue, data: Dict
self, http_msg: HttpMessage, http_dialogue: HttpDialogue, data: Dict
) -> None:
"""Send an OK response with the provided data"""
http_response = http_dialogue.reply(
Expand All @@ -332,7 +339,7 @@ def _send_ok_response(
self.context.outbox.put_message(message=http_response)

def _send_not_found_response(
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
self, http_msg: HttpMessage, http_dialogue: HttpDialogue
) -> None:
"""Send an not found response"""
http_response = http_dialogue.reply(
Expand All @@ -351,16 +358,106 @@ def _send_not_found_response(
def _check_required_funds(self) -> bool:
"""Check the agent has enough funds."""
return (
self.synchronized_data.wallet_balance
> self.context.params.agent_balance_threshold
self.synchronized_data.wallet_balance
> self.context.params.agent_balance_threshold
)

def _check_is_receiving_mech_responses(self) -> bool:
"""Check the agent is making on chain transactions."""
# Checks the most recent decision receive timestamp, which can only be returned after making a mech call
# (an on chain transaction)
return (
self.synchronized_data.decision_receive_timestamp
< int(datetime.utcnow().timestamp())
- self.context.params.expected_mech_response_time
self.synchronized_data.decision_receive_timestamp
< int(datetime.utcnow().timestamp())
- self.context.params.expected_mech_response_time
)

def _handle_get_metrics(self, http_msg, http_dialogue):
"""
Handle the /metrics endpoint.
"""
self.set_metrics()
# Generate the metrics data
metrics_data = generate_latest()

# Create a response with the metrics data
http_response = http_dialogue.reply(
performative=HttpMessage.Performative.RESPONSE,
target_message=http_msg,
version=http_msg.version,
status_code=OK_CODE,
status_text="Success",
headers=f"Content-Type: {prometheus_client.CONTENT_TYPE_LATEST}\n{http_msg.headers}",
body=metrics_data,
)

# Send response
self.context.logger.info("Responding with metrics data")
self.context.outbox.put_message(message=http_response)

def set_metrics(self):
agent_address = self.context.agent_address
safe_address = self.synchronized_data.safe_contract_address
service_id = self.context.params.on_chain_service_id

native_balance = self.synchronized_data.wallet_balance
wxdai_balance = self.synchronized_data.token_balance
# staking_contract_available_slots = self.get_available_staking_slots(LEDGER_API_ADDRESS)
staking_state = self.synchronized_data.service_staking_state.value
time_since_last_successful_mech_tx = self.synchronized_data.decision_receive_timestamp
n_total_mech_requests = len(self.synchronized_data.mech_requests)
# n_successful_mech_requests = len(self.synchronized_data.mech_responses)
# n_failed_mech_requests = n_total_mech_requests - n_successful_mech_requests

NATIVE_BALANCE_GAUGE.labels(agent_address, safe_address, service_id).set(
native_balance)
WXDAI_BALANCE_GAUGE.labels(agent_address, safe_address, service_id).set(wxdai_balance)
# STAKING_CONTRACT_AVAILABLE_SLOTS_GAUGE.set(staking_contract_available_slots)
STAKING_STATE_GAUGE.labels(agent_address, safe_address, service_id).set(staking_state)
TIME_SINCE_LAST_SUCCESSFUL_MECH_TX_GAUGE.labels(agent_address, safe_address, service_id).set(
time_since_last_successful_mech_tx)
TOTAL_MECH_TXS.labels(agent_address, safe_address, service_id).set(n_total_mech_requests)
# TOTAL_SUCCESSFUL_MECH_TXS.labels(agent_address, safe_address, service_id).set(n_successful_mech_requests)
# TOTAL_FAILED_MECH_TXS.labels(agent_address, safe_address, service_id).set(n_failed_mech_requests)


NATIVE_BALANCE_GAUGE = Gauge("olas_agent_native_balance",
"Native token balance in xDai",
['agent_address', 'safe_address', 'service_id']
)

OLAS_BALANCE_GAUGE = Gauge("olas_agent_olas_balance",
"OLAS token balance", ['agent_address', 'safe_address', 'service_id']
)

WXDAI_BALANCE_GAUGE = Gauge("olas_agent_wxdai_balance",
"WXDAI token balance", ['agent_address', 'safe_address', 'service_id']
)

STAKING_CONTRACT_AVAILABLE_SLOTS_GAUGE = Gauge("olas_staking_contract_available_slots",
"Number of available slots in the staking contract", ['agent_address', 'safe_address', 'service_id']
)

STAKING_STATE_GAUGE = Gauge("olas_agent_staked",
"Indicates if an agent is staked (1), not staked (0) or eviceted (2)", ['agent_address', 'safe_address', 'service_id']
)

TIME_SINCE_LAST_SUCCESSFUL_MECH_TX_GAUGE = Gauge("olas_agent_time_since_last_successful_tx",
"Time in seconds since last successful mech transaction", ['agent_address', 'safe_address', 'service_id']
)

TIME_SINCE_LAST_MECH_TX_ATTEMPT = Gauge("olas_agent_time_since_last_tx_attempt",
"Time in seconds since last transaction attempt (successful or not)", ['agent_address', 'safe_address', 'service_id']
)

TOTAL_MECH_TXS = Gauge("olas_agent_txs",
"Total number of transactions", ['agent_address', 'safe_address', 'service_id']
)

TOTAL_SUCCESSFUL_MECH_TXS = Gauge("olas_successful_agent_txs",
"Total successful number of transactions", ['agent_address', 'safe_address', 'service_id']
)

TOTAL_FAILED_MECH_TXS = Gauge("olas_failed_agent_txs",
"Total failed number of transaction", ['agent_address', 'safe_address', 'service_id']
)
1 change: 1 addition & 0 deletions packages/valory/skills/decision_maker_abci/payloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,4 @@ class BetPlacementPayload(MultisigTxPayload):
"""Represents a transaction payload for placing a bet."""

wallet_balance: Optional[int] = None
token_balance: Optional[int] = None
Loading
Loading