• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

safe-global / safe-cli / 9662287756

25 Jun 2024 12:19PM UTC coverage: 87.771% (+0.5%) from 87.279%
9662287756

Pull #419

github

web-flow
Merge d8319c98c into d9ac0c119
Pull Request #419: Support scripting

748 of 858 branches covered (87.18%)

Branch coverage included in aggregate %.

274 of 294 new or added lines in 7 files covered. (93.2%)

6 existing lines in 2 files now uncovered.

2532 of 2879 relevant lines covered (87.95%)

3.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.31
/src/safe_cli/utils.py
1
import os
4✔
2
from typing import List, Optional
4✔
3

4
from eth_typing import ChecksumAddress
4✔
5
from prompt_toolkit import HTML, print_formatted_text
4✔
6

7
from gnosis.eth import EthereumClient
4✔
8
from gnosis.safe.api import TransactionServiceApi
4✔
9

10

11
def get_erc_20_list(
4✔
12
    ethereum_client: EthereumClient,
13
    safe_address: str,
14
    from_block: int,
15
    to_block: int,
16
    block_step: int = 500000,
17
) -> list:
18
    """
19

20
    :param ethereum_client:
21
    :param safe_address:
22
    :param from_block:
23
    :param to_block:
24
    :param block_step: is the number of blocks retrieved for each get until get all blocks between from_block until to_block
25
    :return: a list of address of ERC20 tokens related with the safe_address
26
    """
27
    addresses = set()
4✔
28
    for i in range(from_block, to_block + 1, block_step):
4✔
29
        events = ethereum_client.erc20.get_total_transfer_history(
4✔
30
            from_block=i, to_block=i + (block_step - 1), addresses=[safe_address]
31
        )
32
        for event in events:
4✔
33
            if "value" in event["args"]:
4✔
34
                addresses.add(event["address"])
4✔
35

36
    return addresses
4✔
37

38

39
def get_input(*args, **kwargs):
4✔
40
    return input(*args, **kwargs)
4✔
41

42

43
def yes_or_no_question(question: str, default_no: bool = True) -> bool:
4✔
44
    if "PYTEST_CURRENT_TEST" in os.environ:
4✔
45
        return True  # Ignore confirmations when running tests
4✔
46

47
    choices = " [y/N]: " if default_no else " [Y/n]: "
4✔
48
    default_answer = "n" if default_no else "y"
4✔
49
    reply = str(get_input(question + choices)).lower().strip() or default_answer
4✔
50
    if reply[0] == "y":
4✔
51
        return True
4✔
52
    if reply[0] == "n":
4✔
53
        return False
4✔
54
    else:
55
        return False if default_no else True
4✔
56

57

58
def choose_option_from_list(
4✔
59
    question: str, options: List, default_option: int = 0
60
) -> Optional[int]:
61
    if "PYTEST_CURRENT_TEST" in os.environ:
4✔
62
        return default_option  # Ignore confirmations when running tests
4✔
63
    number_options = len(options)
4✔
64
    for number_option, option in enumerate(options):
4✔
65
        print_formatted_text(HTML(f"{number_option} - <b>{option}</b> "))
4✔
66
    choices = f" [0-{number_options - 1}] default {default_option}: "
4✔
67
    reply = str(get_input(question + choices)).lower().strip() or str(default_option)
4✔
68
    try:
4✔
69
        option = int(reply)
4✔
70
    except ValueError:
4✔
71
        print_formatted_text(HTML("<ansired> Option must be an integer </ansired>"))
4✔
72
        return None
4✔
73

74
    if option not in range(0, number_options):
4✔
75
        print_formatted_text(
4✔
76
            HTML(
77
                f"<ansired> {option} is not between [0-{number_options - 1}] </ansired>"
78
            )
79
        )
80
        return None
4✔
81

82
    return option
4✔
83

84

85
def get_safe_from_owner(owner: ChecksumAddress, node_url: str) -> ChecksumAddress:
4✔
86
    """
87
    Show a list of Safe to chose between them and return the selected one.
88
    :param owner:
89
    :param node_url:
90
    :return: Safe address of a selected Safe
91
    """
92
    ethereum_client = EthereumClient(node_url)
4✔
93
    safe_tx_service = TransactionServiceApi.from_ethereum_client(ethereum_client)
4✔
94
    safes = safe_tx_service.get_safes_for_owner(owner)
4✔
95
    if safes:
4✔
UNCOV
96
        option = choose_option_from_list(
×
97
            "Select the Safe to initialize the safe-cli", safes
98
        )
NEW
99
        if option is None:
×
NEW
100
            raise ValueError("Unable to load Safe to initialize the safe-cli")
×
NEW
101
        return safes[option]
×
102
    else:
103
        raise ValueError(f"No safe was found for the specified owner {owner}")
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc