From 1af4d484fc09b4182cb7e74886e1e36e15c72547 Mon Sep 17 00:00:00 2001 From: kiruxaspb Date: Fri, 28 Feb 2025 19:28:10 +0300 Subject: [PATCH 1/2] Refactor CLI for migration --- .gitignore | 4 +-- README.md | 23 ++++++++++---- requirements.txt | 2 +- setup.py | 2 +- snet/cli/arguments.py | 44 +++++++++++++------------- snet/cli/commands/commands.py | 8 ++--- snet/cli/commands/mpe_account.py | 16 +++++----- snet/cli/commands/mpe_channel.py | 6 ++-- snet/cli/commands/mpe_client.py | 4 +-- snet/cli/commands/mpe_treasurer.py | 8 ++--- snet/cli/config.py | 2 +- snet/cli/identity.py | 7 ++-- snet/cli/metadata/service.py | 2 +- snet/cli/resources/service_schema.json | 2 +- snet/cli/utils/agix2cogs.py | 24 -------------- snet/cli/utils/token2cogs.py | 24 ++++++++++++++ version.py | 2 +- 17 files changed, 95 insertions(+), 85 deletions(-) delete mode 100644 snet/cli/utils/agix2cogs.py create mode 100644 snet/cli/utils/token2cogs.py diff --git a/.gitignore b/.gitignore index b2a9e7e6..ac764b82 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,8 @@ venv/ .idea/ __pycache__ blockchain/node_modules -snet.egg-info/ -snet.cli.egg-info/ +snet_egg-info/ +snet_cli.egg-info/ snet/cli/resources/node_modules snet/cli/resources/proto/*.py build/ diff --git a/README.md b/README.md index 1c215855..a5330f73 100644 --- a/README.md +++ b/README.md @@ -122,18 +122,27 @@ Backward compatibility for other Python versions is not guaranteed. --- -* Clone the git repository +* + +* Install the package in development mode + +### Clone the git repository + ```bash -$ git clone https://github.com/singnet/snet-cli.git -$ cd snet-cli/packages/snet_cli +git clone https://github.com/singnet/snet-cli.git +cd snet-cli ``` -* - -* Install the package in development/editable mode +```bash +pip install -r requirements.txt +``` + +```bash +pip3 install . +``` ```bash -$ pip3 install -e . +snet -h ``` ### Building the Documentation in Markdown files diff --git a/requirements.txt b/requirements.txt index 5580833f..cdbf5c29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,6 @@ jsonschema==4.0.0 eth-account==0.9.0 trezor==0.13.8 ledgerblue==0.1.48 -snet-contracts==0.2.1 +snet-contracts==0.2.2 lighthouseweb3==0.1.4 cryptography==43.0.3 diff --git a/setup.py b/setup.py index 26f55ed8..14d766d3 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ def run(self): }, entry_points={ 'console_scripts': [ - 'snet = snet.cli:main', + 'snet = snet.cli:main' ], } ) diff --git a/snet/cli/arguments.py b/snet/cli/arguments.py index 1bc5d45f..380b0c7e 100644 --- a/snet/cli/arguments.py +++ b/snet/cli/arguments.py @@ -14,7 +14,7 @@ from snet.cli.commands.sdk_command import SDKCommand from snet.cli.config import Config, get_session_keys, get_session_network_keys_removable from snet.cli.identity import get_identity_types -from snet.cli.utils.agix2cogs import stragix2cogs +from snet.cli.utils.token2cogs import strtoken2cogs from snet.cli.utils.utils import type_converter @@ -62,7 +62,7 @@ def add_root_options(parser, config): title="snet commands", metavar="COMMAND") subparsers.required = True - p = subparsers.add_parser("account", help="AGIX account") + p = subparsers.add_parser("account", help="ASI(FET) account") add_mpe_account_options(p) p = subparsers.add_parser("channel", help="Interact with SingularityNET payment channels") @@ -236,7 +236,7 @@ def add_contract_options(parser): contracts = get_all_abi_contract_files() for path in contracts: - if "MultiPartyEscrow" in str(path) or "Registry" in str(path) or "SingularityNetToken" in str(path): + if "MultiPartyEscrow" in str(path) or "Registry" in str(path) or "FetchToken" in str(path): contract_name = re.search( r"([^.]*)\.json", os.path.basename(path)).group(1) contract_p = subparsers.add_parser( @@ -584,32 +584,32 @@ def add_p_snt_address_opt(p): p.set_defaults(fn="print_account") add_eth_call_arguments(p) - p = subparsers.add_parser("balance", help="Print balance of AGIX tokens and balance of MPE wallet") - p.set_defaults(fn="print_agix_and_mpe_balances") + p = subparsers.add_parser("balance", help="Print balance of ASI(FET) tokens and balance of MPE wallet") + p.set_defaults(fn="print_token_and_mpe_balances") p.add_argument("--account", default=None, help="Account to print balance for (default is the current identity)") add_p_snt_address_opt(p) add_p_mpe_address_opt(p) add_eth_call_arguments(p) - p = subparsers.add_parser("deposit", help="Deposit AGIX tokens to MPE wallet") + p = subparsers.add_parser("deposit", help="Deposit ASI(FET) tokens to MPE wallet") p.set_defaults(fn="deposit_to_mpe") - p.add_argument("amount", type=stragix2cogs, help="Amount of AGIX tokens to deposit in MPE wallet", metavar="AMOUNT") + p.add_argument("amount", type=strtoken2cogs, help="Amount of ASI(FET) tokens to deposit in MPE wallet", metavar="AMOUNT") add_p_snt_address_opt(p) add_p_mpe_address_opt(p) add_transaction_arguments(p) - p = subparsers.add_parser("withdraw", help="Withdraw AGIX tokens from MPE wallet") + p = subparsers.add_parser("withdraw", help="Withdraw ASI(FET) tokens from MPE wallet") p.set_defaults(fn="withdraw_from_mpe") - p.add_argument("amount", type=stragix2cogs, help="Amount of AGIX tokens to withdraw from MPE wallet", metavar="AMOUNT") + p.add_argument("amount", type=strtoken2cogs, help="Amount of ASI(FET) tokens to withdraw from MPE wallet", metavar="AMOUNT") add_p_mpe_address_opt(p) add_transaction_arguments(p) - p = subparsers.add_parser("transfer", help="Transfer AGIX tokens inside MPE wallet") + p = subparsers.add_parser("transfer", help="Transfer ASI(FET) tokens inside MPE wallet") p.set_defaults(fn="transfer_in_mpe") p.add_argument("receiver", help="Address of the receiver", metavar="RECEIVER") p.add_argument("amount", - type=stragix2cogs, - help="Amount of AGIX tokens to be transferred to another account inside MPE wallet", + type=strtoken2cogs, + help="Amount of ASI(FET) tokens to be transferred to another account inside MPE wallet", metavar="AMOUNT") add_p_mpe_address_opt(p) add_transaction_arguments(p) @@ -664,8 +664,8 @@ def add_p_open_channel_basic(p): add_group_name(p) p.add_argument("amount", - type=stragix2cogs, - help="Amount of AGIX tokens to put in the new channel", + type=strtoken2cogs, + help="Amount of ASI(FET) tokens to put in the new channel", metavar="AMOUNT") # p.add_argument("group_name", # default=None, @@ -709,8 +709,8 @@ def add_p_set_for_extend_add(_p): title="Expiration and amount") add_p_expiration(expiration_amount_g, is_optional=True) expiration_amount_g.add_argument("--amount", - type=stragix2cogs, - help="Amount of AGIX tokens to add to the channel") + type=strtoken2cogs, + help="Amount of ASI(FET) tokens to add to the channel") add_p_mpe_address_opt(p) add_transaction_arguments(p) @@ -920,8 +920,8 @@ def add_mpe_service_options(parser): nargs='*', help="Endpoints for the first group") p.add_argument("--fixed-price", - type=stragix2cogs, - help="Set fixed price in AGIX token for all methods") + type=strtoken2cogs, + help="Set fixed price in ASI(FET) token for all methods") p.add_argument("--encoding", default="proto", @@ -950,8 +950,8 @@ def add_mpe_service_options(parser): p.add_argument("group_name", help="group name for fixed price method") p.add_argument("price", - type=stragix2cogs, - help="Set fixed price in AGIX token for all methods", + type=strtoken2cogs, + help="Set fixed price in ASI(FET) token for all methods", metavar="PRICE") add_p_metadata_file_opt(p) @@ -970,8 +970,8 @@ def add_mpe_service_options(parser): ) p.add_argument("price", - type=stragix2cogs, - help="Set fixed price in AGIX token for all methods", + type=strtoken2cogs, + help="Set fixed price in ASI(FET) token for all methods", metavar="PRICE") add_p_metadata_file_opt(p) diff --git a/snet/cli/commands/commands.py b/snet/cli/commands/commands.py index aa00f3c1..64b80b91 100644 --- a/snet/cli/commands/commands.py +++ b/snet/cli/commands/commands.py @@ -166,8 +166,8 @@ def get_identity(self): return RpcIdentityProvider(self.w3, self.get_wallet_index()) if identity_type == "mnemonic": return MnemonicIdentityProvider(self.w3, self.config.get_session_field("mnemonic"), self.get_wallet_index()) - if identity_type == "trezor": - return TrezorIdentityProvider(self.w3, self.get_wallet_index()) + # if identity_type == "trezor": + # return TrezorIdentityProvider(self.w3, self.get_wallet_index()) if identity_type == "ledger": return LedgerIdentityProvider(self.w3, self.get_wallet_index()) if identity_type == "key": @@ -358,8 +358,8 @@ def populate_contract_address(self, rez, key): w3=self.w3, contract_name="Registry") rez[key]['default_multipartyescrow_at'] = read_default_contract_address( w3=self.w3, contract_name="MultiPartyEscrow") - rez[key]['default_singularitynettoken_at'] = read_default_contract_address( - w3=self.w3, contract_name="SingularityNetToken") + rez[key]['default_fetchtoken_at'] = read_default_contract_address( + w3=self.w3, contract_name="FetchToken") except Exception as e: pass return diff --git a/snet/cli/commands/mpe_account.py b/snet/cli/commands/mpe_account.py index c5d29ea5..805bb3cd 100644 --- a/snet/cli/commands/mpe_account.py +++ b/snet/cli/commands/mpe_account.py @@ -1,5 +1,5 @@ from snet.cli.commands.commands import BlockchainCommand -from snet.cli.utils.agix2cogs import cogs2stragix +from snet.cli.utils.token2cogs import cogs2strtoken class MPEAccountCommand(BlockchainCommand): @@ -8,31 +8,31 @@ def print_account(self): self.check_ident() self._printout(self.ident.address) - def print_agix_and_mpe_balances(self): - """ Print balance of ETH, AGIX, and MPE wallet """ + def print_token_and_mpe_balances(self): + """ Print balance of ETH, ASI(FET), and MPE wallet """ self.check_ident() if self.args.account: account = self.args.account else: account = self.ident.address eth_wei = self.w3.eth.get_balance(account) - agix_cogs = self.call_contract_command("SingularityNetToken", "balanceOf", [account]) + token_cogs = self.call_contract_command("FetchToken", "balanceOf", [account]) mpe_cogs = self.call_contract_command("MultiPartyEscrow", "balances", [account]) # we cannot use _pprint here because it doesn't conserve order yet self._printout(" account: %s"%account) self._printout(" ETH: %s"%self.w3.from_wei(eth_wei, 'ether')) - self._printout(" AGIX: %s"%cogs2stragix(agix_cogs)) - self._printout(" MPE: %s"%cogs2stragix(mpe_cogs)) + self._printout(" ASI(FET): %s"%cogs2strtoken(token_cogs)) + self._printout(" MPE: %s"%cogs2strtoken(mpe_cogs)) def deposit_to_mpe(self): self.check_ident() amount = self.args.amount mpe_address = self.get_mpe_address() - already_approved = self.call_contract_command("SingularityNetToken", "allowance", [self.ident.address, mpe_address]) + already_approved = self.call_contract_command("FetchToken", "allowance", [self.ident.address, mpe_address]) if already_approved < amount: - self.transact_contract_command("SingularityNetToken", "approve", [mpe_address, amount]) + self.transact_contract_command("FetchToken", "approve", [mpe_address, amount]) self.transact_contract_command("MultiPartyEscrow", "deposit", [amount]) def withdraw_from_mpe(self): diff --git a/snet/cli/commands/mpe_channel.py b/snet/cli/commands/mpe_channel.py index 53fae089..62fdad3f 100644 --- a/snet/cli/commands/mpe_channel.py +++ b/snet/cli/commands/mpe_channel.py @@ -14,7 +14,7 @@ from snet.cli.commands.commands import OrganizationCommand from snet.cli.metadata.service import mpe_service_metadata_from_json, load_mpe_service_metadata from snet.cli.metadata.organization import OrganizationMetadata -from snet.cli.utils.agix2cogs import cogs2stragix +from snet.cli.utils.token2cogs import cogs2strtoken from snet.cli.utils.ipfs_utils import get_from_ipfs_and_checkhash from snet.cli.utils.utils import abi_decode_struct_to_dict, abi_get_element_by_name, \ compile_proto, type_converter, bytesuri_to_hash, get_file_from_filecoin, download_and_safe_extract_proto @@ -286,7 +286,7 @@ def _open_channel_for_org(self, metadata): "MultiPartyEscrow", "balances", [self.ident.address]) if mpe_cogs < self.args.amount: raise Exception( - "insufficient funds. You MPE balance is %s AGIX " % cogs2stragix(mpe_cogs)) + "insufficient funds. You MPE balance is %s ASI(FET) " % cogs2strtoken(mpe_cogs)) group_id = base64.b64decode(metadata.get_group_id_by_group_name(self.args.group_name)) if not group_id: @@ -496,7 +496,7 @@ def _print_channels(self, channels, filters: list[str] = None): for channel_id in channels_ids: channel = self._get_channel_state_from_blockchain(channel_id) channel["channel_id"] = channel_id - channel["value"] = cogs2stragix(channel["value"]) + channel["value"] = cogs2strtoken(channel["value"]) channel["group_id"] = base64.b64encode(channel["groupId"]).decode("ascii") self._printout(self._convert_channel_dict_to_str(channel, filters)) diff --git a/snet/cli/commands/mpe_client.py b/snet/cli/commands/mpe_client.py index 49bb90ad..760cfff4 100644 --- a/snet/cli/commands/mpe_client.py +++ b/snet/cli/commands/mpe_client.py @@ -6,7 +6,7 @@ from eth_account.messages import encode_defunct from snet.cli.commands.mpe_channel import MPEChannelCommand -from snet.cli.utils.agix2cogs import cogs2stragix +from snet.cli.utils.token2cogs import cogs2strtoken from snet.cli.utils.proto_utils import import_protobuf_from_dir, switch_to_json_payload_encoding from snet.cli.utils.utils import open_grpc_channel, rgetattr, RESOURCES_PATH @@ -303,7 +303,7 @@ def call_server_statelessly_with_params(self, params, group_name): server_state = self._get_channel_state_from_server(grpc_channel, channel_id) proceed = self.args.yes or input( - "Price for this call will be %s AGIX (use -y to remove this warning). Proceed? (y/n): " % (cogs2stragix(price))) == "y" + "Price for this call will be %s ASI(FET) (use -y to remove this warning). Proceed? (y/n): " % (cogs2strtoken(price))) == "y" if not proceed: self._error("Cancelled") diff --git a/snet/cli/commands/mpe_treasurer.py b/snet/cli/commands/mpe_treasurer.py index a0855d46..57c9c298 100644 --- a/snet/cli/commands/mpe_treasurer.py +++ b/snet/cli/commands/mpe_treasurer.py @@ -4,7 +4,7 @@ from snet.cli.utils.proto_utils import import_protobuf_from_dir from snet.cli.utils.utils import compile_proto, open_grpc_channel, int4bytes_big, RESOURCES_PATH from snet.cli.commands.mpe_client import MPEClientCommand -from snet.cli.utils.agix2cogs import cogs2stragix +from snet.cli.utils.token2cogs import cogs2strtoken class MPETreasurerCommand(MPEClientCommand): @@ -93,13 +93,13 @@ def _call_StartClaim(self, grpc_channel, channel_id, channel_nonce): def print_unclaimed(self): grpc_channel = open_grpc_channel(self.args.endpoint) payments = self._call_GetListUnclaimed(grpc_channel) - self._printout("# channel_id channel_nonce signed_amount (AGIX)") + self._printout("# channel_id channel_nonce signed_amount (ASI(FET))") total = 0 for p in payments: self._printout("%i %i %s" % ( - p["channel_id"], p["nonce"], cogs2stragix(p["amount"]))) + p["channel_id"], p["nonce"], cogs2strtoken(p["amount"]))) total += p["amount"] - self._printout("# total_unclaimed_in_AGIX = %s" % cogs2stragix(total)) + self._printout("# total_unclaimed_in_AGIX = %s" % cogs2strtoken(total)) def _blockchain_claim(self, payments): for payment in payments: diff --git a/snet/cli/config.py b/snet/cli/config.py index 9c62382c..7747fc36 100644 --- a/snet/cli/config.py +++ b/snet/cli/config.py @@ -289,8 +289,8 @@ def first_identity_message_and_exit(is_sdk=False): " - 'key' (uses a required hex-encoded private key for signing)\n" " - 'ledger' (yields to a required ledger nano s device for signing using a given wallet\n" " index)\n" - " - 'trezor' (yields to a required trezor device for signing using a given wallet index)\n" "\n") + # " - 'trezor' (yields to a required trezor device for signing using a given wallet index)\n" exit(1) diff --git a/snet/cli/identity.py b/snet/cli/identity.py index 0eb4cd4e..67ba62f8 100644 --- a/snet/cli/identity.py +++ b/snet/cli/identity.py @@ -325,8 +325,8 @@ def get_kws_for_identity_type(identity_type): return [("mnemonic", SECRET)] elif identity_type == "key": return [("private_key", SECRET)] - elif identity_type == "trezor": - return [] + # elif identity_type == "trezor": + # return [] elif identity_type == "ledger": return [] elif identity_type == "keystore": @@ -337,7 +337,8 @@ def get_kws_for_identity_type(identity_type): def get_identity_types(): - return ["rpc", "mnemonic", "key", "trezor", "ledger", "keystore"] + # temporary fully removed: trezor + return ["rpc", "mnemonic", "key", "ledger", "keystore"] def sign_transaction_with_private_key(w3, private_key, transaction): diff --git a/snet/cli/metadata/service.py b/snet/cli/metadata/service.py index 6184afd9..39bd7754 100644 --- a/snet/cli/metadata/service.py +++ b/snet/cli/metadata/service.py @@ -21,7 +21,7 @@ Possible pricing models: 1. Fixed price price_model - "fixed_price" - price_in_cogs - unique fixed price in cogs for all method (1 AGIX = 10^8 cogs) + price_in_cogs - unique fixed price in cogs for all method (1 ASI(FET) = 10^18 cogs) (other pricing models can be easily supported) groups [] - group is the number of endpoints which shares same payment channel; grouping strategy is defined by service provider; diff --git a/snet/cli/resources/service_schema.json b/snet/cli/resources/service_schema.json index 8ab85338..a477d141 100644 --- a/snet/cli/resources/service_schema.json +++ b/snet/cli/resources/service_schema.json @@ -56,7 +56,7 @@ "enum": [ "fixed_price", "method_price" ] }, "price_in_cogs": { - "description": "Price in AGIX tokens for all methods", + "description": "Price in ASI(FET) tokens for all methods", "type": "number" }, "default": { diff --git a/snet/cli/utils/agix2cogs.py b/snet/cli/utils/agix2cogs.py deleted file mode 100644 index 382750fe..00000000 --- a/snet/cli/utils/agix2cogs.py +++ /dev/null @@ -1,24 +0,0 @@ -""" Safe conversion between agix(string) and cogs(int) """ -import decimal - -AGIX_TOKEN_DECIMALS = 8 - - -def stragix2cogs(stragix): - if type(stragix) != str: - raise Exception("Parameter should be string") - - # in case user write something stupid we set very big precision - decimal.getcontext().prec = 1000 - cogs_decimal = decimal.Decimal(stragix) * 10 ** AGIX_TOKEN_DECIMALS - cogs_int = int(cogs_decimal) - if cogs_int != cogs_decimal: - raise Exception("AGIX token has only %i decimals" % AGIX_TOKEN_DECIMALS) - return cogs_int - - -def cogs2stragix(cogs_int): - # presicison should be higer then INITIAL_SUPPLY + 1, we set it to 1000 be consistent with stragix2cogs - decimal.getcontext().prec = 1000 - agix_decimal = decimal.Decimal(cogs_int) / 10 ** AGIX_TOKEN_DECIMALS - return format(agix_decimal, 'f') diff --git a/snet/cli/utils/token2cogs.py b/snet/cli/utils/token2cogs.py new file mode 100644 index 00000000..d72b5efd --- /dev/null +++ b/snet/cli/utils/token2cogs.py @@ -0,0 +1,24 @@ +""" Safe conversion between token(string) and cogs(int) """ +import decimal + +TOKEN_DECIMALS = 18 + + +def strtoken2cogs(str_token): + if type(str_token) != str: + raise Exception("Parameter should be string") + + # in case user write something stupid we set very big precision + decimal.getcontext().prec = 1000 + cogs_decimal = decimal.Decimal(str_token) * 10 ** TOKEN_DECIMALS + cogs_int = int(cogs_decimal) + if cogs_int != cogs_decimal: + raise Exception("ASI(FET) token has only %i decimals" % TOKEN_DECIMALS) + return cogs_int + + +def cogs2strtoken(cogs_int): + # presicison should be higer then INITIAL_SUPPLY + 1, we set it to 1000 be consistent with strtoken2cogs + decimal.getcontext().prec = 1000 + token_decimal = decimal.Decimal(cogs_int) / 10 ** TOKEN_DECIMALS + return format(token_decimal, 'f') diff --git a/version.py b/version.py index 54499df3..528787cf 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -__version__ = "2.4.1" +__version__ = "3.0.0" From 838dbbf7855a22516cb5d9c6b78d3ed01abe7ca2 Mon Sep 17 00:00:00 2001 From: kiruxaspb Date: Fri, 28 Feb 2025 19:30:30 +0300 Subject: [PATCH 2/2] Fix markdown --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index a5330f73..48d5c198 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,7 @@ Backward compatibility for other Python versions is not guaranteed. --- -* - -* Install the package in development mode +## Install the package in development mode ### Clone the git repository