diff --git a/packages/packages.json b/packages/packages.json index d8c071ab5..91f37025b 100644 --- a/packages/packages.json +++ b/packages/packages.json @@ -1,15 +1,15 @@ { "dev": { - "skill/valory/market_manager_abci/0.1.0": "bafybeidropskas24c4lcekzdbwoflhnzaglmeqxvpyuoa7cf7q2rf2yex4", - "skill/valory/decision_maker_abci/0.1.0": "bafybeic2yjuwtfxekyukqgewbdnqc56ywuhn3pjgohjedzz7oaylbwqufy", - "skill/valory/trader_abci/0.1.0": "bafybeidnjemlz2kisz3slmdid53bwas44wnu7loubcjahgdzvofskfqzpi", + "skill/valory/market_manager_abci/0.1.0": "bafybeibrjre5yka3sbvb6lsefgc5yutovb6h4ffzrpecplfkjwtl5i36te", + "skill/valory/decision_maker_abci/0.1.0": "bafybeiggsi3hyu2lqqfxh5fonkwh7rdmounrpbkaxtt6aeqm4cr362cwuy", + "skill/valory/trader_abci/0.1.0": "bafybeihqqcq63pijsep4aqyz6criwncga6dgoinkmb6ptbsrcxekw6f4xe", "contract/valory/market_maker/0.1.0": "bafybeif4mm2s3gxtvp227yypkcnna5ftec7vajcftvtbdmqddh7nprah5m", - "agent/valory/trader/0.1.0": "bafybeihqpkckhv2rkldbnaav6jlkiziacqdsbw3suykjzgqls7v3jkomz4", - "service/valory/trader/0.1.0": "bafybeid3r54ylrhu7vhrhzqb3vaqrecvpeuksgnfkjryhpt6ofsqqsa2ve", + "agent/valory/trader/0.1.0": "bafybeien2oswgsiklat7snobp6tt6kwoatbhm23qdcwou4nxzkzvmybefu", + "service/valory/trader/0.1.0": "bafybeidru4qhpp7wgx2qqkg74rvp7fytvl45bj2iosalwava4j3hhsedjy", "contract/valory/erc20/0.1.0": "bafybeieqj7dea4tcv6z2yqkgtmhd23vbiycsr5trhwxdvlbwulpl6vhmam", - "skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeifdiag5des6schlumiyes2nvrlhi6nupvneup247iaswehttg7wqu", + "skill/valory/tx_settlement_multiplexer_abci/0.1.0": "bafybeibda3fyr6hbbnlz5unncuhaidznconrwqa7tqbsuxqpal2vdlalra", "contract/valory/mech/0.1.0": "bafybeihvc6btuk3nvernzcx4qpezvuhiw2wwnagqj5nkeljvszghv7mq64", - "contract/valory/realitio/0.1.0": "bafybeid6kh4tiqswpeufkr7eowmq7seoyhkssnedgzw6pe4h7wswui6dlm", + "contract/valory/realitio/0.1.0": "bafybeiamgkwwqhray4fs2hlipwxkq7mosmi7ev7jut4vneetaaycc4ruji", "contract/valory/realitio_proxy/0.1.0": "bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4", "contract/valory/conditional_tokens/0.1.0": "bafybeifov35k2ifwagzyfvl7km6je6tmyvcqgrccldob3zmbx2af2wzque", "contract/valory/agent_registry/0.1.0": "bafybeifwdtwxdc2jdlhzdyxctqdmoz6zroxf5o4nhuok5l4luvnofqavty", diff --git a/packages/valory/agents/trader/aea-config.yaml b/packages/valory/agents/trader/aea-config.yaml index 76bb53f72..3697d9dc0 100644 --- a/packages/valory/agents/trader/aea-config.yaml +++ b/packages/valory/agents/trader/aea-config.yaml @@ -23,7 +23,7 @@ contracts: - valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y - valory/mech:0.1.0:bafybeihvc6btuk3nvernzcx4qpezvuhiw2wwnagqj5nkeljvszghv7mq64 - valory/conditional_tokens:0.1.0:bafybeifov35k2ifwagzyfvl7km6je6tmyvcqgrccldob3zmbx2af2wzque -- valory/realitio:0.1.0:bafybeid6kh4tiqswpeufkr7eowmq7seoyhkssnedgzw6pe4h7wswui6dlm +- valory/realitio:0.1.0:bafybeiamgkwwqhray4fs2hlipwxkq7mosmi7ev7jut4vneetaaycc4ruji - valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 - valory/agent_registry:0.1.0:bafybeifwdtwxdc2jdlhzdyxctqdmoz6zroxf5o4nhuok5l4luvnofqavty - valory/service_staking_token:0.1.0:bafybeibifxmoeaiptovouispl5jdgm4lduzcfgsx723zlw45cfpllecuwy @@ -43,10 +43,10 @@ skills: - valory/reset_pause_abci:0.1.0:bafybeicpxn2khtaesuf4cq6ypwdmdmonlqroj2q2i6cxvpizc2y4cw66pe - valory/termination_abci:0.1.0:bafybeieqm46zuccaagnko3qlw6p3nvoohdrfgvpmw467r5lyil2dqrzjsy - valory/transaction_settlement_abci:0.1.0:bafybeia6cdxdlqrcwk2maw25fo7dafzd2p3rs7syropvufophk2pitzbwy -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeifdiag5des6schlumiyes2nvrlhi6nupvneup247iaswehttg7wqu -- valory/market_manager_abci:0.1.0:bafybeidropskas24c4lcekzdbwoflhnzaglmeqxvpyuoa7cf7q2rf2yex4 -- valory/decision_maker_abci:0.1.0:bafybeic2yjuwtfxekyukqgewbdnqc56ywuhn3pjgohjedzz7oaylbwqufy -- valory/trader_abci:0.1.0:bafybeidnjemlz2kisz3slmdid53bwas44wnu7loubcjahgdzvofskfqzpi +- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeibda3fyr6hbbnlz5unncuhaidznconrwqa7tqbsuxqpal2vdlalra +- valory/market_manager_abci:0.1.0:bafybeibrjre5yka3sbvb6lsefgc5yutovb6h4ffzrpecplfkjwtl5i36te +- valory/decision_maker_abci:0.1.0:bafybeiggsi3hyu2lqqfxh5fonkwh7rdmounrpbkaxtt6aeqm4cr362cwuy +- valory/trader_abci:0.1.0:bafybeihqqcq63pijsep4aqyz6criwncga6dgoinkmb6ptbsrcxekw6f4xe default_ledger: ethereum required_ledgers: - ethereum diff --git a/packages/valory/contracts/realitio/contract.py b/packages/valory/contracts/realitio/contract.py index cbf501ae6..29b5d66f7 100644 --- a/packages/valory/contracts/realitio/contract.py +++ b/packages/valory/contracts/realitio/contract.py @@ -77,14 +77,11 @@ def get_claim_params( ) return dict(error=msg) - if len(answered) == 0: - msg = ( - f"No answers have been given for question with id {question_id.hex()} " - f"between blocks {from_block} and {to_block}." - ) - return dict(info=msg) - - return dict(answered=answered) + msg = ( + f"Found {len(answered)} answer(s) for question with id {question_id.hex()} " + f"between blocks {from_block} and {to_block}." + ) + return dict(info=msg, answered=answered) @classmethod def build_claim_winnings( diff --git a/packages/valory/contracts/realitio/contract.yaml b/packages/valory/contracts/realitio/contract.yaml index bf6f146b4..8930ab41d 100644 --- a/packages/valory/contracts/realitio/contract.yaml +++ b/packages/valory/contracts/realitio/contract.yaml @@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0' fingerprint: __init__.py: bafybeictahkgfmlqv5kksvj6klmxtmjdpeq4sp3x7dp2yr5x4kmzbcihse build/Realitio.json: bafybeiagi7zoeoy5s7duhg4oeuekj2s6z5mad2z6g2pn3n5elsvze25qiu - contract.py: bafybeiawjv5qeouf6wac5adqzeudl5loaya3mszhc65whb22shsvivjwxm + contract.py: bafybeie4qmxeb3wdok62lsn5eyct25us4qgbgq3qzswnx7a52xfvxo7c6q fingerprint_ignore_patterns: [] class_name: RealitioContract contract_interface_paths: diff --git a/packages/valory/services/trader/service.yaml b/packages/valory/services/trader/service.yaml index 2c744353b..75794e533 100644 --- a/packages/valory/services/trader/service.yaml +++ b/packages/valory/services/trader/service.yaml @@ -7,7 +7,7 @@ license: Apache-2.0 fingerprint: README.md: bafybeigtuothskwyvrhfosps2bu6suauycolj67dpuxqvnicdrdu7yhtvq fingerprint_ignore_patterns: [] -agent: valory/trader:0.1.0:bafybeihqpkckhv2rkldbnaav6jlkiziacqdsbw3suykjzgqls7v3jkomz4 +agent: valory/trader:0.1.0:bafybeien2oswgsiklat7snobp6tt6kwoatbhm23qdcwou4nxzkzvmybefu number_of_agents: 4 deployment: {} --- diff --git a/packages/valory/skills/decision_maker_abci/behaviours/base.py b/packages/valory/skills/decision_maker_abci/behaviours/base.py index f3281e9da..2ae3fd8f5 100644 --- a/packages/valory/skills/decision_maker_abci/behaviours/base.py +++ b/packages/valory/skills/decision_maker_abci/behaviours/base.py @@ -362,20 +362,21 @@ def default_error( f"using {contract_callable!r}: {response_msg}" ) - def contract_interaction_error( - self, contract_id: str, contract_callable: str, response_msg: ContractApiMessage - ) -> None: - """Return a contract interaction error message.""" - # contracts can only return one message, i.e., multiple levels cannot exist. + def _propagate_contract_messages(self, response_msg: ContractApiMessage) -> None: + """Propagate the contract's message to the logger, if exists. + + Contracts can only return one message at a time. + + :param response_msg: the response message from the contract method. + :return: None + """ for level in ("info", "warning", "error"): msg = response_msg.raw_transaction.body.get(level, None) - logger = getattr(self.context.logger, level) if msg is not None: + logger = getattr(self.context.logger, level) logger(msg) return - self.default_error(contract_id, contract_callable, response_msg) - def contract_interact( self, performative: ContractApiMessage.Performative, @@ -399,11 +400,11 @@ def contract_interact( self.default_error(contract_id, contract_callable, response_msg) return False + self._propagate_contract_messages(response_msg) + data = response_msg.raw_transaction.body.get(data_key, None) if data is None: - self.contract_interaction_error( - contract_id, contract_callable, response_msg - ) + self.default_error(contract_id, contract_callable, response_msg) return False setattr(self, placeholder, data) diff --git a/packages/valory/skills/decision_maker_abci/behaviours/reedem.py b/packages/valory/skills/decision_maker_abci/behaviours/reedem.py index 127ec059e..e32c9a04e 100644 --- a/packages/valory/skills/decision_maker_abci/behaviours/reedem.py +++ b/packages/valory/skills/decision_maker_abci/behaviours/reedem.py @@ -536,9 +536,9 @@ def get_claim_params(self) -> WaitableConditionType: ): max_to_block = from_block + batch_size to_block = min(max_to_block, self.redeeming_progress.claim_to_block) - result = yield from self._conditional_tokens_interact( + result = yield from self._realitio_interact( contract_callable="get_claim_params", - data_key="claim_params", + data_key="answered", placeholder=get_name(RedeemBehaviour.claim_params_batch), from_block=from_block, to_block=to_block, @@ -556,6 +556,13 @@ def _build_claim_data(self) -> WaitableConditionType: if not self.redeeming_progress.claim_finished: yield from self.wait_for_condition_with_sleep(self.get_claim_params) + claim_params = self.redeeming_progress.claim_params + if claim_params is None: + self.context.logger.error( + f"Cannot parse incorrectly formatted realitio `LogNewAnswer` events: {self.redeeming_progress.answered}" + ) + return False + result = yield from self._realitio_interact( contract_callable="build_claim_winnings", data_key="data", diff --git a/packages/valory/skills/decision_maker_abci/models.py b/packages/valory/skills/decision_maker_abci/models.py index 1f7b1b43a..afb41b77b 100644 --- a/packages/valory/skills/decision_maker_abci/models.py +++ b/packages/valory/skills/decision_maker_abci/models.py @@ -99,26 +99,29 @@ def claim_finished(self) -> bool: return self.claim_started and self.claim_from_block == self.claim_to_block @property - def claim_params(self) -> ClaimParamsType: + def claim_params(self) -> Optional[ClaimParamsType]: """The claim parameters, prepared for the `claimWinnings` call.""" history_hashes = [] addresses = [] bonds = [] answers = [] - for i, answer in enumerate(reversed(self.answered)): - # history_hashes second-last-to-first, the hash of each history entry, calculated as described here: - # https://realitio.github.io/docs/html/contract_explanation.html#answer-history-entries. - if i == len(self.answered) - 1: - history_hashes.append(ZERO_BYTES) - else: - history_hashes.append(self.answered[i + 1]["args"]["history_hash"]) - - # last-to-first, the address of each answerer or commitment sender - addresses.append(answer["args"]["user"]) - # last-to-first, the bond supplied with each answer or commitment - bonds.append(answer["args"]["bond"]) - # last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal - answers.append(answer["args"]["answer"]) + try: + for i, answer in enumerate(reversed(self.answered)): + # history_hashes second-last-to-first, the hash of each history entry, calculated as described here: + # https://realitio.github.io/docs/html/contract_explanation.html#answer-history-entries. + if i == len(self.answered) - 1: + history_hashes.append(ZERO_BYTES) + else: + history_hashes.append(self.answered[i + 1]["args"]["history_hash"]) + + # last-to-first, the address of each answerer or commitment sender + addresses.append(answer["args"]["user"]) + # last-to-first, the bond supplied with each answer or commitment + bonds.append(answer["args"]["bond"]) + # last-to-first, each answer supplied, or commitment ID if the answer was supplied with commit->reveal + answers.append(answer["args"]["answer"]) + except KeyError: + return None return history_hashes, addresses, bonds, answers diff --git a/packages/valory/skills/decision_maker_abci/skill.yaml b/packages/valory/skills/decision_maker_abci/skill.yaml index e1955b187..736d6525f 100644 --- a/packages/valory/skills/decision_maker_abci/skill.yaml +++ b/packages/valory/skills/decision_maker_abci/skill.yaml @@ -12,20 +12,20 @@ fingerprint: README.md: bafybeia367zzdwndvlhw27rvnwodytjo3ms7gbc3q7mhrrjqjgfasnk47i __init__.py: bafybeih563ujnigeci2ldzh7hakbau6a222vsed7leg3b7lq32vcn3nm4a behaviours/__init__.py: bafybeih6ddz2ocvm6x6ytvlbcz6oi4snb5ee5xh5h65nq4w2qf7fd7zfky - behaviours/base.py: bafybeiffvzohjzr6rubdccfcbhgbjyyxxx2flldavubwtjuac2hai2nrdy + behaviours/base.py: bafybeidlbdyrcd2sifjmbxql4mdki3mpzxbu6bug2e2ljmd7lnliycc7hm behaviours/bet_placement.py: bafybeigtz4uimsqjjwq4r5p3a5v6niqdtqezbuf2ghy6o7syhsh4k5gjfa behaviours/blacklisting.py: bafybeicl6b4hcmqmekta2mcuhkkydnzk7jmic6k44e6ns3u2ibad3awzvu behaviours/decision_receive.py: bafybeifacce2ke7oltnwnpdjdqfd74eaaw5wxnjfzk6c5tqdsxsmbzjj3m behaviours/decision_request.py: bafybeibrk6jxalkgspinmjboqr3o6d6hl6mxtlkif74a5p32vp2zzhhzua behaviours/handle_failed_tx.py: bafybeidxpc6u575ymct5tdwutvzov6zqfdoio5irgldn3fw7q3lg36mmxm - behaviours/reedem.py: bafybeiewhlzhvrjtllym3jyk5fzci4r67fgutgzgrsmv4t3uvrejm7aaki + behaviours/reedem.py: bafybeiepr4sellesn37csr7tmd4yhdsnn6y2jmy6kaculty6pffjc6tawe behaviours/round_behaviour.py: bafybeig4tdktyu6hapoqymnxh2bgpds547st6a44heue657wkctwe4gjvm behaviours/sampling.py: bafybeieu4obvwhsquvgmdi7moo4eajdh376oqlzb4zu3wsznovg2o5x2de behaviours/tool_selection.py: bafybeigfr2frkljrxyfxs5p3j42equzehgaqtkyuxk6eiujyudr6ajqakm dialogues.py: bafybeigpwuzku3we7axmxeamg7vn656maww6emuztau5pg3ebsoquyfdqm fsm_specification.yaml: bafybeifnob3ceim2mj7lqagtnpwqjqqxs5eg3oiwc73gwm6x5i2dvvlcya handlers.py: bafybeihj33szgrcxnpd73s4nvluyxwwsvhjum2cuq3ilhhe6vfola3k7vy - models.py: bafybeibcdzwl33kge725ivlz4emclzj2tu7cvbzrnwa3v7tuux37lwt5vm + models.py: bafybeib5qqd7cty2onkkocwbeueosra4xkgv4z7u2xnrhrkc63xb6jjs7q payloads.py: bafybeifhq6stu4vp2ef4qvihxgpos3yc2zcuaja2safwt7efdidoejgvqa policy.py: bafybeidpmx4ek3qze63zpuwixyf6t7bdv62ewgkzt3ljrzadiwdw64cueq redeem_info.py: bafybeibddfxwp3577c3dl2utaowwltquu5fg6crezpumoebw563wxpbfrm @@ -50,7 +50,7 @@ contracts: - valory/multisend:0.1.0:bafybeig5byt5urg2d2bsecufxe5ql7f4mezg3mekfleeh32nmuusx66p4y - valory/mech:0.1.0:bafybeihvc6btuk3nvernzcx4qpezvuhiw2wwnagqj5nkeljvszghv7mq64 - valory/conditional_tokens:0.1.0:bafybeifov35k2ifwagzyfvl7km6je6tmyvcqgrccldob3zmbx2af2wzque -- valory/realitio:0.1.0:bafybeid6kh4tiqswpeufkr7eowmq7seoyhkssnedgzw6pe4h7wswui6dlm +- valory/realitio:0.1.0:bafybeiamgkwwqhray4fs2hlipwxkq7mosmi7ev7jut4vneetaaycc4ruji - valory/realitio_proxy:0.1.0:bafybeidx37xzjjmapwacedgzhum6grfzhp5vhouz4zu3pvpgdy5pgb2fr4 - valory/agent_registry:0.1.0:bafybeifwdtwxdc2jdlhzdyxctqdmoz6zroxf5o4nhuok5l4luvnofqavty protocols: @@ -58,7 +58,7 @@ protocols: - valory/ledger_api:1.0.0:bafybeige5agrztgzfevyglf7mb4o7pzfttmq4f6zi765y4g2zvftbyowru skills: - valory/abstract_round_abci:0.1.0:bafybeid7neqpxxe4ualp23gxgrtpf6r5u3myr2mmc4uvwameyqshfdoydq -- valory/market_manager_abci:0.1.0:bafybeidropskas24c4lcekzdbwoflhnzaglmeqxvpyuoa7cf7q2rf2yex4 +- valory/market_manager_abci:0.1.0:bafybeibrjre5yka3sbvb6lsefgc5yutovb6h4ffzrpecplfkjwtl5i36te - valory/transaction_settlement_abci:0.1.0:bafybeia6cdxdlqrcwk2maw25fo7dafzd2p3rs7syropvufophk2pitzbwy behaviours: main: diff --git a/packages/valory/skills/market_manager_abci/rounds.py b/packages/valory/skills/market_manager_abci/rounds.py index bd12c00c9..6e0eac088 100644 --- a/packages/valory/skills/market_manager_abci/rounds.py +++ b/packages/valory/skills/market_manager_abci/rounds.py @@ -114,7 +114,7 @@ def end_block(self) -> Optional[Tuple[BaseSynchronizedData, Enum]]: if event != Event.FETCH_ERROR: return res - synced_data.update(SynchronizedData, bets=synced_data.bets) + synced_data.update(SynchronizedData, bets=synced_data.db.get("bets", "")) return synced_data, event diff --git a/packages/valory/skills/market_manager_abci/skill.yaml b/packages/valory/skills/market_manager_abci/skill.yaml index ca4442035..71ff2b133 100644 --- a/packages/valory/skills/market_manager_abci/skill.yaml +++ b/packages/valory/skills/market_manager_abci/skill.yaml @@ -20,7 +20,7 @@ fingerprint: handlers.py: bafybeihot2i2yvfkz2gcowvt66wdu6tkjbmv7hsmc4jzt4reqeaiuphbtu models.py: bafybeifmb4cojxesv2lcw6j3pm3yqjpsiuwyxpuexjbz656fpapdqcj2ba payloads.py: bafybeiamavgddfbzofpsjthmw6j7g2dyxm7fb6hvdb47kweyrx4w2ihcfi - rounds.py: bafybeib2jkzzpnmx6eebw3cw6t2hlzxktumbzrerjlowlpv532eink6g7e + rounds.py: bafybeihsphyqat2sn46nukisxpvx5g2yfal4iyobhnoccbeavfz7xnhhri fingerprint_ignore_patterns: [] connections: [] contracts: [] diff --git a/packages/valory/skills/trader_abci/skill.yaml b/packages/valory/skills/trader_abci/skill.yaml index dd2de3c85..5cf25a943 100644 --- a/packages/valory/skills/trader_abci/skill.yaml +++ b/packages/valory/skills/trader_abci/skill.yaml @@ -24,9 +24,9 @@ skills: - valory/reset_pause_abci:0.1.0:bafybeicpxn2khtaesuf4cq6ypwdmdmonlqroj2q2i6cxvpizc2y4cw66pe - valory/transaction_settlement_abci:0.1.0:bafybeia6cdxdlqrcwk2maw25fo7dafzd2p3rs7syropvufophk2pitzbwy - valory/termination_abci:0.1.0:bafybeieqm46zuccaagnko3qlw6p3nvoohdrfgvpmw467r5lyil2dqrzjsy -- valory/market_manager_abci:0.1.0:bafybeidropskas24c4lcekzdbwoflhnzaglmeqxvpyuoa7cf7q2rf2yex4 -- valory/decision_maker_abci:0.1.0:bafybeic2yjuwtfxekyukqgewbdnqc56ywuhn3pjgohjedzz7oaylbwqufy -- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeifdiag5des6schlumiyes2nvrlhi6nupvneup247iaswehttg7wqu +- valory/market_manager_abci:0.1.0:bafybeibrjre5yka3sbvb6lsefgc5yutovb6h4ffzrpecplfkjwtl5i36te +- valory/decision_maker_abci:0.1.0:bafybeiggsi3hyu2lqqfxh5fonkwh7rdmounrpbkaxtt6aeqm4cr362cwuy +- valory/tx_settlement_multiplexer_abci:0.1.0:bafybeibda3fyr6hbbnlz5unncuhaidznconrwqa7tqbsuxqpal2vdlalra behaviours: main: args: {} diff --git a/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml b/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml index 46a1eab6a..69aadaa8b 100644 --- a/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml +++ b/packages/valory/skills/tx_settlement_multiplexer_abci/skill.yaml @@ -20,7 +20,7 @@ contracts: [] protocols: [] skills: - valory/abstract_round_abci:0.1.0:bafybeid7neqpxxe4ualp23gxgrtpf6r5u3myr2mmc4uvwameyqshfdoydq -- valory/decision_maker_abci:0.1.0:bafybeic2yjuwtfxekyukqgewbdnqc56ywuhn3pjgohjedzz7oaylbwqufy +- valory/decision_maker_abci:0.1.0:bafybeiggsi3hyu2lqqfxh5fonkwh7rdmounrpbkaxtt6aeqm4cr362cwuy behaviours: main: args: {}