From 7baf64a4e292e539e6c3fab02523193fc6436217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B4=CF=85=CF=82?= Date: Wed, 23 Oct 2024 15:19:17 -0400 Subject: [PATCH 1/2] added `--only-generate` & `--quiet` args for testing vanity Safe addresses --- src/safe_cli/safe_creator.py | 58 +++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/safe_cli/safe_creator.py b/src/safe_cli/safe_creator.py index 5f177081..917967cd 100644 --- a/src/safe_cli/safe_creator.py +++ b/src/safe_cli/safe_creator.py @@ -34,7 +34,7 @@ def get_usage_msg(): return """ - safe-creator [-h] [-v] [--threshold THRESHOLD] [--owners OWNERS [OWNERS ...]] [--safe-contract SAFE_CONTRACT] [--proxy-factory PROXY_FACTORY] [--callback-handler CALLBACK_HANDLER] [--salt-nonce SALT_NONCE] [--without-events] node_url private_key + safe-creator [-h] [-v] [--quiet] [--threshold THRESHOLD] [--owners OWNERS [OWNERS ...]] [--safe-contract SAFE_CONTRACT] [--proxy-factory PROXY_FACTORY] [--callback-handler CALLBACK_HANDLER] [--salt-nonce SALT_NONCE] [--without-events] [--only-generate] node_url private_key Example: safe-creator https://sepolia.drpc.org 0000000000000000000000000000000000000000000000000000000000000000 @@ -54,6 +54,12 @@ def setup_argument_parser(): parser.add_argument( "private_key", help="Deployer private_key", type=check_private_key ) + parser.add_argument( + "--quiet", + help="Limit output to only prompts, errors, and the address of the created Safe", + default=False, + action="store_true", + ) parser.add_argument( "--threshold", help="Number of owners required to execute transactions on the created Safe. It must" @@ -93,20 +99,24 @@ def setup_argument_parser(): default=secrets.randbits(256), type=int, ) - parser.add_argument( "--without-events", help="Use non events deployment of the Safe instead of the regular one. Recommended for mainnet to save gas costs when using the Safe", default=False, action="store_true", ) + parser.add_argument( + "--only-generate", + help="Only generate the projected Safe address, do not actually create it", + default=False, + action="store_true", + ) return parser def main(*args, **kwargs) -> EthereumTxSent: parser = setup_argument_parser() args = parser.parse_args() - print_formatted_text(text2art("Safe Creator")) # Print fancy text node_url: URI = args.node_url account: LocalAccount = Account.from_key(args.private_key) owners: List[str] = args.owners if args.owners else [account.address] @@ -118,9 +128,12 @@ def main(*args, **kwargs) -> EthereumTxSent: payment = 0 payment_receiver = NULL_ADDRESS + if not args.quiet: + print_formatted_text(text2art("Safe Creator")) # Print fancy text + if len(owners) < threshold: print_formatted_text( - "Threshold cannot be bigger than the number of unique owners" + f"Threshold cannot be bigger than the number of unique owners ({len(owners)})" ) sys.exit(1) @@ -169,10 +182,11 @@ def main(*args, **kwargs) -> EthereumTxSent: ether_account_balance = round( ethereum_client.w3.from_wei(account_balance, "ether"), 6 ) - print_formatted_text( - f"Network {ethereum_client.get_network().name} - Sender {account.address} - " - f"Balance: {ether_account_balance}Ξ" - ) + if not args.quiet: + print_formatted_text( + f"Network {ethereum_client.get_network().name} - Sender {account.address} - " + f"Balance: {ether_account_balance}Ξ" + ) if not ethereum_client.w3.eth.get_code( safe_contract_address @@ -180,16 +194,18 @@ def main(*args, **kwargs) -> EthereumTxSent: print_formatted_text("Network not supported") sys.exit(1) - print_formatted_text( - f"Creating new Safe with owners={owners} threshold={threshold} salt-nonce={salt_nonce}" - ) + if not args.quiet: + print_formatted_text( + f"Creating new Safe with owners={owners} threshold={threshold} salt-nonce={salt_nonce}" + ) safe_version = Safe(safe_contract_address, ethereum_client).retrieve_version() - print_formatted_text( - f"Safe-master-copy={safe_contract_address} version={safe_version}\n" - f"Fallback-handler={fallback_handler}\n" - f"Proxy factory={proxy_factory_address}" - ) - if yes_or_no_question("Do you want to continue?"): + if not args.quiet: + print_formatted_text( + f"Safe-master-copy={safe_contract_address} version={safe_version}\n" + f"Fallback-handler={fallback_handler}\n" + f"Proxy factory={proxy_factory_address}" + ) + if args.only_generate or yes_or_no_question("Do you want to continue?"): safe_contract = get_safe_V1_4_1_contract( ethereum_client.w3, safe_contract_address ) @@ -214,7 +230,13 @@ def main(*args, **kwargs) -> EthereumTxSent: print_formatted_text(f"Safe on {expected_safe_address} is already deployed") sys.exit(1) - if yes_or_no_question( + if args.only_generate: + if args.quiet: + print_formatted_text(expected_safe_address) + else: + print_formatted_text(f"Safe will be deployed on {expected_safe_address}") + sys.exit(0) + elif yes_or_no_question( f"Safe will be deployed on {expected_safe_address}, looks good?" ): ethereum_tx_sent = proxy_factory.deploy_proxy_contract_with_nonce( From 73ea4e6260da93bef3668213a51a1a257d1499f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B4=CF=85=CF=82?= Date: Tue, 29 Oct 2024 20:49:01 -0400 Subject: [PATCH 2/2] =?UTF-8?q?renaming=20to=20`--dry-run`=20&=20not=20che?= =?UTF-8?q?cking=20balance=20on=20a=20dry=20run=20=F0=9F=A6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/safe_cli/safe_creator.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/safe_cli/safe_creator.py b/src/safe_cli/safe_creator.py index 917967cd..195a9935 100644 --- a/src/safe_cli/safe_creator.py +++ b/src/safe_cli/safe_creator.py @@ -106,7 +106,7 @@ def setup_argument_parser(): action="store_true", ) parser.add_argument( - "--only-generate", + "--dry-run", help="Only generate the projected Safe address, do not actually create it", default=False, action="store_true", @@ -173,20 +173,21 @@ def main(*args, **kwargs) -> EthereumTxSent: ) sys.exit(1) - account_balance: int = ethereum_client.get_balance(account.address) - if not account_balance: - print_formatted_text( - "Client does not have any funds. Let's try anyway in case it's a network without gas costs" - ) - else: - ether_account_balance = round( - ethereum_client.w3.from_wei(account_balance, "ether"), 6 - ) - if not args.quiet: + if not args.dry_run: + account_balance: int = ethereum_client.get_balance(account.address) + if not account_balance: print_formatted_text( - f"Network {ethereum_client.get_network().name} - Sender {account.address} - " - f"Balance: {ether_account_balance}Ξ" + "Client does not have any funds. Let's try anyway in case it's a network without gas costs" + ) + else: + ether_account_balance = round( + ethereum_client.w3.from_wei(account_balance, "ether"), 6 ) + if not args.quiet: + print_formatted_text( + f"Network {ethereum_client.get_network().name} - Sender {account.address} - " + f"Balance: {ether_account_balance}Ξ" + ) if not ethereum_client.w3.eth.get_code( safe_contract_address @@ -205,7 +206,7 @@ def main(*args, **kwargs) -> EthereumTxSent: f"Fallback-handler={fallback_handler}\n" f"Proxy factory={proxy_factory_address}" ) - if args.only_generate or yes_or_no_question("Do you want to continue?"): + if args.dry_run or yes_or_no_question("Do you want to continue?"): safe_contract = get_safe_V1_4_1_contract( ethereum_client.w3, safe_contract_address ) @@ -230,7 +231,7 @@ def main(*args, **kwargs) -> EthereumTxSent: print_formatted_text(f"Safe on {expected_safe_address} is already deployed") sys.exit(1) - if args.only_generate: + if args.dry_run: if args.quiet: print_formatted_text(expected_safe_address) else: