From 73ba53e35e164c6009667b9ab8c506877301f161 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Thu, 9 May 2019 11:38:00 +0200 Subject: [PATCH 01/11] Monorepo first commit Reorganized sdk and cli to be two different packages in the same repository Moved sdk to cli repo Rewrote SDK to match JS SDK implementation CircleCI fix --- .circleci/config.yml | 8 +- .gitignore | 28 ++-- MANIFEST.in => snet_cli/MANIFEST.in | 0 {docs => snet_cli/docs}/Makefile | 0 {docs => snet_cli/docs}/build-docs.sh | 0 {docs => snet_cli/docs}/source/conf.py | 0 .../docs}/source/generate_rst.py | 0 .../docs}/source/img/singularityNET.png | Bin .../docs}/source/index_template.tpl | 0 .../docs}/source/snet-cli-static/theme.css | 0 .../docs}/source/subcommand_template.tpl | 0 {scripts => snet_cli/scripts}/blockchain | 2 +- {scripts => snet_cli/scripts}/package-pip | 0 setup.py => snet_cli/setup.py | 0 snet_cli/{ => snet_cli}/__init__.py | 0 snet_cli/{ => snet_cli}/_vendor/__init__.py | 0 .../_vendor/ledgerblue/BlueHSMServer_pb2.py | 0 .../_vendor/ledgerblue/Dongle.py | 0 .../_vendor/ledgerblue/__init__.py | 0 .../_vendor/ledgerblue/checkGenuine.py | 0 .../{ => snet_cli}/_vendor/ledgerblue/comm.py | 0 .../_vendor/ledgerblue/commException.py | 0 .../_vendor/ledgerblue/commHTTP.py | 0 .../_vendor/ledgerblue/commU2F.py | 0 .../_vendor/ledgerblue/deleteApp.py | 0 .../_vendor/ledgerblue/deployed.py | 0 .../_vendor/ledgerblue/derivePassphrase.py | 0 .../_vendor/ledgerblue/ecWrapper.py | 0 .../_vendor/ledgerblue/endorsementSetup.py | 0 .../ledgerblue/endorsementSetupLedger.py | 0 .../_vendor/ledgerblue/genCAPair.py | 0 .../_vendor/ledgerblue/getMemInfo.py | 0 .../_vendor/ledgerblue/hashApp.py | 0 .../_vendor/ledgerblue/hexLoader.py | 0 .../_vendor/ledgerblue/hexParser.py | 0 .../_vendor/ledgerblue/hostOnboard.py | 0 .../_vendor/ledgerblue/ledgerWrapper.py | 0 .../_vendor/ledgerblue/listApps.py | 0 .../_vendor/ledgerblue/loadApp.py | 0 .../_vendor/ledgerblue/loadMCU.py | 0 .../_vendor/ledgerblue/mcuBootloader.py | 0 .../_vendor/ledgerblue/resetCustomCA.py | 0 .../_vendor/ledgerblue/runApp.py | 0 .../_vendor/ledgerblue/runScript.py | 0 .../_vendor/ledgerblue/setupCustomCA.py | 0 .../_vendor/ledgerblue/signApp.py | 0 .../_vendor/ledgerblue/updateFirmware.py | 0 .../_vendor/ledgerblue/verifyApp.py | 0 .../_vendor/ledgerblue/verifyEndorsement1.py | 0 .../_vendor/ledgerblue/verifyEndorsement2.py | 0 snet_cli/{ => snet_cli}/arguments.py | 0 snet_cli/{ => snet_cli}/commands.py | 0 snet_cli/{ => snet_cli}/config.py | 0 snet_cli/{ => snet_cli}/contract.py | 0 snet_cli/{ => snet_cli}/identity.py | 0 .../{ => snet_cli}/mpe_account_command.py | 0 .../{ => snet_cli}/mpe_channel_command.py | 0 snet_cli/{ => snet_cli}/mpe_client_command.py | 0 .../{ => snet_cli}/mpe_service_command.py | 0 .../{ => snet_cli}/mpe_service_metadata.py | 0 .../{ => snet_cli}/mpe_treasurer_command.py | 0 .../resources/contracts/placeholder.txt | 0 .../resources/proto/control_service.proto | 0 .../resources/proto/merckledag.proto | 0 .../resources/proto/state_service.proto | 0 .../resources/proto/unixfs.proto | 0 snet_cli/{ => snet_cli}/sdk_command.py | 0 snet_cli/{ => snet_cli}/utils.py | 0 snet_cli/{ => snet_cli}/utils_agi2cogs.py | 0 snet_cli/{ => snet_cli}/utils_config.py | 0 snet_cli/{ => snet_cli}/utils_ipfs.py | 0 snet_cli/{ => snet_cli}/utils_proto.py | 0 snet_cli/{ => snet_cli}/version.py | 0 {test => snet_cli/test}/README.md | 0 .../script10_claim_timeout_all.sh | 0 .../script11_update_metadata.sh | 0 .../script12_extend_add_for_service.sh | 0 .../script13_call_reinitialize.sh | 0 .../script15_sdk_generate_client_library.sh | 0 .../functional_tests/script1_twogroups.sh | 0 .../script2_deposit_transfer.sh | 0 .../script3_without_addresses.sh | 0 .../script4_only_with_networks.sh | 0 .../script5_identity1_rpc_mnemonic.sh | 0 .../functional_tests/script6_organization.sh | 0 .../functional_tests/script7_contracts.sh | 0 .../functional_tests/script8_networks.sh | 0 .../functional_tests/script9_treasurer.sh | 0 .../service_spec1/ExampleService.proto | 0 .../simple_daemon/test_simple_daemon.py | 0 .../unit_tests/test_mpe_service_metadata_1.py | 0 .../test}/utils/reset_environment.sh | 0 snet_cli/test/utils/run_all_functional.sh | 5 + snet_sdk/LICENSE | 21 +++ snet_sdk/MANIFEST.in | 3 + snet_sdk/README.md | 101 ++++++++++++ snet_sdk/blockchain/package.json | 6 + snet_sdk/scripts/blockchain | 55 +++++++ snet_sdk/scripts/package-pip | 3 + snet_sdk/setup.py | 23 +++ snet_sdk/snet_sdk/__init__.py | 71 ++++++++ snet_sdk/snet_sdk/account.py | 88 ++++++++++ snet_sdk/snet_sdk/contract.py | 27 ++++ .../snet_sdk/generic_client_interceptor.py | 55 +++++++ snet_sdk/snet_sdk/mpe_contract.py | 72 +++++++++ snet_sdk/snet_sdk/payment_channel.py | 54 +++++++ .../__init__.py | 0 .../default.py | 45 ++++++ .../resources/contracts/placeholder.txt | 0 snet_sdk/snet_sdk/service_client.py | 127 +++++++++++++++ snet_sdk/snet_sdk/state_service_pb2.py | 153 ++++++++++++++++++ snet_sdk/snet_sdk/state_service_pb2_grpc.py | 54 +++++++ snet_sdk/snet_sdk/utils.py | 41 +++++ test/utils/run_all_functional.sh | 5 - 114 files changed, 1026 insertions(+), 21 deletions(-) rename MANIFEST.in => snet_cli/MANIFEST.in (100%) rename {docs => snet_cli/docs}/Makefile (100%) rename {docs => snet_cli/docs}/build-docs.sh (100%) rename {docs => snet_cli/docs}/source/conf.py (100%) rename {docs => snet_cli/docs}/source/generate_rst.py (100%) rename {docs => snet_cli/docs}/source/img/singularityNET.png (100%) rename {docs => snet_cli/docs}/source/index_template.tpl (100%) rename {docs => snet_cli/docs}/source/snet-cli-static/theme.css (100%) rename {docs => snet_cli/docs}/source/subcommand_template.tpl (100%) rename {scripts => snet_cli/scripts}/blockchain (98%) rename {scripts => snet_cli/scripts}/package-pip (100%) rename setup.py => snet_cli/setup.py (100%) rename snet_cli/{ => snet_cli}/__init__.py (100%) rename snet_cli/{ => snet_cli}/_vendor/__init__.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/BlueHSMServer_pb2.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/Dongle.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/__init__.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/checkGenuine.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/comm.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/commException.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/commHTTP.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/commU2F.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/deleteApp.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/deployed.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/derivePassphrase.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/ecWrapper.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/endorsementSetup.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/endorsementSetupLedger.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/genCAPair.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/getMemInfo.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/hashApp.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/hexLoader.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/hexParser.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/hostOnboard.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/ledgerWrapper.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/listApps.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/loadApp.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/loadMCU.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/mcuBootloader.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/resetCustomCA.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/runApp.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/runScript.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/setupCustomCA.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/signApp.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/updateFirmware.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/verifyApp.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/verifyEndorsement1.py (100%) rename snet_cli/{ => snet_cli}/_vendor/ledgerblue/verifyEndorsement2.py (100%) rename snet_cli/{ => snet_cli}/arguments.py (100%) rename snet_cli/{ => snet_cli}/commands.py (100%) rename snet_cli/{ => snet_cli}/config.py (100%) rename snet_cli/{ => snet_cli}/contract.py (100%) rename snet_cli/{ => snet_cli}/identity.py (100%) rename snet_cli/{ => snet_cli}/mpe_account_command.py (100%) rename snet_cli/{ => snet_cli}/mpe_channel_command.py (100%) rename snet_cli/{ => snet_cli}/mpe_client_command.py (100%) rename snet_cli/{ => snet_cli}/mpe_service_command.py (100%) rename snet_cli/{ => snet_cli}/mpe_service_metadata.py (100%) rename snet_cli/{ => snet_cli}/mpe_treasurer_command.py (100%) rename snet_cli/{ => snet_cli}/resources/contracts/placeholder.txt (100%) rename snet_cli/{ => snet_cli}/resources/proto/control_service.proto (100%) rename snet_cli/{ => snet_cli}/resources/proto/merckledag.proto (100%) rename snet_cli/{ => snet_cli}/resources/proto/state_service.proto (100%) rename snet_cli/{ => snet_cli}/resources/proto/unixfs.proto (100%) rename snet_cli/{ => snet_cli}/sdk_command.py (100%) rename snet_cli/{ => snet_cli}/utils.py (100%) rename snet_cli/{ => snet_cli}/utils_agi2cogs.py (100%) rename snet_cli/{ => snet_cli}/utils_config.py (100%) rename snet_cli/{ => snet_cli}/utils_ipfs.py (100%) rename snet_cli/{ => snet_cli}/utils_proto.py (100%) rename snet_cli/{ => snet_cli}/version.py (100%) rename {test => snet_cli/test}/README.md (100%) rename {test => snet_cli/test}/functional_tests/script10_claim_timeout_all.sh (100%) rename {test => snet_cli/test}/functional_tests/script11_update_metadata.sh (100%) rename {test => snet_cli/test}/functional_tests/script12_extend_add_for_service.sh (100%) rename {test => snet_cli/test}/functional_tests/script13_call_reinitialize.sh (100%) rename {test => snet_cli/test}/functional_tests/script15_sdk_generate_client_library.sh (100%) rename {test => snet_cli/test}/functional_tests/script1_twogroups.sh (100%) rename {test => snet_cli/test}/functional_tests/script2_deposit_transfer.sh (100%) rename {test => snet_cli/test}/functional_tests/script3_without_addresses.sh (100%) rename {test => snet_cli/test}/functional_tests/script4_only_with_networks.sh (100%) rename {test => snet_cli/test}/functional_tests/script5_identity1_rpc_mnemonic.sh (100%) rename {test => snet_cli/test}/functional_tests/script6_organization.sh (100%) rename {test => snet_cli/test}/functional_tests/script7_contracts.sh (100%) rename {test => snet_cli/test}/functional_tests/script8_networks.sh (100%) rename {test => snet_cli/test}/functional_tests/script9_treasurer.sh (100%) rename {test => snet_cli/test}/functional_tests/service_spec1/ExampleService.proto (100%) rename {test => snet_cli/test}/functional_tests/simple_daemon/test_simple_daemon.py (100%) rename {test => snet_cli/test}/unit_tests/test_mpe_service_metadata_1.py (100%) rename {test => snet_cli/test}/utils/reset_environment.sh (100%) create mode 100755 snet_cli/test/utils/run_all_functional.sh create mode 100644 snet_sdk/LICENSE create mode 100644 snet_sdk/MANIFEST.in create mode 100644 snet_sdk/README.md create mode 100644 snet_sdk/blockchain/package.json create mode 100755 snet_sdk/scripts/blockchain create mode 100755 snet_sdk/scripts/package-pip create mode 100644 snet_sdk/setup.py create mode 100644 snet_sdk/snet_sdk/__init__.py create mode 100644 snet_sdk/snet_sdk/account.py create mode 100644 snet_sdk/snet_sdk/contract.py create mode 100644 snet_sdk/snet_sdk/generic_client_interceptor.py create mode 100644 snet_sdk/snet_sdk/mpe_contract.py create mode 100644 snet_sdk/snet_sdk/payment_channel.py create mode 100644 snet_sdk/snet_sdk/payment_channel_management_strategies/__init__.py create mode 100644 snet_sdk/snet_sdk/payment_channel_management_strategies/default.py create mode 100644 snet_sdk/snet_sdk/resources/contracts/placeholder.txt create mode 100644 snet_sdk/snet_sdk/service_client.py create mode 100644 snet_sdk/snet_sdk/state_service_pb2.py create mode 100644 snet_sdk/snet_sdk/state_service_pb2_grpc.py create mode 100644 snet_sdk/snet_sdk/utils.py delete mode 100755 test/utils/run_all_functional.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index fade56e7..a18ffc1c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,13 +21,13 @@ jobs: - run: name: Install snet-cli command: | - ./scripts/blockchain install - sudo pip3 install -e . + ./snet_cli/scripts/blockchain install + sudo pip3 install -e ./snet_cli - run: name: Install platform-contracts from master command: | # Install platform-contracts (from master) - # we will deploy contracts from test/utils/reset_enviroment.sh + # we will deploy contracts from snet_cli/test/utils/reset_enviroment.sh cd .. git clone https://github.com/singnet/platform-contracts cd platform-contracts @@ -42,7 +42,7 @@ jobs: - run: name: Functional tests command: | - bash -ex test/utils/run_all_functional.sh + bash -ex snet_cli/test/utils/run_all_functional.sh - run: name: Trigger platform-pipeline build command: | diff --git a/.gitignore b/.gitignore index 006bc0d4..1621ffed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,18 @@ -venv/ -.idea/ -snet_cli.egg-info/ blockchain/node_modules/ -__pycache__/ -snet_cli/resources/contracts/abi -snet_cli/resources/contracts/networks -snet_cli/resources/proto/*.py -snet_cli/resources/node_modules -build/ -dist/ -client_libraries/ +snet_cli/venv/ +.idea/ +snet_cli/snet_cli.egg-info/ +snet_cli/snet_cli/resources/contracts/abi +snet_cli/snet_cli/resources/contracts/networks +snet_cli/snet_cli/resources/proto/*.py +snet_cli/snet_cli/resources/node_modules +snet_cli/build/ +snet_cli/dist/ + +snet_sdk/venv/ +snet_sdk/snet_sdk.egg-info/ +__pycache__ +snet_sdk/snet_sdk/resources/contracts/abi +snet_sdk/snet_sdk/resources/contracts/networks +snet_sdk/build/ +snet_sdk/dist/ diff --git a/MANIFEST.in b/snet_cli/MANIFEST.in similarity index 100% rename from MANIFEST.in rename to snet_cli/MANIFEST.in diff --git a/docs/Makefile b/snet_cli/docs/Makefile similarity index 100% rename from docs/Makefile rename to snet_cli/docs/Makefile diff --git a/docs/build-docs.sh b/snet_cli/docs/build-docs.sh similarity index 100% rename from docs/build-docs.sh rename to snet_cli/docs/build-docs.sh diff --git a/docs/source/conf.py b/snet_cli/docs/source/conf.py similarity index 100% rename from docs/source/conf.py rename to snet_cli/docs/source/conf.py diff --git a/docs/source/generate_rst.py b/snet_cli/docs/source/generate_rst.py similarity index 100% rename from docs/source/generate_rst.py rename to snet_cli/docs/source/generate_rst.py diff --git a/docs/source/img/singularityNET.png b/snet_cli/docs/source/img/singularityNET.png similarity index 100% rename from docs/source/img/singularityNET.png rename to snet_cli/docs/source/img/singularityNET.png diff --git a/docs/source/index_template.tpl b/snet_cli/docs/source/index_template.tpl similarity index 100% rename from docs/source/index_template.tpl rename to snet_cli/docs/source/index_template.tpl diff --git a/docs/source/snet-cli-static/theme.css b/snet_cli/docs/source/snet-cli-static/theme.css similarity index 100% rename from docs/source/snet-cli-static/theme.css rename to snet_cli/docs/source/snet-cli-static/theme.css diff --git a/docs/source/subcommand_template.tpl b/snet_cli/docs/source/subcommand_template.tpl similarity index 100% rename from docs/source/subcommand_template.tpl rename to snet_cli/docs/source/subcommand_template.tpl diff --git a/scripts/blockchain b/snet_cli/scripts/blockchain similarity index 98% rename from scripts/blockchain rename to snet_cli/scripts/blockchain index e943b8cf..4edb62ef 100755 --- a/scripts/blockchain +++ b/snet_cli/scripts/blockchain @@ -10,7 +10,7 @@ import sys def main(): assert len(sys.argv) > 1, "please select a target from 'install', 'uninstall'" target = sys.argv[1] - blockchain_dir = pathlib.Path(__file__).absolute().parent.parent.joinpath("blockchain") + blockchain_dir = pathlib.Path(__file__).absolute().parent.parent.parent.joinpath("blockchain") node_modules_dir = blockchain_dir.joinpath("node_modules") platform_json_src_dir = node_modules_dir.joinpath("singularitynet-platform-contracts") token_json_src_dir = node_modules_dir.joinpath("singularitynet-token-contracts") diff --git a/scripts/package-pip b/snet_cli/scripts/package-pip similarity index 100% rename from scripts/package-pip rename to snet_cli/scripts/package-pip diff --git a/setup.py b/snet_cli/setup.py similarity index 100% rename from setup.py rename to snet_cli/setup.py diff --git a/snet_cli/__init__.py b/snet_cli/snet_cli/__init__.py similarity index 100% rename from snet_cli/__init__.py rename to snet_cli/snet_cli/__init__.py diff --git a/snet_cli/_vendor/__init__.py b/snet_cli/snet_cli/_vendor/__init__.py similarity index 100% rename from snet_cli/_vendor/__init__.py rename to snet_cli/snet_cli/_vendor/__init__.py diff --git a/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py b/snet_cli/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py rename to snet_cli/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py diff --git a/snet_cli/_vendor/ledgerblue/Dongle.py b/snet_cli/snet_cli/_vendor/ledgerblue/Dongle.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/Dongle.py rename to snet_cli/snet_cli/_vendor/ledgerblue/Dongle.py diff --git a/snet_cli/_vendor/ledgerblue/__init__.py b/snet_cli/snet_cli/_vendor/ledgerblue/__init__.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/__init__.py rename to snet_cli/snet_cli/_vendor/ledgerblue/__init__.py diff --git a/snet_cli/_vendor/ledgerblue/checkGenuine.py b/snet_cli/snet_cli/_vendor/ledgerblue/checkGenuine.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/checkGenuine.py rename to snet_cli/snet_cli/_vendor/ledgerblue/checkGenuine.py diff --git a/snet_cli/_vendor/ledgerblue/comm.py b/snet_cli/snet_cli/_vendor/ledgerblue/comm.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/comm.py rename to snet_cli/snet_cli/_vendor/ledgerblue/comm.py diff --git a/snet_cli/_vendor/ledgerblue/commException.py b/snet_cli/snet_cli/_vendor/ledgerblue/commException.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/commException.py rename to snet_cli/snet_cli/_vendor/ledgerblue/commException.py diff --git a/snet_cli/_vendor/ledgerblue/commHTTP.py b/snet_cli/snet_cli/_vendor/ledgerblue/commHTTP.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/commHTTP.py rename to snet_cli/snet_cli/_vendor/ledgerblue/commHTTP.py diff --git a/snet_cli/_vendor/ledgerblue/commU2F.py b/snet_cli/snet_cli/_vendor/ledgerblue/commU2F.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/commU2F.py rename to snet_cli/snet_cli/_vendor/ledgerblue/commU2F.py diff --git a/snet_cli/_vendor/ledgerblue/deleteApp.py b/snet_cli/snet_cli/_vendor/ledgerblue/deleteApp.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/deleteApp.py rename to snet_cli/snet_cli/_vendor/ledgerblue/deleteApp.py diff --git a/snet_cli/_vendor/ledgerblue/deployed.py b/snet_cli/snet_cli/_vendor/ledgerblue/deployed.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/deployed.py rename to snet_cli/snet_cli/_vendor/ledgerblue/deployed.py diff --git a/snet_cli/_vendor/ledgerblue/derivePassphrase.py b/snet_cli/snet_cli/_vendor/ledgerblue/derivePassphrase.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/derivePassphrase.py rename to snet_cli/snet_cli/_vendor/ledgerblue/derivePassphrase.py diff --git a/snet_cli/_vendor/ledgerblue/ecWrapper.py b/snet_cli/snet_cli/_vendor/ledgerblue/ecWrapper.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/ecWrapper.py rename to snet_cli/snet_cli/_vendor/ledgerblue/ecWrapper.py diff --git a/snet_cli/_vendor/ledgerblue/endorsementSetup.py b/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetup.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/endorsementSetup.py rename to snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetup.py diff --git a/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py b/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py rename to snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py diff --git a/snet_cli/_vendor/ledgerblue/genCAPair.py b/snet_cli/snet_cli/_vendor/ledgerblue/genCAPair.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/genCAPair.py rename to snet_cli/snet_cli/_vendor/ledgerblue/genCAPair.py diff --git a/snet_cli/_vendor/ledgerblue/getMemInfo.py b/snet_cli/snet_cli/_vendor/ledgerblue/getMemInfo.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/getMemInfo.py rename to snet_cli/snet_cli/_vendor/ledgerblue/getMemInfo.py diff --git a/snet_cli/_vendor/ledgerblue/hashApp.py b/snet_cli/snet_cli/_vendor/ledgerblue/hashApp.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/hashApp.py rename to snet_cli/snet_cli/_vendor/ledgerblue/hashApp.py diff --git a/snet_cli/_vendor/ledgerblue/hexLoader.py b/snet_cli/snet_cli/_vendor/ledgerblue/hexLoader.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/hexLoader.py rename to snet_cli/snet_cli/_vendor/ledgerblue/hexLoader.py diff --git a/snet_cli/_vendor/ledgerblue/hexParser.py b/snet_cli/snet_cli/_vendor/ledgerblue/hexParser.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/hexParser.py rename to snet_cli/snet_cli/_vendor/ledgerblue/hexParser.py diff --git a/snet_cli/_vendor/ledgerblue/hostOnboard.py b/snet_cli/snet_cli/_vendor/ledgerblue/hostOnboard.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/hostOnboard.py rename to snet_cli/snet_cli/_vendor/ledgerblue/hostOnboard.py diff --git a/snet_cli/_vendor/ledgerblue/ledgerWrapper.py b/snet_cli/snet_cli/_vendor/ledgerblue/ledgerWrapper.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/ledgerWrapper.py rename to snet_cli/snet_cli/_vendor/ledgerblue/ledgerWrapper.py diff --git a/snet_cli/_vendor/ledgerblue/listApps.py b/snet_cli/snet_cli/_vendor/ledgerblue/listApps.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/listApps.py rename to snet_cli/snet_cli/_vendor/ledgerblue/listApps.py diff --git a/snet_cli/_vendor/ledgerblue/loadApp.py b/snet_cli/snet_cli/_vendor/ledgerblue/loadApp.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/loadApp.py rename to snet_cli/snet_cli/_vendor/ledgerblue/loadApp.py diff --git a/snet_cli/_vendor/ledgerblue/loadMCU.py b/snet_cli/snet_cli/_vendor/ledgerblue/loadMCU.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/loadMCU.py rename to snet_cli/snet_cli/_vendor/ledgerblue/loadMCU.py diff --git a/snet_cli/_vendor/ledgerblue/mcuBootloader.py b/snet_cli/snet_cli/_vendor/ledgerblue/mcuBootloader.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/mcuBootloader.py rename to snet_cli/snet_cli/_vendor/ledgerblue/mcuBootloader.py diff --git a/snet_cli/_vendor/ledgerblue/resetCustomCA.py b/snet_cli/snet_cli/_vendor/ledgerblue/resetCustomCA.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/resetCustomCA.py rename to snet_cli/snet_cli/_vendor/ledgerblue/resetCustomCA.py diff --git a/snet_cli/_vendor/ledgerblue/runApp.py b/snet_cli/snet_cli/_vendor/ledgerblue/runApp.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/runApp.py rename to snet_cli/snet_cli/_vendor/ledgerblue/runApp.py diff --git a/snet_cli/_vendor/ledgerblue/runScript.py b/snet_cli/snet_cli/_vendor/ledgerblue/runScript.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/runScript.py rename to snet_cli/snet_cli/_vendor/ledgerblue/runScript.py diff --git a/snet_cli/_vendor/ledgerblue/setupCustomCA.py b/snet_cli/snet_cli/_vendor/ledgerblue/setupCustomCA.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/setupCustomCA.py rename to snet_cli/snet_cli/_vendor/ledgerblue/setupCustomCA.py diff --git a/snet_cli/_vendor/ledgerblue/signApp.py b/snet_cli/snet_cli/_vendor/ledgerblue/signApp.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/signApp.py rename to snet_cli/snet_cli/_vendor/ledgerblue/signApp.py diff --git a/snet_cli/_vendor/ledgerblue/updateFirmware.py b/snet_cli/snet_cli/_vendor/ledgerblue/updateFirmware.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/updateFirmware.py rename to snet_cli/snet_cli/_vendor/ledgerblue/updateFirmware.py diff --git a/snet_cli/_vendor/ledgerblue/verifyApp.py b/snet_cli/snet_cli/_vendor/ledgerblue/verifyApp.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/verifyApp.py rename to snet_cli/snet_cli/_vendor/ledgerblue/verifyApp.py diff --git a/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py b/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/verifyEndorsement1.py rename to snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py diff --git a/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py b/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py similarity index 100% rename from snet_cli/_vendor/ledgerblue/verifyEndorsement2.py rename to snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py diff --git a/snet_cli/arguments.py b/snet_cli/snet_cli/arguments.py similarity index 100% rename from snet_cli/arguments.py rename to snet_cli/snet_cli/arguments.py diff --git a/snet_cli/commands.py b/snet_cli/snet_cli/commands.py similarity index 100% rename from snet_cli/commands.py rename to snet_cli/snet_cli/commands.py diff --git a/snet_cli/config.py b/snet_cli/snet_cli/config.py similarity index 100% rename from snet_cli/config.py rename to snet_cli/snet_cli/config.py diff --git a/snet_cli/contract.py b/snet_cli/snet_cli/contract.py similarity index 100% rename from snet_cli/contract.py rename to snet_cli/snet_cli/contract.py diff --git a/snet_cli/identity.py b/snet_cli/snet_cli/identity.py similarity index 100% rename from snet_cli/identity.py rename to snet_cli/snet_cli/identity.py diff --git a/snet_cli/mpe_account_command.py b/snet_cli/snet_cli/mpe_account_command.py similarity index 100% rename from snet_cli/mpe_account_command.py rename to snet_cli/snet_cli/mpe_account_command.py diff --git a/snet_cli/mpe_channel_command.py b/snet_cli/snet_cli/mpe_channel_command.py similarity index 100% rename from snet_cli/mpe_channel_command.py rename to snet_cli/snet_cli/mpe_channel_command.py diff --git a/snet_cli/mpe_client_command.py b/snet_cli/snet_cli/mpe_client_command.py similarity index 100% rename from snet_cli/mpe_client_command.py rename to snet_cli/snet_cli/mpe_client_command.py diff --git a/snet_cli/mpe_service_command.py b/snet_cli/snet_cli/mpe_service_command.py similarity index 100% rename from snet_cli/mpe_service_command.py rename to snet_cli/snet_cli/mpe_service_command.py diff --git a/snet_cli/mpe_service_metadata.py b/snet_cli/snet_cli/mpe_service_metadata.py similarity index 100% rename from snet_cli/mpe_service_metadata.py rename to snet_cli/snet_cli/mpe_service_metadata.py diff --git a/snet_cli/mpe_treasurer_command.py b/snet_cli/snet_cli/mpe_treasurer_command.py similarity index 100% rename from snet_cli/mpe_treasurer_command.py rename to snet_cli/snet_cli/mpe_treasurer_command.py diff --git a/snet_cli/resources/contracts/placeholder.txt b/snet_cli/snet_cli/resources/contracts/placeholder.txt similarity index 100% rename from snet_cli/resources/contracts/placeholder.txt rename to snet_cli/snet_cli/resources/contracts/placeholder.txt diff --git a/snet_cli/resources/proto/control_service.proto b/snet_cli/snet_cli/resources/proto/control_service.proto similarity index 100% rename from snet_cli/resources/proto/control_service.proto rename to snet_cli/snet_cli/resources/proto/control_service.proto diff --git a/snet_cli/resources/proto/merckledag.proto b/snet_cli/snet_cli/resources/proto/merckledag.proto similarity index 100% rename from snet_cli/resources/proto/merckledag.proto rename to snet_cli/snet_cli/resources/proto/merckledag.proto diff --git a/snet_cli/resources/proto/state_service.proto b/snet_cli/snet_cli/resources/proto/state_service.proto similarity index 100% rename from snet_cli/resources/proto/state_service.proto rename to snet_cli/snet_cli/resources/proto/state_service.proto diff --git a/snet_cli/resources/proto/unixfs.proto b/snet_cli/snet_cli/resources/proto/unixfs.proto similarity index 100% rename from snet_cli/resources/proto/unixfs.proto rename to snet_cli/snet_cli/resources/proto/unixfs.proto diff --git a/snet_cli/sdk_command.py b/snet_cli/snet_cli/sdk_command.py similarity index 100% rename from snet_cli/sdk_command.py rename to snet_cli/snet_cli/sdk_command.py diff --git a/snet_cli/utils.py b/snet_cli/snet_cli/utils.py similarity index 100% rename from snet_cli/utils.py rename to snet_cli/snet_cli/utils.py diff --git a/snet_cli/utils_agi2cogs.py b/snet_cli/snet_cli/utils_agi2cogs.py similarity index 100% rename from snet_cli/utils_agi2cogs.py rename to snet_cli/snet_cli/utils_agi2cogs.py diff --git a/snet_cli/utils_config.py b/snet_cli/snet_cli/utils_config.py similarity index 100% rename from snet_cli/utils_config.py rename to snet_cli/snet_cli/utils_config.py diff --git a/snet_cli/utils_ipfs.py b/snet_cli/snet_cli/utils_ipfs.py similarity index 100% rename from snet_cli/utils_ipfs.py rename to snet_cli/snet_cli/utils_ipfs.py diff --git a/snet_cli/utils_proto.py b/snet_cli/snet_cli/utils_proto.py similarity index 100% rename from snet_cli/utils_proto.py rename to snet_cli/snet_cli/utils_proto.py diff --git a/snet_cli/version.py b/snet_cli/snet_cli/version.py similarity index 100% rename from snet_cli/version.py rename to snet_cli/snet_cli/version.py diff --git a/test/README.md b/snet_cli/test/README.md similarity index 100% rename from test/README.md rename to snet_cli/test/README.md diff --git a/test/functional_tests/script10_claim_timeout_all.sh b/snet_cli/test/functional_tests/script10_claim_timeout_all.sh similarity index 100% rename from test/functional_tests/script10_claim_timeout_all.sh rename to snet_cli/test/functional_tests/script10_claim_timeout_all.sh diff --git a/test/functional_tests/script11_update_metadata.sh b/snet_cli/test/functional_tests/script11_update_metadata.sh similarity index 100% rename from test/functional_tests/script11_update_metadata.sh rename to snet_cli/test/functional_tests/script11_update_metadata.sh diff --git a/test/functional_tests/script12_extend_add_for_service.sh b/snet_cli/test/functional_tests/script12_extend_add_for_service.sh similarity index 100% rename from test/functional_tests/script12_extend_add_for_service.sh rename to snet_cli/test/functional_tests/script12_extend_add_for_service.sh diff --git a/test/functional_tests/script13_call_reinitialize.sh b/snet_cli/test/functional_tests/script13_call_reinitialize.sh similarity index 100% rename from test/functional_tests/script13_call_reinitialize.sh rename to snet_cli/test/functional_tests/script13_call_reinitialize.sh diff --git a/test/functional_tests/script15_sdk_generate_client_library.sh b/snet_cli/test/functional_tests/script15_sdk_generate_client_library.sh similarity index 100% rename from test/functional_tests/script15_sdk_generate_client_library.sh rename to snet_cli/test/functional_tests/script15_sdk_generate_client_library.sh diff --git a/test/functional_tests/script1_twogroups.sh b/snet_cli/test/functional_tests/script1_twogroups.sh similarity index 100% rename from test/functional_tests/script1_twogroups.sh rename to snet_cli/test/functional_tests/script1_twogroups.sh diff --git a/test/functional_tests/script2_deposit_transfer.sh b/snet_cli/test/functional_tests/script2_deposit_transfer.sh similarity index 100% rename from test/functional_tests/script2_deposit_transfer.sh rename to snet_cli/test/functional_tests/script2_deposit_transfer.sh diff --git a/test/functional_tests/script3_without_addresses.sh b/snet_cli/test/functional_tests/script3_without_addresses.sh similarity index 100% rename from test/functional_tests/script3_without_addresses.sh rename to snet_cli/test/functional_tests/script3_without_addresses.sh diff --git a/test/functional_tests/script4_only_with_networks.sh b/snet_cli/test/functional_tests/script4_only_with_networks.sh similarity index 100% rename from test/functional_tests/script4_only_with_networks.sh rename to snet_cli/test/functional_tests/script4_only_with_networks.sh diff --git a/test/functional_tests/script5_identity1_rpc_mnemonic.sh b/snet_cli/test/functional_tests/script5_identity1_rpc_mnemonic.sh similarity index 100% rename from test/functional_tests/script5_identity1_rpc_mnemonic.sh rename to snet_cli/test/functional_tests/script5_identity1_rpc_mnemonic.sh diff --git a/test/functional_tests/script6_organization.sh b/snet_cli/test/functional_tests/script6_organization.sh similarity index 100% rename from test/functional_tests/script6_organization.sh rename to snet_cli/test/functional_tests/script6_organization.sh diff --git a/test/functional_tests/script7_contracts.sh b/snet_cli/test/functional_tests/script7_contracts.sh similarity index 100% rename from test/functional_tests/script7_contracts.sh rename to snet_cli/test/functional_tests/script7_contracts.sh diff --git a/test/functional_tests/script8_networks.sh b/snet_cli/test/functional_tests/script8_networks.sh similarity index 100% rename from test/functional_tests/script8_networks.sh rename to snet_cli/test/functional_tests/script8_networks.sh diff --git a/test/functional_tests/script9_treasurer.sh b/snet_cli/test/functional_tests/script9_treasurer.sh similarity index 100% rename from test/functional_tests/script9_treasurer.sh rename to snet_cli/test/functional_tests/script9_treasurer.sh diff --git a/test/functional_tests/service_spec1/ExampleService.proto b/snet_cli/test/functional_tests/service_spec1/ExampleService.proto similarity index 100% rename from test/functional_tests/service_spec1/ExampleService.proto rename to snet_cli/test/functional_tests/service_spec1/ExampleService.proto diff --git a/test/functional_tests/simple_daemon/test_simple_daemon.py b/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py similarity index 100% rename from test/functional_tests/simple_daemon/test_simple_daemon.py rename to snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py diff --git a/test/unit_tests/test_mpe_service_metadata_1.py b/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py similarity index 100% rename from test/unit_tests/test_mpe_service_metadata_1.py rename to snet_cli/test/unit_tests/test_mpe_service_metadata_1.py diff --git a/test/utils/reset_environment.sh b/snet_cli/test/utils/reset_environment.sh similarity index 100% rename from test/utils/reset_environment.sh rename to snet_cli/test/utils/reset_environment.sh diff --git a/snet_cli/test/utils/run_all_functional.sh b/snet_cli/test/utils/run_all_functional.sh new file mode 100755 index 00000000..7d38afb8 --- /dev/null +++ b/snet_cli/test/utils/run_all_functional.sh @@ -0,0 +1,5 @@ +for f in snet_cli/test/functional_tests/*.sh +do + bash -ex snet_cli/test/utils/reset_environment.sh --i-no-what-i-am-doing + bash -ex -c "cd snet_cli/test/functional_tests; bash -ex `basename $f`" +done diff --git a/snet_sdk/LICENSE b/snet_sdk/LICENSE new file mode 100644 index 00000000..c674cd51 --- /dev/null +++ b/snet_sdk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 SingularityNET + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/snet_sdk/MANIFEST.in b/snet_sdk/MANIFEST.in new file mode 100644 index 00000000..5f2a16ee --- /dev/null +++ b/snet_sdk/MANIFEST.in @@ -0,0 +1,3 @@ +include snet_sdk/resources/proto/* +include snet_sdk/resources/contracts/abi/* +include snet_sdk/resources/contracts/networks/* diff --git a/snet_sdk/README.md b/snet_sdk/README.md new file mode 100644 index 00000000..4d2cb275 --- /dev/null +++ b/snet_sdk/README.md @@ -0,0 +1,101 @@ +# snet-sdk-python + +SingularityNET SDK for Python + +## Getting Started + +These instructions are for the development and use of the SingularityNET SDK for Python. + +### Usage + +The SingularityNET SDK allows you to import compiled client libraries for your service or services or choice and make calls to those services programmatically from your application by setting up state channels with the providers of those services and making gRPC calls to the SingularityNET daemons for those services by selecting a channel with sufficient funding and supplying the appropriate metadata for authentication. + +Once you have installed the snet-sdk in your current environment and it's in your PYTHONPATH, you should import it and create an instance of the base sdk class: + +```python +from snet_sdk import Snet +import config +snet = Snet(private_key=config.private_key) +``` + +Now, the instance of the sdk can be used to instantiate clients for SingularityNET services. To interact with those services, the sdk needs to be supplied the compiled client libraries and a reference to their path on your file system. + +To generate the client libraries, you need the SingularityNET Command Line Interface, or CLI, which you can download from PyPi, see [https://github.com/singnet/snet-cli#installing-with-pip](https://github.com/singnet/snet-cli#installing-with-pip) + +Once you have the CLI installed, run the following command: +```bash +snet sdk generate-client-library python +``` + +Optionally, you can specify an output path; otherwise it's going to be `./client_libraries/python//` + +Now, by default the sdk is going to look for those client libraries in the `./grpc//` in the directory of the main process of the module it's being imported by. + +Once you have the generated client libraries in place, you can create an instance of a SingularityNET service client: +```python +client = snet.client("", "") +``` + +The client exposes the following properties and methods: +- All of the modules from the generated client library as `client.grpc. 1, "please select a target from 'install', 'uninstall'" + target = sys.argv[1] + blockchain_dir = pathlib.Path(__file__).absolute().parent.parent.parent.joinpath("blockchain") + node_modules_dir = blockchain_dir.joinpath("node_modules") + platform_json_src_dir = node_modules_dir.joinpath("singularitynet-platform-contracts") + token_json_src_dir = node_modules_dir.joinpath("singularitynet-token-contracts") + token_contract_name = "SingularityNetToken" + contract_json_dest_dir = pathlib.Path(__file__).absolute().parent.parent.joinpath("snet_sdk", "resources", "contracts") + abi_contract_names = ["Registry", "MultiPartyEscrow"] + networks_contract_names = ["Registry", "MultiPartyEscrow"] + + npm_location = shutil.which('npm') + if not npm_location: + raise Exception("This script requires 'npm' to be installed and in your PATH") + + if target == "install": + shutil.rmtree(contract_json_dest_dir) + + subprocess.call([npm_location, "install"], cwd=blockchain_dir) + + os.makedirs(contract_json_dest_dir.joinpath("abi"), exist_ok=True) + os.makedirs(contract_json_dest_dir.joinpath("networks"), exist_ok=True) + + for contract_name in abi_contract_names: + shutil.copy(platform_json_src_dir.joinpath("abi", "{}.json".format(contract_name)), + contract_json_dest_dir.joinpath("abi", "{}.json".format(contract_name))) + for contract_name in networks_contract_names: + shutil.copy(platform_json_src_dir.joinpath("networks", "{}.json".format(contract_name)), + contract_json_dest_dir.joinpath("networks", "{}.json".format(contract_name))) + + shutil.copy(token_json_src_dir.joinpath("abi", "{}.json".format(token_contract_name)), + contract_json_dest_dir.joinpath("abi", "{}.json".format(token_contract_name))) + shutil.copy(token_json_src_dir.joinpath("networks", "{}.json".format(token_contract_name)), + contract_json_dest_dir.joinpath("networks", "{}.json".format(token_contract_name))) + elif target == "uninstall": + try: + shutil.rmtree(node_modules_dir) + shutil.rmtree(contract_json_dest_dir.joinpath("abi")) + shutil.rmtree(contract_json_dest_dir.joinpath("networks")) + except FileNotFoundError: + pass + + +if __name__ == "__main__": + main() diff --git a/snet_sdk/scripts/package-pip b/snet_sdk/scripts/package-pip new file mode 100755 index 00000000..4dda00f6 --- /dev/null +++ b/snet_sdk/scripts/package-pip @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +python3.6 setup.py sdist bdist_wheel diff --git a/snet_sdk/setup.py b/snet_sdk/setup.py new file mode 100644 index 00000000..6e0530ff --- /dev/null +++ b/snet_sdk/setup.py @@ -0,0 +1,23 @@ +from setuptools import setup, find_packages +import re + +with open('snet_sdk/__init__.py', 'rt', encoding='utf8') as f: + version = re.search(r'__version__ = "(.*?)"', f.read()).group(1) + +setup( + name='snet_sdk', + version=version, + packages=find_packages(), + url='https://github.com/singnet/snet-sdk-python', + license='MIT', + author='SingularityNET Foundation', + author_email='info@singularitynet.io', + description='SingularityNET Python SDK', + install_requires=[ + 'grpcio-tools==1.17.1', + 'ecdsa==0.13', + 'web3==4.2.1', + 'ipfsapi==0.4.2.post1', + 'rfc3986==1.1.0' + ] +) diff --git a/snet_sdk/snet_sdk/__init__.py b/snet_sdk/snet_sdk/__init__.py new file mode 100644 index 00000000..f1b69224 --- /dev/null +++ b/snet_sdk/snet_sdk/__init__.py @@ -0,0 +1,71 @@ +import operator +from functools import reduce +import sys +import os +import importlib +import json +import base64 +from pathlib import PurePath, Path +from urllib.parse import urljoin + +import hashlib +import collections +import web3 +from web3.gas_strategies.rpc import rpc_gas_price_strategy +from eth_account.messages import defunct_hash_message +from rfc3986 import urlparse +import ipfsapi +from web3.utils.datastructures import AttributeDict, MutableAttributeDict + +import snet_sdk.generic_client_interceptor as generic_client_interceptor + +from snet_sdk.utils import get_contract_object +from snet_sdk.service_client import ServiceClient +from snet_sdk.account import Account +from snet_sdk.mpe_contract import MPEContract +from snet_sdk.payment_channel_management_strategies.default import PaymentChannelManagementStrategy + +__version__ = "0.0.1" + + +class SnetSDK: + """Base Snet SDK""" + def __init__( + self, + config + ): + self._config = config + + # Instantiate Ethereum client + eth_rpc_endpoint = self._config.get("eth_rpc_endpoint", "https://mainnet.infura.io") + provider = web3.HTTPProvider(eth_rpc_endpoint) + self.web3 = web3.Web3(provider) + self.web3.eth.setGasPriceStrategy(rpc_gas_price_strategy) + + self.mpe_contract = MPEContract(self.web3) + + # Instantiate IPFS client + ipfs_rpc_endpoint = self._config.get("ipfs_rpc_endpoint", "https://ipfs.singularitynet.io:80") + ipfs_rpc_endpoint = urlparse(ipfs_rpc_endpoint) + ipfs_scheme = ipfs_rpc_endpoint.scheme if ipfs_rpc_endpoint.scheme else "http" + ipfs_port = ipfs_rpc_endpoint.port if ipfs_rpc_endpoint.port else 5001 + self.ipfs_client = ipfsapi.connect(urljoin(ipfs_scheme, ipfs_rpc_endpoint.hostname), ipfs_port) + + self.registry_contract = get_contract_object(self.web3, "Registry.json") + self.account = Account(self.web3, config, self.mpe_contract) + + self.block_offset = self._config.get("block_offset", 604800) + + def create_service_client(self, org_id, service_id, service_stub, group_name="default_group", payment_channel_management_strategy=PaymentChannelManagementStrategy, options={}): + service_metadata = self.service_metadata(org_id, service_id) + try: + group = next(filter(lambda group: group["group_name"] == group_name, service_metadata.groups)) + except StopIteration: + raise ValueError("Group[name: {}] not found for orgId: {} and serviceId: {}".format(group_name, org_id, service_id)) + service_client = ServiceClient(self, service_metadata, group, service_stub, payment_channel_management_strategy(self), options) + return service_client + + def service_metadata(self, org_id, service_id): + (found, registration_id, metadata_uri, tags) = self.registry_contract.functions.getServiceRegistrationById(bytes(org_id, "utf-8"), bytes(service_id, "utf-8")).call() + metadata = AttributeDict(json.loads(self.ipfs_client.cat(metadata_uri.rstrip(b"\0").decode('ascii')[7:]))) + return metadata diff --git a/snet_sdk/snet_sdk/account.py b/snet_sdk/snet_sdk/account.py new file mode 100644 index 00000000..4164e8ca --- /dev/null +++ b/snet_sdk/snet_sdk/account.py @@ -0,0 +1,88 @@ +import json + +from snet_sdk.utils import normalize_private_key, get_address_from_private, get_contract_object + +DEFAULT_GAS = 210000 + + +class TransactionError(Exception): + """Raised when an Ethereum transaction receipt has a status of 0. Can provide a custom message. Optionally includes receipt""" + def __init__(self, message, receipt=None): + super().__init__(message) + self.message = message + self.receipt = receipt + def __str__(self): + return self.message + + +class Account: + def __init__(self, w3, config, mpe_contract): + self.config = config + self.web3 = w3 + self.mpe_contract = mpe_contract + self.token_contract = get_contract_object(self.web3, "SingularityNetToken.json") + private_key = config.get("private_key", None) + signer_private_key = config.get("signer_private_key", None) + if private_key is not None: + self.private_key = normalize_private_key(config["private_key"]) + if signer_private_key is not None: + self.signer_private_key = normalize_private_key(config["signer_private_key"]) + else: + self.signer_private_key = self.private_key + self.address = get_address_from_private(self.private_key) + self.signer_address = get_address_from_private(self.signer_private_key) + self.nonce = 0 + + + def _get_nonce(self): + nonce = self.web3.eth.getTransactionCount(self.address) + if self.nonce >= nonce: + nonce = self.nonce + 1 + self.nonce = nonce + return nonce + + + def _get_gas_price(self): + return self.web3.eth.generateGasPrice() + + + def _send_signed_transaction(self, contract_fn, *args): + transaction = contract_fn(*args).buildTransaction({ + "chainId": int(self.web3.version.network), + "gas": DEFAULT_GAS, + "gasPrice": self._get_gas_price(), + "nonce": self._get_nonce() + }) + signed_txn = self.web3.eth.account.signTransaction(transaction, private_key=self.private_key) + return self.web3.toHex(self.web3.eth.sendRawTransaction(signed_txn.rawTransaction)) + + + def send_transaction(self, contract_fn, *args): + txn_hash = self._send_signed_transaction(contract_fn, *args) + return self.web3.eth.waitForTransactionReceipt(txn_hash) + + + def _parse_receipt(self, receipt, event, encoder=json.JSONEncoder): + if receipt.status == 0: + raise TransactionError("Transaction failed", receipt) + else: + return json.dumps(dict(event().processReceipt(receipt)[0]["args"]), cls=encoder) + + + def escrow_balance(self): + return self.mpe_contract.balance(self.address) + + + def deposit_to_escrow_account(self, amount_in_cogs): + already_approved = self.allowance() + if amount_in_cogs > already_approved: + self.approve_transfer(amount_in_cogs) + return self.mpe_contract.deposit(self, amount_in_cogs) + + + def approve_transfer(self, amount_in_cogs): + return self.send_transaction(self.token_contract.functions.approve(self.mpe_contract.contract.address, amount_in_cogs)) + + + def allowance(self): + return self.token_contract.functions.allowance(self.address, self.mpe_contract.contract.address).call() diff --git a/snet_sdk/snet_sdk/contract.py b/snet_sdk/snet_sdk/contract.py new file mode 100644 index 00000000..c23eaddc --- /dev/null +++ b/snet_sdk/snet_sdk/contract.py @@ -0,0 +1,27 @@ +class Contract: + def __init__(self, w3, address, abi): + self.w3 = w3 + self.contract = self.w3.eth.contract(address=self.w3.toChecksumAddress(address), abi=abi) + self.abi = abi + + def call(self, function_name, *positional_inputs, **named_inputs): + return getattr(self.contract.functions, function_name)(*positional_inputs, **named_inputs).call() + + def build_transaction(self, function_name, from_address, gas_price, *positional_inputs, **named_inputs): + nonce = self.w3.eth.getTransactionCount(from_address) + chain_id = self.w3.version.network + return getattr(self.contract.functions, function_name)(*positional_inputs, **named_inputs).buildTransaction({ + "from": from_address, + "nonce": nonce, + "gasPrice": gas_price, + "chainId": int(chain_id) + }) + + def process_receipt(self, receipt): + events = [] + + contract_events = map(lambda e: e["name"], filter(lambda e: e["type"] == "event", self.abi)) + for contract_event in contract_events: + events.extend(getattr(self.contract.events, contract_event)().processReceipt(receipt)) + + return events diff --git a/snet_sdk/snet_sdk/generic_client_interceptor.py b/snet_sdk/snet_sdk/generic_client_interceptor.py new file mode 100644 index 00000000..d2bb7e56 --- /dev/null +++ b/snet_sdk/snet_sdk/generic_client_interceptor.py @@ -0,0 +1,55 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Base class for interceptors that operate on all RPC types.""" + +import grpc + + +class _GenericClientInterceptor( + grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInterceptor, + grpc.StreamUnaryClientInterceptor, grpc.StreamStreamClientInterceptor): + + def __init__(self, interceptor_function): + self._fn = interceptor_function + + def intercept_unary_unary(self, continuation, client_call_details, request): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, iter((request,)), False, False) + response = continuation(new_details, next(new_request_iterator)) + return postprocess(response) if postprocess else response + + def intercept_unary_stream(self, continuation, client_call_details, + request): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, iter((request,)), False, True) + response_it = continuation(new_details, next(new_request_iterator)) + return postprocess(response_it) if postprocess else response_it + + def intercept_stream_unary(self, continuation, client_call_details, + request_iterator): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, request_iterator, True, False) + response = continuation(new_details, new_request_iterator) + return postprocess(response) if postprocess else response + + def intercept_stream_stream(self, continuation, client_call_details, + request_iterator): + new_details, new_request_iterator, postprocess = self._fn( + client_call_details, request_iterator, True, True) + response_it = continuation(new_details, new_request_iterator) + return postprocess(response_it) if postprocess else response_it + + +def create(intercept_call): + return _GenericClientInterceptor(intercept_call) diff --git a/snet_sdk/snet_sdk/mpe_contract.py b/snet_sdk/snet_sdk/mpe_contract.py new file mode 100644 index 00000000..3e879352 --- /dev/null +++ b/snet_sdk/snet_sdk/mpe_contract.py @@ -0,0 +1,72 @@ +import base64 + +import web3 +from snet_sdk.utils import get_contract_object, get_contract_deployment_block +from snet_sdk.payment_channel import PaymentChannel + +BLOCKS_PER_BATCH = 20000 +EVENT_ABI = {'anonymous': False, 'inputs': [{'indexed': False, 'name': 'channelId', 'type': 'uint256'}, {'indexed': False, 'name': 'nonce', 'type': 'uint256'}, {'indexed': True, 'name': 'sender', 'type': 'address'}, {'indexed': False, 'name': 'signer', 'type': 'address'}, {'indexed': True, 'name': 'recipient', 'type': 'address'}, {'indexed': True, 'name': 'groupId', 'type': 'bytes32'}, {'indexed': False, 'name': 'amount', 'type': 'uint256'}, {'indexed': False, 'name': 'expiration', 'type': 'uint256'}], 'name': 'ChannelOpen', 'type': 'event'} + + +class MPEContract: + def __init__(self, w3): + self.web3 = w3 + self.contract = get_contract_object(self.web3, "MultiPartyEscrow.json") + self.event_topics = [self.web3.sha3(text="ChannelOpen(uint256,uint256,address,address,address,bytes32,uint256,uint256)").hex()] + self.deployment_block = get_contract_deployment_block(self.web3, "MultiPartyEscrow.json") + + + def get_past_open_channels(self, account, service, starting_block_number=0, to_block_number=None): + if to_block_number is None: + to_block_number = self.web3.eth.getBlock("latest")["number"] + + if starting_block_number == 0: + starting_block_number = self.deployment_block + + logs = [] + from_block = starting_block_number + while from_block <= to_block_number: + to_block = min(from_block + BLOCKS_PER_BATCH, to_block_number) + logs = logs + self.web3.eth.getLogs({"fromBlock" : from_block, "toBlock": to_block, "address": self.contract.address, "topics": self.event_topics}) + from_block = to_block + 1 + + channels_opened = list(filter(lambda channel: channel.sender == account.address and channel.signer == account.signer_address and channel.recipient == service.group["payment_address"], [web3.utils.events.get_event_data(EVENT_ABI, l)["args"] for l in logs])) + return list(map(lambda channel: PaymentChannel(channel["channelId"], self.web3, account, service, self), channels_opened)) + + + def balance(self, address): + return self.contract.functions.balances(address).call() + + + def deposit(self, account, amount_in_cogs): + return account.send_transaction(self.contract.functions.deposit, amount_in_cogs) + + + def open_channel(self, account, service, amount, expiration): + return account.send_transaction(self.contract.functions.openChannel, account.signer_address, service.group["payment_address"], base64.b64decode(str(service.group["group_id"])), amount, expiration) + + + def deposit_and_open_channel(self, account, service, amount, expiration): + already_approved_amount = account.allowance() + if amount > already_approved_amount: + account.approve_transfer(amount) + return account.send_transaction(self.contract.functions.depositAndOpenChannel, account.signer_address, service.group["payment_address"], base64.b64decode(str(service.group["group_id"])), amount, expiration) + + + def channel_add_funds(self, account, channel_id, amount): + self._fund_escrow_account(account, amount) + return account.send_transaction(self.contract.functions.channelAddFunds, channel_id, amount) + + + def channel_extend(self, account, channel_id, expiration): + return account.send_transaction(self.contract.functions.channelExtend, channel_id, expiration) + + + def channel_extend_and_add_funds(self, account, channel_id, expiration, amount): + self._fund_escrow_account(account, amount) + return account.send_transaction(self.contract.functions.channelExtendAndAddFunds, channel_id, expiration, amount) + + def _fund_escrow_account(self, account, amount): + current_escrow_balance = self.balance(account.address) + if amount > current_escrow_balance: + account.deposit_to_escrow_account(amount - current_escrow_balance) diff --git a/snet_sdk/snet_sdk/payment_channel.py b/snet_sdk/snet_sdk/payment_channel.py new file mode 100644 index 00000000..87cdbd30 --- /dev/null +++ b/snet_sdk/snet_sdk/payment_channel.py @@ -0,0 +1,54 @@ +import web3 +from eth_account.messages import defunct_hash_message + +import snet_sdk.state_service_pb2 as state_service_pb2 + +class PaymentChannel: + def __init__(self, channel_id, w3, account, service, mpe_contract): + self.channel_id = channel_id + self.web3 = w3 + self.account = account + self.mpe_contract = mpe_contract + self.payment_channel_state_service_client = service.payment_channel_state_service_client + self.state = { + "nonce": 0, + "last_signed_amount": 0 + } + + + def add_funds(self, amount): + return self.mpe_contract.channel_add_funds(self.account, self.channel_id, amount) + + + def extend_expiration(self, expiration): + return self.mpe_contract.channel_extend(self.account, self.channel_id, expiration) + + + def extend_and_add_funds(self, expiration, amount): + return self.mpe_contract.channel_extend_and_add_funds(self.account, self.channel_id, expiration, amount) + + + def sync_state(self): + channel_blockchain_data = self.mpe_contract.contract.functions.channels(self.channel_id).call() + (current_nonce, last_signed_amount) = self._get_current_channel_state() + nonce = channel_blockchain_data[0] + total_amount = channel_blockchain_data[5] + expiration = channel_blockchain_data[6] + available_amount = total_amount - last_signed_amount + self.state = { + "current_nonce": current_nonce, + "last_signed_amount": last_signed_amount, + "nonce": nonce, + "total_amount": total_amount, + "expiration": expiration, + "available_amount": available_amount + } + + + def _get_current_channel_state(self): + stub = self.payment_channel_state_service_client + message = web3.Web3.soliditySha3(["uint256"], [self.channel_id]) + signature = self.web3.eth.account.signHash(defunct_hash_message(message), self.account.signer_private_key).signature + request = state_service_pb2.ChannelStateRequest(channel_id=web3.Web3.toBytes(self.channel_id), signature=bytes(signature)) + response = stub.GetChannelState(request) + return int.from_bytes(response.current_nonce, byteorder="big"), int.from_bytes(response.current_signed_amount, byteorder="big") diff --git a/snet_sdk/snet_sdk/payment_channel_management_strategies/__init__.py b/snet_sdk/snet_sdk/payment_channel_management_strategies/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py b/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py new file mode 100644 index 00000000..60147274 --- /dev/null +++ b/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py @@ -0,0 +1,45 @@ +class PaymentChannelManagementStrategy: + def __init__(self, sdk_context): + self.sdk_context = sdk_context + + def select_channel(self, service_client): + account = self.sdk_context.account + service_client.load_open_channels() + service_client.update_channel_states() + payment_channels = service_client.payment_channels + service_call_price = service_client.metadata.pricing["price_in_cogs"] + mpe_balance = account.escrow_balance() + default_expiration = service_client.default_channel_expiration() + + if len(payment_channels) == 0: + if mpe_balance > service_call_price: + return service_client.open_channel(service_call_price, default_expiration + self.sdk_context.block_offset) + return service_client.deposit_and_open_channel(service_call_price, default_expiration + self.sdk_context.block_offset) + + funded_valid_channels = [channel for channel in payment_channels if self._has_sufficient_funds(channel, service_call_price) and self._is_valid(channel, default_expiration)] + if len(funded_valid_channels): + return funded_valid_channels[0] + + funded_channels = [channel for channel in payment_channels if self._has_sufficient_funds(channel, service_call_price)] + if len(funded_channels): + funded_channels[0].extend_expiration(default_expiration + self.sdk_context.block_offset) + return funded_channels[0] + + valid_channels = [channel for channel in payment_channels if self._is_valid(channel, default_expiration)] + if len(valid_channels): + valid_channels[0].add_funds(service_call_price) + return valid_channels[0] + + first_expired_and_unfunded_channel = payment_channels[0] + first_expired_and_unfunded_channel.extend_and_add_funds(default_expiration + self.sdk_context.block_offset, service_call_price) + return first_expired_and_unfunded_channel + + + @staticmethod + def _has_sufficient_funds(channel, amount): + return channel.state["available_amount"] >= amount + + + @staticmethod + def _is_valid(channel, expiry): + return channel.state["expiration"] >= expiry diff --git a/snet_sdk/snet_sdk/resources/contracts/placeholder.txt b/snet_sdk/snet_sdk/resources/contracts/placeholder.txt new file mode 100644 index 00000000..e69de29b diff --git a/snet_sdk/snet_sdk/service_client.py b/snet_sdk/snet_sdk/service_client.py new file mode 100644 index 00000000..8039e369 --- /dev/null +++ b/snet_sdk/snet_sdk/service_client.py @@ -0,0 +1,127 @@ +import collections +import grpc +import web3 +from rfc3986 import urlparse +from eth_account.messages import defunct_hash_message + +import snet_sdk.generic_client_interceptor as generic_client_interceptor + +import snet_sdk.state_service_pb2_grpc as state_service_pb2_grpc + + +class _ClientCallDetails( + collections.namedtuple( + '_ClientCallDetails', + ('method', 'timeout', 'metadata', 'credentials')), + grpc.ClientCallDetails): + pass + + +class ServiceClient: + def __init__(self, sdk, metadata, group, service_stub, payment_channel_management_strategy, options): + self.sdk = sdk + self.options = options + self.group = group + self.metadata = metadata + self.payment_channel_management_strategy = payment_channel_management_strategy + self.payment_channel_state_service_client = self._generate_payment_channel_state_service_client() + self.expiry_threshold = self.metadata.payment_expiration_threshold + self.stub = self._generate_grpc_stub(service_stub) + self.payment_channels = [] + self.last_read_block = 0 + + + def _generate_grpc_stub(self, service_stub): + grpc_channel = self._get_grpc_channel() + disable_blockchain_operations = self.options.get("disable_blockchain_operations", False) + if disable_blockchain_operations is False: + grpc_channel = grpc.intercept_channel(grpc_channel, generic_client_interceptor.create(self._intercept_call)) + stub_instance = service_stub(grpc_channel) + return stub_instance + + + def _get_grpc_channel(self): + endpoint = self.options.get("endpoint", None) + if endpoint is None: + endpoint = next(filter(lambda endpoint: endpoint["group_name"] == self.group["group_name"], self.metadata["endpoints"]))["endpoint"] + endpoint_object = urlparse(endpoint) + if endpoint_object.port is not None: + channel_endpoint = endpoint_object.hostname + ":" + str(endpoint_object.port) + else: + channel_endpoint = endpoint_object.hostname + + if endpoint_object.scheme == "http": + return grpc.insecure_channel(channel_endpoint) + elif endpoint_object.scheme == "https": + return grpc.secure_channel(channel_endpoint, grpc.ssl_channel_credentials()) + else: + raise ValueError('Unsupported scheme in service metadata ("{}")'.format(endpoint_object.scheme)) + + + def _get_service_call_metadata(self): + channel = self.payment_channel_management_strategy.select_channel(self) + amount = channel.state["last_signed_amount"] + int(self.metadata.pricing["price_in_cogs"]) + message = web3.Web3.soliditySha3( + ["address", "uint256", "uint256", "uint256"], + [self.sdk.mpe_contract.contract.address, channel.channel_id, channel.state["nonce"], amount] + ) + signature = bytes(self.sdk.web3.eth.account.signHash(defunct_hash_message(message), self.sdk.account.signer_private_key).signature) + metadata = [ + ("snet-payment-type", "escrow"), + ("snet-payment-channel-id", str(channel.channel_id)), + ("snet-payment-channel-nonce", str(channel.state["nonce"])), + ("snet-payment-channel-amount", str(amount)), + ("snet-payment-channel-signature-bin", signature) + ] + return metadata + + + def _intercept_call(self, client_call_details, request_iterator, request_streaming, + response_streaming): + metadata = [] + if client_call_details.metadata is not None: + metadata = list(client_call_details.metadata) + metadata.extend(self._get_service_call_metadata()) + client_call_details = _ClientCallDetails( + client_call_details.method, client_call_details.timeout, metadata, + client_call_details.credentials) + return client_call_details, request_iterator, None + + + def load_open_channels(self): + current_block_number = self.sdk.web3.eth.getBlock("latest").number + new_payment_channels = self.sdk.mpe_contract.get_past_open_channels(self.sdk.account, self, self.last_read_block) + self.payment_channels = self.payment_channels + new_payment_channels + self.last_read_block = current_block_number + return self.payment_channels + + + def update_channel_states(self): + for channel in self.payment_channels: + channel.sync_state() + return self.payment_channels + + + def default_channel_expiration(self): + current_block_number = self.sdk.web3.eth.getBlock("latest").number + return current_block_number + self.expiry_threshold + + + def _generate_payment_channel_state_service_client(self): + grpc_channel = self._get_grpc_channel() + return state_service_pb2_grpc.PaymentChannelStateServiceStub(grpc_channel) + + + def open_channel(self, amount, expiration): + receipt = self.sdk.mpe_contract.open_channel(self.sdk.account, self, amount, expiration) + return self._get_newly_opened_channel(receipt) + + + def deposit_and_open_channel(self, amount, expiration): + receipt = self.sdk.mpe_contract.deposit_and_open_channel(self.sdk.account, self, amount, expiration) + return self._get_newly_opened_channel(receipt) + + + def _get_newly_opened_channel(self, receipt): + open_channels = self.sdk.mpe_contract.get_past_open_channels(self.sdk.account, self, receipt["blockNumber"], receipt["blockNumber"]) + return open_channels[0] diff --git a/snet_sdk/snet_sdk/state_service_pb2.py b/snet_sdk/snet_sdk/state_service_pb2.py new file mode 100644 index 00000000..bac2e3fa --- /dev/null +++ b/snet_sdk/snet_sdk/state_service_pb2.py @@ -0,0 +1,153 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: state_service.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='state_service.proto', + package='escrow', + syntax='proto3', + serialized_pb=_b('\n\x13state_service.proto\x12\x06\x65scrow\"<\n\x13\x43hannelStateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"d\n\x11\x43hannelStateReply\x12\x15\n\rcurrent_nonce\x18\x01 \x01(\x0c\x12\x1d\n\x15\x63urrent_signed_amount\x18\x02 \x01(\x0c\x12\x19\n\x11\x63urrent_signature\x18\x03 \x01(\x0c\x32i\n\x1aPaymentChannelStateService\x12K\n\x0fGetChannelState\x12\x1b.escrow.ChannelStateRequest\x1a\x19.escrow.ChannelStateReply\"\x00\x62\x06proto3') +) + + + + +_CHANNELSTATEREQUEST = _descriptor.Descriptor( + name='ChannelStateRequest', + full_name='escrow.ChannelStateRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='channel_id', full_name='escrow.ChannelStateRequest.channel_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='signature', full_name='escrow.ChannelStateRequest.signature', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=31, + serialized_end=91, +) + + +_CHANNELSTATEREPLY = _descriptor.Descriptor( + name='ChannelStateReply', + full_name='escrow.ChannelStateReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='current_nonce', full_name='escrow.ChannelStateReply.current_nonce', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='current_signed_amount', full_name='escrow.ChannelStateReply.current_signed_amount', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='current_signature', full_name='escrow.ChannelStateReply.current_signature', index=2, + number=3, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=93, + serialized_end=193, +) + +DESCRIPTOR.message_types_by_name['ChannelStateRequest'] = _CHANNELSTATEREQUEST +DESCRIPTOR.message_types_by_name['ChannelStateReply'] = _CHANNELSTATEREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +ChannelStateRequest = _reflection.GeneratedProtocolMessageType('ChannelStateRequest', (_message.Message,), dict( + DESCRIPTOR = _CHANNELSTATEREQUEST, + __module__ = 'state_service_pb2' + # @@protoc_insertion_point(class_scope:escrow.ChannelStateRequest) + )) +_sym_db.RegisterMessage(ChannelStateRequest) + +ChannelStateReply = _reflection.GeneratedProtocolMessageType('ChannelStateReply', (_message.Message,), dict( + DESCRIPTOR = _CHANNELSTATEREPLY, + __module__ = 'state_service_pb2' + # @@protoc_insertion_point(class_scope:escrow.ChannelStateReply) + )) +_sym_db.RegisterMessage(ChannelStateReply) + + + +_PAYMENTCHANNELSTATESERVICE = _descriptor.ServiceDescriptor( + name='PaymentChannelStateService', + full_name='escrow.PaymentChannelStateService', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=195, + serialized_end=300, + methods=[ + _descriptor.MethodDescriptor( + name='GetChannelState', + full_name='escrow.PaymentChannelStateService.GetChannelState', + index=0, + containing_service=None, + input_type=_CHANNELSTATEREQUEST, + output_type=_CHANNELSTATEREPLY, + options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_PAYMENTCHANNELSTATESERVICE) + +DESCRIPTOR.services_by_name['PaymentChannelStateService'] = _PAYMENTCHANNELSTATESERVICE + +# @@protoc_insertion_point(module_scope) diff --git a/snet_sdk/snet_sdk/state_service_pb2_grpc.py b/snet_sdk/snet_sdk/state_service_pb2_grpc.py new file mode 100644 index 00000000..bb7e8122 --- /dev/null +++ b/snet_sdk/snet_sdk/state_service_pb2_grpc.py @@ -0,0 +1,54 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import snet_sdk.state_service_pb2 as state__service__pb2 + + +class PaymentChannelStateServiceStub(object): + """PaymentChannelStateService contains methods to get the MultiPartyEscrow + payment channel state. + channel_id, channel_nonce, value and amount fields below in fact are + Solidity uint256 values. Which are big-endian integers padded by zeros, see + https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetChannelState = channel.unary_unary( + '/escrow.PaymentChannelStateService/GetChannelState', + request_serializer=state__service__pb2.ChannelStateRequest.SerializeToString, + response_deserializer=state__service__pb2.ChannelStateReply.FromString, + ) + + +class PaymentChannelStateServiceServicer(object): + """PaymentChannelStateService contains methods to get the MultiPartyEscrow + payment channel state. + channel_id, channel_nonce, value and amount fields below in fact are + Solidity uint256 values. Which are big-endian integers padded by zeros, see + https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding + """ + + def GetChannelState(self, request, context): + """GetChannelState method returns a channel state by channel id. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_PaymentChannelStateServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetChannelState': grpc.unary_unary_rpc_method_handler( + servicer.GetChannelState, + request_deserializer=state__service__pb2.ChannelStateRequest.FromString, + response_serializer=state__service__pb2.ChannelStateReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'escrow.PaymentChannelStateService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/snet_sdk/snet_sdk/utils.py b/snet_sdk/snet_sdk/utils.py new file mode 100644 index 00000000..5654523d --- /dev/null +++ b/snet_sdk/snet_sdk/utils.py @@ -0,0 +1,41 @@ +import os +import json +from pathlib import PurePath + +import web3 +import ecdsa +import hashlib + + +cur_dir = PurePath(os.path.realpath(__file__)).parent + + +def get_contract_object(w3, contract_file): + with open(cur_dir.joinpath("resources", "contracts", "abi", contract_file)) as f: + abi = json.load(f) + with open(cur_dir.joinpath("resources", "contracts", "networks", contract_file)) as f: + networks = json.load(f) + address = w3.toChecksumAddress(networks[w3.version.network]["address"]) + return w3.eth.contract(abi=abi, address=address) + + +def get_contract_deployment_block(w3, contract_file): + with open(cur_dir.joinpath("resources", "contracts", "networks", contract_file)) as f: + networks = json.load(f) + txn_hash = networks[w3.version.network]["transactionHash"] + return w3.eth.getTransactionReceipt(txn_hash).blockNumber + + +def normalize_private_key(private_key): + if private_key.startswith("0x"): + private_key = bytes(bytearray.fromhex(private_key[2:])) + else: + private_key = bytes(bytearray.fromhex(private_key)) + return private_key + + +def get_address_from_private(private_key): + public_key = ecdsa.SigningKey.from_string(string=private_key, + curve=ecdsa.SECP256k1, + hashfunc=hashlib.sha256).get_verifying_key() + return web3.Web3.toChecksumAddress("0x" + web3.Web3.sha3(hexstr=public_key.to_string().hex())[12:].hex()) diff --git a/test/utils/run_all_functional.sh b/test/utils/run_all_functional.sh deleted file mode 100755 index 72fe98b6..00000000 --- a/test/utils/run_all_functional.sh +++ /dev/null @@ -1,5 +0,0 @@ -for f in test/functional_tests/*.sh -do - bash -ex test/utils/reset_environment.sh --i-no-what-i-am-doing - bash -ex -c "cd test/functional_tests; bash -ex `basename $f`" -done From 45581ad23e3ecff849fc6bd6ec921f0916f3b554 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Wed, 5 Jun 2019 11:09:12 +0200 Subject: [PATCH 02/11] fix gitignore --- .gitignore | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 1621ffed..85af91f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,3 @@ -blockchain/node_modules/ -snet_cli/venv/ .idea/ -snet_cli/snet_cli.egg-info/ -snet_cli/snet_cli/resources/contracts/abi -snet_cli/snet_cli/resources/contracts/networks -snet_cli/snet_cli/resources/proto/*.py -snet_cli/snet_cli/resources/node_modules -snet_cli/build/ -snet_cli/dist/ - -snet_sdk/venv/ -snet_sdk/snet_sdk.egg-info/ __pycache__ -snet_sdk/snet_sdk/resources/contracts/abi -snet_sdk/snet_sdk/resources/contracts/networks -snet_sdk/build/ -snet_sdk/dist/ +blockchain/node_modules From 8c018f91d91218936fa2416dd39f52cf3ea3b1d4 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Thu, 23 May 2019 13:18:06 +0200 Subject: [PATCH 03/11] fix to setup.py to include contract jsons --- snet_sdk/setup.py | 3 ++- snet_sdk/snet_sdk/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/snet_sdk/setup.py b/snet_sdk/setup.py index 6e0530ff..1379a283 100644 --- a/snet_sdk/setup.py +++ b/snet_sdk/setup.py @@ -19,5 +19,6 @@ 'web3==4.2.1', 'ipfsapi==0.4.2.post1', 'rfc3986==1.1.0' - ] + ], + include_package_data=True ) diff --git a/snet_sdk/snet_sdk/__init__.py b/snet_sdk/snet_sdk/__init__.py index f1b69224..5b84d0d1 100644 --- a/snet_sdk/snet_sdk/__init__.py +++ b/snet_sdk/snet_sdk/__init__.py @@ -25,7 +25,7 @@ from snet_sdk.mpe_contract import MPEContract from snet_sdk.payment_channel_management_strategies.default import PaymentChannelManagementStrategy -__version__ = "0.0.1" +__version__ = "0.0.2" class SnetSDK: From 46bef8231892fb46648f73ff832de23b69050de2 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Thu, 23 May 2019 14:03:58 +0200 Subject: [PATCH 04/11] renamed stub object to service in service_client, exposing grpc channel with interceptor in service_client instance --- snet_sdk/snet_sdk/service_client.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/snet_sdk/snet_sdk/service_client.py b/snet_sdk/snet_sdk/service_client.py index 8039e369..3ed39c52 100644 --- a/snet_sdk/snet_sdk/service_client.py +++ b/snet_sdk/snet_sdk/service_client.py @@ -24,18 +24,20 @@ def __init__(self, sdk, metadata, group, service_stub, payment_channel_managemen self.group = group self.metadata = metadata self.payment_channel_management_strategy = payment_channel_management_strategy - self.payment_channel_state_service_client = self._generate_payment_channel_state_service_client() self.expiry_threshold = self.metadata.payment_expiration_threshold - self.stub = self._generate_grpc_stub(service_stub) + self._base_grpc_channel = self._get_grpc_channel() + self.grpc_channel = grpc.intercept_channel(self._base_grpc_channel, generic_client_interceptor.create(self._intercept_call)) + self.payment_channel_state_service_client = self._generate_payment_channel_state_service_client() + self.service = self._generate_grpc_stub(service_stub) self.payment_channels = [] self.last_read_block = 0 def _generate_grpc_stub(self, service_stub): - grpc_channel = self._get_grpc_channel() + grpc_channel = self._base_grpc_channel disable_blockchain_operations = self.options.get("disable_blockchain_operations", False) if disable_blockchain_operations is False: - grpc_channel = grpc.intercept_channel(grpc_channel, generic_client_interceptor.create(self._intercept_call)) + grpc_channel = self.grpc_channel stub_instance = service_stub(grpc_channel) return stub_instance @@ -108,7 +110,7 @@ def default_channel_expiration(self): def _generate_payment_channel_state_service_client(self): - grpc_channel = self._get_grpc_channel() + grpc_channel = self._base_grpc_channel return state_service_pb2_grpc.PaymentChannelStateServiceStub(grpc_channel) From 35325c6ea5865f5a8c7f528ecd16f5f15294060c Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Thu, 23 May 2019 15:11:35 +0200 Subject: [PATCH 05/11] Moved block_offset to payment channel strategy from config as an optional parameter Added call allowance to payment channel strategy as an optional parameter Split .gitignore to have a top level one and separate ones for each package Same for LICENSE Updated CLI README, added top-level README (sdk-specific is still in progress) --- README.md | 124 ++---------------- snet_cli/.gitignore | 7 + snet_cli/LICENSE | 21 +++ snet_cli/README.md | 124 ++++++++++++++++++ snet_sdk/.gitignore | 6 + snet_sdk/snet_sdk/__init__.py | 1 - .../default.py | 16 ++- 7 files changed, 176 insertions(+), 123 deletions(-) create mode 100644 snet_cli/.gitignore create mode 100644 snet_cli/LICENSE create mode 100644 snet_cli/README.md create mode 100644 snet_sdk/.gitignore diff --git a/README.md b/README.md index 4b025ec5..77976127 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,18 @@ -# snet-cli +# snet-python-monorepo [![CircleCI](https://circleci.com/gh/singnet/snet-cli.svg?style=svg)](https://circleci.com/gh/singnet/snet-cli) -SingularityNET CLI +SingularityNET Python Monorepo -## Getting Started +## Packages +This repository is a monorepo that includes several packages that we publish to PyPI from a shared codebase, specifically: -These instructions are for the development and use of the SingularityNET CLI. -For further details, please check our full [Documentation](http://snet-cli-docs.singularitynet.io/). +|Package |Description | +|----------------------------------------------|---------------------------------------------------------------------| +|[snet-cli](https://pypi.org/project/snet-cli/)|Command line interface to interact with the SingularityNET platform | +|[snet-sdk](https://pypi.org/project/snet-sdk/)|Integrate SingularityNET services seamlessly into Python applications| -### Installing with pip - -#### Install prerequisites - -You should have python with version >= 3.6.5 and pip installed. - -Additionally you should install the following packages: - -* libudev -* libusb 1.0 - -If you use Ubuntu (or any Linux distribution with APT package support) you should do the following: - -```bash -sudo apt-get install libudev-dev libusb-1.0-0-dev -``` - -#### Install snet-cli using pip - -```bash -$ pip3 install snet-cli -``` - - -#### Enabling commands autocomplete -If you want to enable auto completion of commands, you should install the following package -* python-argcomplete - -On ubuntu (or any Linux distribution with APT package support), you should do the following - -```bash -sudo apt install python-argcomplete -``` -After the package is installed, activate autocomplete - -##### for all python commands (which includes snet commands as well) - -```bash -sudo activate-global-python-argcomplete -``` -Note: Changes will not take effect until shell is restarted. - -##### only for snet commands, then you should do the following -```bash -echo 'eval "$(register-python-argcomplete snet)"' >> ~/.bashrc -``` -then -```bash -source ~/.bashrc -``` - -## Commands - -Complete documentation is available [here](http://snet-cli-docs.singularitynet.io/) - - -## Development - -### Installing - -#### Prerequisites - -* [Python 3.6.5](https://www.python.org/downloads/release/python-365/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) - ---- - -* Clone the git repository -```bash -$ git clone git@github.com:singnet/snet-cli.git -$ cd snet-cli -``` - -* Install development/test blockchain dependencies -```bash -$ ./scripts/blockchain install -``` - -* Install the package in development/editable mode -```bash -$ pip3 install -e . -``` - -#### Building Docs - -* Install sphinx, sphinx-argparse and the rtd theme -```bash -$ pip install sphinx -$ pip install sphinx-argparse -$ pip install sphinx-rtd-theme -``` - -* Run the build-docs.sh in the docs directory -```bash -$ cd docs -$ sh build-docs.sh -``` - -The documentation is generated under the docs/build/html folder - -### Release - -This project is published to [PyPI](https://pypi.org/project/snet-cli/). - -### Versioning - -We use [SemVer](http://semver.org/) for versioning. For the versions available, see the -[tags on this repository](https://github.com/singnet/snet-cli/tags). - ## License This project is licensed under the MIT License - see the -[LICENSE](https://github.com/singnet/alpha-daemon/blob/master/LICENSE) file for details. +[LICENSE](https://github.com/singnet/snet-cli/blob/master/LICENSE) file for details. diff --git a/snet_cli/.gitignore b/snet_cli/.gitignore new file mode 100644 index 00000000..3e31273b --- /dev/null +++ b/snet_cli/.gitignore @@ -0,0 +1,7 @@ +venv/ +snet_cli.egg-info/ +snet_cli/resources/contracts/abi +snet_cli/resources/contracts/networks +snet_cli/resources/proto/*.py +build/ +dist/ diff --git a/snet_cli/LICENSE b/snet_cli/LICENSE new file mode 100644 index 00000000..c674cd51 --- /dev/null +++ b/snet_cli/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 SingularityNET + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/snet_cli/README.md b/snet_cli/README.md new file mode 100644 index 00000000..c9bd46b4 --- /dev/null +++ b/snet_cli/README.md @@ -0,0 +1,124 @@ +# snet-cli + +[![CircleCI](https://circleci.com/gh/singnet/snet-cli.svg?style=svg)](https://circleci.com/gh/singnet/snet-cli) + +SingularityNET CLI + +## Getting Started + +These instructions are for the development and use of the SingularityNET CLI. +For further details, please check our full [Documentation](http://snet-cli-docs.singularitynet.io/). + +### Installing with pip + +#### Install prerequisites + +You should have python with version >= 3.6.5 and pip installed. + +Additionally you should install the following packages: + +* libudev +* libusb 1.0 + +If you use Ubuntu (or any Linux distribution with APT package support) you should do the following: + +```bash +sudo apt-get install libudev-dev libusb-1.0-0-dev +``` + +#### Install snet-cli using pip + +```bash +$ pip3 install snet-cli +``` + + +#### Enabling commands autocomplete +If you want to enable auto completion of commands, you should install the following package +* python-argcomplete + +On ubuntu (or any Linux distribution with APT package support), you should do the following + +```bash +sudo apt install python-argcomplete +``` +After the package is installed, activate autocomplete + +##### for all python commands (which includes snet commands as well) + +```bash +sudo activate-global-python-argcomplete +``` +Note: Changes will not take effect until shell is restarted. + +##### only for snet commands, then you should do the following +```bash +echo 'eval "$(register-python-argcomplete snet)"' >> ~/.bashrc +``` +then +```bash +source ~/.bashrc +``` + +## Commands + +Complete documentation is available [here](http://snet-cli-docs.singularitynet.io/) + + +## Development + +### Installing + +#### Prerequisites + +* [Python 3.6.5](https://www.python.org/downloads/release/python-365/) +* [Node 8+ w/npm](https://nodejs.org/en/download/) + +--- + +* Clone the git repository +```bash +$ git clone git@github.com:singnet/snet-cli.git +$ cd snet-cli/snet_cli +``` + +* Install development/test blockchain dependencies +```bash +$ ./scripts/blockchain install +``` + +* Install the package in development/editable mode +```bash +$ pip3 install -e . +``` + +#### Building Docs + +* Install sphinx, sphinx-argparse and the rtd theme +```bash +$ pip install sphinx +$ pip install sphinx-argparse +$ pip install sphinx-rtd-theme +``` + +* Run the build-docs.sh in the docs directory +```bash +$ cd docs +$ sh build-docs.sh +``` + +The documentation is generated under the docs/build/html folder + +### Release + +This project is published to [PyPI](https://pypi.org/project/snet-cli/). + +### Versioning + +We use [SemVer](http://semver.org/) for versioning. For the versions available, see the +[tags on this repository](https://github.com/singnet/snet-cli/tags). + +## License + +This project is licensed under the MIT License - see the +[LICENSE](https://github.com/singnet/alpha-daemon/blob/master/LICENSE) file for details. diff --git a/snet_sdk/.gitignore b/snet_sdk/.gitignore new file mode 100644 index 00000000..bbdffa01 --- /dev/null +++ b/snet_sdk/.gitignore @@ -0,0 +1,6 @@ +venv/ +snet_sdk.egg-info/ +snet_sdk/resources/contracts/abi +snet_sdk/resources/contracts/networks +build/ +dist/ diff --git a/snet_sdk/snet_sdk/__init__.py b/snet_sdk/snet_sdk/__init__.py index 5b84d0d1..b780ec27 100644 --- a/snet_sdk/snet_sdk/__init__.py +++ b/snet_sdk/snet_sdk/__init__.py @@ -54,7 +54,6 @@ def __init__( self.registry_contract = get_contract_object(self.web3, "Registry.json") self.account = Account(self.web3, config, self.mpe_contract) - self.block_offset = self._config.get("block_offset", 604800) def create_service_client(self, org_id, service_id, service_stub, group_name="default_group", payment_channel_management_strategy=PaymentChannelManagementStrategy, options={}): service_metadata = self.service_metadata(org_id, service_id) diff --git a/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py b/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py index 60147274..56b5ff99 100644 --- a/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py +++ b/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py @@ -1,6 +1,8 @@ class PaymentChannelManagementStrategy: - def __init__(self, sdk_context): + def __init__(self, sdk_context, block_offset=0, call_allowance=1): self.sdk_context = sdk_context + self.block_offset = block_offset + self.call_allowance = call_allowance def select_channel(self, service_client): account = self.sdk_context.account @@ -12,9 +14,9 @@ def select_channel(self, service_client): default_expiration = service_client.default_channel_expiration() if len(payment_channels) == 0: - if mpe_balance > service_call_price: - return service_client.open_channel(service_call_price, default_expiration + self.sdk_context.block_offset) - return service_client.deposit_and_open_channel(service_call_price, default_expiration + self.sdk_context.block_offset) + if mpe_balance > service_call_price*self.call_allowance: + return service_client.open_channel(service_call_price*self.call_allowance, default_expiration + self.block_offset) + return service_client.deposit_and_open_channel(service_call_price*self.call_allowance - mpe_balance, default_expiration + self.block_offset) funded_valid_channels = [channel for channel in payment_channels if self._has_sufficient_funds(channel, service_call_price) and self._is_valid(channel, default_expiration)] if len(funded_valid_channels): @@ -22,16 +24,16 @@ def select_channel(self, service_client): funded_channels = [channel for channel in payment_channels if self._has_sufficient_funds(channel, service_call_price)] if len(funded_channels): - funded_channels[0].extend_expiration(default_expiration + self.sdk_context.block_offset) + funded_channels[0].extend_expiration(default_expiration + self.block_offset) return funded_channels[0] valid_channels = [channel for channel in payment_channels if self._is_valid(channel, default_expiration)] if len(valid_channels): - valid_channels[0].add_funds(service_call_price) + valid_channels[0].add_funds(service_call_price*self.call_allowance) return valid_channels[0] first_expired_and_unfunded_channel = payment_channels[0] - first_expired_and_unfunded_channel.extend_and_add_funds(default_expiration + self.sdk_context.block_offset, service_call_price) + first_expired_and_unfunded_channel.extend_and_add_funds(default_expiration + self.block_offset, service_call_price*self.call_allowance) return first_expired_and_unfunded_channel From 96633a4a44ac615b474da04af36c4779df8960fa Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Thu, 23 May 2019 16:26:52 +0200 Subject: [PATCH 06/11] updated readme for SDK, fixed a link in the CLI readme --- snet_cli/README.md | 2 +- snet_sdk/README.md | 82 ++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/snet_cli/README.md b/snet_cli/README.md index c9bd46b4..d3401870 100644 --- a/snet_cli/README.md +++ b/snet_cli/README.md @@ -121,4 +121,4 @@ We use [SemVer](http://semver.org/) for versioning. For the versions available, ## License This project is licensed under the MIT License - see the -[LICENSE](https://github.com/singnet/alpha-daemon/blob/master/LICENSE) file for details. +[LICENSE](https://github.com/singnet/snet-cli/blob/master/snet_cli/LICENSE) file for details. diff --git a/snet_sdk/README.md b/snet_sdk/README.md index 4d2cb275..66cf47da 100644 --- a/snet_sdk/README.md +++ b/snet_sdk/README.md @@ -6,56 +6,68 @@ SingularityNET SDK for Python These instructions are for the development and use of the SingularityNET SDK for Python. -### Usage +### Core concepts + +The SingularityNET SDK allows you to make calls to SingularityNET services programmatically from your application. +To communicate between clients and services, SingularityNET uses [gRPC](https://grpc.io/). +To handle payment of services, SingularityNET uses [Ethereum state channels](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/). +The SingularityNET SDK abstracts and manages state channels with service providers on behalf of the user and handles authentication with the SingularityNET services. -The SingularityNET SDK allows you to import compiled client libraries for your service or services or choice and make calls to those services programmatically from your application by setting up state channels with the providers of those services and making gRPC calls to the SingularityNET daemons for those services by selecting a channel with sufficient funding and supplying the appropriate metadata for authentication. +### Usage -Once you have installed the snet-sdk in your current environment and it's in your PYTHONPATH, you should import it and create an instance of the base sdk class: +To call a SingularityNET service, the user must be able to deposit funds (AGI tokens) to the [Multi-Party Escrow](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/) Smart Contract. +To deposit these tokens or do any other transaction on the Ethereum blockchain, the user must possess an Ethereum identity with available Ether. -```python -from snet_sdk import Snet -import config -snet = Snet(private_key=config.private_key) -``` -Now, the instance of the sdk can be used to instantiate clients for SingularityNET services. To interact with those services, the sdk needs to be supplied the compiled client libraries and a reference to their path on your file system. - -To generate the client libraries, you need the SingularityNET Command Line Interface, or CLI, which you can download from PyPi, see [https://github.com/singnet/snet-cli#installing-with-pip](https://github.com/singnet/snet-cli#installing-with-pip) +To interact with SingularityNET services, you must compile the appropriate client libraries for that service. +To generate the client libraries to use in your application, you need the SingularityNET Command Line Interface, or CLI, which you can download from PyPi, see [https://github.com/singnet/snet-cli#installing-with-pip](https://github.com/singnet/snet-cli/snet_cli#installing-with-pip) Once you have the CLI installed, run the following command: ```bash snet sdk generate-client-library python ``` -Optionally, you can specify an output path; otherwise it's going to be `./client_libraries/python//` +Optionally, you can specify an output path; otherwise it's going to be `./client_libraries/python///`. +You should move or copy these generated files to the root of your project. -Now, by default the sdk is going to look for those client libraries in the `./grpc//` in the directory of the main process of the module it's being imported by. - -Once you have the generated client libraries in place, you can create an instance of a SingularityNET service client: +Once you have installed the snet-sdk in your current environment and it's in your PYTHONPATH, you should import it and create an instance of the base sdk class: + ```python -client = snet.client("", "") +from snet_sdk import SnetSDK +from config import config +snet = SnetSDK(config) ``` -The client exposes the following properties and methods: -- All of the modules from the generated client library as `client.grpc. Date: Wed, 5 Jun 2019 11:25:32 +0200 Subject: [PATCH 07/11] removed unused imports, moved version, removed unused resources from manifest --- snet_sdk/MANIFEST.in | 1 - snet_sdk/setup.py | 10 ++++++---- snet_sdk/snet_sdk/__init__.py | 15 +-------------- snet_sdk/snet_sdk/version.py | 1 + 4 files changed, 8 insertions(+), 19 deletions(-) create mode 100644 snet_sdk/snet_sdk/version.py diff --git a/snet_sdk/MANIFEST.in b/snet_sdk/MANIFEST.in index 5f2a16ee..03b788b6 100644 --- a/snet_sdk/MANIFEST.in +++ b/snet_sdk/MANIFEST.in @@ -1,3 +1,2 @@ -include snet_sdk/resources/proto/* include snet_sdk/resources/contracts/abi/* include snet_sdk/resources/contracts/networks/* diff --git a/snet_sdk/setup.py b/snet_sdk/setup.py index 1379a283..e81f6706 100644 --- a/snet_sdk/setup.py +++ b/snet_sdk/setup.py @@ -1,18 +1,20 @@ from setuptools import setup, find_packages import re -with open('snet_sdk/__init__.py', 'rt', encoding='utf8') as f: - version = re.search(r'__version__ = "(.*?)"', f.read()).group(1) +version_dict = {} +with open("./snet_sdk/version.py") as fp: + exec(fp.read(), version_dict) setup( name='snet_sdk', - version=version, + version=version_dict['__version__'], packages=find_packages(), - url='https://github.com/singnet/snet-sdk-python', + url='https://github.com/singnet/snet-cli/tree/master/snet_sdk', license='MIT', author='SingularityNET Foundation', author_email='info@singularitynet.io', description='SingularityNET Python SDK', + python_requires='>=3.6', install_requires=[ 'grpcio-tools==1.17.1', 'ecdsa==0.13', diff --git a/snet_sdk/snet_sdk/__init__.py b/snet_sdk/snet_sdk/__init__.py index b780ec27..5837883f 100644 --- a/snet_sdk/snet_sdk/__init__.py +++ b/snet_sdk/snet_sdk/__init__.py @@ -1,23 +1,12 @@ -import operator -from functools import reduce -import sys -import os -import importlib import json import base64 -from pathlib import PurePath, Path from urllib.parse import urljoin -import hashlib -import collections import web3 from web3.gas_strategies.rpc import rpc_gas_price_strategy -from eth_account.messages import defunct_hash_message from rfc3986 import urlparse import ipfsapi -from web3.utils.datastructures import AttributeDict, MutableAttributeDict - -import snet_sdk.generic_client_interceptor as generic_client_interceptor +from web3.utils.datastructures import AttributeDict from snet_sdk.utils import get_contract_object from snet_sdk.service_client import ServiceClient @@ -25,8 +14,6 @@ from snet_sdk.mpe_contract import MPEContract from snet_sdk.payment_channel_management_strategies.default import PaymentChannelManagementStrategy -__version__ = "0.0.2" - class SnetSDK: """Base Snet SDK""" diff --git a/snet_sdk/snet_sdk/version.py b/snet_sdk/snet_sdk/version.py new file mode 100644 index 00000000..ae736254 --- /dev/null +++ b/snet_sdk/snet_sdk/version.py @@ -0,0 +1 @@ +__version__ = "0.1.3" From 63e2a0a7ebc763f52404b783ec4d508b74be8fd1 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Sat, 8 Jun 2019 02:50:37 +0200 Subject: [PATCH 08/11] Set up monorepo: this monorepo is organized as a PEP 420 compliant namespace (https://www.python.org/dev/peps/pep-0420/). The sdk package has been restructured to conform to the PEP 420 namespace package specification and it's under the "snet" namespace. The cli package is both a regular package and a namespace package. setup.py for the monorepo itself installs the dependencies for all packages in the repository. Each package and the overarching monorepo also have "requirements.txt" files for local installations and CI enviroments: by installing via "requirements.txt", the dependencies listed in "setup.py" are only pulled and installed from PyPI if a local version is not already available. This allows to get dependencies within the monorepo to be installed from the local filesystem. The whole package is called "snet" and gives the name to the namespace. The subpackages are "snet.sdk", "snet.snet_cli" and snet_cli (since the CLI package is both within the namespace and a regular package). Going forward, all of the code in the "snet_cli" package can be migrated to the namespace package: both were kept momentarily for compatibility. In this scenario, everything inside the "snet.sdk" package has visibility on the contents of the "snet.snet_cli" package and vice-versa. Everything inside the "snet_cli" regular package has visibility on the contents of the "snet.snet_cli" package due to the regular Python import mechanics, but it has no visibility on the contents of the "snet.sdk" package (and vice-versa). So, the shared code between the SDK and the CLI goes under the "snet.snet_cli" package which is at "packages/snet_cli/snet/snet_cli". Code and assets deduplication: thanks to the new structure, everything under "resources" has been moved to the "snet.snet_cli" package and is now shared between the SDK and CLI. Specifically, this includes the json artifacts from the compilation and deployment of the smart contracts, the raw ".proto" files to interact with the daemon and the compiled python client libraries. Changes: since the CLI is both a namespace package and a regular package, changes to the code have been kept to a minimum. The only change of note is that state service does not compile its own ".proto" files at runtime inside the user's home directory anymore but they are imported from the "resources" directory under the "snet.snet_cli" namespace package, where they are compiled during setup. --- .circleci/config.yml | 8 +- .gitignore | 2 + packages/sdk/.gitignore | 4 + {snet_cli => packages/sdk}/LICENSE | 0 {snet_sdk => packages/sdk}/README.md | 0 packages/sdk/requirements.txt | 3 + .../sdk}/scripts/package-pip | 0 packages/sdk/setup.py | 43 +++++ .../sdk/snet/sdk}/__init__.py | 13 +- .../sdk/snet/sdk}/account.py | 2 +- .../snet/sdk}/generic_client_interceptor.py | 0 .../sdk/snet/sdk}/mpe_contract.py | 6 +- .../sdk/snet/sdk}/payment_channel.py | 5 +- .../__init__.py | 0 .../default.py | 0 .../sdk/snet/sdk}/service_client.py | 9 +- packages/sdk/snet/sdk/version.py | 1 + packages/snet_cli/.gitignore | 8 + {snet_sdk => packages/snet_cli}/LICENSE | 0 packages/snet_cli/MANIFEST.in | 11 ++ {snet_cli => packages/snet_cli}/README.md | 0 {snet_cli => packages/snet_cli}/docs/Makefile | 0 .../snet_cli}/docs/build-docs.sh | 0 .../snet_cli}/docs/source/conf.py | 0 .../snet_cli}/docs/source/generate_rst.py | 0 .../docs/source/img/singularityNET.png | Bin .../snet_cli}/docs/source/index_template.tpl | 0 .../docs/source/snet-cli-static/theme.css | 0 .../docs/source/subcommand_template.tpl | 0 packages/snet_cli/requirements.txt | 2 + .../snet_cli}/scripts/blockchain | 5 +- .../snet_cli}/scripts/package-pip | 0 {snet_cli => packages/snet_cli}/setup.py | 13 +- .../snet_cli/snet/snet_cli}/__init__.py | 0 .../resources/contracts/placeholder.txt | 0 .../snet/snet_cli}/resources/package.json | 0 .../resources/proto/control_service.proto | 0 .../snet_cli/resources/proto/merckledag.proto | 0 .../resources/proto/state_service.proto | 0 .../snet_cli/resources/proto/unixfs.proto | 0 .../snet_cli/snet}/snet_cli/utils.py | 56 ++++++- .../snet_cli/snet}/snet_cli/utils_proto.py | 0 .../snet_cli}/snet_cli/__init__.py | 1 + .../snet_cli/snet_cli/_vendor/__init__.py | 0 .../_vendor/ledgerblue/BlueHSMServer_pb2.py | 0 .../snet_cli/_vendor/ledgerblue/Dongle.py | 0 .../snet_cli/_vendor/ledgerblue/__init__.py | 0 .../_vendor/ledgerblue/checkGenuine.py | 0 .../snet_cli/_vendor/ledgerblue/comm.py | 0 .../_vendor/ledgerblue/commException.py | 0 .../snet_cli/_vendor/ledgerblue/commHTTP.py | 0 .../snet_cli/_vendor/ledgerblue/commU2F.py | 0 .../snet_cli/_vendor/ledgerblue/deleteApp.py | 0 .../snet_cli/_vendor/ledgerblue/deployed.py | 0 .../_vendor/ledgerblue/derivePassphrase.py | 0 .../snet_cli/_vendor/ledgerblue/ecWrapper.py | 0 .../_vendor/ledgerblue/endorsementSetup.py | 0 .../ledgerblue/endorsementSetupLedger.py | 0 .../snet_cli/_vendor/ledgerblue/genCAPair.py | 0 .../snet_cli/_vendor/ledgerblue/getMemInfo.py | 0 .../snet_cli/_vendor/ledgerblue/hashApp.py | 0 .../snet_cli/_vendor/ledgerblue/hexLoader.py | 0 .../snet_cli/_vendor/ledgerblue/hexParser.py | 0 .../_vendor/ledgerblue/hostOnboard.py | 0 .../_vendor/ledgerblue/ledgerWrapper.py | 0 .../snet_cli/_vendor/ledgerblue/listApps.py | 0 .../snet_cli/_vendor/ledgerblue/loadApp.py | 0 .../snet_cli/_vendor/ledgerblue/loadMCU.py | 0 .../_vendor/ledgerblue/mcuBootloader.py | 0 .../_vendor/ledgerblue/resetCustomCA.py | 0 .../snet_cli/_vendor/ledgerblue/runApp.py | 0 .../snet_cli/_vendor/ledgerblue/runScript.py | 0 .../_vendor/ledgerblue/setupCustomCA.py | 0 .../snet_cli/_vendor/ledgerblue/signApp.py | 0 .../_vendor/ledgerblue/updateFirmware.py | 0 .../snet_cli/_vendor/ledgerblue/verifyApp.py | 0 .../_vendor/ledgerblue/verifyEndorsement1.py | 0 .../_vendor/ledgerblue/verifyEndorsement2.py | 0 .../snet_cli}/snet_cli/arguments.py | 5 +- .../snet_cli}/snet_cli/commands.py | 15 +- .../snet_cli}/snet_cli/config.py | 0 .../snet_cli}/snet_cli/contract.py | 0 .../snet_cli}/snet_cli/identity.py | 15 +- .../snet_cli}/snet_cli/mpe_account_command.py | 0 .../snet_cli}/snet_cli/mpe_channel_command.py | 18 ++- .../snet_cli}/snet_cli/mpe_client_command.py | 17 +- .../snet_cli}/snet_cli/mpe_service_command.py | 17 +- .../snet_cli/mpe_service_metadata.py | 3 +- .../snet_cli/mpe_treasurer_command.py | 14 +- .../snet_cli}/snet_cli/sdk_command.py | 5 +- .../snet_cli}/snet_cli/utils_agi2cogs.py | 0 .../snet_cli}/snet_cli/utils_config.py | 2 +- .../snet_cli}/snet_cli/utils_ipfs.py | 4 +- .../snet_cli}/snet_cli/version.py | 0 .../snet_cli}/test/README.md | 0 .../script10_claim_timeout_all.sh | 0 .../script11_update_metadata.sh | 0 .../script12_extend_add_for_service.sh | 0 .../script13_call_reinitialize.sh | 0 .../script15_sdk_generate_client_library.sh | 0 .../functional_tests/script1_twogroups.sh | 0 .../script2_deposit_transfer.sh | 0 .../script3_without_addresses.sh | 2 +- .../script4_only_with_networks.sh | 14 +- .../script5_identity1_rpc_mnemonic.sh | 0 .../functional_tests/script6_organization.sh | 0 .../functional_tests/script7_contracts.sh | 0 .../test/functional_tests/script8_networks.sh | 0 .../functional_tests/script9_treasurer.sh | 0 .../service_spec1/ExampleService.proto | 0 .../simple_daemon/test_simple_daemon.py | 8 +- .../unit_tests/test_mpe_service_metadata_1.py | 0 .../snet_cli}/test/utils/reset_environment.sh | 2 +- .../snet_cli/test/utils/run_all_functional.sh | 5 + requirements.txt | 4 + setup.py | 53 ++++++ snet_cli/.gitignore | 7 - snet_cli/MANIFEST.in | 5 - snet_cli/scripts/blockchain | 55 ------- snet_cli/test/utils/run_all_functional.sh | 5 - snet_sdk/.gitignore | 6 - snet_sdk/MANIFEST.in | 2 - snet_sdk/blockchain/package.json | 6 - snet_sdk/setup.py | 26 --- snet_sdk/snet_sdk/contract.py | 27 ---- snet_sdk/snet_sdk/state_service_pb2.py | 153 ------------------ snet_sdk/snet_sdk/state_service_pb2_grpc.py | 54 ------- snet_sdk/snet_sdk/utils.py | 41 ----- snet_sdk/snet_sdk/version.py | 1 - 129 files changed, 298 insertions(+), 485 deletions(-) create mode 100644 packages/sdk/.gitignore rename {snet_cli => packages/sdk}/LICENSE (100%) rename {snet_sdk => packages/sdk}/README.md (100%) create mode 100644 packages/sdk/requirements.txt rename {snet_cli => packages/sdk}/scripts/package-pip (100%) create mode 100644 packages/sdk/setup.py rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/__init__.py (88%) rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/account.py (96%) rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/generic_client_interceptor.py (100%) rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/mpe_contract.py (96%) rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/payment_channel.py (91%) rename {snet_cli/snet_cli/_vendor => packages/sdk/snet/sdk/payment_channel_management_strategies}/__init__.py (100%) rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/payment_channel_management_strategies/default.py (100%) rename {snet_sdk/snet_sdk => packages/sdk/snet/sdk}/service_client.py (94%) create mode 100644 packages/sdk/snet/sdk/version.py create mode 100644 packages/snet_cli/.gitignore rename {snet_sdk => packages/snet_cli}/LICENSE (100%) create mode 100644 packages/snet_cli/MANIFEST.in rename {snet_cli => packages/snet_cli}/README.md (100%) rename {snet_cli => packages/snet_cli}/docs/Makefile (100%) rename {snet_cli => packages/snet_cli}/docs/build-docs.sh (100%) rename {snet_cli => packages/snet_cli}/docs/source/conf.py (100%) rename {snet_cli => packages/snet_cli}/docs/source/generate_rst.py (100%) rename {snet_cli => packages/snet_cli}/docs/source/img/singularityNET.png (100%) rename {snet_cli => packages/snet_cli}/docs/source/index_template.tpl (100%) rename {snet_cli => packages/snet_cli}/docs/source/snet-cli-static/theme.css (100%) rename {snet_cli => packages/snet_cli}/docs/source/subcommand_template.tpl (100%) create mode 100644 packages/snet_cli/requirements.txt rename {snet_sdk => packages/snet_cli}/scripts/blockchain (90%) rename {snet_sdk => packages/snet_cli}/scripts/package-pip (100%) rename {snet_cli => packages/snet_cli}/setup.py (82%) rename {snet_sdk/snet_sdk/payment_channel_management_strategies => packages/snet_cli/snet/snet_cli}/__init__.py (100%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/resources/contracts/placeholder.txt (100%) rename {snet_cli => packages/snet_cli/snet/snet_cli}/resources/package.json (100%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/resources/proto/control_service.proto (100%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/resources/proto/merckledag.proto (100%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/resources/proto/state_service.proto (100%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/resources/proto/unixfs.proto (100%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/utils.py (80%) rename {snet_cli => packages/snet_cli/snet}/snet_cli/utils_proto.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/__init__.py (99%) rename snet_sdk/snet_sdk/resources/contracts/placeholder.txt => packages/snet_cli/snet_cli/_vendor/__init__.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/Dongle.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/__init__.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/checkGenuine.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/comm.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/commException.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/commHTTP.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/commU2F.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/deleteApp.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/deployed.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/derivePassphrase.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/ecWrapper.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/endorsementSetup.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/genCAPair.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/getMemInfo.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/hashApp.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/hexLoader.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/hexParser.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/hostOnboard.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/ledgerWrapper.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/listApps.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/loadApp.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/loadMCU.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/mcuBootloader.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/resetCustomCA.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/runApp.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/runScript.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/setupCustomCA.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/signApp.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/updateFirmware.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/verifyApp.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/arguments.py (99%) rename {snet_cli => packages/snet_cli}/snet_cli/commands.py (99%) rename {snet_cli => packages/snet_cli}/snet_cli/config.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/contract.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/identity.py (97%) rename {snet_cli => packages/snet_cli}/snet_cli/mpe_account_command.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/mpe_channel_command.py (99%) rename {snet_cli => packages/snet_cli}/snet_cli/mpe_client_command.py (95%) rename {snet_cli => packages/snet_cli}/snet_cli/mpe_service_command.py (99%) rename {snet_cli => packages/snet_cli}/snet_cli/mpe_service_metadata.py (99%) rename {snet_cli => packages/snet_cli}/snet_cli/mpe_treasurer_command.py (97%) rename {snet_cli => packages/snet_cli}/snet_cli/sdk_command.py (95%) rename {snet_cli => packages/snet_cli}/snet_cli/utils_agi2cogs.py (100%) rename {snet_cli => packages/snet_cli}/snet_cli/utils_config.py (98%) rename {snet_cli => packages/snet_cli}/snet_cli/utils_ipfs.py (96%) rename {snet_cli => packages/snet_cli}/snet_cli/version.py (100%) rename {snet_cli => packages/snet_cli}/test/README.md (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script10_claim_timeout_all.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script11_update_metadata.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script12_extend_add_for_service.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script13_call_reinitialize.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script15_sdk_generate_client_library.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script1_twogroups.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script2_deposit_transfer.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script3_without_addresses.sh (98%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script4_only_with_networks.sh (90%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script5_identity1_rpc_mnemonic.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script6_organization.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script7_contracts.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script8_networks.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/script9_treasurer.sh (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/service_spec1/ExampleService.proto (100%) rename {snet_cli => packages/snet_cli}/test/functional_tests/simple_daemon/test_simple_daemon.py (95%) rename {snet_cli => packages/snet_cli}/test/unit_tests/test_mpe_service_metadata_1.py (100%) rename {snet_cli => packages/snet_cli}/test/utils/reset_environment.sh (98%) create mode 100755 packages/snet_cli/test/utils/run_all_functional.sh create mode 100644 requirements.txt create mode 100644 setup.py delete mode 100644 snet_cli/.gitignore delete mode 100644 snet_cli/MANIFEST.in delete mode 100755 snet_cli/scripts/blockchain delete mode 100755 snet_cli/test/utils/run_all_functional.sh delete mode 100644 snet_sdk/.gitignore delete mode 100644 snet_sdk/MANIFEST.in delete mode 100644 snet_sdk/blockchain/package.json delete mode 100644 snet_sdk/setup.py delete mode 100644 snet_sdk/snet_sdk/contract.py delete mode 100644 snet_sdk/snet_sdk/state_service_pb2.py delete mode 100644 snet_sdk/snet_sdk/state_service_pb2_grpc.py delete mode 100644 snet_sdk/snet_sdk/utils.py delete mode 100644 snet_sdk/snet_sdk/version.py diff --git a/.circleci/config.yml b/.circleci/config.yml index a18ffc1c..023b98d1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,13 +21,13 @@ jobs: - run: name: Install snet-cli command: | - ./snet_cli/scripts/blockchain install - sudo pip3 install -e ./snet_cli + ./packages/snet_cli/scripts/blockchain install + sudo pip3 install -e ./packages/snet_cli - run: name: Install platform-contracts from master command: | # Install platform-contracts (from master) - # we will deploy contracts from snet_cli/test/utils/reset_enviroment.sh + # we will deploy contracts from packages/snet_cli/test/utils/reset_enviroment.sh cd .. git clone https://github.com/singnet/platform-contracts cd platform-contracts @@ -42,7 +42,7 @@ jobs: - run: name: Functional tests command: | - bash -ex snet_cli/test/utils/run_all_functional.sh + bash -ex packages/snet_cli/test/utils/run_all_functional.sh - run: name: Trigger platform-pipeline build command: | diff --git a/.gitignore b/.gitignore index 85af91f3..101f0af2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +venv/ .idea/ __pycache__ blockchain/node_modules +snet.egg-info/ diff --git a/packages/sdk/.gitignore b/packages/sdk/.gitignore new file mode 100644 index 00000000..674694bb --- /dev/null +++ b/packages/sdk/.gitignore @@ -0,0 +1,4 @@ +venv/ +snet.sdk.egg-info/ +build/ +dist/ diff --git a/snet_cli/LICENSE b/packages/sdk/LICENSE similarity index 100% rename from snet_cli/LICENSE rename to packages/sdk/LICENSE diff --git a/snet_sdk/README.md b/packages/sdk/README.md similarity index 100% rename from snet_sdk/README.md rename to packages/sdk/README.md diff --git a/packages/sdk/requirements.txt b/packages/sdk/requirements.txt new file mode 100644 index 00000000..63cab9eb --- /dev/null +++ b/packages/sdk/requirements.txt @@ -0,0 +1,3 @@ +--index-url https://pypi.python.org/simple +../snet_cli/ +-e . diff --git a/snet_cli/scripts/package-pip b/packages/sdk/scripts/package-pip similarity index 100% rename from snet_cli/scripts/package-pip rename to packages/sdk/scripts/package-pip diff --git a/packages/sdk/setup.py b/packages/sdk/setup.py new file mode 100644 index 00000000..cd28bfe0 --- /dev/null +++ b/packages/sdk/setup.py @@ -0,0 +1,43 @@ +import pkg_resources +from setuptools import setup, find_namespace_packages + + +PACKAGE_NAME = 'snet.sdk' + + +def is_package_installed(package_name): + installed_modules = [p.project_name for p in pkg_resources.working_set] + return package_name in installed_modules + + +dependencies = [] + + +if is_package_installed('snet-cli'): + # The default setup.py in the snet_cli package for local development installs the whole snet_cli package, + # not the standalone snet.snet_cli namespace package; if a strict dependency on snet.snet_cli was enforced, + # this setup.py would fetch it from PyPI. So, if snet_cli is installed and in your Python path, the + # dependency on snet.snet_cli will be skipped. + # If snet_cli is not available, snet.snet_cli will be fetched from PyPI. + print("Package 'snet_cli' is installed and in your PYTHONPATH: skipping snet.snet_cli dependency") +else: + dependencies.append('snet.snet_cli') + + +version_dict = {} +with open("./snet/sdk/version.py") as fp: + exec(fp.read(), version_dict) + +setup( + name=PACKAGE_NAME, + version=version_dict['__version__'], + packages=find_namespace_packages(include=['snet.*']), + namespace_packages=['snet'], + url='https://github.com/singnet/snet-cli/tree/master/snet_sdk', + license='MIT', + author='SingularityNET Foundation', + author_email='info@singularitynet.io', + description='SingularityNET Python SDK', + python_requires='>=3.6', + install_requires=dependencies +) diff --git a/snet_sdk/snet_sdk/__init__.py b/packages/sdk/snet/sdk/__init__.py similarity index 88% rename from snet_sdk/snet_sdk/__init__.py rename to packages/sdk/snet/sdk/__init__.py index 5837883f..59c70790 100644 --- a/snet_sdk/snet_sdk/__init__.py +++ b/packages/sdk/snet/sdk/__init__.py @@ -6,13 +6,14 @@ from web3.gas_strategies.rpc import rpc_gas_price_strategy from rfc3986 import urlparse import ipfsapi -from web3.utils.datastructures import AttributeDict +from web3.datastructures import AttributeDict -from snet_sdk.utils import get_contract_object -from snet_sdk.service_client import ServiceClient -from snet_sdk.account import Account -from snet_sdk.mpe_contract import MPEContract -from snet_sdk.payment_channel_management_strategies.default import PaymentChannelManagementStrategy +from snet.sdk.service_client import ServiceClient +from snet.sdk.account import Account +from snet.sdk.mpe_contract import MPEContract +from snet.sdk.payment_channel_management_strategies.default import PaymentChannelManagementStrategy + +from snet.snet_cli.utils import get_contract_object class SnetSDK: diff --git a/snet_sdk/snet_sdk/account.py b/packages/sdk/snet/sdk/account.py similarity index 96% rename from snet_sdk/snet_sdk/account.py rename to packages/sdk/snet/sdk/account.py index 4164e8ca..eb1a6460 100644 --- a/snet_sdk/snet_sdk/account.py +++ b/packages/sdk/snet/sdk/account.py @@ -1,6 +1,6 @@ import json -from snet_sdk.utils import normalize_private_key, get_address_from_private, get_contract_object +from snet.snet_cli.utils import normalize_private_key, get_address_from_private, get_contract_object DEFAULT_GAS = 210000 diff --git a/snet_sdk/snet_sdk/generic_client_interceptor.py b/packages/sdk/snet/sdk/generic_client_interceptor.py similarity index 100% rename from snet_sdk/snet_sdk/generic_client_interceptor.py rename to packages/sdk/snet/sdk/generic_client_interceptor.py diff --git a/snet_sdk/snet_sdk/mpe_contract.py b/packages/sdk/snet/sdk/mpe_contract.py similarity index 96% rename from snet_sdk/snet_sdk/mpe_contract.py rename to packages/sdk/snet/sdk/mpe_contract.py index 3e879352..8a608fce 100644 --- a/snet_sdk/snet_sdk/mpe_contract.py +++ b/packages/sdk/snet/sdk/mpe_contract.py @@ -1,8 +1,10 @@ import base64 import web3 -from snet_sdk.utils import get_contract_object, get_contract_deployment_block -from snet_sdk.payment_channel import PaymentChannel +from snet.sdk.payment_channel import PaymentChannel + +from snet.snet_cli.utils import get_contract_object, get_contract_deployment_block + BLOCKS_PER_BATCH = 20000 EVENT_ABI = {'anonymous': False, 'inputs': [{'indexed': False, 'name': 'channelId', 'type': 'uint256'}, {'indexed': False, 'name': 'nonce', 'type': 'uint256'}, {'indexed': True, 'name': 'sender', 'type': 'address'}, {'indexed': False, 'name': 'signer', 'type': 'address'}, {'indexed': True, 'name': 'recipient', 'type': 'address'}, {'indexed': True, 'name': 'groupId', 'type': 'bytes32'}, {'indexed': False, 'name': 'amount', 'type': 'uint256'}, {'indexed': False, 'name': 'expiration', 'type': 'uint256'}], 'name': 'ChannelOpen', 'type': 'event'} diff --git a/snet_sdk/snet_sdk/payment_channel.py b/packages/sdk/snet/sdk/payment_channel.py similarity index 91% rename from snet_sdk/snet_sdk/payment_channel.py rename to packages/sdk/snet/sdk/payment_channel.py index 87cdbd30..60538504 100644 --- a/snet_sdk/snet_sdk/payment_channel.py +++ b/packages/sdk/snet/sdk/payment_channel.py @@ -1,7 +1,8 @@ import web3 +import importlib from eth_account.messages import defunct_hash_message -import snet_sdk.state_service_pb2 as state_service_pb2 +from snet.snet_cli.utils import RESOURCES_PATH, add_to_path class PaymentChannel: def __init__(self, channel_id, w3, account, service, mpe_contract): @@ -49,6 +50,8 @@ def _get_current_channel_state(self): stub = self.payment_channel_state_service_client message = web3.Web3.soliditySha3(["uint256"], [self.channel_id]) signature = self.web3.eth.account.signHash(defunct_hash_message(message), self.account.signer_private_key).signature + with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): + state_service_pb2 = importlib.import_module("state_service_pb2") request = state_service_pb2.ChannelStateRequest(channel_id=web3.Web3.toBytes(self.channel_id), signature=bytes(signature)) response = stub.GetChannelState(request) return int.from_bytes(response.current_nonce, byteorder="big"), int.from_bytes(response.current_signed_amount, byteorder="big") diff --git a/snet_cli/snet_cli/_vendor/__init__.py b/packages/sdk/snet/sdk/payment_channel_management_strategies/__init__.py similarity index 100% rename from snet_cli/snet_cli/_vendor/__init__.py rename to packages/sdk/snet/sdk/payment_channel_management_strategies/__init__.py diff --git a/snet_sdk/snet_sdk/payment_channel_management_strategies/default.py b/packages/sdk/snet/sdk/payment_channel_management_strategies/default.py similarity index 100% rename from snet_sdk/snet_sdk/payment_channel_management_strategies/default.py rename to packages/sdk/snet/sdk/payment_channel_management_strategies/default.py diff --git a/snet_sdk/snet_sdk/service_client.py b/packages/sdk/snet/sdk/service_client.py similarity index 94% rename from snet_sdk/snet_sdk/service_client.py rename to packages/sdk/snet/sdk/service_client.py index 3ed39c52..31b71394 100644 --- a/snet_sdk/snet_sdk/service_client.py +++ b/packages/sdk/snet/sdk/service_client.py @@ -1,12 +1,13 @@ import collections +import importlib + import grpc import web3 from rfc3986 import urlparse from eth_account.messages import defunct_hash_message -import snet_sdk.generic_client_interceptor as generic_client_interceptor - -import snet_sdk.state_service_pb2_grpc as state_service_pb2_grpc +import snet.sdk.generic_client_interceptor as generic_client_interceptor +from snet.snet_cli.utils import RESOURCES_PATH, add_to_path class _ClientCallDetails( @@ -111,6 +112,8 @@ def default_channel_expiration(self): def _generate_payment_channel_state_service_client(self): grpc_channel = self._base_grpc_channel + with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): + state_service_pb2_grpc = importlib.import_module("state_service_pb2_grpc") return state_service_pb2_grpc.PaymentChannelStateServiceStub(grpc_channel) diff --git a/packages/sdk/snet/sdk/version.py b/packages/sdk/snet/sdk/version.py new file mode 100644 index 00000000..bbab0242 --- /dev/null +++ b/packages/sdk/snet/sdk/version.py @@ -0,0 +1 @@ +__version__ = "0.1.4" diff --git a/packages/snet_cli/.gitignore b/packages/snet_cli/.gitignore new file mode 100644 index 00000000..e86739fb --- /dev/null +++ b/packages/snet_cli/.gitignore @@ -0,0 +1,8 @@ +venv/ +snet_cli.egg-info/ +snet/snet_cli/resources/contracts/abi +snet/snet_cli/resources/contracts/networks +snet/snet_cli/resources/node_modules +snet/snet_cli/resources/proto/*.py +build/ +dist/ diff --git a/snet_sdk/LICENSE b/packages/snet_cli/LICENSE similarity index 100% rename from snet_sdk/LICENSE rename to packages/snet_cli/LICENSE diff --git a/packages/snet_cli/MANIFEST.in b/packages/snet_cli/MANIFEST.in new file mode 100644 index 00000000..e9df6bc0 --- /dev/null +++ b/packages/snet_cli/MANIFEST.in @@ -0,0 +1,11 @@ +include snet/snet_cli/resources/proto/* +include snet/snet_cli/resources/contracts/abi/* +include snet/snet_cli/resources/contracts/networks/* +include snet/snet_cli/resources/package.json + +recursive-include snet_cli/_vendor * + +recursive-exclude * .git +recursive-exclude * node_modules +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] diff --git a/snet_cli/README.md b/packages/snet_cli/README.md similarity index 100% rename from snet_cli/README.md rename to packages/snet_cli/README.md diff --git a/snet_cli/docs/Makefile b/packages/snet_cli/docs/Makefile similarity index 100% rename from snet_cli/docs/Makefile rename to packages/snet_cli/docs/Makefile diff --git a/snet_cli/docs/build-docs.sh b/packages/snet_cli/docs/build-docs.sh similarity index 100% rename from snet_cli/docs/build-docs.sh rename to packages/snet_cli/docs/build-docs.sh diff --git a/snet_cli/docs/source/conf.py b/packages/snet_cli/docs/source/conf.py similarity index 100% rename from snet_cli/docs/source/conf.py rename to packages/snet_cli/docs/source/conf.py diff --git a/snet_cli/docs/source/generate_rst.py b/packages/snet_cli/docs/source/generate_rst.py similarity index 100% rename from snet_cli/docs/source/generate_rst.py rename to packages/snet_cli/docs/source/generate_rst.py diff --git a/snet_cli/docs/source/img/singularityNET.png b/packages/snet_cli/docs/source/img/singularityNET.png similarity index 100% rename from snet_cli/docs/source/img/singularityNET.png rename to packages/snet_cli/docs/source/img/singularityNET.png diff --git a/snet_cli/docs/source/index_template.tpl b/packages/snet_cli/docs/source/index_template.tpl similarity index 100% rename from snet_cli/docs/source/index_template.tpl rename to packages/snet_cli/docs/source/index_template.tpl diff --git a/snet_cli/docs/source/snet-cli-static/theme.css b/packages/snet_cli/docs/source/snet-cli-static/theme.css similarity index 100% rename from snet_cli/docs/source/snet-cli-static/theme.css rename to packages/snet_cli/docs/source/snet-cli-static/theme.css diff --git a/snet_cli/docs/source/subcommand_template.tpl b/packages/snet_cli/docs/source/subcommand_template.tpl similarity index 100% rename from snet_cli/docs/source/subcommand_template.tpl rename to packages/snet_cli/docs/source/subcommand_template.tpl diff --git a/packages/snet_cli/requirements.txt b/packages/snet_cli/requirements.txt new file mode 100644 index 00000000..ea8d66ba --- /dev/null +++ b/packages/snet_cli/requirements.txt @@ -0,0 +1,2 @@ +--index-url https://pypi.python.org/simple +-e . diff --git a/snet_sdk/scripts/blockchain b/packages/snet_cli/scripts/blockchain similarity index 90% rename from snet_sdk/scripts/blockchain rename to packages/snet_cli/scripts/blockchain index f49e73de..46cf9904 100755 --- a/snet_sdk/scripts/blockchain +++ b/packages/snet_cli/scripts/blockchain @@ -10,12 +10,13 @@ import sys def main(): assert len(sys.argv) > 1, "please select a target from 'install', 'uninstall'" target = sys.argv[1] - blockchain_dir = pathlib.Path(__file__).absolute().parent.parent.parent.joinpath("blockchain") + cur_dir = pathlib.Path(__file__).absolute().parent + blockchain_dir = cur_dir.parent.parent.parent.joinpath("blockchain") node_modules_dir = blockchain_dir.joinpath("node_modules") platform_json_src_dir = node_modules_dir.joinpath("singularitynet-platform-contracts") token_json_src_dir = node_modules_dir.joinpath("singularitynet-token-contracts") token_contract_name = "SingularityNetToken" - contract_json_dest_dir = pathlib.Path(__file__).absolute().parent.parent.joinpath("snet_sdk", "resources", "contracts") + contract_json_dest_dir = cur_dir.parent.joinpath("snet", "snet_cli", "resources", "contracts") abi_contract_names = ["Registry", "MultiPartyEscrow"] networks_contract_names = ["Registry", "MultiPartyEscrow"] diff --git a/snet_sdk/scripts/package-pip b/packages/snet_cli/scripts/package-pip similarity index 100% rename from snet_sdk/scripts/package-pip rename to packages/snet_cli/scripts/package-pip diff --git a/snet_cli/setup.py b/packages/snet_cli/setup.py similarity index 82% rename from snet_cli/setup.py rename to packages/snet_cli/setup.py index e234abc8..fd0fa2d4 100644 --- a/snet_cli/setup.py +++ b/packages/snet_cli/setup.py @@ -1,14 +1,14 @@ -from setuptools import setup, find_packages +from setuptools import setup, find_packages, find_namespace_packages from setuptools.command.develop import develop as _develop from setuptools.command.install import install as _install def install_and_compile_proto(): - import snet_cli - from snet_cli.utils import compile_proto as compile_proto + import snet.snet_cli + from snet.snet_cli.utils import compile_proto as compile_proto from pathlib import Path - proto_dir = Path(__file__).absolute().parent.joinpath("snet_cli", "resources", "proto") - dest_dir = Path(snet_cli.__file__).absolute().parent.joinpath("resources", "proto") + proto_dir = Path(__file__).absolute().parent.joinpath("snet", "snet_cli", "resources", "proto") + dest_dir = Path(snet.snet_cli.__file__).absolute().parent.joinpath("resources", "proto") print(proto_dir, "->", dest_dir) for fn in proto_dir.glob('*.proto'): print("Compiling protobuf", fn) @@ -37,7 +37,8 @@ def run(self): setup( name='snet-cli', version=version_dict['__version__'], - packages=find_packages(), + packages=find_namespace_packages(include=['snet.*'])+find_packages(), + namespace_packages=['snet'], url='https://github.com/singnet/snet-cli', license='MIT', author='SingularityNET Foundation', diff --git a/snet_sdk/snet_sdk/payment_channel_management_strategies/__init__.py b/packages/snet_cli/snet/snet_cli/__init__.py similarity index 100% rename from snet_sdk/snet_sdk/payment_channel_management_strategies/__init__.py rename to packages/snet_cli/snet/snet_cli/__init__.py diff --git a/snet_cli/snet_cli/resources/contracts/placeholder.txt b/packages/snet_cli/snet/snet_cli/resources/contracts/placeholder.txt similarity index 100% rename from snet_cli/snet_cli/resources/contracts/placeholder.txt rename to packages/snet_cli/snet/snet_cli/resources/contracts/placeholder.txt diff --git a/snet_cli/resources/package.json b/packages/snet_cli/snet/snet_cli/resources/package.json similarity index 100% rename from snet_cli/resources/package.json rename to packages/snet_cli/snet/snet_cli/resources/package.json diff --git a/snet_cli/snet_cli/resources/proto/control_service.proto b/packages/snet_cli/snet/snet_cli/resources/proto/control_service.proto similarity index 100% rename from snet_cli/snet_cli/resources/proto/control_service.proto rename to packages/snet_cli/snet/snet_cli/resources/proto/control_service.proto diff --git a/snet_cli/snet_cli/resources/proto/merckledag.proto b/packages/snet_cli/snet/snet_cli/resources/proto/merckledag.proto similarity index 100% rename from snet_cli/snet_cli/resources/proto/merckledag.proto rename to packages/snet_cli/snet/snet_cli/resources/proto/merckledag.proto diff --git a/snet_cli/snet_cli/resources/proto/state_service.proto b/packages/snet_cli/snet/snet_cli/resources/proto/state_service.proto similarity index 100% rename from snet_cli/snet_cli/resources/proto/state_service.proto rename to packages/snet_cli/snet/snet_cli/resources/proto/state_service.proto diff --git a/snet_cli/snet_cli/resources/proto/unixfs.proto b/packages/snet_cli/snet/snet_cli/resources/proto/unixfs.proto similarity index 100% rename from snet_cli/snet_cli/resources/proto/unixfs.proto rename to packages/snet_cli/snet/snet_cli/resources/proto/unixfs.proto diff --git a/snet_cli/snet_cli/utils.py b/packages/snet_cli/snet/snet_cli/utils.py similarity index 80% rename from snet_cli/snet_cli/utils.py rename to packages/snet_cli/snet/snet_cli/utils.py index d85dbefb..7bf982ad 100644 --- a/snet_cli/snet_cli/utils.py +++ b/packages/snet_cli/snet/snet_cli/utils.py @@ -2,9 +2,10 @@ import os import subprocess import functools +import sys from urllib.parse import urlparse -from pathlib import Path +from pathlib import Path, PurePath import web3 import pkg_resources @@ -12,6 +13,9 @@ from grpc_tools.protoc import main as protoc +RESOURCES_PATH = PurePath(os.path.realpath(__file__)).parent.joinpath("resources") + + class DefaultAttributeObject(object): def __init__(self, **kwargs): for k, v in kwargs.items(): @@ -122,7 +126,7 @@ def walk_imports(entry_path): return seen_paths -def get_contract_def(contract_name, contract_artifacts_root=Path(__file__).absolute().parent.joinpath("resources", "contracts")): +def get_contract_def(contract_name, contract_artifacts_root=RESOURCES_PATH.joinpath("contracts")): contract_def = {} with open(Path(__file__).absolute().parent.joinpath(contract_artifacts_root, "abi", "{}.json".format(contract_name))) as f: contract_def["abi"] = json.load(f) @@ -159,12 +163,11 @@ def compile_proto(entry_path, codegen_dir, proto_file=None, target_language="pyt compiler_args.append("--grpc_python_out={}".format(codegen_dir)) compiler = protoc elif target_language == "nodejs": - resources_path = Path(os.path.dirname(os.path.realpath(__file__))).joinpath("resources") - protoc_node_compiler_path = resources_path.joinpath("node_modules").joinpath("grpc-tools").joinpath("bin").joinpath("protoc.js").absolute() - grpc_node_plugin_path = resources_path.joinpath("node_modules").joinpath("grpc-tools").joinpath("bin").joinpath("grpc_node_plugin").resolve() + protoc_node_compiler_path = Path(RESOURCES_PATH.joinpath("node_modules").joinpath("grpc-tools").joinpath("bin").joinpath("protoc.js")).absolute() + grpc_node_plugin_path = Path(RESOURCES_PATH.joinpath("node_modules").joinpath("grpc-tools").joinpath("bin").joinpath("grpc_node_plugin")).resolve() if not os.path.isfile(protoc_node_compiler_path) or not os.path.isfile(grpc_node_plugin_path): print("Missing required node.js protoc compiler. Retrieving from npm...") - subprocess.run(["npm", "install"], cwd=resources_path) + subprocess.run(["npm", "install"], cwd=RESOURCES_PATH) compiler_args.append("--js_out=import_style=commonjs,binary:{}".format(codegen_dir)) compiler_args.append("--grpc_out={}".format(codegen_dir)) compiler_args.append("--plugin=protoc-gen-grpc={}".format(grpc_node_plugin_path)) @@ -181,6 +184,7 @@ def compile_proto(entry_path, codegen_dir, proto_file=None, target_language="pyt return False except Exception as e: + print(e) return False def abi_get_element_by_name(abi, name): @@ -253,3 +257,43 @@ def rgetattr(obj, attr): 2 """ return functools.reduce(getattr, [obj] + attr.split('.')) + + +def get_contract_object(w3, contract_file): + with open(RESOURCES_PATH.joinpath("contracts", "abi", contract_file)) as f: + abi = json.load(f) + with open(RESOURCES_PATH.joinpath("contracts", "networks", contract_file)) as f: + networks = json.load(f) + address = w3.toChecksumAddress(networks[w3.version.network]["address"]) + return w3.eth.contract(abi=abi, address=address) + + +def get_contract_deployment_block(w3, contract_file): + with open(RESOURCES_PATH.joinpath("contracts", "networks", contract_file)) as f: + networks = json.load(f) + txn_hash = networks[w3.version.network]["transactionHash"] + return w3.eth.getTransactionReceipt(txn_hash).blockNumber + + +def normalize_private_key(private_key): + if private_key.startswith("0x"): + private_key = bytes(bytearray.fromhex(private_key[2:])) + else: + private_key = bytes(bytearray.fromhex(private_key)) + return private_key + + +def get_address_from_private(private_key): + return web3.eth.Account.privateKeyToAccount(private_key).address + + +class add_to_path(): + def __init__(self, path): + self.path = path + def __enter__(self): + sys.path.insert(0, self.path) + def __exit__(self, exc_type, exc_value, traceback): + try: + sys.path.remove(self.path) + except ValueError: + pass diff --git a/snet_cli/snet_cli/utils_proto.py b/packages/snet_cli/snet/snet_cli/utils_proto.py similarity index 100% rename from snet_cli/snet_cli/utils_proto.py rename to packages/snet_cli/snet/snet_cli/utils_proto.py diff --git a/snet_cli/snet_cli/__init__.py b/packages/snet_cli/snet_cli/__init__.py similarity index 99% rename from snet_cli/snet_cli/__init__.py rename to packages/snet_cli/snet_cli/__init__.py index 633e954f..6483d16d 100644 --- a/snet_cli/snet_cli/__init__.py +++ b/packages/snet_cli/snet_cli/__init__.py @@ -7,6 +7,7 @@ from snet_cli.config import Config import argcomplete + def main(): try: argv = sys.argv[1:] diff --git a/snet_sdk/snet_sdk/resources/contracts/placeholder.txt b/packages/snet_cli/snet_cli/_vendor/__init__.py similarity index 100% rename from snet_sdk/snet_sdk/resources/contracts/placeholder.txt rename to packages/snet_cli/snet_cli/_vendor/__init__.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/BlueHSMServer_pb2.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/Dongle.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/Dongle.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/Dongle.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/Dongle.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/__init__.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/__init__.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/__init__.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/__init__.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/checkGenuine.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/checkGenuine.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/checkGenuine.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/checkGenuine.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/comm.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/comm.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/comm.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/comm.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/commException.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/commException.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/commException.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/commException.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/commHTTP.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/commHTTP.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/commHTTP.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/commHTTP.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/commU2F.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/commU2F.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/commU2F.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/commU2F.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/deleteApp.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/deleteApp.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/deleteApp.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/deleteApp.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/deployed.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/deployed.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/deployed.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/deployed.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/derivePassphrase.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/derivePassphrase.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/derivePassphrase.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/derivePassphrase.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/ecWrapper.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/ecWrapper.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/ecWrapper.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/ecWrapper.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetup.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetup.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetup.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetup.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/endorsementSetupLedger.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/genCAPair.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/genCAPair.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/genCAPair.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/genCAPair.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/getMemInfo.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/getMemInfo.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/getMemInfo.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/getMemInfo.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/hashApp.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/hashApp.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/hashApp.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/hashApp.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/hexLoader.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/hexLoader.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/hexLoader.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/hexLoader.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/hexParser.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/hexParser.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/hexParser.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/hexParser.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/hostOnboard.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/hostOnboard.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/hostOnboard.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/hostOnboard.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/ledgerWrapper.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/ledgerWrapper.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/ledgerWrapper.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/ledgerWrapper.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/listApps.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/listApps.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/listApps.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/listApps.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/loadApp.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/loadApp.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/loadApp.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/loadApp.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/loadMCU.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/loadMCU.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/loadMCU.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/loadMCU.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/mcuBootloader.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/mcuBootloader.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/mcuBootloader.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/mcuBootloader.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/resetCustomCA.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/resetCustomCA.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/resetCustomCA.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/resetCustomCA.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/runApp.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/runApp.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/runApp.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/runApp.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/runScript.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/runScript.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/runScript.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/runScript.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/setupCustomCA.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/setupCustomCA.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/setupCustomCA.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/setupCustomCA.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/signApp.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/signApp.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/signApp.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/signApp.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/updateFirmware.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/updateFirmware.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/updateFirmware.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/updateFirmware.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/verifyApp.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/verifyApp.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/verifyApp.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/verifyApp.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement1.py diff --git a/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py b/packages/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py similarity index 100% rename from snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py rename to packages/snet_cli/snet_cli/_vendor/ledgerblue/verifyEndorsement2.py diff --git a/snet_cli/snet_cli/arguments.py b/packages/snet_cli/snet_cli/arguments.py similarity index 99% rename from snet_cli/snet_cli/arguments.py rename to packages/snet_cli/snet_cli/arguments.py index 259de685..92c334bd 100644 --- a/snet_cli/snet_cli/arguments.py +++ b/packages/snet_cli/snet_cli/arguments.py @@ -7,7 +7,6 @@ from snet_cli.commands import IdentityCommand, SessionSetCommand, SessionShowCommand, NetworkCommand, ContractCommand, \ OrganizationCommand, VersionCommand from snet_cli.identity import get_identity_types -from snet_cli.utils import type_converter, get_contract_def from snet_cli.mpe_account_command import MPEAccountCommand from snet_cli.mpe_service_command import MPEServiceCommand from snet_cli.mpe_channel_command import MPEChannelCommand @@ -17,6 +16,8 @@ from snet_cli.utils_agi2cogs import stragi2cogs from snet_cli.config import Config, get_session_keys, get_session_network_keys_removable +from snet.snet_cli.utils import type_converter, get_contract_def, RESOURCES_PATH + class CustomParser(argparse.ArgumentParser): def __init__(self, default_choice=None, *args, **kwargs): @@ -234,7 +235,7 @@ def add_contract_options(parser): subparsers = parser.add_subparsers(title="contracts", metavar="CONTRACT") subparsers.required = True - for path in Path(__file__).absolute().parent.joinpath("resources", "contracts", "abi").glob("*json"): + for path in Path(RESOURCES_PATH.joinpath("contracts", "abi")).glob("*json"): contract_name = re.search(r"([^.]*)\.json", os.path.basename(path)).group(1) contract_p = subparsers.add_parser(contract_name, help="{} contract".format(contract_name)) add_contract_function_options(contract_p, contract_name) diff --git a/snet_cli/snet_cli/commands.py b/packages/snet_cli/snet_cli/commands.py similarity index 99% rename from snet_cli/snet_cli/commands.py rename to packages/snet_cli/snet_cli/commands.py index 16d27169..0f5ffd20 100644 --- a/snet_cli/snet_cli/commands.py +++ b/packages/snet_cli/snet_cli/commands.py @@ -3,23 +3,22 @@ import sys from textwrap import indent from urllib.parse import urljoin +import secrets +import string +from web3.eth import is_checksum_address +from web3.gas_strategies.time_based import fast_gas_price_strategy, medium_gas_price_strategy, slow_gas_price_strategy import ipfsapi import yaml from rfc3986 import urlparse -from snet_cli.contract import Contract -from snet_cli.identity import get_kws_for_identity_type -from snet_cli.utils import DefaultAttributeObject, get_web3, serializable, type_converter, get_contract_def, get_cli_version, bytes32_to_str - from snet_cli.utils_config import get_contract_address, get_field_from_args_or_session, read_default_contract_address from snet_cli.identity import RpcIdentityProvider, MnemonicIdentityProvider, TrezorIdentityProvider, \ LedgerIdentityProvider, KeyIdentityProvider, KeyStoreIdentityProvider -from web3.eth import is_checksum_address -import secrets -import string -from web3.gas_strategies.time_based import fast_gas_price_strategy, medium_gas_price_strategy, slow_gas_price_strategy +from snet_cli.contract import Contract +from snet_cli.identity import get_kws_for_identity_type +from snet.snet_cli.utils import DefaultAttributeObject, get_web3, serializable, type_converter, get_contract_def, get_cli_version, bytes32_to_str class Command(object): diff --git a/snet_cli/snet_cli/config.py b/packages/snet_cli/snet_cli/config.py similarity index 100% rename from snet_cli/snet_cli/config.py rename to packages/snet_cli/snet_cli/config.py diff --git a/snet_cli/snet_cli/contract.py b/packages/snet_cli/snet_cli/contract.py similarity index 100% rename from snet_cli/snet_cli/contract.py rename to packages/snet_cli/snet_cli/contract.py diff --git a/snet_cli/snet_cli/identity.py b/packages/snet_cli/snet_cli/identity.py similarity index 97% rename from snet_cli/snet_cli/identity.py rename to packages/snet_cli/snet_cli/identity.py index bad5b0d1..4b8a2f89 100644 --- a/snet_cli/snet_cli/identity.py +++ b/packages/snet_cli/snet_cli/identity.py @@ -16,7 +16,10 @@ from snet_cli._vendor.ledgerblue.comm import getDongle from snet_cli._vendor.ledgerblue.commException import CommException - + +from snet.snet_cli.utils import get_address_from_private, normalize_private_key + + BIP32_HARDEN = 0x80000000 @@ -37,12 +40,8 @@ def sign_message_after_soliditySha3(self, message): class KeyIdentityProvider(IdentityProvider): def __init__(self, w3, private_key): self.w3 = w3 - if private_key.startswith("0x"): - self.private_key = bytes(bytearray.fromhex(private_key[2:])) - else: - self.private_key = bytes(bytearray.fromhex(private_key)) - - self.address = web3.eth.Account.privateKeyToAccount(self.private_key).address + self.private_key = normalize_private_key(private_key) + self.address = get_address_from_private(self.private_key) def get_address(self): return self.address @@ -116,7 +115,7 @@ def __init__(self, w3, mnemonic, index): change_subtree = account_subtree.subkey(i=0) account = change_subtree.subkey(i=index) self.private_key = account.secret_exponent().to_bytes(32, 'big') - self.address = web3.eth.Account.privateKeyToAccount(self.private_key).address + self.address = get_address_from_private(self.private_key) def get_address(self): return self.address diff --git a/snet_cli/snet_cli/mpe_account_command.py b/packages/snet_cli/snet_cli/mpe_account_command.py similarity index 100% rename from snet_cli/snet_cli/mpe_account_command.py rename to packages/snet_cli/snet_cli/mpe_account_command.py diff --git a/snet_cli/snet_cli/mpe_channel_command.py b/packages/snet_cli/snet_cli/mpe_channel_command.py similarity index 99% rename from snet_cli/snet_cli/mpe_channel_command.py rename to packages/snet_cli/snet_cli/mpe_channel_command.py index faf114da..ad027878 100644 --- a/snet_cli/snet_cli/mpe_channel_command.py +++ b/packages/snet_cli/snet_cli/mpe_channel_command.py @@ -1,19 +1,21 @@ - -from snet_cli.mpe_service_command import MPEServiceCommand -from snet_cli.utils import compile_proto import base64 from pathlib import Path import os -from snet_cli.utils import get_contract_def, abi_get_element_by_name, abi_decode_struct_to_dict -from snet_cli.mpe_service_metadata import load_mpe_service_metadata -from snet_cli.utils_ipfs import safe_extract_proto_from_ipfs import shutil import tempfile -from snet_cli.utils_agi2cogs import cogs2stragi import pickle +from collections import defaultdict + from web3.utils.encoding import pad_hex from web3.utils.events import get_event_data -from collections import defaultdict + +from snet_cli.mpe_service_command import MPEServiceCommand +from snet_cli.mpe_service_metadata import load_mpe_service_metadata +from snet_cli.utils_ipfs import safe_extract_proto_from_ipfs +from snet_cli.utils_agi2cogs import cogs2stragi + +from snet.snet_cli.utils import compile_proto, get_contract_def, abi_get_element_by_name, abi_decode_struct_to_dict + # we inherit MPEServiceCommand because we need _get_service_metadata_from_registry class MPEChannelCommand(MPEServiceCommand): diff --git a/snet_cli/snet_cli/mpe_client_command.py b/packages/snet_cli/snet_cli/mpe_client_command.py similarity index 95% rename from snet_cli/snet_cli/mpe_client_command.py rename to packages/snet_cli/snet_cli/mpe_client_command.py index 8e1e1e8c..82fa1885 100644 --- a/snet_cli/snet_cli/mpe_client_command.py +++ b/packages/snet_cli/snet_cli/mpe_client_command.py @@ -1,13 +1,16 @@ -from snet_cli.mpe_channel_command import MPEChannelCommand import base64 from pathlib import Path import json import sys + import grpc from eth_account.messages import defunct_hash_message -from snet_cli.utils_proto import import_protobuf_from_dir, switch_to_json_payload_encoding + +from snet_cli.mpe_channel_command import MPEChannelCommand from snet_cli.utils_agi2cogs import cogs2stragi -from snet_cli.utils import open_grpc_channel, rgetattr, compile_proto + +from snet.snet_cli.utils import open_grpc_channel, rgetattr, compile_proto, RESOURCES_PATH +from snet.snet_cli.utils_proto import import_protobuf_from_dir, switch_to_json_payload_encoding # we inherit MPEChannelCommand because client needs channels @@ -149,14 +152,10 @@ def call_server_lowlevel(self): # III. Stateless client related functions def _get_channel_state_from_server(self, grpc_channel, channel_id): - # Compile protobuf if needed - codegen_dir = Path.home().joinpath(".snet", "mpe_client", "state_service") - proto_dir = Path(__file__).absolute().parent.joinpath("resources", "proto") - if (not codegen_dir.joinpath("state_service_pb2.py").is_file()): - compile_proto(proto_dir, codegen_dir, proto_file = "state_service.proto") + proto_dir = RESOURCES_PATH.joinpath("proto") # make PaymentChannelStateService.GetChannelState call to the daemon - stub_class, request_class, _ = import_protobuf_from_dir(codegen_dir, "GetChannelState") + stub_class, request_class, _ = import_protobuf_from_dir(proto_dir, "GetChannelState") message = self.w3.soliditySha3(["uint256"], [channel_id]) signature = self.ident.sign_message_after_soliditySha3(message) diff --git a/snet_cli/snet_cli/mpe_service_command.py b/packages/snet_cli/snet_cli/mpe_service_command.py similarity index 99% rename from snet_cli/snet_cli/mpe_service_command.py rename to packages/snet_cli/snet_cli/mpe_service_command.py index 22e035c3..9c8f416f 100644 --- a/snet_cli/snet_cli/mpe_service_command.py +++ b/packages/snet_cli/snet_cli/mpe_service_command.py @@ -1,14 +1,17 @@ -from snet_cli.commands import BlockchainCommand -import snet_cli.utils_ipfs as utils_ipfs -from snet_cli.mpe_service_metadata import MPEServiceMetadata, load_mpe_service_metadata, mpe_service_metadata_from_json -from snet_cli.utils import type_converter, bytes32_to_str, open_grpc_channel -from snet_cli.utils_ipfs import hash_to_bytesuri, bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs import web3 import json import grpc +from collections import defaultdict + from grpc_health.v1 import health_pb2 as heartb_pb2 from grpc_health.v1 import health_pb2_grpc as heartb_pb2_grpc -from collections import defaultdict + +from snet_cli.commands import BlockchainCommand +import snet_cli.utils_ipfs as utils_ipfs +from snet_cli.mpe_service_metadata import MPEServiceMetadata, load_mpe_service_metadata, mpe_service_metadata_from_json +from snet_cli.utils_ipfs import hash_to_bytesuri, bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs + +from snet.snet_cli.utils import type_converter, bytes32_to_str, open_grpc_channel class MPEServiceCommand(BlockchainCommand): @@ -218,4 +221,4 @@ def extract_service_api_from_registry(self): def delete_service_registration(self): params = [type_converter("bytes32")(self.args.org_id), type_converter("bytes32")(self.args.service_id)] - self.transact_contract_command("Registry", "deleteServiceRegistration", params) \ No newline at end of file + self.transact_contract_command("Registry", "deleteServiceRegistration", params) diff --git a/snet_cli/snet_cli/mpe_service_metadata.py b/packages/snet_cli/snet_cli/mpe_service_metadata.py similarity index 99% rename from snet_cli/snet_cli/mpe_service_metadata.py rename to packages/snet_cli/snet_cli/mpe_service_metadata.py index 91c935b4..9ab8054c 100644 --- a/snet_cli/snet_cli/mpe_service_metadata.py +++ b/packages/snet_cli/snet_cli/mpe_service_metadata.py @@ -39,9 +39,10 @@ import base64 import secrets -from snet_cli.utils import is_valid_endpoint from collections import defaultdict +from snet.snet_cli.utils import is_valid_endpoint + # TODO: we should use some standard solution here class MPEServiceMetadata: diff --git a/snet_cli/snet_cli/mpe_treasurer_command.py b/packages/snet_cli/snet_cli/mpe_treasurer_command.py similarity index 97% rename from snet_cli/snet_cli/mpe_treasurer_command.py rename to packages/snet_cli/snet_cli/mpe_treasurer_command.py index f603cec1..5452cec3 100644 --- a/snet_cli/snet_cli/mpe_treasurer_command.py +++ b/packages/snet_cli/snet_cli/mpe_treasurer_command.py @@ -1,11 +1,13 @@ -from snet_cli.mpe_client_command import MPEClientCommand -from snet_cli.utils import compile_proto, open_grpc_channel from pathlib import Path + +import web3 import grpc -from snet_cli.utils_proto import import_protobuf_from_dir -from snet_cli.utils import int4bytes_big + +from snet_cli.mpe_client_command import MPEClientCommand from snet_cli.utils_agi2cogs import cogs2stragi -import web3 + +from snet.snet_cli.utils_proto import import_protobuf_from_dir +from snet.snet_cli.utils import compile_proto, open_grpc_channel, int4bytes_big, RESOURCES_PATH class MPETreasurerCommand(MPEClientCommand): @@ -32,7 +34,7 @@ def _get_stub_and_request_classes(self, service_name): """ import protobuf and return stub and request class """ # Compile protobuf if needed codegen_dir = Path.home().joinpath(".snet", "mpe_client", "control_service") - proto_dir = Path(__file__).absolute().parent.joinpath("resources", "proto") + proto_dir = RESOURCES_PATH.joinpath("proto") if (not codegen_dir.joinpath("control_service_pb2.py").is_file()): compile_proto(proto_dir, codegen_dir, proto_file = "control_service.proto") diff --git a/snet_cli/snet_cli/sdk_command.py b/packages/snet_cli/snet_cli/sdk_command.py similarity index 95% rename from snet_cli/snet_cli/sdk_command.py rename to packages/snet_cli/snet_cli/sdk_command.py index e31ba930..a4a651c0 100644 --- a/snet_cli/snet_cli/sdk_command.py +++ b/packages/snet_cli/snet_cli/sdk_command.py @@ -1,12 +1,13 @@ -from snet_cli.mpe_service_command import MPEServiceCommand import os from pathlib import Path, PurePath from tempfile import TemporaryDirectory -from snet_cli.utils import type_converter, bytes32_to_str, compile_proto +from snet_cli.mpe_service_command import MPEServiceCommand from snet_cli.utils_ipfs import bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs from snet_cli.mpe_service_metadata import mpe_service_metadata_from_json +from snet.snet_cli.utils import type_converter, bytes32_to_str, compile_proto + class SDKCommand(MPEServiceCommand): def generate_client_library(self): diff --git a/snet_cli/snet_cli/utils_agi2cogs.py b/packages/snet_cli/snet_cli/utils_agi2cogs.py similarity index 100% rename from snet_cli/snet_cli/utils_agi2cogs.py rename to packages/snet_cli/snet_cli/utils_agi2cogs.py diff --git a/snet_cli/snet_cli/utils_config.py b/packages/snet_cli/snet_cli/utils_config.py similarity index 98% rename from snet_cli/snet_cli/utils_config.py rename to packages/snet_cli/snet_cli/utils_config.py index f1e4a66f..f07e1a38 100644 --- a/snet_cli/snet_cli/utils_config.py +++ b/packages/snet_cli/snet_cli/utils_config.py @@ -1,4 +1,4 @@ -from snet_cli.utils import get_contract_def +from snet.snet_cli.utils import get_contract_def def get_contract_address(cmd, contract_name, error_message = None): """ diff --git a/snet_cli/snet_cli/utils_ipfs.py b/packages/snet_cli/snet_cli/utils_ipfs.py similarity index 96% rename from snet_cli/snet_cli/utils_ipfs.py rename to packages/snet_cli/snet_cli/utils_ipfs.py index 28a2ba1c..c5f24a7a 100644 --- a/snet_cli/snet_cli/utils_ipfs.py +++ b/packages/snet_cli/snet_cli/utils_ipfs.py @@ -38,8 +38,8 @@ def get_from_ipfs_and_checkhash(ipfs_client, ipfs_hash_base58, validate=True): We must check the hash becasue we cannot believe that ipfs_client wasn't been compromise """ if validate: - from snet_cli.resources.proto.unixfs_pb2 import Data - from snet_cli.resources.proto.merckledag_pb2 import MerkleNode + from snet.snet_cli.resources.proto.unixfs_pb2 import Data + from snet.snet_cli.resources.proto.merckledag_pb2 import MerkleNode # No nice Python library to parse ipfs blocks, so do it ourselves. block_data = ipfs_client.block_get(ipfs_hash_base58) diff --git a/snet_cli/snet_cli/version.py b/packages/snet_cli/snet_cli/version.py similarity index 100% rename from snet_cli/snet_cli/version.py rename to packages/snet_cli/snet_cli/version.py diff --git a/snet_cli/test/README.md b/packages/snet_cli/test/README.md similarity index 100% rename from snet_cli/test/README.md rename to packages/snet_cli/test/README.md diff --git a/snet_cli/test/functional_tests/script10_claim_timeout_all.sh b/packages/snet_cli/test/functional_tests/script10_claim_timeout_all.sh similarity index 100% rename from snet_cli/test/functional_tests/script10_claim_timeout_all.sh rename to packages/snet_cli/test/functional_tests/script10_claim_timeout_all.sh diff --git a/snet_cli/test/functional_tests/script11_update_metadata.sh b/packages/snet_cli/test/functional_tests/script11_update_metadata.sh similarity index 100% rename from snet_cli/test/functional_tests/script11_update_metadata.sh rename to packages/snet_cli/test/functional_tests/script11_update_metadata.sh diff --git a/snet_cli/test/functional_tests/script12_extend_add_for_service.sh b/packages/snet_cli/test/functional_tests/script12_extend_add_for_service.sh similarity index 100% rename from snet_cli/test/functional_tests/script12_extend_add_for_service.sh rename to packages/snet_cli/test/functional_tests/script12_extend_add_for_service.sh diff --git a/snet_cli/test/functional_tests/script13_call_reinitialize.sh b/packages/snet_cli/test/functional_tests/script13_call_reinitialize.sh similarity index 100% rename from snet_cli/test/functional_tests/script13_call_reinitialize.sh rename to packages/snet_cli/test/functional_tests/script13_call_reinitialize.sh diff --git a/snet_cli/test/functional_tests/script15_sdk_generate_client_library.sh b/packages/snet_cli/test/functional_tests/script15_sdk_generate_client_library.sh similarity index 100% rename from snet_cli/test/functional_tests/script15_sdk_generate_client_library.sh rename to packages/snet_cli/test/functional_tests/script15_sdk_generate_client_library.sh diff --git a/snet_cli/test/functional_tests/script1_twogroups.sh b/packages/snet_cli/test/functional_tests/script1_twogroups.sh similarity index 100% rename from snet_cli/test/functional_tests/script1_twogroups.sh rename to packages/snet_cli/test/functional_tests/script1_twogroups.sh diff --git a/snet_cli/test/functional_tests/script2_deposit_transfer.sh b/packages/snet_cli/test/functional_tests/script2_deposit_transfer.sh similarity index 100% rename from snet_cli/test/functional_tests/script2_deposit_transfer.sh rename to packages/snet_cli/test/functional_tests/script2_deposit_transfer.sh diff --git a/snet_cli/test/functional_tests/script3_without_addresses.sh b/packages/snet_cli/test/functional_tests/script3_without_addresses.sh similarity index 98% rename from snet_cli/test/functional_tests/script3_without_addresses.sh rename to packages/snet_cli/test/functional_tests/script3_without_addresses.sh index 85120223..57f9d014 100755 --- a/snet_cli/test/functional_tests/script3_without_addresses.sh +++ b/packages/snet_cli/test/functional_tests/script3_without_addresses.sh @@ -2,7 +2,7 @@ # check how snet-cli works if we pass contract address via command line interface # remove networks -rm -rf ../../snet_cli/resources/contracts/networks/*.json +rm -rf ../../snet/snet_cli/resources/contracts/networks/*.json #unset addresses snet unset current_singularitynettoken_at || echo "could fail if hasn't been set (it is ok)" diff --git a/snet_cli/test/functional_tests/script4_only_with_networks.sh b/packages/snet_cli/test/functional_tests/script4_only_with_networks.sh similarity index 90% rename from snet_cli/test/functional_tests/script4_only_with_networks.sh rename to packages/snet_cli/test/functional_tests/script4_only_with_networks.sh index a2050646..9bbd80da 100755 --- a/snet_cli/test/functional_tests/script4_only_with_networks.sh +++ b/packages/snet_cli/test/functional_tests/script4_only_with_networks.sh @@ -7,7 +7,7 @@ # In this test we check this priority -rm -rf ../../snet_cli/resources/contracts/networks/*.json +rm -rf ../../snet/snet_cli/resources/contracts/networks/*.json #unset addresses snet unset current_singularitynettoken_at || echo "could fail if hasn't been set (it is ok)" @@ -20,9 +20,9 @@ snet organization create testo --org-id testo -y -q && exit 1 || echo "fail as # set networks -echo '{"829257324":{"events":{},"links":{},"address":"0x5c7a4290f6f8ff64c69eeffdfafc8644a4ec3a4e","transactionHash":""}}' > ../../snet_cli/resources/contracts/networks/MultiPartyEscrow.json -echo '{"829257324":{"events":{},"links":{},"address":"0x4e74fefa82e83e0964f0d9f53c68e03f7298a8b2","transactionHash":""}}' > ../../snet_cli/resources/contracts/networks/Registry.json -echo '{"829257324":{"events":{},"links":{},"address":"0x6e5f20669177f5bdf3703ec5ea9c4d4fe3aabd14","transactionHash":""}}' > ../../snet_cli/resources/contracts/networks/SingularityNetToken.json +echo '{"829257324":{"events":{},"links":{},"address":"0x5c7a4290f6f8ff64c69eeffdfafc8644a4ec3a4e","transactionHash":""}}' > ../../snet/snet_cli/resources/contracts/networks/MultiPartyEscrow.json +echo '{"829257324":{"events":{},"links":{},"address":"0x4e74fefa82e83e0964f0d9f53c68e03f7298a8b2","transactionHash":""}}' > ../../snet/snet_cli/resources/contracts/networks/Registry.json +echo '{"829257324":{"events":{},"links":{},"address":"0x6e5f20669177f5bdf3703ec5ea9c4d4fe3aabd14","transactionHash":""}}' > ../../snet/snet_cli/resources/contracts/networks/SingularityNetToken.json # this should work @@ -50,9 +50,9 @@ snet organization delete testo -y -q --registry-at 0x4e74fefa82e8 # set INVALID networks -echo '{"829257324":{"events":{},"links":{},"address":"0x1c7a4290f6f8ff64c69eeffdfafc8644a4ec3a4e","transactionHash":""}}' > ../../snet_cli/resources/contracts/networks/MultiPartyEscrow.json -echo '{"829257324":{"events":{},"links":{},"address":"0x1e74fefa82e83e0964f0d9f53c68e03f7298a8b2","transactionHash":""}}' > ../../snet_cli/resources/contracts/networks/Registry.json -echo '{"829257324":{"events":{},"links":{},"address":"0x1e5f20669177f5bdf3703ec5ea9c4d4fe3aabd14","transactionHash":""}}' > ../../snet_cli/resources/contracts/networks/SingularityNetToken.json +echo '{"829257324":{"events":{},"links":{},"address":"0x1c7a4290f6f8ff64c69eeffdfafc8644a4ec3a4e","transactionHash":""}}' > ../../snet/snet_cli/resources/contracts/networks/MultiPartyEscrow.json +echo '{"829257324":{"events":{},"links":{},"address":"0x1e74fefa82e83e0964f0d9f53c68e03f7298a8b2","transactionHash":""}}' > ../../snet/snet_cli/resources/contracts/networks/Registry.json +echo '{"829257324":{"events":{},"links":{},"address":"0x1e5f20669177f5bdf3703ec5ea9c4d4fe3aabd14","transactionHash":""}}' > ../../snet/snet_cli/resources/contracts/networks/SingularityNetToken.json # this should fail (because addresses in networks are invalid ) snet account balance && exit 1 || echo "fail as expected" diff --git a/snet_cli/test/functional_tests/script5_identity1_rpc_mnemonic.sh b/packages/snet_cli/test/functional_tests/script5_identity1_rpc_mnemonic.sh similarity index 100% rename from snet_cli/test/functional_tests/script5_identity1_rpc_mnemonic.sh rename to packages/snet_cli/test/functional_tests/script5_identity1_rpc_mnemonic.sh diff --git a/snet_cli/test/functional_tests/script6_organization.sh b/packages/snet_cli/test/functional_tests/script6_organization.sh similarity index 100% rename from snet_cli/test/functional_tests/script6_organization.sh rename to packages/snet_cli/test/functional_tests/script6_organization.sh diff --git a/snet_cli/test/functional_tests/script7_contracts.sh b/packages/snet_cli/test/functional_tests/script7_contracts.sh similarity index 100% rename from snet_cli/test/functional_tests/script7_contracts.sh rename to packages/snet_cli/test/functional_tests/script7_contracts.sh diff --git a/snet_cli/test/functional_tests/script8_networks.sh b/packages/snet_cli/test/functional_tests/script8_networks.sh similarity index 100% rename from snet_cli/test/functional_tests/script8_networks.sh rename to packages/snet_cli/test/functional_tests/script8_networks.sh diff --git a/snet_cli/test/functional_tests/script9_treasurer.sh b/packages/snet_cli/test/functional_tests/script9_treasurer.sh similarity index 100% rename from snet_cli/test/functional_tests/script9_treasurer.sh rename to packages/snet_cli/test/functional_tests/script9_treasurer.sh diff --git a/snet_cli/test/functional_tests/service_spec1/ExampleService.proto b/packages/snet_cli/test/functional_tests/service_spec1/ExampleService.proto similarity index 100% rename from snet_cli/test/functional_tests/service_spec1/ExampleService.proto rename to packages/snet_cli/test/functional_tests/service_spec1/ExampleService.proto diff --git a/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py b/packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py similarity index 95% rename from snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py rename to packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py index a43aaa7e..8681b573 100644 --- a/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py +++ b/packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py @@ -1,14 +1,16 @@ -from snet_cli.utils import compile_proto, DefaultAttributeObject from concurrent import futures import time import web3 + from snet_cli.mpe_channel_command import MPEChannelCommand from snet_cli.config import Config +from snet.snet_cli.utils import compile_proto, DefaultAttributeObject + compile_proto("../service_spec1", ".", proto_file = "ExampleService.proto") -compile_proto("../../../snet_cli/resources/proto/", ".", proto_file = "state_service.proto") -compile_proto("../../../snet_cli/resources/proto/", ".", proto_file = "control_service.proto") +compile_proto("../../../snet/snet_cli/resources/proto/", ".", proto_file = "state_service.proto") +compile_proto("../../../snet/snet_cli/resources/proto/", ".", proto_file = "control_service.proto") PRICE = 10000 import grpc diff --git a/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py b/packages/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py similarity index 100% rename from snet_cli/test/unit_tests/test_mpe_service_metadata_1.py rename to packages/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py diff --git a/snet_cli/test/utils/reset_environment.sh b/packages/snet_cli/test/utils/reset_environment.sh similarity index 98% rename from snet_cli/test/utils/reset_environment.sh rename to packages/snet_cli/test/utils/reset_environment.sh index d35f6d49..ed2b534a 100755 --- a/snet_cli/test/utils/reset_environment.sh +++ b/packages/snet_cli/test/utils/reset_environment.sh @@ -16,7 +16,7 @@ fi # I. restart ipfs killall ipfs || echo "supress an error" -sudo rm -rf ~/.ipfs/ +sudo rm -rf ~/.ipfs ipfs init ipfs bootstrap rm --all ipfs config Addresses.API /ip4/127.0.0.1/tcp/5002 diff --git a/packages/snet_cli/test/utils/run_all_functional.sh b/packages/snet_cli/test/utils/run_all_functional.sh new file mode 100755 index 00000000..63c69ece --- /dev/null +++ b/packages/snet_cli/test/utils/run_all_functional.sh @@ -0,0 +1,5 @@ +for f in packages/snet_cli/test/functional_tests/*.sh +do + bash -ex packages/snet_cli/test/utils/reset_environment.sh --i-no-what-i-am-doing + bash -ex -c "cd packages/snet_cli/test/functional_tests; bash -ex `basename $f`" +done diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..89b31b4f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +--index-url https://pypi.python.org/simple +packages/snet_cli/ +packages/sdk/ +-e . diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..3f40806e --- /dev/null +++ b/setup.py @@ -0,0 +1,53 @@ +import sys +import os +import subprocess +from setuptools import setup +from setuptools.command.develop import develop +from setuptools.command.install import install + +PACKAGE_NAME = 'snet' +SOURCES = { + 'snet_cli': 'packages/snet_cli', + 'sdk': 'packages/sdk', +} + +def install_packages(sources, develop=False): + print("installing all packages in {} mode".format( + "development" if develop else "normal")) + wd = os.getcwd() + for k, v in sources.items(): + try: + os.chdir(os.path.join(wd, v)) + if develop: + subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-e', '.']) + else: + subprocess.check_call([sys.executable, '-m', 'pip', 'install', '.']) + except Exception as e: + print("Oops, something went wrong installing", k) + print(e) + finally: + os.chdir(wd) + +class DevelopCmd(develop): + """ Add custom steps for the develop command """ + def run(self): + install_packages(SOURCES, develop=True) + develop.run(self) + +class InstallCmd(install): + """ Add custom steps for the install command """ + def run(self): + install_packages(SOURCES, develop=False) + install.run(self) +setup( + name=PACKAGE_NAME, + version="0.0.1", + author="SingularityNET Foundation", + author_email="info@singularitynet.io", + description="SingularityNET Monorepo", + license="MIT", + cmdclass={ + 'install': InstallCmd, + 'develop': DevelopCmd, + } +) diff --git a/snet_cli/.gitignore b/snet_cli/.gitignore deleted file mode 100644 index 3e31273b..00000000 --- a/snet_cli/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -venv/ -snet_cli.egg-info/ -snet_cli/resources/contracts/abi -snet_cli/resources/contracts/networks -snet_cli/resources/proto/*.py -build/ -dist/ diff --git a/snet_cli/MANIFEST.in b/snet_cli/MANIFEST.in deleted file mode 100644 index c5e35bef..00000000 --- a/snet_cli/MANIFEST.in +++ /dev/null @@ -1,5 +0,0 @@ -include snet_cli/resources/proto/* -include snet_cli/resources/contracts/abi/* -include snet_cli/resources/contracts/networks/* -include snet_cli/resources/package.json -include snet_cli/_vendor/* diff --git a/snet_cli/scripts/blockchain b/snet_cli/scripts/blockchain deleted file mode 100755 index 4edb62ef..00000000 --- a/snet_cli/scripts/blockchain +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 - -import os -import pathlib -import shutil -import subprocess -import sys - - -def main(): - assert len(sys.argv) > 1, "please select a target from 'install', 'uninstall'" - target = sys.argv[1] - blockchain_dir = pathlib.Path(__file__).absolute().parent.parent.parent.joinpath("blockchain") - node_modules_dir = blockchain_dir.joinpath("node_modules") - platform_json_src_dir = node_modules_dir.joinpath("singularitynet-platform-contracts") - token_json_src_dir = node_modules_dir.joinpath("singularitynet-token-contracts") - token_contract_name = "SingularityNetToken" - contract_json_dest_dir = pathlib.Path(__file__).absolute().parent.parent.joinpath("snet_cli", "resources", "contracts") - abi_contract_names = ["Registry", "MultiPartyEscrow"] - networks_contract_names = ["Registry", "MultiPartyEscrow"] - - npm_location = shutil.which('npm') - if not npm_location: - raise Exception("This script requires 'npm' to be installed and in your PATH") - - if target == "install": - shutil.rmtree(contract_json_dest_dir) - - subprocess.call([npm_location, "install"], cwd=blockchain_dir) - - os.makedirs(contract_json_dest_dir.joinpath("abi"), exist_ok=True) - os.makedirs(contract_json_dest_dir.joinpath("networks"), exist_ok=True) - - for contract_name in abi_contract_names: - shutil.copy(platform_json_src_dir.joinpath("abi", "{}.json".format(contract_name)), - contract_json_dest_dir.joinpath("abi", "{}.json".format(contract_name))) - for contract_name in networks_contract_names: - shutil.copy(platform_json_src_dir.joinpath("networks", "{}.json".format(contract_name)), - contract_json_dest_dir.joinpath("networks", "{}.json".format(contract_name))) - - shutil.copy(token_json_src_dir.joinpath("abi", "{}.json".format(token_contract_name)), - contract_json_dest_dir.joinpath("abi", "{}.json".format(token_contract_name))) - shutil.copy(token_json_src_dir.joinpath("networks", "{}.json".format(token_contract_name)), - contract_json_dest_dir.joinpath("networks", "{}.json".format(token_contract_name))) - elif target == "uninstall": - try: - shutil.rmtree(node_modules_dir) - shutil.rmtree(contract_json_dest_dir.joinpath("abi")) - shutil.rmtree(contract_json_dest_dir.joinpath("networks")) - except FileNotFoundError: - pass - - -if __name__ == "__main__": - main() diff --git a/snet_cli/test/utils/run_all_functional.sh b/snet_cli/test/utils/run_all_functional.sh deleted file mode 100755 index 7d38afb8..00000000 --- a/snet_cli/test/utils/run_all_functional.sh +++ /dev/null @@ -1,5 +0,0 @@ -for f in snet_cli/test/functional_tests/*.sh -do - bash -ex snet_cli/test/utils/reset_environment.sh --i-no-what-i-am-doing - bash -ex -c "cd snet_cli/test/functional_tests; bash -ex `basename $f`" -done diff --git a/snet_sdk/.gitignore b/snet_sdk/.gitignore deleted file mode 100644 index bbdffa01..00000000 --- a/snet_sdk/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -venv/ -snet_sdk.egg-info/ -snet_sdk/resources/contracts/abi -snet_sdk/resources/contracts/networks -build/ -dist/ diff --git a/snet_sdk/MANIFEST.in b/snet_sdk/MANIFEST.in deleted file mode 100644 index 03b788b6..00000000 --- a/snet_sdk/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include snet_sdk/resources/contracts/abi/* -include snet_sdk/resources/contracts/networks/* diff --git a/snet_sdk/blockchain/package.json b/snet_sdk/blockchain/package.json deleted file mode 100644 index 733f416d..00000000 --- a/snet_sdk/blockchain/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": { - "singularitynet-platform-contracts": "0.2.6", - "singularitynet-token-contracts": "2.0.1" - } -} diff --git a/snet_sdk/setup.py b/snet_sdk/setup.py deleted file mode 100644 index e81f6706..00000000 --- a/snet_sdk/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -from setuptools import setup, find_packages -import re - -version_dict = {} -with open("./snet_sdk/version.py") as fp: - exec(fp.read(), version_dict) - -setup( - name='snet_sdk', - version=version_dict['__version__'], - packages=find_packages(), - url='https://github.com/singnet/snet-cli/tree/master/snet_sdk', - license='MIT', - author='SingularityNET Foundation', - author_email='info@singularitynet.io', - description='SingularityNET Python SDK', - python_requires='>=3.6', - install_requires=[ - 'grpcio-tools==1.17.1', - 'ecdsa==0.13', - 'web3==4.2.1', - 'ipfsapi==0.4.2.post1', - 'rfc3986==1.1.0' - ], - include_package_data=True -) diff --git a/snet_sdk/snet_sdk/contract.py b/snet_sdk/snet_sdk/contract.py deleted file mode 100644 index c23eaddc..00000000 --- a/snet_sdk/snet_sdk/contract.py +++ /dev/null @@ -1,27 +0,0 @@ -class Contract: - def __init__(self, w3, address, abi): - self.w3 = w3 - self.contract = self.w3.eth.contract(address=self.w3.toChecksumAddress(address), abi=abi) - self.abi = abi - - def call(self, function_name, *positional_inputs, **named_inputs): - return getattr(self.contract.functions, function_name)(*positional_inputs, **named_inputs).call() - - def build_transaction(self, function_name, from_address, gas_price, *positional_inputs, **named_inputs): - nonce = self.w3.eth.getTransactionCount(from_address) - chain_id = self.w3.version.network - return getattr(self.contract.functions, function_name)(*positional_inputs, **named_inputs).buildTransaction({ - "from": from_address, - "nonce": nonce, - "gasPrice": gas_price, - "chainId": int(chain_id) - }) - - def process_receipt(self, receipt): - events = [] - - contract_events = map(lambda e: e["name"], filter(lambda e: e["type"] == "event", self.abi)) - for contract_event in contract_events: - events.extend(getattr(self.contract.events, contract_event)().processReceipt(receipt)) - - return events diff --git a/snet_sdk/snet_sdk/state_service_pb2.py b/snet_sdk/snet_sdk/state_service_pb2.py deleted file mode 100644 index bac2e3fa..00000000 --- a/snet_sdk/snet_sdk/state_service_pb2.py +++ /dev/null @@ -1,153 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: state_service.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='state_service.proto', - package='escrow', - syntax='proto3', - serialized_pb=_b('\n\x13state_service.proto\x12\x06\x65scrow\"<\n\x13\x43hannelStateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"d\n\x11\x43hannelStateReply\x12\x15\n\rcurrent_nonce\x18\x01 \x01(\x0c\x12\x1d\n\x15\x63urrent_signed_amount\x18\x02 \x01(\x0c\x12\x19\n\x11\x63urrent_signature\x18\x03 \x01(\x0c\x32i\n\x1aPaymentChannelStateService\x12K\n\x0fGetChannelState\x12\x1b.escrow.ChannelStateRequest\x1a\x19.escrow.ChannelStateReply\"\x00\x62\x06proto3') -) - - - - -_CHANNELSTATEREQUEST = _descriptor.Descriptor( - name='ChannelStateRequest', - full_name='escrow.ChannelStateRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='channel_id', full_name='escrow.ChannelStateRequest.channel_id', index=0, - number=1, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='signature', full_name='escrow.ChannelStateRequest.signature', index=1, - number=2, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=31, - serialized_end=91, -) - - -_CHANNELSTATEREPLY = _descriptor.Descriptor( - name='ChannelStateReply', - full_name='escrow.ChannelStateReply', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='current_nonce', full_name='escrow.ChannelStateReply.current_nonce', index=0, - number=1, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='current_signed_amount', full_name='escrow.ChannelStateReply.current_signed_amount', index=1, - number=2, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='current_signature', full_name='escrow.ChannelStateReply.current_signature', index=2, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=93, - serialized_end=193, -) - -DESCRIPTOR.message_types_by_name['ChannelStateRequest'] = _CHANNELSTATEREQUEST -DESCRIPTOR.message_types_by_name['ChannelStateReply'] = _CHANNELSTATEREPLY -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ChannelStateRequest = _reflection.GeneratedProtocolMessageType('ChannelStateRequest', (_message.Message,), dict( - DESCRIPTOR = _CHANNELSTATEREQUEST, - __module__ = 'state_service_pb2' - # @@protoc_insertion_point(class_scope:escrow.ChannelStateRequest) - )) -_sym_db.RegisterMessage(ChannelStateRequest) - -ChannelStateReply = _reflection.GeneratedProtocolMessageType('ChannelStateReply', (_message.Message,), dict( - DESCRIPTOR = _CHANNELSTATEREPLY, - __module__ = 'state_service_pb2' - # @@protoc_insertion_point(class_scope:escrow.ChannelStateReply) - )) -_sym_db.RegisterMessage(ChannelStateReply) - - - -_PAYMENTCHANNELSTATESERVICE = _descriptor.ServiceDescriptor( - name='PaymentChannelStateService', - full_name='escrow.PaymentChannelStateService', - file=DESCRIPTOR, - index=0, - options=None, - serialized_start=195, - serialized_end=300, - methods=[ - _descriptor.MethodDescriptor( - name='GetChannelState', - full_name='escrow.PaymentChannelStateService.GetChannelState', - index=0, - containing_service=None, - input_type=_CHANNELSTATEREQUEST, - output_type=_CHANNELSTATEREPLY, - options=None, - ), -]) -_sym_db.RegisterServiceDescriptor(_PAYMENTCHANNELSTATESERVICE) - -DESCRIPTOR.services_by_name['PaymentChannelStateService'] = _PAYMENTCHANNELSTATESERVICE - -# @@protoc_insertion_point(module_scope) diff --git a/snet_sdk/snet_sdk/state_service_pb2_grpc.py b/snet_sdk/snet_sdk/state_service_pb2_grpc.py deleted file mode 100644 index bb7e8122..00000000 --- a/snet_sdk/snet_sdk/state_service_pb2_grpc.py +++ /dev/null @@ -1,54 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -import snet_sdk.state_service_pb2 as state__service__pb2 - - -class PaymentChannelStateServiceStub(object): - """PaymentChannelStateService contains methods to get the MultiPartyEscrow - payment channel state. - channel_id, channel_nonce, value and amount fields below in fact are - Solidity uint256 values. Which are big-endian integers padded by zeros, see - https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetChannelState = channel.unary_unary( - '/escrow.PaymentChannelStateService/GetChannelState', - request_serializer=state__service__pb2.ChannelStateRequest.SerializeToString, - response_deserializer=state__service__pb2.ChannelStateReply.FromString, - ) - - -class PaymentChannelStateServiceServicer(object): - """PaymentChannelStateService contains methods to get the MultiPartyEscrow - payment channel state. - channel_id, channel_nonce, value and amount fields below in fact are - Solidity uint256 values. Which are big-endian integers padded by zeros, see - https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding - """ - - def GetChannelState(self, request, context): - """GetChannelState method returns a channel state by channel id. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_PaymentChannelStateServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetChannelState': grpc.unary_unary_rpc_method_handler( - servicer.GetChannelState, - request_deserializer=state__service__pb2.ChannelStateRequest.FromString, - response_serializer=state__service__pb2.ChannelStateReply.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'escrow.PaymentChannelStateService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/snet_sdk/snet_sdk/utils.py b/snet_sdk/snet_sdk/utils.py deleted file mode 100644 index 5654523d..00000000 --- a/snet_sdk/snet_sdk/utils.py +++ /dev/null @@ -1,41 +0,0 @@ -import os -import json -from pathlib import PurePath - -import web3 -import ecdsa -import hashlib - - -cur_dir = PurePath(os.path.realpath(__file__)).parent - - -def get_contract_object(w3, contract_file): - with open(cur_dir.joinpath("resources", "contracts", "abi", contract_file)) as f: - abi = json.load(f) - with open(cur_dir.joinpath("resources", "contracts", "networks", contract_file)) as f: - networks = json.load(f) - address = w3.toChecksumAddress(networks[w3.version.network]["address"]) - return w3.eth.contract(abi=abi, address=address) - - -def get_contract_deployment_block(w3, contract_file): - with open(cur_dir.joinpath("resources", "contracts", "networks", contract_file)) as f: - networks = json.load(f) - txn_hash = networks[w3.version.network]["transactionHash"] - return w3.eth.getTransactionReceipt(txn_hash).blockNumber - - -def normalize_private_key(private_key): - if private_key.startswith("0x"): - private_key = bytes(bytearray.fromhex(private_key[2:])) - else: - private_key = bytes(bytearray.fromhex(private_key)) - return private_key - - -def get_address_from_private(private_key): - public_key = ecdsa.SigningKey.from_string(string=private_key, - curve=ecdsa.SECP256k1, - hashfunc=hashlib.sha256).get_verifying_key() - return web3.Web3.toChecksumAddress("0x" + web3.Web3.sha3(hexstr=public_key.to_string().hex())[12:].hex()) diff --git a/snet_sdk/snet_sdk/version.py b/snet_sdk/snet_sdk/version.py deleted file mode 100644 index ae736254..00000000 --- a/snet_sdk/snet_sdk/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.1.3" From 7113b172ec0375eb79cde355da082b68c938a743 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Sat, 8 Jun 2019 04:22:16 +0200 Subject: [PATCH 09/11] Fixed mutable argument in service client constructor, getting abi for OpenChannel event from the contract object using web3 function passing instance of payment channel management strategy to service client --- packages/sdk/snet/sdk/__init__.py | 8 ++++++-- packages/sdk/snet/sdk/mpe_contract.py | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/sdk/snet/sdk/__init__.py b/packages/sdk/snet/sdk/__init__.py index 59c70790..fadb1bcd 100644 --- a/packages/sdk/snet/sdk/__init__.py +++ b/packages/sdk/snet/sdk/__init__.py @@ -43,13 +43,17 @@ def __init__( self.account = Account(self.web3, config, self.mpe_contract) - def create_service_client(self, org_id, service_id, service_stub, group_name="default_group", payment_channel_management_strategy=PaymentChannelManagementStrategy, options={}): + def create_service_client(self, org_id, service_id, service_stub, group_name="default_group", payment_channel_management_strategy=PaymentChannelManagementStrategy, options=None): + if options is None: + options = dict() + service_metadata = self.service_metadata(org_id, service_id) try: group = next(filter(lambda group: group["group_name"] == group_name, service_metadata.groups)) except StopIteration: raise ValueError("Group[name: {}] not found for orgId: {} and serviceId: {}".format(group_name, org_id, service_id)) - service_client = ServiceClient(self, service_metadata, group, service_stub, payment_channel_management_strategy(self), options) + strategy = payment_channel_management_strategy(self) + service_client = ServiceClient(self, service_metadata, group, service_stub, strategy, options) return service_client def service_metadata(self, org_id, service_id): diff --git a/packages/sdk/snet/sdk/mpe_contract.py b/packages/sdk/snet/sdk/mpe_contract.py index 8a608fce..8ef3dcaf 100644 --- a/packages/sdk/snet/sdk/mpe_contract.py +++ b/packages/sdk/snet/sdk/mpe_contract.py @@ -3,11 +3,10 @@ import web3 from snet.sdk.payment_channel import PaymentChannel -from snet.snet_cli.utils import get_contract_object, get_contract_deployment_block +from snet.snet_cli.utils import get_contract_object, get_contract_deployment_block BLOCKS_PER_BATCH = 20000 -EVENT_ABI = {'anonymous': False, 'inputs': [{'indexed': False, 'name': 'channelId', 'type': 'uint256'}, {'indexed': False, 'name': 'nonce', 'type': 'uint256'}, {'indexed': True, 'name': 'sender', 'type': 'address'}, {'indexed': False, 'name': 'signer', 'type': 'address'}, {'indexed': True, 'name': 'recipient', 'type': 'address'}, {'indexed': True, 'name': 'groupId', 'type': 'bytes32'}, {'indexed': False, 'name': 'amount', 'type': 'uint256'}, {'indexed': False, 'name': 'expiration', 'type': 'uint256'}], 'name': 'ChannelOpen', 'type': 'event'} class MPEContract: @@ -32,7 +31,8 @@ def get_past_open_channels(self, account, service, starting_block_number=0, to_b logs = logs + self.web3.eth.getLogs({"fromBlock" : from_block, "toBlock": to_block, "address": self.contract.address, "topics": self.event_topics}) from_block = to_block + 1 - channels_opened = list(filter(lambda channel: channel.sender == account.address and channel.signer == account.signer_address and channel.recipient == service.group["payment_address"], [web3.utils.events.get_event_data(EVENT_ABI, l)["args"] for l in logs])) + event_abi = self.contract._find_matching_event_abi(event_name="ChannelOpen") + channels_opened = list(filter(lambda channel: channel.sender == account.address and channel.signer == account.signer_address and channel.recipient == service.group["payment_address"], [web3.utils.events.get_event_data(event_abi, l)["args"] for l in logs])) return list(map(lambda channel: PaymentChannel(channel["channelId"], self.web3, account, service, self), channels_opened)) From 22ed5db6038c08c21ccebb3ebe4854a63deff15c Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Tue, 11 Jun 2019 05:01:05 +0200 Subject: [PATCH 10/11] fixed basic setup for CLI, added setup and requirements for namespace package, moved version identifier --- packages/snet_cli/.gitignore | 1 + .../snet_cli/scripts/package-namespace-pip | 3 + packages/snet_cli/setup-namespace.py | 68 +++++++++++++++++++ packages/snet_cli/setup.py | 2 +- .../snet_cli/{ => snet}/snet_cli/version.py | 0 5 files changed, 73 insertions(+), 1 deletion(-) create mode 100755 packages/snet_cli/scripts/package-namespace-pip create mode 100644 packages/snet_cli/setup-namespace.py rename packages/snet_cli/{ => snet}/snet_cli/version.py (100%) diff --git a/packages/snet_cli/.gitignore b/packages/snet_cli/.gitignore index e86739fb..0bf999a7 100644 --- a/packages/snet_cli/.gitignore +++ b/packages/snet_cli/.gitignore @@ -1,5 +1,6 @@ venv/ snet_cli.egg-info/ +snet.snet_cli.egg-info/ snet/snet_cli/resources/contracts/abi snet/snet_cli/resources/contracts/networks snet/snet_cli/resources/node_modules diff --git a/packages/snet_cli/scripts/package-namespace-pip b/packages/snet_cli/scripts/package-namespace-pip new file mode 100755 index 00000000..086a88f2 --- /dev/null +++ b/packages/snet_cli/scripts/package-namespace-pip @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +python3.6 setup-namespace.py sdist bdist_wheel diff --git a/packages/snet_cli/setup-namespace.py b/packages/snet_cli/setup-namespace.py new file mode 100644 index 00000000..0fec53da --- /dev/null +++ b/packages/snet_cli/setup-namespace.py @@ -0,0 +1,68 @@ +from setuptools import setup, find_namespace_packages +from setuptools.command.develop import develop as _develop +from setuptools.command.install import install as _install + + +def install_and_compile_proto(): + import snet.snet_cli + from snet.snet_cli.utils import compile_proto as compile_proto + from pathlib import Path + proto_dir = Path(__file__).absolute().parent.joinpath("snet", "snet_cli", "resources", "proto") + dest_dir = Path(snet.snet_cli.__file__).absolute().parent.joinpath("resources", "proto") + print(proto_dir, "->", dest_dir) + for fn in proto_dir.glob('*.proto'): + print("Compiling protobuf", fn) + compile_proto(proto_dir, dest_dir, proto_file=fn) + + +class develop(_develop): + """Post-installation for development mode.""" + + def run(self): + _develop.run(self) + self.execute(install_and_compile_proto, (), msg="Compile protocol buffers") + + +class install(_install): + """Post-installation for installation mode.""" + + def run(self): + _install.run(self) + self.execute(install_and_compile_proto, (), msg="Compile protocol buffers") + + +version_dict = {} +with open("./snet/snet_cli/version.py") as fp: + exec(fp.read(), version_dict) +setup( + name='snet.snet-cli', + version=version_dict['__version__'], + packages=find_namespace_packages(include=['snet.*']), + namespace_packages=['snet'], + url='https://github.com/singnet/snet-cli', + license='MIT', + author='SingularityNET Foundation', + author_email='info@singularitynet.io', + description='SingularityNET CLI standalone namespace package', + python_requires='>=3.6', + install_requires=[ + 'grpcio-tools==1.19.0', + 'jsonrpcclient==2.5.2', + 'web3==4.8.3', + 'mnemonic==0.18', + 'pycoin>=0.80', + 'rlp==1.0.1', + 'pyyaml>=4.2b1', + 'ipfsapi==0.4.2.post1', + 'rfc3986==1.1.0', + 'pymultihash==0.8.2', + 'base58==1.0.2', + 'argcomplete>=1.9.4', + 'grpcio-health-checking==1.19.0' + ], + cmdclass={ + 'develop': develop, + 'install': install + }, + include_package_data=True +) diff --git a/packages/snet_cli/setup.py b/packages/snet_cli/setup.py index fd0fa2d4..faca0963 100644 --- a/packages/snet_cli/setup.py +++ b/packages/snet_cli/setup.py @@ -32,7 +32,7 @@ def run(self): version_dict = {} -with open("./snet_cli/version.py") as fp: +with open("./snet/snet_cli/version.py") as fp: exec(fp.read(), version_dict) setup( name='snet-cli', diff --git a/packages/snet_cli/snet_cli/version.py b/packages/snet_cli/snet/snet_cli/version.py similarity index 100% rename from packages/snet_cli/snet_cli/version.py rename to packages/snet_cli/snet/snet_cli/version.py From ca6044b0cd5cef975122996f25c34fc32802ca60 Mon Sep 17 00:00:00 2001 From: Valerio Versace Date: Mon, 24 Jun 2019 20:27:59 +0200 Subject: [PATCH 11/11] Moved mpe_channel_command, mpe_service_metadata and contract to shared package Refactored SDK package to use shared code --- packages/sdk/snet/sdk/__init__.py | 22 ++++++------ packages/sdk/snet/sdk/account.py | 2 +- .../default.py | 34 ++++++------------- packages/sdk/snet/sdk/service_client.py | 6 ++-- .../snet_cli/{ => snet}/snet_cli/contract.py | 0 .../snet_cli/mpe_channel_command.py | 4 +-- .../snet_cli/mpe_service_metadata.py | 0 .../{ => snet}/snet_cli/utils_ipfs.py | 0 packages/snet_cli/snet_cli/arguments.py | 2 +- packages/snet_cli/snet_cli/commands.py | 2 +- .../snet_cli/snet_cli/mpe_client_command.py | 2 +- .../snet_cli/snet_cli/mpe_service_command.py | 6 ++-- packages/snet_cli/snet_cli/sdk_command.py | 3 +- .../simple_daemon/test_simple_daemon.py | 2 +- .../unit_tests/test_mpe_service_metadata_1.py | 3 +- 15 files changed, 39 insertions(+), 49 deletions(-) rename packages/snet_cli/{ => snet}/snet_cli/contract.py (100%) rename packages/snet_cli/{ => snet}/snet_cli/mpe_channel_command.py (99%) rename packages/snet_cli/{ => snet}/snet_cli/mpe_service_metadata.py (100%) rename packages/snet_cli/{ => snet}/snet_cli/utils_ipfs.py (100%) diff --git a/packages/sdk/snet/sdk/__init__.py b/packages/sdk/snet/sdk/__init__.py index fadb1bcd..5228005a 100644 --- a/packages/sdk/snet/sdk/__init__.py +++ b/packages/sdk/snet/sdk/__init__.py @@ -3,7 +3,7 @@ from urllib.parse import urljoin import web3 -from web3.gas_strategies.rpc import rpc_gas_price_strategy +from web3.gas_strategies.time_based import medium_gas_price_strategy from rfc3986 import urlparse import ipfsapi from web3.datastructures import AttributeDict @@ -14,6 +14,8 @@ from snet.sdk.payment_channel_management_strategies.default import PaymentChannelManagementStrategy from snet.snet_cli.utils import get_contract_object +from snet.snet_cli.utils_ipfs import bytesuri_to_hash, get_from_ipfs_and_checkhash +from snet.snet_cli.mpe_service_metadata import mpe_service_metadata_from_json class SnetSDK: @@ -28,7 +30,7 @@ def __init__( eth_rpc_endpoint = self._config.get("eth_rpc_endpoint", "https://mainnet.infura.io") provider = web3.HTTPProvider(eth_rpc_endpoint) self.web3 = web3.Web3(provider) - self.web3.eth.setGasPriceStrategy(rpc_gas_price_strategy) + self.web3.eth.setGasPriceStrategy(medium_gas_price_strategy) self.mpe_contract = MPEContract(self.web3) @@ -43,20 +45,20 @@ def __init__( self.account = Account(self.web3, config, self.mpe_contract) - def create_service_client(self, org_id, service_id, service_stub, group_name="default_group", payment_channel_management_strategy=PaymentChannelManagementStrategy, options=None): + def create_service_client(self, org_id, service_id, service_stub, group_name=None, payment_channel_management_strategy=PaymentChannelManagementStrategy, options=None): if options is None: options = dict() - service_metadata = self.service_metadata(org_id, service_id) - try: - group = next(filter(lambda group: group["group_name"] == group_name, service_metadata.groups)) - except StopIteration: - raise ValueError("Group[name: {}] not found for orgId: {} and serviceId: {}".format(group_name, org_id, service_id)) + service_metadata = self.get_service_metadata(org_id, service_id) + group = service_metadata.get_group(group_name) strategy = payment_channel_management_strategy(self) service_client = ServiceClient(self, service_metadata, group, service_stub, strategy, options) return service_client - def service_metadata(self, org_id, service_id): + + def get_service_metadata(self, org_id, service_id): (found, registration_id, metadata_uri, tags) = self.registry_contract.functions.getServiceRegistrationById(bytes(org_id, "utf-8"), bytes(service_id, "utf-8")).call() - metadata = AttributeDict(json.loads(self.ipfs_client.cat(metadata_uri.rstrip(b"\0").decode('ascii')[7:]))) + metadata_hash = bytesuri_to_hash(metadata_uri) + metadata_json = get_from_ipfs_and_checkhash(self.ipfs_client, metadata_hash) + metadata = mpe_service_metadata_from_json(metadata_json) return metadata diff --git a/packages/sdk/snet/sdk/account.py b/packages/sdk/snet/sdk/account.py index eb1a6460..b8971ea0 100644 --- a/packages/sdk/snet/sdk/account.py +++ b/packages/sdk/snet/sdk/account.py @@ -49,7 +49,7 @@ def _get_gas_price(self): def _send_signed_transaction(self, contract_fn, *args): transaction = contract_fn(*args).buildTransaction({ "chainId": int(self.web3.version.network), - "gas": DEFAULT_GAS, + "gas": DEFAULT_GAS, "gasPrice": self._get_gas_price(), "nonce": self._get_nonce() }) diff --git a/packages/sdk/snet/sdk/payment_channel_management_strategies/default.py b/packages/sdk/snet/sdk/payment_channel_management_strategies/default.py index 56b5ff99..3a8d1e45 100644 --- a/packages/sdk/snet/sdk/payment_channel_management_strategies/default.py +++ b/packages/sdk/snet/sdk/payment_channel_management_strategies/default.py @@ -9,32 +9,20 @@ def select_channel(self, service_client): service_client.load_open_channels() service_client.update_channel_states() payment_channels = service_client.payment_channels - service_call_price = service_client.metadata.pricing["price_in_cogs"] + service_call_price = service_client.metadata["pricing"]["price_in_cogs"] mpe_balance = account.escrow_balance() default_expiration = service_client.default_channel_expiration() - if len(payment_channels) == 0: - if mpe_balance > service_call_price*self.call_allowance: - return service_client.open_channel(service_call_price*self.call_allowance, default_expiration + self.block_offset) - return service_client.deposit_and_open_channel(service_call_price*self.call_allowance - mpe_balance, default_expiration + self.block_offset) - - funded_valid_channels = [channel for channel in payment_channels if self._has_sufficient_funds(channel, service_call_price) and self._is_valid(channel, default_expiration)] - if len(funded_valid_channels): - return funded_valid_channels[0] - - funded_channels = [channel for channel in payment_channels if self._has_sufficient_funds(channel, service_call_price)] - if len(funded_channels): - funded_channels[0].extend_expiration(default_expiration + self.block_offset) - return funded_channels[0] - - valid_channels = [channel for channel in payment_channels if self._is_valid(channel, default_expiration)] - if len(valid_channels): - valid_channels[0].add_funds(service_call_price*self.call_allowance) - return valid_channels[0] - - first_expired_and_unfunded_channel = payment_channels[0] - first_expired_and_unfunded_channel.extend_and_add_funds(default_expiration + self.block_offset, service_call_price*self.call_allowance) - return first_expired_and_unfunded_channel + payment_channel = payment_channels[0] + + if self._has_sufficient_funds(payment_channel, service_call_price) and not self._is_valid(payment_channel, default_expiration): + payment_channel.extend_expiration(default_expiration + self.block_offset) + elif not self._has_sufficient_funds(payment_channel, service_call_price) and self._is_valid(payment_channel, default_expiration): + payment_channel.add_funds(service_call_price*self.call_allowance) + elif not self._has_sufficient_funds(payment_channel, service_call_price) and not self._is_valid(payment_channel, default_expiration): + payment_channel.extend_and_add_funds(default_expiration + self.block_offset, service_call_price*self.call_allowance) + + return payment_channel @staticmethod diff --git a/packages/sdk/snet/sdk/service_client.py b/packages/sdk/snet/sdk/service_client.py index 31b71394..912d0d83 100644 --- a/packages/sdk/snet/sdk/service_client.py +++ b/packages/sdk/snet/sdk/service_client.py @@ -25,7 +25,7 @@ def __init__(self, sdk, metadata, group, service_stub, payment_channel_managemen self.group = group self.metadata = metadata self.payment_channel_management_strategy = payment_channel_management_strategy - self.expiry_threshold = self.metadata.payment_expiration_threshold + self.expiry_threshold = self.metadata["payment_expiration_threshold"] self._base_grpc_channel = self._get_grpc_channel() self.grpc_channel = grpc.intercept_channel(self._base_grpc_channel, generic_client_interceptor.create(self._intercept_call)) self.payment_channel_state_service_client = self._generate_payment_channel_state_service_client() @@ -46,7 +46,7 @@ def _generate_grpc_stub(self, service_stub): def _get_grpc_channel(self): endpoint = self.options.get("endpoint", None) if endpoint is None: - endpoint = next(filter(lambda endpoint: endpoint["group_name"] == self.group["group_name"], self.metadata["endpoints"]))["endpoint"] + endpoint = self.metadata.get_endpoints_for_group(self.group["group_name"])[0] endpoint_object = urlparse(endpoint) if endpoint_object.port is not None: channel_endpoint = endpoint_object.hostname + ":" + str(endpoint_object.port) @@ -63,7 +63,7 @@ def _get_grpc_channel(self): def _get_service_call_metadata(self): channel = self.payment_channel_management_strategy.select_channel(self) - amount = channel.state["last_signed_amount"] + int(self.metadata.pricing["price_in_cogs"]) + amount = channel.state["last_signed_amount"] + int(self.metadata["pricing"]["price_in_cogs"]) message = web3.Web3.soliditySha3( ["address", "uint256", "uint256", "uint256"], [self.sdk.mpe_contract.contract.address, channel.channel_id, channel.state["nonce"], amount] diff --git a/packages/snet_cli/snet_cli/contract.py b/packages/snet_cli/snet/snet_cli/contract.py similarity index 100% rename from packages/snet_cli/snet_cli/contract.py rename to packages/snet_cli/snet/snet_cli/contract.py diff --git a/packages/snet_cli/snet_cli/mpe_channel_command.py b/packages/snet_cli/snet/snet_cli/mpe_channel_command.py similarity index 99% rename from packages/snet_cli/snet_cli/mpe_channel_command.py rename to packages/snet_cli/snet/snet_cli/mpe_channel_command.py index ad027878..8f4e9865 100644 --- a/packages/snet_cli/snet_cli/mpe_channel_command.py +++ b/packages/snet_cli/snet/snet_cli/mpe_channel_command.py @@ -10,10 +10,10 @@ from web3.utils.events import get_event_data from snet_cli.mpe_service_command import MPEServiceCommand -from snet_cli.mpe_service_metadata import load_mpe_service_metadata -from snet_cli.utils_ipfs import safe_extract_proto_from_ipfs from snet_cli.utils_agi2cogs import cogs2stragi +from snet.snet_cli.utils_ipfs import safe_extract_proto_from_ipfs +from snet.snet_cli.mpe_service_metadata import load_mpe_service_metadata from snet.snet_cli.utils import compile_proto, get_contract_def, abi_get_element_by_name, abi_decode_struct_to_dict diff --git a/packages/snet_cli/snet_cli/mpe_service_metadata.py b/packages/snet_cli/snet/snet_cli/mpe_service_metadata.py similarity index 100% rename from packages/snet_cli/snet_cli/mpe_service_metadata.py rename to packages/snet_cli/snet/snet_cli/mpe_service_metadata.py diff --git a/packages/snet_cli/snet_cli/utils_ipfs.py b/packages/snet_cli/snet/snet_cli/utils_ipfs.py similarity index 100% rename from packages/snet_cli/snet_cli/utils_ipfs.py rename to packages/snet_cli/snet/snet_cli/utils_ipfs.py diff --git a/packages/snet_cli/snet_cli/arguments.py b/packages/snet_cli/snet_cli/arguments.py index 92c334bd..38b11daa 100644 --- a/packages/snet_cli/snet_cli/arguments.py +++ b/packages/snet_cli/snet_cli/arguments.py @@ -9,13 +9,13 @@ from snet_cli.identity import get_identity_types from snet_cli.mpe_account_command import MPEAccountCommand from snet_cli.mpe_service_command import MPEServiceCommand -from snet_cli.mpe_channel_command import MPEChannelCommand from snet_cli.mpe_client_command import MPEClientCommand from snet_cli.mpe_treasurer_command import MPETreasurerCommand from snet_cli.sdk_command import SDKCommand from snet_cli.utils_agi2cogs import stragi2cogs from snet_cli.config import Config, get_session_keys, get_session_network_keys_removable +from snet.snet_cli.mpe_channel_command import MPEChannelCommand from snet.snet_cli.utils import type_converter, get_contract_def, RESOURCES_PATH diff --git a/packages/snet_cli/snet_cli/commands.py b/packages/snet_cli/snet_cli/commands.py index 0f5ffd20..8f854d91 100644 --- a/packages/snet_cli/snet_cli/commands.py +++ b/packages/snet_cli/snet_cli/commands.py @@ -15,9 +15,9 @@ from snet_cli.utils_config import get_contract_address, get_field_from_args_or_session, read_default_contract_address from snet_cli.identity import RpcIdentityProvider, MnemonicIdentityProvider, TrezorIdentityProvider, \ LedgerIdentityProvider, KeyIdentityProvider, KeyStoreIdentityProvider -from snet_cli.contract import Contract from snet_cli.identity import get_kws_for_identity_type +from snet.snet_cli.contract import Contract from snet.snet_cli.utils import DefaultAttributeObject, get_web3, serializable, type_converter, get_contract_def, get_cli_version, bytes32_to_str diff --git a/packages/snet_cli/snet_cli/mpe_client_command.py b/packages/snet_cli/snet_cli/mpe_client_command.py index 82fa1885..47713759 100644 --- a/packages/snet_cli/snet_cli/mpe_client_command.py +++ b/packages/snet_cli/snet_cli/mpe_client_command.py @@ -6,10 +6,10 @@ import grpc from eth_account.messages import defunct_hash_message -from snet_cli.mpe_channel_command import MPEChannelCommand from snet_cli.utils_agi2cogs import cogs2stragi from snet.snet_cli.utils import open_grpc_channel, rgetattr, compile_proto, RESOURCES_PATH +from snet.snet_cli.mpe_channel_command import MPEChannelCommand from snet.snet_cli.utils_proto import import_protobuf_from_dir, switch_to_json_payload_encoding diff --git a/packages/snet_cli/snet_cli/mpe_service_command.py b/packages/snet_cli/snet_cli/mpe_service_command.py index 9c8f416f..32f45c2d 100644 --- a/packages/snet_cli/snet_cli/mpe_service_command.py +++ b/packages/snet_cli/snet_cli/mpe_service_command.py @@ -7,10 +7,10 @@ from grpc_health.v1 import health_pb2_grpc as heartb_pb2_grpc from snet_cli.commands import BlockchainCommand -import snet_cli.utils_ipfs as utils_ipfs -from snet_cli.mpe_service_metadata import MPEServiceMetadata, load_mpe_service_metadata, mpe_service_metadata_from_json -from snet_cli.utils_ipfs import hash_to_bytesuri, bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs +import snet.snet_cli.utils_ipfs as utils_ipfs +from snet.snet_cli.utils_ipfs import hash_to_bytesuri, bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs +from snet.snet_cli.mpe_service_metadata import MPEServiceMetadata, load_mpe_service_metadata, mpe_service_metadata_from_json from snet.snet_cli.utils import type_converter, bytes32_to_str, open_grpc_channel class MPEServiceCommand(BlockchainCommand): diff --git a/packages/snet_cli/snet_cli/sdk_command.py b/packages/snet_cli/snet_cli/sdk_command.py index a4a651c0..58c62e28 100644 --- a/packages/snet_cli/snet_cli/sdk_command.py +++ b/packages/snet_cli/snet_cli/sdk_command.py @@ -3,9 +3,8 @@ from tempfile import TemporaryDirectory from snet_cli.mpe_service_command import MPEServiceCommand -from snet_cli.utils_ipfs import bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs -from snet_cli.mpe_service_metadata import mpe_service_metadata_from_json +from snet.snet_cli.utils_ipfs import bytesuri_to_hash, get_from_ipfs_and_checkhash, safe_extract_proto_from_ipfs from snet.snet_cli.utils import type_converter, bytes32_to_str, compile_proto class SDKCommand(MPEServiceCommand): diff --git a/packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py b/packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py index 8681b573..b965bc5a 100644 --- a/packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py +++ b/packages/snet_cli/test/functional_tests/simple_daemon/test_simple_daemon.py @@ -2,9 +2,9 @@ import time import web3 -from snet_cli.mpe_channel_command import MPEChannelCommand from snet_cli.config import Config +from snet.snet_cli.mpe_channel_command import MPEChannelCommand from snet.snet_cli.utils import compile_proto, DefaultAttributeObject diff --git a/packages/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py b/packages/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py index a95ae516..fa9cad91 100644 --- a/packages/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py +++ b/packages/snet_cli/test/unit_tests/test_mpe_service_metadata_1.py @@ -1,5 +1,6 @@ import unittest -from snet_cli.mpe_service_metadata import MPEServiceMetadata + +from snet.snet_cli.mpe_service_metadata import MPEServiceMetadata class TestStringMethods(unittest.TestCase):