Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The package is published in PyPI at the following link:

|Package |Description |
|----------------------------------------------|---------------------------------------------------------------------|
|[snet-cli](https://pypi.org/project/snet.cli/)|Command line interface to interact with the SingularityNET platform |
|[snet.cli](https://pypi.org/project/snet.cli/)|Command line interface to interact with the SingularityNET platform |

## License

Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@ jsonschema==4.0.0
eth-account==0.9.0
trezor==0.13.8
ledgerblue==0.1.48
validators==0.28.1
snet.contracts==0.1.1
8 changes: 7 additions & 1 deletion snet/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@
# PYTHON_ARGCOMPLETE_OK

import sys
import warnings

import argcomplete

from snet.cli import arguments
with warnings.catch_warnings():
# Suppress the eth-typing package`s warnings related to some new networks
warnings.filterwarnings("ignore", "Network .* does not have a valid ChainId. eth-typing should be "
"updated with the latest networks.", UserWarning)
from snet.cli import arguments

from snet.cli.config import Config


Expand Down
6 changes: 5 additions & 1 deletion snet/cli/commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
read_default_contract_address
from snet.cli.utils.ipfs_utils import bytesuri_to_hash, get_from_ipfs_and_checkhash, \
hash_to_bytesuri, publish_file_in_ipfs
from snet.cli.utils.utils import DefaultAttributeObject, get_web3, serializable, type_converter, \
from snet.cli.utils.utils import DefaultAttributeObject, get_web3, is_valid_url, serializable, type_converter, \
get_cli_version, bytes32_to_str


Expand Down Expand Up @@ -392,6 +392,10 @@ def add_group(self):
"Organization metadata json file not found ,Please check --metadata-file path ")
raise e

for endpoint in self.args.endpoints:
if not is_valid_url(endpoint):
raise Exception(f"Invalid {endpoint} endpoint passed")

payment_storage_client = PaymentStorageClient(self.args.payment_channel_connection_timeout,
self.args.payment_channel_request_timeout, self.args.endpoints)
payment = Payment(self.args.payment_address, self.args.payment_expiration_threshold,
Expand Down
4 changes: 3 additions & 1 deletion snet/cli/commands/mpe_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from snet.cli.metadata.organization import OrganizationMetadata
from snet.cli.metadata.service import MPEServiceMetadata, load_mpe_service_metadata, mpe_service_metadata_from_json
from snet.cli.utils import ipfs_utils
from snet.cli.utils.utils import open_grpc_channel, type_converter
from snet.cli.utils.utils import is_valid_url, open_grpc_channel, type_converter


class MPEServiceCommand(BlockchainCommand):
Expand Down Expand Up @@ -120,6 +120,8 @@ def publish_proto_metadata_init(self):
metadata.add_group(self.args.group_name)
if self.args.endpoints:
for endpoint in self.args.endpoints:
if not is_valid_url(endpoint):
raise Exception(f"Invalid {endpoint} endpoint passed")
metadata.add_endpoint_to_group(
self.args.group_name, endpoint)
if self.args.fixed_price is not None:
Expand Down
81 changes: 64 additions & 17 deletions snet/cli/config.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
from configparser import ConfigParser, ExtendedInterpolation
from pathlib import Path
import sys

default_snet_folder = Path("~").expanduser().joinpath(".snet")
DEFAULT_NETWORK = "sepolia"


class Config(ConfigParser):
def __init__(self, _snet_folder=default_snet_folder):
def __init__(self, _snet_folder=default_snet_folder, sdk_config=None):
super(Config, self).__init__(interpolation=ExtendedInterpolation(), delimiters=("=",))
self._config_file = _snet_folder.joinpath("config")
self.sdk_config = sdk_config
self.is_sdk = True if sdk_config else False
if self._config_file.exists():
with open(self._config_file) as f:
self.read_file(f)
Expand All @@ -21,7 +25,7 @@ def get_session_network_name(self):

def safe_get_session_identity_network_names(self):
if "identity" not in self["session"]:
first_identity_message_and_exit()
first_identity_message_and_exit(is_sdk=self.is_sdk)

session_identity = self["session"]["identity"]
self._check_section("identity.%s" % session_identity)
Expand Down Expand Up @@ -128,7 +132,7 @@ def set_network_field(self, network, key, value):
self._get_network_section(network)[key] = str(value)
self._persist()

def add_identity(self, identity_name, identity, out_f):
def add_identity(self, identity_name, identity, out_f=sys.stdout):
identity_section = "identity.%s" % identity_name
if identity_section in self:
raise Exception("Identity section %s already exists in config" % identity_section)
Expand Down Expand Up @@ -190,7 +194,18 @@ def create_default_config(self):
"default_eth_rpc_endpoint": "https://sepolia.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5",
}
self["ipfs"] = {"default_ipfs_endpoint": "/dns/ipfs.singularitynet.io/tcp/80/"}
self["session"] = {"network": "sepolia"}
network = self.get_param_from_sdk_config("network")
if network:
if network not in self.get_all_networks_names():
raise Exception("Network '%s' is not in config" % network)
self["session"] = {"network": network}
else:
self["session"] = {"network": DEFAULT_NETWORK}
identity_name = self.get_param_from_sdk_config("identity_name")
identity_type = self.get_param_from_sdk_config("identity_type")
if identity_name and identity_type:
identity = self.setup_identity()
self.add_identity(identity_name, identity)
self._persist()
print("We've created configuration file with default values in: %s\n" % str(self._config_file))

Expand All @@ -203,19 +218,51 @@ def _persist(self):
self.write(f)
self._config_file.chmod(0o600)


def first_identity_message_and_exit():
print("\nPlease create your first identity by running 'snet identity create'.\n\n"
"The available identity types are:\n"
" - 'rpc' (yields to a required ethereum json-rpc endpoint for signing using a given wallet\n"
" index)\n"
" - 'mnemonic' (uses a required bip39 mnemonic for HDWallet/account derivation and signing\n"
" using a given wallet index)\n"
" - '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")
def get_param_from_sdk_config(self, param: str, alternative=None):
if self.sdk_config:
return self.sdk_config.get(param, alternative)
return None

def setup_identity(self):
identity_type = self.get_param_from_sdk_config("identity_type")
private_key = self.get_param_from_sdk_config("private_key")
default_wallet_index = self.get_param_from_sdk_config("wallet_index", 0)
if not identity_type:
raise Exception("identity_type not passed")
if identity_type == "key":
identity = {
"identity_type": "key",
"private_key": private_key,
"default_wallet_index": default_wallet_index
}
# TODO: logic for other identity_type
else:
print("\nThe identity_type parameter value you passed is not supported "
"by the sdk at this time.\n")
print("The available identity types are:\n"
" - 'key' (uses a required hex-encoded private key for signing)\n\n")
exit(1)
return identity


def first_identity_message_and_exit(is_sdk=False):
if is_sdk:
print("\nPlease create your first identity by passing the 'identity_name' "
"and 'identity_type' parameters in SDK config.\n")
print("The available identity types are:\n"
" - 'key' (uses a required hex-encoded private key for signing)\n\n")
else:
print("\nPlease create your first identity by running 'snet identity create'.\n\n")
print("The available identity types are:\n"
" - 'rpc' (yields to a required ethereum json-rpc endpoint for signing using a given wallet\n"
" index)\n"
" - 'mnemonic' (uses a required bip39 mnemonic for HDWallet/account derivation and signing\n"
" using a given wallet index)\n"
" - '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")
exit(1)


Expand Down
4 changes: 2 additions & 2 deletions snet/cli/metadata/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from json import JSONEncoder
import json

import validators
from snet.cli.utils.utils import is_valid_url


class DefaultEncoder(JSONEncoder):
Expand Down Expand Up @@ -34,7 +34,7 @@ def from_json(cls, json_data: dict):
endpoints = json_data["endpoints"]
if endpoints:
for endpoint in endpoints:
if not validators.url(endpoint):
if not is_valid_url(endpoint):
raise Exception("Invalid endpoint passed in json file")
return cls(**json_data)

Expand Down
Loading