diff --git a/.circleci/config.yml b/.circleci/config.yml index 49adf8ef..c6f2d034 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: docker: - - image: circleci/python:3.8.3-node + - image: cimg/python:3.11.6-node working_directory: ~/singnet/snet-cli environment: TRIGGER_BUILD_BRANCH: master @@ -17,8 +17,8 @@ jobs: [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" source "$NVM_DIR/nvm.sh" - nvm install 14.19.3 - nvm alias default 14.19.3 + nvm install 18.18.2 + nvm alias default 18.18.2 nvm use default - run: name: Install tools and ipfs @@ -37,10 +37,10 @@ jobs: ./packages/snet_cli/scripts/blockchain install sudo pip3 install -e ./packages/snet_cli - run: - name: Install snet-dk + name: Install snet-sdk command: | - ./packages/snet_cli/scripts/blockchain install - sudo pip3 install -e ./packages/sdk + ./packages/snet_cli/scripts/blockchain install + sudo pip3 install -e ./packages/sdk - run: name: Install platform-contracts from master command: | @@ -58,24 +58,24 @@ jobs: - run: name: Build example service command: | - cd ~/singnet - git clone https://github.com/singnet/example-service.git - cd example-service - pip3 install -r requirements.txt - sh buildproto.sh + cd ~/singnet + git clone https://github.com/singnet/example-service.git + cd example-service + pip3 install -r requirements.txt + sh buildproto.sh - run: name: Set up for snet daemon command: | - cd .. - mkdir snet-daemon - cd snet-daemon - - wget https://github.com/singnet/snet-daemon/releases/download/v5.0.1/snet-daemon-v5.0.1-linux-amd64.tar.gz - tar -xvf snet-daemon-v5.0.1-linux-amd64.tar.gz - cd snet-daemon-v5.0.1-linux-amd64 - cp ~/singnet/snet-cli/packages/sdk/testcases/functional_tests/snetd.config.json ~/singnet/snet-daemon/snet-daemon-v5.0.1-linux-amd64 + cd .. + mkdir snet-daemon + cd snet-daemon + + wget https://github.com/singnet/snet-daemon/releases/download/v5.0.1/snet-daemon-v5.0.1-linux-amd64.tar.gz + tar -xvf snet-daemon-v5.0.1-linux-amd64.tar.gz + cd snet-daemon-v5.0.1-linux-amd64 + cp ~/singnet/snet-cli/packages/sdk/testcases/functional_tests/snetd.config.json ~/singnet/snet-daemon/snet-daemon-v5.0.1-linux-amd64 - run: @@ -84,26 +84,26 @@ jobs: sudo pip3 install nose nosetests -v --with-doctest - run: - name: Functional tests fro snet-cli + name: Functional tests for snet-cli command: | cd .. cd snet-cli sudo npm install -g node-gyp@8.4.1 - bash -ex packages/snet_cli/test/utils/run_all_functional.sh + bash -ex packages/snet_cli/test/utils/run_all_functional.sh - run: name: Functional tests for sdk command: | - bash -ex packages/sdk/testcases/utils/run_all_functional.sh + bash -ex packages/sdk/testcases/utils/run_all_functional.sh - run: name: Trigger platform-pipeline build command: | - if [ "$CIRCLE_BRANCH" == "$TRIGGER_BUILD_BRANCH" ] - then - curl -u ${CIRCLECI_PLATFORM_PIPELINE_TOKEN}: \ - -d build_parameters[CIRCLE_JOB]=build \ - -d build_parameters[PARENT_PROJECT_REPONAME]="$CIRCLE_PROJECT_REPONAME" \ - -d build_parameters[PARENT_BRANCH]="$CIRCLE_BRANCH" \ - -d build_parameters[PARENT_BUILD_URL]="$CIRCLE_BUILD_URL" \ - https://circleci.com/api/v1.1/project/github/singnet/platform-pipeline/tree/${TRIGGER_BUILD_BRANCH} - fi + if [ "$CIRCLE_BRANCH" == "$TRIGGER_BUILD_BRANCH" ] + then + curl -u ${CIRCLECI_PLATFORM_PIPELINE_TOKEN}: \ + -d build_parameters[CIRCLE_JOB]=build \ + -d build_parameters[PARENT_PROJECT_REPONAME]="$CIRCLE_PROJECT_REPONAME" \ + -d build_parameters[PARENT_BRANCH]="$CIRCLE_BRANCH" \ + -d build_parameters[PARENT_BUILD_URL]="$CIRCLE_BUILD_URL" \ + https://circleci.com/api/v1.1/project/github/singnet/platform-pipeline/tree/${TRIGGER_BUILD_BRANCH} + fi diff --git a/README.md b/README.md index a52b2795..4f0e78cd 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ For further details, please check our full [Documentation](http://snet-cli-docs. #### Install prerequisites -You should have python with version 3.7 and pip installed. +You should have python with version 3.11 and pip installed. Additionally you should install the following packages: @@ -91,8 +91,9 @@ Complete documentation is available [here](http://snet-cli-docs.singularitynet.i #### Prerequisites -* [Python 3.7](https://www.python.org/downloads/release/python-370/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) +* [Python 3.11.6](https://www.python.org/downloads/release/python-3116/) + +Backward compatibility for other Python versions is not guaranteed. --- @@ -100,11 +101,6 @@ Complete documentation is available [here](http://snet-cli-docs.singularitynet.i ```bash $ git clone https://github.com/singnet/snet-cli.git $ cd snet-cli/packages/snet_cli -``` - -* Install development/test blockchain dependencies -```bash -$ ./scripts/blockchain install ``` * Install the package in development/editable mode @@ -160,7 +156,7 @@ The SingularityNET SDK abstracts and manages state channels with service provide ### Usage -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 call a SingularityNET service, the user must be able to deposit funds (AGIX 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. @@ -236,8 +232,9 @@ For more information about gRPC and how to use it with Python, please see: #### Prerequisites -* [Python 3.7](https://www.python.org/downloads/release/python-370/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) +* [Python 3.11.6](https://www.python.org/downloads/release/python-3116/) + +Backward compatibility for other Python versions is not guaranteed. --- @@ -245,11 +242,6 @@ For more information about gRPC and how to use it with Python, please see: ```bash $ git clone git@github.com:singnet/snet-cli.git $ cd snet-cli/snet_sdk -``` - -* Install development/test blockchain dependencies -```bash -$ ./scripts/blockchain install ``` * Install the package in development/editable mode @@ -283,7 +275,7 @@ The SingularityNET SDK abstracts and manages state channels with service provide ### Usage -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 call a SingularityNET service, the user must be able to deposit funds (AGIX 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. @@ -349,8 +341,9 @@ For more information about gRPC and how to use it with Python, please see: #### Prerequisites -* [Python 3.7](https://www.python.org/downloads/release/python-377/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) +* [Python 3.11.6](https://www.python.org/downloads/release/python-3116/) + +Backward compatibility for other Python versions is not guaranteed. --- @@ -358,11 +351,6 @@ For more information about gRPC and how to use it with Python, please see: ```bash $ git clone git@github.com:singnet/snet-cli.git $ cd snet-cli/snet_sdk -``` - -* Install development/test blockchain dependencies -```bash -$ ./scripts/blockchain install ``` * Install the package in development/editable mode diff --git a/blockchain/package-lock.json b/blockchain/package-lock.json index 07cd91a3..a7a60efd 100644 --- a/blockchain/package-lock.json +++ b/blockchain/package-lock.json @@ -1,25 +1,32 @@ { + "name": "blockchain", + "lockfileVersion": 3, "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@openzeppelin/contracts": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.1.tgz", - "integrity": "sha512-cUriqMauq1ylzP2TxePNdPqkwI7Le3Annh4K9rrpvKfSBB/bdW+Iu1ihBaTIABTAAJ85LmKL5SSPPL9ry8d1gQ==" + "packages": { + "": { + "dependencies": { + "singularitynet-platform-contracts": "1.0.2", + "singularitynet-token-contracts": "3.0.1" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.2.tgz", + "integrity": "sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==" }, - "singularitynet-platform-contracts": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/singularitynet-platform-contracts/-/singularitynet-platform-contracts-1.0.1.tgz", - "integrity": "sha512-EX7izqXvVUVUvIiqbWWnr0kIjhmR5+y7PDXybEcEHoOs/DDZ2SSmJH72dEUJLRJX11usUPm3nroZJwShjFYDeQ==", - "requires": { - "singularitynet-token-contracts": "^3.0.0" + "node_modules/singularitynet-platform-contracts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/singularitynet-platform-contracts/-/singularitynet-platform-contracts-1.0.2.tgz", + "integrity": "sha512-5+0j1+UhPuFRD37XG7UxaqekYVvbEJ1xmfqBG0VlMnl+1khAXWw8C1+i3FYdyoZvMPtcIEH5iAoFsouBW91GQA==", + "dependencies": { + "singularitynet-token-contracts": "^3.0.1" } }, - "singularitynet-token-contracts": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/singularitynet-token-contracts/-/singularitynet-token-contracts-3.0.0.tgz", - "integrity": "sha512-f2auof9gSN8TQNPZkdN8GvKFqY6rQTgmIrPzRgKR3H5xZ9OO5RGAWxFDsaCmBFjQqL+9ba7AaPgEMdRJ6OHs9g==", - "requires": { + "node_modules/singularitynet-token-contracts": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/singularitynet-token-contracts/-/singularitynet-token-contracts-3.0.1.tgz", + "integrity": "sha512-SBKlHkwQOLNma3H+jNXqh2dK5BZgHeECfpxurHBrwLQpe0wkePpWVAlYIZZTsdmwsPA4OpJR1nim6ON3RxGtQg==", + "dependencies": { "@openzeppelin/contracts": "^3.2.0" } } diff --git a/packages/sdk/README.md b/packages/sdk/README.md index 48f58bf6..51c81acd 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -16,7 +16,7 @@ The SingularityNET SDK abstracts and manages state channels with service provide ### Usage -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 call a SingularityNET service, the user must be able to deposit funds (AGIX 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. @@ -92,20 +92,16 @@ For more information about gRPC and how to use it with Python, please see: #### Prerequisites -* [Python 3.7](https://www.python.org/downloads/release/python-377/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) +* [Python 3.11.6](https://www.python.org/downloads/release/python-3116/) + +Backward compatibility for other Python versions is not guaranteed. --- * Clone the git repository ```bash $ git clone git@github.com:singnet/snet-cli.git -$ cd snet-cli/snet_sdk -``` - -* Install development/test blockchain dependencies -```bash -$ ./scripts/blockchain install +$ cd snet-cli/packages/sdk ``` * Install the package in development/editable mode @@ -139,7 +135,7 @@ The SingularityNET SDK abstracts and manages state channels with service provide ### Usage -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 call a SingularityNET service, the user must be able to deposit funds (AGIX 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. @@ -203,10 +199,9 @@ For more information about gRPC and how to use it with Python, please see: ### Prerequisites -* [Python 3.6.5](https://www.python.org/downloads/release/python-365/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) +* [Python 3.11.6](https://www.python.org/downloads/release/python-365/) -`Note!` don't use Python 3.8.2 +Backward compatibility for other Python versions is not guaranteed. --- @@ -228,11 +223,6 @@ $ pip install -r requirements.txt ``` -* Install development/test blockchain dependencies -```bash -$ ./scripts/blockchain install -``` - * Blockchain configuration If required, you can view/edit the snet-cli configuration of ipfs, eth_rpc in `~/.snet/config ` for various networks. diff --git a/packages/sdk/scripts/package-pip b/packages/sdk/scripts/package-pip index d63beaeb..b58c7dfc 100755 --- a/packages/sdk/scripts/package-pip +++ b/packages/sdk/scripts/package-pip @@ -1,3 +1,3 @@ #!/usr/bin/env bash -python3.7 setup.py sdist bdist_wheel +python3.11 setup.py sdist bdist_wheel diff --git a/packages/sdk/setup.py b/packages/sdk/setup.py index fa447767..3914bfe5 100644 --- a/packages/sdk/setup.py +++ b/packages/sdk/setup.py @@ -45,7 +45,7 @@ def is_package_installed(package_name): author='SingularityNET Foundation', author_email='info@singularitynet.io', description='SingularityNET Python SDK', - python_requires='>=3.7', + python_requires='>=3.11', install_requires=dependencies, long_description=long_description, long_description_content_type='text/markdown' diff --git a/packages/sdk/snet/sdk/__init__.py b/packages/sdk/snet/sdk/__init__.py index a5e6d553..7b4d9e94 100644 --- a/packages/sdk/snet/sdk/__init__.py +++ b/packages/sdk/snet/sdk/__init__.py @@ -14,9 +14,8 @@ import web3 -from web3.gas_strategies.time_based import medium_gas_price_strategy from rfc3986 import urlparse -import ipfsapi +import ipfshttpclient from snet.sdk.service_client import ServiceClient from snet.sdk.account import Account @@ -41,7 +40,6 @@ def __init__( eth_rpc_endpoint = self._config.get("eth_rpc_endpoint", "https://mainnet.infura.io/v3/e7732e1f679e461b9bb4da5653ac3fc2") provider = web3.HTTPProvider(eth_rpc_endpoint) self.web3 = web3.Web3(provider) - self.web3.eth.setGasPriceStrategy(medium_gas_price_strategy) # Get MPE contract address from config if specified; mostly for local testing _mpe_contract_address = self._config.get("mpe_contract_address", None) @@ -51,11 +49,8 @@ def __init__( self.mpe_contract = MPEContract(self.web3, _mpe_contract_address) # 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) + ipfs_endpoint = self._config.get("default_ipfs_endpoint", "/dns/ipfs.singularitynet.io/tcp/80/") + self.ipfs_client = ipfshttpclient.connect(ipfs_endpoint) # Get Registry contract address from config if specified; mostly for local testing _registry_contract_address = self._config.get("registry_contract_address", None) @@ -79,7 +74,7 @@ def create_service_client(self, org_id, service_id, service_stub, group_name=Non options['concurrency'] = self._config.get("concurrency", True) if self._metadata_provider is None: - self._metadata_provider = IPFSMetadataProvider( self.ipfs_client ,self.registry_contract,) + self._metadata_provider = IPFSMetadataProvider(self.ipfs_client, self.registry_contract) service_metadata = self._metadata_provider.enhance_service_metadata(org_id, service_id) group = self._get_service_group_details(service_metadata, group_name) diff --git a/packages/sdk/snet/sdk/account.py b/packages/sdk/snet/sdk/account.py index 04e0030a..0f771631 100644 --- a/packages/sdk/snet/sdk/account.py +++ b/packages/sdk/snet/sdk/account.py @@ -45,29 +45,38 @@ def __init__(self, w3, config, mpe_contract): self.nonce = 0 def _get_nonce(self): - nonce = self.web3.eth.getTransactionCount(self.address) + nonce = self.web3.eth.get_transaction_count(self.address) if self.nonce >= nonce: nonce = self.nonce + 1 self.nonce = nonce return nonce def _get_gas_price(self): - return int(self.web3.eth.generateGasPrice()) + gas_price = self.web3.eth.gas_price + if gas_price <= 15000000000: + gas_price += gas_price * 1 / 3 + elif gas_price > 15000000000 and gas_price <= 50000000000: + gas_price += gas_price * 1 / 5 + elif gas_price > 50000000000 and gas_price <= 150000000000: + gas_price += 7000000000 + elif gas_price > 150000000000: + gas_price += gas_price * 1 / 10 + return int(gas_price) def _send_signed_transaction(self, contract_fn, *args): - transaction = contract_fn(*args).buildTransaction({ - "chainId": int(self.web3.version.network), + transaction = contract_fn(*args).build_transaction({ + "chainId": int(self.web3.net.version), "gas": DEFAULT_GAS, "gasPrice": self._get_gas_price(), "nonce": self._get_nonce() }) - signed_txn = self.web3.eth.account.signTransaction( + signed_txn = self.web3.eth.account.sign_transaction( transaction, private_key=self.private_key) - return self.web3.toHex(self.web3.eth.sendRawTransaction(signed_txn.rawTransaction)) + return self.web3.to_hex(self.web3.eth.send_raw_transaction(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, TRANSACTION_TIMEOUT) + return self.web3.eth.wait_for_transaction_receipt(txn_hash, TRANSACTION_TIMEOUT) def _parse_receipt(self, receipt, event, encoder=json.JSONEncoder): if receipt.status == 0: @@ -85,7 +94,8 @@ def deposit_to_escrow_account(self, 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) + 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/packages/sdk/snet/sdk/concurrency_manager.py b/packages/sdk/snet/sdk/concurrency_manager.py index 5d73f89f..90d90002 100644 --- a/packages/sdk/snet/sdk/concurrency_manager.py +++ b/packages/sdk/snet/sdk/concurrency_manager.py @@ -56,13 +56,13 @@ def __get_token_for_amount(self, service_client, channel, amount): stub = self.__get_stub_for_get_token(service_client) with add_to_path(str(RESOURCES_PATH.joinpath("proto"))): token_service_pb2 = importlib.import_module("token_service_pb2") - current_block_number = service_client.sdk_web3.eth.getBlock("latest").number - message = web3.Web3.soliditySha3( + current_block_number = service_client.sdk_web3.eth.get_block("latest").number + message = web3.Web3.solidity_keccak( ["string", "address", "uint256", "uint256", "uint256"], ["__MPE_claim_message", service_client.mpe_address, channel.channel_id, nonce, amount] ) mpe_signature = service_client.generate_signature(message) - message = web3.Web3.soliditySha3( + message = web3.Web3.solidity_keccak( ["bytes", "uint256"], [mpe_signature, current_block_number] ) diff --git a/packages/sdk/snet/sdk/metadata_provider/ipfs_metadata_provider.py b/packages/sdk/snet/sdk/metadata_provider/ipfs_metadata_provider.py index 5d7fa3d6..f4fc66df 100644 --- a/packages/sdk/snet/sdk/metadata_provider/ipfs_metadata_provider.py +++ b/packages/sdk/snet/sdk/metadata_provider/ipfs_metadata_provider.py @@ -1,7 +1,7 @@ from snet.snet_cli.metadata.service import mpe_service_metadata_from_json from snet.snet_cli.utils.ipfs_utils import bytesuri_to_hash, get_from_ipfs_and_checkhash - +import web3 import json @@ -12,8 +12,10 @@ def __init__(self, ipfs_client, registry_contract): self._ipfs_client = ipfs_client def fetch_org_metadata(self, org_id): - (found, id, metadata_uri, owner, members, service_ids) = self.registry_contract.functions.getOrganizationById( - bytes(org_id, "utf-8")).call() + org = web3.Web3.to_bytes(text=org_id).ljust(32, b"\0") + found, id, metadata_uri, owner, members, service_ids = self.registry_contract.functions.getOrganizationById( + org + ).call() if found is not True: raise Exception('Organization with org ID "{}" not found '.format(org_id)) @@ -23,8 +25,11 @@ def fetch_org_metadata(self, org_id): return org_metadata def fetch_service_metadata(self, org_id, service_id): - (found, registration_id, metadata_uri) = self.registry_contract.functions.getServiceRegistrationById( - bytes(org_id, "utf-8"), bytes(service_id, "utf-8")).call() + org = web3.Web3.to_bytes(text=org_id).ljust(32, b"\0") + service = web3.Web3.to_bytes(text=service_id).ljust(32, b"\0") + + found, registration_id, metadata_uri = self.registry_contract.functions.getServiceRegistrationById( + org, service).call() if found is not True: raise Exception('No service "{}" found in organization "{}"'.format(service_id, org_id)) diff --git a/packages/sdk/snet/sdk/mpe/mpe_contract.py b/packages/sdk/snet/sdk/mpe/mpe_contract.py index ac6a4936..ef38f503 100644 --- a/packages/sdk/snet/sdk/mpe/mpe_contract.py +++ b/packages/sdk/snet/sdk/mpe/mpe_contract.py @@ -1,7 +1,6 @@ from snet.snet_cli.utils.utils import get_contract_deployment_block, get_contract_object - class MPEContract: def __init__(self, w3, address=None): self.web3 = w3 @@ -9,12 +8,11 @@ def __init__(self, w3, address=None): self.contract = get_contract_object(self.web3, "MultiPartyEscrow.json") else: self.contract = get_contract_object(self.web3, "MultiPartyEscrow.json", address) - self.event_topics = [self.web3.sha3( + self.event_topics = [self.web3.keccak( text="ChannelOpen(uint256,uint256,address,address,address,bytes32,uint256,uint256)").hex()] self.deployment_block = get_contract_deployment_block( self.web3, "MultiPartyEscrow.json") - def balance(self, address): return self.contract.functions.balances(address).call() diff --git a/packages/sdk/snet/sdk/mpe/payment_channel.py b/packages/sdk/snet/sdk/mpe/payment_channel.py index 5d34c32f..10e87309 100644 --- a/packages/sdk/snet/sdk/mpe/payment_channel.py +++ b/packages/sdk/snet/sdk/mpe/payment_channel.py @@ -4,7 +4,9 @@ from snet.snet_cli.utils.utils import RESOURCES_PATH, add_to_path + class PaymentChannel: + def __init__(self, channel_id, w3, account, payment_channel_state_service_client, mpe_contract): self.channel_id = channel_id self.web3 = w3 @@ -16,19 +18,15 @@ def __init__(self, channel_id, w3, account, payment_channel_state_service_client "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() @@ -45,14 +43,13 @@ def sync_state(self): "available_amount": available_amount } - def _get_current_channel_state(self): stub = self.payment_channel_state_service_client - current_block_number = self.web3.eth.getBlock("latest").number - message = web3.Web3.soliditySha3(["string","address","uint256","uint256"], ["__get_channel_state",web3.Web3.toChecksumAddress(self.mpe_contract.contract.address),self.channel_id,current_block_number]) + current_block_number = self.web3.eth.get_block("latest").number + message = web3.Web3.solidity_keccak(["string","address","uint256","uint256"], ["__get_channel_state",web3.Web3.to_checksum_address(self.mpe_contract.contract.address),self.channel_id,current_block_number]) 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),current_block=current_block_number) + request = state_service_pb2.ChannelStateRequest(channel_id=web3.Web3.to_bytes(self.channel_id), signature=bytes(signature),current_block=current_block_number) 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/packages/sdk/snet/sdk/mpe/payment_channel_provider.py b/packages/sdk/snet/sdk/mpe/payment_channel_provider.py index 475916fb..de73b9cd 100644 --- a/packages/sdk/snet/sdk/mpe/payment_channel_provider.py +++ b/packages/sdk/snet/sdk/mpe/payment_channel_provider.py @@ -1,9 +1,13 @@ import web3 +from web3._utils.events import get_event_data +from eth_abi.codec import ABICodec + from snet.sdk.mpe.mpe_contract import MPEContract from snet.sdk.mpe.payment_channel import PaymentChannel from snet.snet_cli.utils.utils import get_contract_deployment_block + BLOCKS_PER_BATCH = 5000 @@ -13,7 +17,7 @@ def __init__(self, w3, payment_channel_state_service_client, mpe_contract): self.web3 = w3 self.mpe_contract = mpe_contract - self.event_topics = [self.web3.sha3( + self.event_topics = [self.web3.keccak( text="ChannelOpen(uint256,uint256,address,address,address,bytes32,uint256,uint256)").hex()] self.deployment_block = get_contract_deployment_block( self.web3, "MultiPartyEscrow.json") @@ -21,29 +25,30 @@ def __init__(self, w3, payment_channel_state_service_client, mpe_contract): def get_past_open_channels(self, account, payment_address, group_id, starting_block_number=0, to_block_number=None): if to_block_number is None: - to_block_number = self.web3.eth.getBlock("latest")["number"] + to_block_number = self.web3.eth.block_number if starting_block_number == 0: starting_block_number = self.deployment_block + codec: ABICodec = self.web3.codec + 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, + logs = logs + self.web3.eth.get_logs({"fromBlock": from_block, "toBlock": to_block, "address": self.mpe_contract.contract.address, "topics": self.event_topics}) from_block = to_block + 1 event_abi = self.mpe_contract.contract._find_matching_event_abi( event_name="ChannelOpen") - channels_opened = list(filter( lambda channel: (channel.sender == account.address or channel.signer == account.signer_address) and channel.recipient == payment_address and channel.groupId == group_id, - [web3.utils.events.get_event_data( - event_abi, l)["args"] for l in logs] + + [get_event_data(codec, event_abi, l)["args"] for l in logs] )) return list(map(lambda channel: PaymentChannel(channel["channelId"], self.web3, account, self.payment_channel_state_service_client, self.mpe_contract), diff --git a/packages/sdk/snet/sdk/payment_strategies/freecall_payment_strategy.py b/packages/sdk/snet/sdk/payment_strategies/freecall_payment_strategy.py index 117d3f72..eda7b7e0 100644 --- a/packages/sdk/snet/sdk/payment_strategies/freecall_payment_strategy.py +++ b/packages/sdk/snet/sdk/payment_strategies/freecall_payment_strategy.py @@ -78,7 +78,7 @@ def generate_signature(self, service_client): current_block_number = service_client.get_current_block_number() - message = web3.Web3.soliditySha3( + message = web3.Web3.solidity_keccak( ["string", "string", "string", "string", "string", "uint256", "bytes32"], ["__prefix_free_trial", email, org_id, service_id, group_id, current_block_number, token_for_free_call] diff --git a/packages/sdk/snet/sdk/payment_strategies/paidcall_payment_strategy.py b/packages/sdk/snet/sdk/payment_strategies/paidcall_payment_strategy.py index e8493f0c..5903dba8 100644 --- a/packages/sdk/snet/sdk/payment_strategies/paidcall_payment_strategy.py +++ b/packages/sdk/snet/sdk/payment_strategies/paidcall_payment_strategy.py @@ -13,7 +13,7 @@ def get_price(self, service_client): def get_payment_metadata(self, service_client): channel = self.select_channel(service_client) amount = channel.state["last_signed_amount"] + int(self.get_price(service_client)) - message = web3.Web3.soliditySha3( + message = web3.Web3.solidity_keccak( ["string", "address", "uint256", "uint256", "uint256"], ["__MPE_claim_message", service_client.mpe_address, channel.channel_id, channel.state["nonce"], diff --git a/packages/sdk/snet/sdk/payment_strategies/payment_staregy.py b/packages/sdk/snet/sdk/payment_strategies/payment_staregy.py index d98a8c78..d840eb9f 100644 --- a/packages/sdk/snet/sdk/payment_strategies/payment_staregy.py +++ b/packages/sdk/snet/sdk/payment_strategies/payment_staregy.py @@ -3,6 +3,5 @@ class PaymentStrategy(object): def get_payment_metadata(self,service_client): pass - def get_price(self,service_client): pass diff --git a/packages/sdk/snet/sdk/service_client.py b/packages/sdk/snet/sdk/service_client.py index 921a3c42..617284b2 100644 --- a/packages/sdk/snet/sdk/service_client.py +++ b/packages/sdk/snet/sdk/service_client.py @@ -105,10 +105,10 @@ def _filter_existing_channels_from_new_payment_channels(self, new_payment_channe return new_channels_to_be_added def load_open_channels(self): - current_block_number = self.sdk_web3.eth.getBlock("latest").number - payment_addrss = self.group["payment"]["payment_address"] + current_block_number = self.sdk_web3.eth.block_number + payment_address = self.group["payment"]["payment_address"] group_id = base64.b64decode(str(self.group["group_id"])) - new_payment_channels = self.payment_channel_provider.get_past_open_channels(self.account, payment_addrss, + new_payment_channels = self.payment_channel_provider.get_past_open_channels(self.account, payment_address, group_id, self.last_read_block) self.payment_channels = self.payment_channels + self._filter_existing_channels_from_new_payment_channels( new_payment_channels) @@ -116,7 +116,7 @@ def load_open_channels(self): return self.payment_channels def get_current_block_number(self): - return self.sdk_web3.eth.getBlock("latest").number + return self.sdk_web3.eth.block_number def update_channel_states(self): for channel in self.payment_channels: @@ -124,7 +124,7 @@ def update_channel_states(self): return self.payment_channels def default_channel_expiration(self): - current_block_number = self.sdk_web3.eth.getBlock("latest").number + current_block_number = self.sdk_web3.eth.get_block("latest").number return current_block_number + self.expiry_threshold def _generate_payment_channel_state_service_client(self): diff --git a/packages/sdk/snet/sdk/version.py b/packages/sdk/snet/sdk/version.py index 61a3b9aa..6d1c74fb 100644 --- a/packages/sdk/snet/sdk/version.py +++ b/packages/sdk/snet/sdk/version.py @@ -1 +1 @@ -__version__ = "v3.0.2" +__version__ = "v3.1.0" diff --git a/packages/snet_cli/.gitignore b/packages/snet_cli/.gitignore index 0bf999a7..21f7c0b6 100644 --- a/packages/snet_cli/.gitignore +++ b/packages/snet_cli/.gitignore @@ -1,8 +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 snet/snet_cli/resources/proto/*.py build/ diff --git a/packages/snet_cli/README.md b/packages/snet_cli/README.md index d3401870..8bf12b8d 100644 --- a/packages/snet_cli/README.md +++ b/packages/snet_cli/README.md @@ -13,7 +13,7 @@ For further details, please check our full [Documentation](http://snet-cli-docs. #### Install prerequisites -You should have python with version >= 3.6.5 and pip installed. +You should have python with version >= [3.11.6](https://www.python.org/downloads/release/python-3116/) and pip installed. Additionally you should install the following packages: @@ -71,8 +71,9 @@ Complete documentation is available [here](http://snet-cli-docs.singularitynet.i #### Prerequisites -* [Python 3.6.5](https://www.python.org/downloads/release/python-365/) -* [Node 8+ w/npm](https://nodejs.org/en/download/) +* [Python 3.11.6](https://www.python.org/downloads/release/python-365/) + +Backward compatibility for other Python versions is not guaranteed. --- diff --git a/packages/snet_cli/common_dependencies.py b/packages/snet_cli/common_dependencies.py index 1fe04d7c..a51ec2a0 100644 --- a/packages/snet_cli/common_dependencies.py +++ b/packages/snet_cli/common_dependencies.py @@ -3,25 +3,25 @@ common_dependencies = [ - 'protobuf==3.10.0', - 'grpcio-tools==1.19.0', - 'wheel==0.30.0', - 'jsonrpcclient==2.5.2', - 'eth-hash==0.3.3', - 'rlp==1.0.1', - 'eth-rlp==0.1.2', - 'web3==4.8.3', - 'mnemonic==0.18', - 'pycoin==0.80', - 'pyyaml==4.2b1', - 'ipfsapi==0.4.2.post1', - 'rfc3986==1.1.0', + 'protobuf==4.21.6', + 'grpcio-tools==1.59.0', + 'wheel==0.41.2', + 'jsonrpcclient==4.0.3', + 'eth-hash==0.5.2', + 'rlp==3.0.0', + 'eth-rlp==0.3.0', + 'web3==6.11.1', + 'mnemonic==0.20', + 'pycoin==0.92.20230326', + 'pyyaml==6.0.1', + 'ipfshttpclient==0.4.13.2', + 'rfc3986==2.0.0', 'pymultihash==0.8.2', - 'base58==1.0.2', - 'argcomplete==1.9.4', - 'grpcio-health-checking==1.19.0', - 'jsonschema==3.2.0', - 'eth-account==0.3.0' + 'base58==2.1.1', + 'argcomplete==3.1.2', + 'grpcio-health-checking==1.59.0', + 'jsonschema==4.0.0', + 'eth-account==0.9.0' ] diff --git a/packages/snet_cli/scripts/package-namespace-pip b/packages/snet_cli/scripts/package-namespace-pip index 086a88f2..4115ece6 100755 --- a/packages/snet_cli/scripts/package-namespace-pip +++ b/packages/snet_cli/scripts/package-namespace-pip @@ -1,3 +1,3 @@ #!/usr/bin/env bash -python3.6 setup-namespace.py sdist bdist_wheel +python3.11 setup-namespace.py sdist bdist_wheel diff --git a/packages/snet_cli/scripts/package-pip b/packages/snet_cli/scripts/package-pip index 4dda00f6..b58c7dfc 100755 --- a/packages/snet_cli/scripts/package-pip +++ b/packages/snet_cli/scripts/package-pip @@ -1,3 +1,3 @@ #!/usr/bin/env bash -python3.6 setup.py sdist bdist_wheel +python3.11 setup.py sdist bdist_wheel diff --git a/packages/snet_cli/setup-namespace.py b/packages/snet_cli/setup-namespace.py index ff936450..b11276aa 100644 --- a/packages/snet_cli/setup-namespace.py +++ b/packages/snet_cli/setup-namespace.py @@ -17,7 +17,7 @@ author='SingularityNET Foundation', author_email='info@singularitynet.io', description='SingularityNET CLI standalone namespace package', - python_requires='>=3.6', + python_requires='>=3.11', install_requires=common_dependencies, cmdclass={ 'develop': develop, diff --git a/packages/snet_cli/setup.py b/packages/snet_cli/setup.py index 8287bb56..81931ab8 100644 --- a/packages/snet_cli/setup.py +++ b/packages/snet_cli/setup.py @@ -17,10 +17,10 @@ author='SingularityNET Foundation', author_email='info@singularitynet.io', description='SingularityNET CLI', - python_requires='>=3.6', + python_requires='>=3.11', install_requires=common_dependencies + [ - 'trezor==0.9.1', - 'ledgerblue==0.1.27', + 'trezor==0.13.8', + 'ledgerblue==0.1.48', ], cmdclass={ 'develop': develop, diff --git a/packages/snet_cli/snet/snet_cli/contract.py b/packages/snet_cli/snet/snet_cli/contract.py index c23eaddc..6c79d1fe 100644 --- a/packages/snet_cli/snet/snet_cli/contract.py +++ b/packages/snet_cli/snet/snet_cli/contract.py @@ -1,16 +1,16 @@ 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.contract = self.w3.eth.contract(address=self.w3.to_checksum_address(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({ + nonce = self.w3.eth.get_transaction_count(from_address) + chain_id = self.w3.net.version + return getattr(self.contract.functions, function_name)(*positional_inputs, **named_inputs).build_transaction({ "from": from_address, "nonce": nonce, "gasPrice": gas_price, @@ -22,6 +22,6 @@ def process_receipt(self, receipt): 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)) + events.extend(getattr(self.contract.events, contract_event)().process_receipt(receipt)) return events diff --git a/packages/snet_cli/snet/snet_cli/metadata/service.py b/packages/snet_cli/snet/snet_cli/metadata/service.py index cb5819a1..98d4717f 100644 --- a/packages/snet_cli/snet/snet_cli/metadata/service.py +++ b/packages/snet_cli/snet/snet_cli/metadata/service.py @@ -21,7 +21,7 @@ Possible pricing models: 1. Fixed price price_model - "fixed_price" - price_in_cogs - unique fixed price in cogs for all method (1 AGI = 10^8 cogs) + price_in_cogs - unique fixed price in cogs for all method (1 AGIX = 10^8 cogs) (other pricing models can be easily supported) groups [] - group is the number of endpoints which shares same payment channel; grouping strategy is defined by service provider; @@ -74,20 +74,20 @@ def __init__(self): "groups": [], "assets": {}, "media": [], - "tags" : [] + "tags": [] } def set_simple_field(self, f, v): - if (f != "display_name" and f != "encoding" and f != "model_ipfs_hash" and f != "mpe_address" and - f != "service_type" and f != "payment_expiration_threshold" and f != "service_description"): + if f != "display_name" and f != "encoding" and f != "model_ipfs_hash" and f != "mpe_address" and \ + f != "service_type" and f != "payment_expiration_threshold" and f != "service_description": raise Exception("unknown field in MPEServiceMetadata") self.m[f] = v def set_fixed_price_in_cogs(self, group_name, price): - if (type(price) != int): + if type(price) != int: raise Exception("Price should have int type") - if (not self.is_group_name_exists(group_name)): + if not self.is_group_name_exists(group_name): raise Exception("the group %s is not present" % str(group_name)) for group in self.m["groups"]: @@ -107,10 +107,10 @@ def set_fixed_price_in_cogs(self, group_name, price): "price_in_cogs": price, "default": True}] def set_method_price_in_cogs(self, group_name, package_name, service_name, method, price): - if (type(price) != int): + if type(price) != int: raise Exception("Price should have int type") - if (not self.is_group_name_exists(group_name)): + if not self.is_group_name_exists(group_name): raise Exception("the group %s is not present" % str(group_name)) groups = self.m["groups"] @@ -158,7 +158,7 @@ def set_method_price_in_cogs(self, group_name, package_name, service_name, metho def add_group(self, group_name): """ Return new group_id in base64 """ - if (self.is_group_name_exists(group_name)): + if self.is_group_name_exists(group_name): raise Exception("the group \"%s\" is already present" % str(group_name)) @@ -179,7 +179,7 @@ def add_tag(self, tag_name): if not "tags" in self.m: self.m["tags"] = [] - if (tag_name in self.m["tags"]): + if tag_name in self.m["tags"]: print(f"The tag {str(tag_name)} is already present") return self.m["tags"] += [tag_name] @@ -187,14 +187,14 @@ def add_tag(self, tag_name): def remove_tag(self, tag_name): if not "tags" in self.m: self.m["tags"] = [] - - if (tag_name not in self.m["tags"]): + + if tag_name not in self.m["tags"]: print(f"The tag {str(tag_name)} is not found") return self.m["tags"].remove(tag_name) def add_asset(self, asset_ipfs_hash, asset_type): - # Check if we need to validation if ssame asset type is added twice if we need to add it or replace the existing one + # Check if we need to validation if same asset type is added twice if we need to add it or replace the existing one if 'assets' not in self.m: self.m['assets'] = {} @@ -230,15 +230,15 @@ def add_endpoint_to_group(self, group_name, endpoint): endpoint = 'http://' + endpoint if not is_valid_endpoint(endpoint): raise Exception("Endpoint is not a valid URL") - if (not self.is_group_name_exists(group_name)): + if not self.is_group_name_exists(group_name): raise Exception("the group %s is not present" % str(group_name)) - if (endpoint in self.get_all_endpoints_for_group(group_name)): + if endpoint in self.get_all_endpoints_for_group(group_name): raise Exception("the endpoint %s is already present" % str(endpoint)) groups = self.m["groups"] for group in groups: - if (group["group_name"] == group_name): + if group["group_name"] == group_name: if 'endpoints' in group: group['endpoints'].append(endpoint) else: @@ -257,7 +257,7 @@ def is_group_name_exists(self, group_name): """ check if group with given name is already exists """ groups = self.m["groups"] for g in groups: - if (g["group_name"] == group_name): + if g["group_name"] == group_name: return True return False @@ -266,7 +266,7 @@ def get_group_by_group_id(self, group_id): group_id_base64 = base64.b64encode(group_id).decode('ascii') groups = self.m["groups"] for g in groups: - if (g["group_id"] == group_id_base64): + if g["group_id"] == group_id_base64: return g return None @@ -293,7 +293,7 @@ def set_from_json(self, j): # check that it contains required fields self.m = json.loads(j) if not "tags" in self.m: - self.m["tags"] = [] + self.m["tags"] = [] def load(self, file_name): with open(file_name) as f: @@ -312,10 +312,10 @@ def __contains__(self, key): def get_group_name_nonetrick(self, group_name=None): """ In all getter function in case of single payment group, group_name can be None """ groups = self.m["groups"] - if (len(groups) == 0): + if len(groups) == 0: raise Exception("Cannot find any groups in metadata") - if (not group_name): - if (len(groups) > 1): + if not group_name: + if len(groups) > 1: raise Exception( "We have more than one payment group in metadata, so group_name should be specified") return groups[0]["group_name"] @@ -324,7 +324,7 @@ def get_group_name_nonetrick(self, group_name=None): def get_group(self, group_name=None): group_name = self.get_group_name_nonetrick(group_name) for g in self.m["groups"]: - if (g["group_name"] == group_name): + if g["group_name"] == group_name: return g raise Exception('Cannot find group "%s" in metadata' % group_name) @@ -487,9 +487,9 @@ def swap_media_order(self, move_from, move_to): self.m['media'][move_to - 1], self.m['media'][move_from - 1] = self.m['media'][move_from - 1], self.m['media'][ move_to - 1] self.m['media'][move_to - 1]['order'], self.m['media'][move_from - 1]['order'] = self.m['media'][move_from - 1][ - 'order'], \ - self.m['media'][move_to - 1][ - 'order'] + 'order'], \ + self.m['media'][move_to - 1][ + 'order'] def change_media_order(self): """Mini REPL to change order of all individual media""" diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/abi/MultiPartyEscrow.json b/packages/snet_cli/snet/snet_cli/resources/contracts/abi/MultiPartyEscrow.json new file mode 100644 index 00000000..5bf9a698 --- /dev/null +++ b/packages/snet_cli/snet/snet_cli/resources/contracts/abi/MultiPartyEscrow.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"channelId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"additionalFunds","type":"uint256"}],"name":"ChannelAddFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"channelId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"plannedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sendBackAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"keepAmount","type":"uint256"}],"name":"ChannelClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"channelId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newExpiration","type":"uint256"}],"name":"ChannelExtend","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"channelId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"bytes32","name":"groupId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"ChannelOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"channelId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimAmount","type":"uint256"}],"name":"ChannelSenderClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawFunds","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"channels","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes32","name":"groupId","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[],"name":"nextChannelId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[],"name":"token","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedMessages","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes32","name":"groupId","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"openChannel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes32","name":"groupId","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"uint256","name":"messageNonce","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"openChannelByThirdParty","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes32","name":"groupId","type":"bytes32"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"expiration","type":"uint256"}],"name":"depositAndOpenChannel","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"channelIds","type":"uint256[]"},{"internalType":"uint256[]","name":"actualAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"plannedAmounts","type":"uint256[]"},{"internalType":"bool[]","name":"isSendbacks","type":"bool[]"},{"internalType":"uint8[]","name":"v","type":"uint8[]"},{"internalType":"bytes32[]","name":"r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"s","type":"bytes32[]"}],"name":"multiChannelClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"channelId","type":"uint256"},{"internalType":"uint256","name":"actualAmount","type":"uint256"},{"internalType":"uint256","name":"plannedAmount","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"bool","name":"isSendback","type":"bool"}],"name":"channelClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"channelId","type":"uint256"},{"internalType":"uint256","name":"newExpiration","type":"uint256"}],"name":"channelExtend","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"channelId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"channelAddFunds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"channelId","type":"uint256"},{"internalType":"uint256","name":"newExpiration","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"channelExtendAndAddFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"channelId","type":"uint256"}],"name":"channelClaimTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/abi/Registry.json b/packages/snet_cli/snet/snet_cli/resources/contracts/abi/Registry.json new file mode 100644 index 00000000..cf7494dd --- /dev/null +++ b/packages/snet_cli/snet/snet_cli/resources/contracts/abi/Registry.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"}],"name":"OrganizationCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"}],"name":"OrganizationDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"}],"name":"OrganizationModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"serviceId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"metadataURI","type":"bytes"}],"name":"ServiceCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"serviceId","type":"bytes32"}],"name":"ServiceDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"serviceId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"metadataURI","type":"bytes"}],"name":"ServiceMetadataModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orgId","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"serviceId","type":"bytes32"}],"name":"ServiceTagsModified","type":"event"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"bytes","name":"orgMetadataURI","type":"bytes"},{"internalType":"address[]","name":"members","type":"address[]"}],"name":"createOrganization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOrganizationOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"bytes","name":"orgMetadataURI","type":"bytes"}],"name":"changeOrganizationMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"address[]","name":"newMembers","type":"address[]"}],"name":"addOrganizationMembers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"address[]","name":"existingMembers","type":"address[]"}],"name":"removeOrganizationMembers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"}],"name":"deleteOrganization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"bytes32","name":"serviceId","type":"bytes32"},{"internalType":"bytes","name":"metadataURI","type":"bytes"}],"name":"createServiceRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"bytes32","name":"serviceId","type":"bytes32"},{"internalType":"bytes","name":"metadataURI","type":"bytes"}],"name":"updateServiceRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"bytes32","name":"serviceId","type":"bytes32"}],"name":"deleteServiceRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"listOrganizations","outputs":[{"internalType":"bytes32[]","name":"orgIds","type":"bytes32[]"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"}],"name":"getOrganizationById","outputs":[{"internalType":"bool","name":"found","type":"bool"},{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes","name":"orgMetadataURI","type":"bytes"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address[]","name":"members","type":"address[]"},{"internalType":"bytes32[]","name":"serviceIds","type":"bytes32[]"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"}],"name":"listServicesForOrganization","outputs":[{"internalType":"bool","name":"found","type":"bool"},{"internalType":"bytes32[]","name":"serviceIds","type":"bytes32[]"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"orgId","type":"bytes32"},{"internalType":"bytes32","name":"serviceId","type":"bytes32"}],"name":"getServiceRegistrationById","outputs":[{"internalType":"bool","name":"found","type":"bool"},{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"bytes","name":"metadataURI","type":"bytes"}],"stateMutability":"view","type":"function","constant":true}] diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/abi/SingularityNetToken.json b/packages/snet_cli/snet/snet_cli/resources/contracts/abi/SingularityNetToken.json new file mode 100644 index 00000000..1ce2bc94 --- /dev/null +++ b/packages/snet_cli/snet/snet_cli/resources/contracts/abi/SingularityNetToken.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function","constant":true},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/networks/MultiPartyEscrow.json b/packages/snet_cli/snet/snet_cli/resources/contracts/networks/MultiPartyEscrow.json new file mode 100644 index 00000000..b6cf8a4f --- /dev/null +++ b/packages/snet_cli/snet/snet_cli/resources/contracts/networks/MultiPartyEscrow.json @@ -0,0 +1,251 @@ +{ + "1": { + "events": { + "0xb0e2286f86435d8f98d9cf1c908b693792eb905dd03cd40d2b1d23a3e5311a40": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "channelId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "additionalFunds", + "type": "uint256" + } + ], + "name": "ChannelAddFunds", + "type": "event" + }, + "0x77c3504a57863d978ba4c28ea297490f1f4814365f5ed32b35cbf5b695db003c": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "channelId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "plannedAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sendBackAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "keepAmount", + "type": "uint256" + } + ], + "name": "ChannelClaim", + "type": "event" + }, + "0xf8d4e64f6b2b3db6aaf38b319e259285a48ecd0c5bc0115c9928aba297c73420": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "channelId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newExpiration", + "type": "uint256" + } + ], + "name": "ChannelExtend", + "type": "event" + }, + "0x172899db3034d5e4e68a2873998cc66a59bad4610fa6319a51f31f75e84452b7": { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "channelId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "signer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "groupId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "expiration", + "type": "uint256" + } + ], + "name": "ChannelOpen", + "type": "event" + }, + "0x592ba8545b0ef2ef56ac54c4db27df2bdbb2a60acc1c5a4ac134eccc20cb8096": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "channelId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "claimAmount", + "type": "uint256" + } + ], + "name": "ChannelSenderClaim", + "type": "event" + }, + "0xd241e73300212f6df233a8e6d3146b88a9d4964e06621d54b5ff6afeba7b1b88": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DepositFunds", + "type": "event" + }, + "0x5a0155838afb0f859197785e575b9ad1afeb456c6e522b6f632ee8465941315e": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferFunds", + "type": "event" + }, + "0x21901fa892c430ea8bd38b9390225ac8e67eac75ee10ffba16feefc539a288f9": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawFunds", + "type": "event" + } + }, + "links": {}, + "address": "0x5e592F9b1d303183d963635f895f0f0C48284f4e", + "transactionHash": "0x3cd235303853dab271613a7679c9c5bfc7c86b05305620dadaaa7c46920b66c7" + }, + "5": { + "events": {}, + "links": {}, + "address": "0x6245F856EFFBDB3ED6a3c64385b27A78B42F65e1", + "transactionHash": "0xdb1cdc89f29bbf175043a4370924b32ed7a5bdee079ae58b912cd14a4fb9a6b1" + }, + "11155111": { + "events": {}, + "links": {}, + "address": "0x7E0aF8988DF45B824b2E0e0A87c6196897744970", + "transactionHash": "0x672e9051b5f5c8b071f3a408ef98b6a59c914f870ddf5db5a2aacd7836eaac8a" + } +} \ No newline at end of file diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/networks/Registry.json b/packages/snet_cli/snet/snet_cli/resources/contracts/networks/Registry.json new file mode 100644 index 00000000..e76dc2b1 --- /dev/null +++ b/packages/snet_cli/snet/snet_cli/resources/contracts/networks/Registry.json @@ -0,0 +1,205 @@ +{ + "1": { + "events": { + "0x0e7857bfbd020070a2c8d2fe38c788de1e6adc88cb46f60cf6ec7cd385e81db1": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + } + ], + "name": "OrganizationCreated", + "type": "event" + }, + "0xb1dbc279d80967cb8113073651e5919753c82fad7b002581eb7a020eaf89e9a7": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + } + ], + "name": "OrganizationDeleted", + "type": "event" + }, + "0x06ccb920be65231f5c9d04dd4883d3c7648ebe5f5317cc7177ee4f4a7cc2d038": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + } + ], + "name": "OrganizationModified", + "type": "event" + }, + "0x3229c7118d95880b1bb8abc6231f47f1a63d7b1e7e22fbd91a8ccffc9fa75df9": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "serviceId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "metadataURI", + "type": "bytes" + } + ], + "name": "ServiceCreated", + "type": "event" + }, + "0x3caed2ddcd24bae20b0075a02d974ba3a229dace98271af93ce8c8f3ebd9d272": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "serviceId", + "type": "bytes32" + } + ], + "name": "ServiceDeleted", + "type": "event" + }, + "0xb7b13a2b2a9c0147b27815cbec2c7e5ed10588c9d5812211619614c379174c5a": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "serviceId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "metadataURI", + "type": "bytes" + } + ], + "name": "ServiceMetadataModified", + "type": "event" + }, + "0xd8b715d9bf49bca034a993b5b934475414e84c904dcbf90dbddd139808b97b05": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "serviceId", + "type": "bytes32" + } + ], + "name": "ServiceTagsModified", + "type": "event" + }, + "0x5124da9b6fa39b72e36fd353b25ddc71861b18c5dcafea15e97a850a1696adbc": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "typeRepositoryId", + "type": "bytes32" + } + ], + "name": "TypeRepositoryCreated", + "type": "event" + }, + "0x6ede3bb1e53daa5c72ee70092a3ce9a7dadac03f980fe8726ad2716c7f871d54": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "typeRepositoryId", + "type": "bytes32" + } + ], + "name": "TypeRepositoryDeleted", + "type": "event" + }, + "0xea3bcbabd0c9d3dae0474b21e6aeef5b2598eafe710788a0da66a15ffb65f449": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "orgId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "typeRepositoryId", + "type": "bytes32" + } + ], + "name": "TypeRepositoryModified", + "type": "event" + } + }, + "links": {}, + "address": "0x247DEbEBB766E4fA99667265A158060018D5f4F8", + "transactionHash": "0x6290f6227af2ded31ef5e5a99e8fc0dfee9524446d944446edd1e784bababe74" + }, + "5": { + "events": {}, + "links": {}, + "address": "0x0DD7feC305f2374d7eed35d6d28134936c025A7A", + "transactionHash": "0x973454b14e7fb52b2a733a3f3738dc2cfa657c1fcbd3e343e41bb51711849cee" + }, + "11155111": { + "events": {}, + "links": {}, + "address": "0x4DCc70c6FCE4064803f0ae0cE48497B3f7182e5D", + "transactionHash": "0xc54823ed287fe4a4c7a85595d8ae19a2200492fa830401e1d7edc10ef80470c5" + } +} \ No newline at end of file diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/networks/SingularityNetToken.json b/packages/snet_cli/snet/snet_cli/resources/contracts/networks/SingularityNetToken.json new file mode 100644 index 00000000..bab06543 --- /dev/null +++ b/packages/snet_cli/snet/snet_cli/resources/contracts/networks/SingularityNetToken.json @@ -0,0 +1,172 @@ +{ + "1": { + "events": { + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + "0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258": { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + "0xf6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + "0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa": { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + } + }, + "links": {}, + "address": "0x5B7533812759B45C2B44C19e320ba2cD2681b542", + "transactionHash": "0xc1dc6cb2b75d85546a8bc57692f4a0d13fe46afba2e015640eb2f2d933c34dd3" + }, + "5": { + "events": {}, + "links": {}, + "address": "0xdd4292864063d0DA1F294AC65D74d55a44F4766C", + "transactionHash": "0x17ee6cdb55eacd55f86328ff9bc61bacc0925d2aeb5bbaff21fac17cf2160bcb" + }, + "11155111": { + "events": {}, + "links": {}, + "address": "0xf703b9aB8931B6590CFc95183be4fEf278732016", + "transactionHash": "0xf7220529c44ab1fb50d62f4e8793e153e0986b9caa12f320261b2d8369d58437" + } +} \ No newline at end of file diff --git a/packages/snet_cli/snet/snet_cli/resources/contracts/placeholder.txt b/packages/snet_cli/snet/snet_cli/resources/contracts/placeholder.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/snet_cli/snet/snet_cli/resources/service_schema b/packages/snet_cli/snet/snet_cli/resources/service_schema index b9e1e0cd..27ea583f 100644 --- a/packages/snet_cli/snet/snet_cli/resources/service_schema +++ b/packages/snet_cli/snet/snet_cli/resources/service_schema @@ -21,9 +21,9 @@ "enum": [ "proto", "json" ] }, "service_type": { - "description": "Service type [grpc, jsonrpc, process]", + "description": "Service type [grpc, jsonrpc, process, http]", "type": "string", - "enum": [ "grpc", "jsonrpc", "process" ] + "enum": [ "grpc", "jsonrpc", "process", "http" ] }, "model_ipfs_hash": { "description": "Hash of directory which contains protobuf files", @@ -58,7 +58,7 @@ "enum": [ "fixed_price", "method_price" ] }, "price_in_cogs": { - "description": "Price in AGI tokens for all methods", + "description": "Price in AGIX tokens for all methods", "type": "number" }, "default": { diff --git a/packages/snet_cli/snet/snet_cli/utils/ipfs_utils.py b/packages/snet_cli/snet/snet_cli/utils/ipfs_utils.py index 07d32f53..7fdc4f57 100644 --- a/packages/snet_cli/snet/snet_cli/utils/ipfs_utils.py +++ b/packages/snet_cli/snet/snet_cli/utils/ipfs_utils.py @@ -29,12 +29,12 @@ def publish_proto_in_ipfs(ipfs_client, protodir): return base58 encoded ipfs hash """ - if (not os.path.isdir(protodir)): + if not os.path.isdir(protodir): raise Exception("Directory %s doesn't exists" % protodir) files = glob.glob(os.path.join(protodir, "*.proto")) - if (len(files) == 0): + if len(files) == 0: raise Exception("Cannot find any %s files" % (os.path.join(protodir, "*.proto"))) @@ -60,7 +60,7 @@ def get_from_ipfs_and_checkhash(ipfs_client, ipfs_hash_base58, validate=True): 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) + block_data = ipfs_client.block.get(ipfs_hash_base58) mn = MerkleNode() mn.ParseFromString(block_data) unixfs_data = Data() @@ -94,7 +94,7 @@ def hash_to_bytesuri(s): def bytesuri_to_hash(s): s = s.rstrip(b"\0").decode('ascii') - if (not s.startswith("ipfs://")): + if not s.startswith("ipfs://"): raise Exception("We support only ipfs uri in Registry") return s[7:] @@ -108,14 +108,14 @@ def safe_extract_proto_from_ipfs(ipfs_client, ipfs_hash, protodir): spec_tar = get_from_ipfs_and_checkhash(ipfs_client, ipfs_hash) with tarfile.open(fileobj=io.BytesIO(spec_tar)) as f: for m in f.getmembers(): - if (os.path.dirname(m.name) != ""): + if os.path.dirname(m.name) != "": raise Exception( "tarball has directories. We do not support it.") - if (not m.isfile()): + if not m.isfile(): raise Exception( "tarball contains %s which is not a files" % m.name) fullname = os.path.join(protodir, m.name) - if (os.path.exists(fullname)): + if os.path.exists(fullname): raise Exception("%s already exists." % fullname) # now it is safe to call extractall f.extractall(protodir) diff --git a/packages/snet_cli/snet/snet_cli/utils/utils.py b/packages/snet_cli/snet/snet_cli/utils/utils.py index 60735218..cfb5eedd 100644 --- a/packages/snet_cli/snet/snet_cli/utils/utils.py +++ b/packages/snet_cli/snet/snet_cli/utils/utils.py @@ -8,7 +8,10 @@ from pathlib import Path, PurePath import web3 -import pkg_resources + +import importlib.resources +from importlib.metadata import distribution + import grpc from grpc_tools.protoc import main as protoc @@ -72,7 +75,7 @@ def serializable(o): def safe_address_converter(a): - if not web3.eth.is_checksum_address(a): + if not web3.Web3.is_checksum_address(a): raise Exception("%s is not is not a valid Ethereum checksum address" % a) return a @@ -82,12 +85,12 @@ def type_converter(t): return lambda x: list(map(type_converter(t.replace("[]", "")), json.loads(x))) else: if "int" in t: - return lambda x: web3.Web3.toInt(text=x) + return lambda x: web3.Web3.to_int(text=x) elif "bytes32" in t: - return lambda x: web3.Web3.toBytes(text=x).ljust(32, b"\0") if not x.startswith( - "0x") else web3.Web3.toBytes(hexstr=x).ljust(32, b"\0") + return lambda x: web3.Web3.to_bytes(text=x).ljust(32, b"\0") if not x.startswith( + "0x") else web3.Web3.to_bytes(hexstr=x).ljust(32, b"\0") elif "byte" in t: - return lambda x: web3.Web3.toBytes(text=x) if not x.startswith("0x") else web3.Web3.toBytes(hexstr=x) + return lambda x: web3.Web3.to_bytes(text=x) if not x.startswith("0x") else web3.Web3.to_bytes(hexstr=x) elif "address" in t: return safe_address_converter else: @@ -150,14 +153,14 @@ def read_temp_tar(f): def get_cli_version(): - return pkg_resources.get_distribution("snet-cli").version + return distribution("snet-cli").version def compile_proto(entry_path, codegen_dir, proto_file=None, target_language="python"): try: if not os.path.exists(codegen_dir): os.makedirs(codegen_dir) - proto_include = pkg_resources.resource_filename('grpc_tools', '_proto') + proto_include = importlib.resources.files('grpc_tools') / '_proto' compiler_args = [ "-I{}".format(entry_path), @@ -201,9 +204,9 @@ def compile_proto(entry_path, codegen_dir, proto_file=None, target_language="pyt def abi_get_element_by_name(abi, name): """ Return element of abi (return None if fails to find) """ - if (abi and "abi" in abi): + if abi and "abi" in abi: for a in abi["abi"]: - if ("name" in a and a["name"] == name): + if "name" in a and a["name"] == name: return a return None @@ -260,7 +263,7 @@ def open_grpc_channel(endpoint): _GB = 1024 ** 3 options = [('grpc.max_send_message_length', _GB), ('grpc.max_receive_message_length', _GB)] - if (endpoint.startswith("https://")): + if endpoint.startswith("https://"): return grpc.secure_channel(remove_http_https_prefix(endpoint), grpc.ssl_channel_credentials(root_certificates=certificate)) return grpc.insecure_channel(remove_http_https_prefix(endpoint)) @@ -281,10 +284,10 @@ def get_contract_object(w3, contract_file, address=None): with open(RESOURCES_PATH.joinpath("contracts", "abi", contract_file)) as f: abi = json.load(f) if address: - return w3.eth.contract(abi=abi, address=w3.toChecksumAddress(address)) + return w3.eth.contract(abi=abi, address=w3.to_checksum_address(address)) with open(RESOURCES_PATH.joinpath("contracts", "networks", contract_file)) as f: networks = json.load(f) - address = w3.toChecksumAddress(networks[w3.version.network]["address"]) + address = w3.to_checksum_address(networks[w3.net.version]["address"]) return w3.eth.contract(abi=abi, address=address) @@ -292,11 +295,11 @@ def get_contract_deployment_block(w3, contract_file): try: 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 + txn_hash = networks[w3.net.version]["transactionHash"] + return w3.eth.get_transaction_receipt(txn_hash).blockNumber except Exception: # TODO Hack as currenlty dependecy is on snet-cli so for test purpose return 0,need to remove dependecies from snet-cli ,currently very tightly coupled with it - if w3.version.network in [1, 3, 42]: + if w3.net.version in [1, 5, 11155111]: raise Exception("Transaction hash not found for deployed mpe contract") return 0 @@ -310,7 +313,7 @@ def normalize_private_key(private_key): def get_address_from_private(private_key): - return web3.eth.Account.privateKeyToAccount(private_key).address + return web3.Account.from_key(private_key).address class add_to_path(): diff --git a/packages/snet_cli/snet/snet_cli/version.py b/packages/snet_cli/snet/snet_cli/version.py index bee97a9d..51f8c49e 100644 --- a/packages/snet_cli/snet/snet_cli/version.py +++ b/packages/snet_cli/snet/snet_cli/version.py @@ -1 +1 @@ -__version__ = "v2.0.9" +__version__ = "v2.1.0" diff --git a/packages/snet_cli/snet_cli/__init__.py b/packages/snet_cli/snet_cli/__init__.py index 6483d16d..d3e82630 100644 --- a/packages/snet_cli/snet_cli/__init__.py +++ b/packages/snet_cli/snet_cli/__init__.py @@ -22,7 +22,7 @@ def main(): getattr(args.cmd(conf, args), args.fn)() except Exception as e: - if (sys.argv[1] == "--print-traceback"): + if sys.argv[1] == "--print-traceback": raise else: print("Error:", e) diff --git a/packages/snet_cli/snet_cli/arguments.py b/packages/snet_cli/snet_cli/arguments.py index d5ff5001..8f063152 100644 --- a/packages/snet_cli/snet_cli/arguments.py +++ b/packages/snet_cli/snet_cli/arguments.py @@ -12,7 +12,7 @@ from snet_cli.commands.mpe_client import MPEClientCommand from snet_cli.commands.mpe_treasurer import MPETreasurerCommand from snet_cli.commands.sdk_command import SDKCommand -from snet_cli.utils.agi2cogs import stragi2cogs +from snet_cli.utils.agix2cogs import stragix2cogs from snet_cli.config import Config, get_session_keys, get_session_network_keys_removable from snet_cli.commands.mpe_channel import MPEChannelCommand @@ -63,7 +63,7 @@ def add_root_options(parser, config): title="snet commands", metavar="COMMAND") subparsers.required = True - p = subparsers.add_parser("account", help="AGI account") + p = subparsers.add_parser("account", help="AGIX account") add_mpe_account_options(p) p = subparsers.add_parser("channel", help="Interact with SingularityNET payment channels") @@ -277,7 +277,6 @@ def add_organization_options(parser): p = subparsers.add_parser("print-metadata", help="Print metadata for given organization") p.set_defaults(fn="print_metadata") - p.add_argument("org_name", help="Organization name") p.add_argument("org_id", help="Organization Id") p = subparsers.add_parser("add-group", help="Add group to organization") @@ -572,32 +571,32 @@ def add_p_snt_address_opt(p): p.set_defaults(fn="print_account") add_eth_call_arguments(p) - p = subparsers.add_parser("balance", help="Print balance of AGI tokens and balance of MPE wallet") - p.set_defaults(fn="print_agi_and_mpe_balances") + p = subparsers.add_parser("balance", help="Print balance of AGIX tokens and balance of MPE wallet") + p.set_defaults(fn="print_agix_and_mpe_balances") p.add_argument("--account", default=None, help="Account to print balance for (default is the current identity)") add_p_snt_address_opt(p) add_p_mpe_address_opt(p) add_eth_call_arguments(p) - p = subparsers.add_parser("deposit", help="Deposit AGI tokens to MPE wallet") + p = subparsers.add_parser("deposit", help="Deposit AGIX tokens to MPE wallet") p.set_defaults(fn="deposit_to_mpe") - p.add_argument("amount", type=stragi2cogs, help="Amount of AGI tokens to deposit in MPE wallet", metavar="AMOUNT") + p.add_argument("amount", type=stragix2cogs, help="Amount of AGIX tokens to deposit in MPE wallet", metavar="AMOUNT") add_p_snt_address_opt(p) add_p_mpe_address_opt(p) add_transaction_arguments(p) - p = subparsers.add_parser("withdraw", help="Withdraw AGI tokens from MPE wallet") + p = subparsers.add_parser("withdraw", help="Withdraw AGIX tokens from MPE wallet") p.set_defaults(fn="withdraw_from_mpe") - p.add_argument("amount", type=stragi2cogs, help="Amount of AGI tokens to withdraw from MPE wallet", metavar="AMOUNT") + p.add_argument("amount", type=stragix2cogs, help="Amount of AGIX tokens to withdraw from MPE wallet", metavar="AMOUNT") add_p_mpe_address_opt(p) add_transaction_arguments(p) - p = subparsers.add_parser("transfer", help="Transfer AGI tokens inside MPE wallet") + p = subparsers.add_parser("transfer", help="Transfer AGIX tokens inside MPE wallet") p.set_defaults(fn="transfer_in_mpe") p.add_argument("receiver", help="Address of the receiver", metavar="RECEIVER") p.add_argument("amount", - type=stragi2cogs, - help="Amount of AGI tokens to be transferred to another account inside MPE wallet", + type=stragix2cogs, + help="Amount of AGIX tokens to be transferred to another account inside MPE wallet", metavar="AMOUNT") add_p_mpe_address_opt(p) add_transaction_arguments(p) @@ -637,7 +636,7 @@ def add_p_group_name(p): def add_p_expiration(p, is_optional): h = "expiration time in blocks (), or in blocks related to the current_block (+blocks), or in days related to the current_block and assuming 15 sec/block (+days)" - if (is_optional): + if is_optional: p.add_argument("--expiration", help=h) else: p.add_argument("expiration", @@ -652,8 +651,8 @@ def add_p_open_channel_basic(p): add_group_name(p) p.add_argument("amount", - type=stragi2cogs, - help="Amount of AGI tokens to put in the new channel", + type=stragix2cogs, + help="Amount of AGIX tokens to put in the new channel", metavar="AMOUNT") # p.add_argument("group_name", # default=None, @@ -726,8 +725,8 @@ def add_p_set_for_extend_add(_p): title="Expiration and amount") add_p_expiration(expiration_amount_g, is_optional=True) expiration_amount_g.add_argument("--amount", - type=stragi2cogs, - help="Amount of AGI tokens to add to the channel") + type=stragix2cogs, + help="Amount of AGIX tokens to add to the channel") add_p_mpe_address_opt(p) add_transaction_arguments(p) @@ -960,8 +959,8 @@ def add_mpe_service_options(parser): nargs='*', help="Endpoints for the first group") p.add_argument("--fixed-price", - type=stragi2cogs, - help="Set fixed price in AGI token for all methods") + type=stragix2cogs, + help="Set fixed price in AGIX token for all methods") p.add_argument("--encoding", default="proto", @@ -988,8 +987,8 @@ def add_mpe_service_options(parser): p.add_argument("group_name", help="group name for fixed price method") p.add_argument("price", - type=stragi2cogs, - help="Set fixed price in AGI token for all methods", + type=stragix2cogs, + help="Set fixed price in AGIX token for all methods", metavar="PRICE") add_p_metadata_file_opt(p) @@ -1008,8 +1007,8 @@ def add_mpe_service_options(parser): ) p.add_argument("price", - type=stragi2cogs, - help="Set fixed price in AGI token for all methods", + type=stragix2cogs, + help="Set fixed price in AGIX token for all methods", metavar="PRICE") add_p_metadata_file_opt(p) diff --git a/packages/snet_cli/snet_cli/commands/commands.py b/packages/snet_cli/snet_cli/commands/commands.py index 749338c4..ac792d9f 100644 --- a/packages/snet_cli/snet_cli/commands/commands.py +++ b/packages/snet_cli/snet_cli/commands/commands.py @@ -6,7 +6,7 @@ from textwrap import indent from urllib.parse import urljoin -import ipfsapi +import ipfshttpclient import yaml from rfc3986 import urlparse from snet.snet_cli.contract import Contract @@ -19,8 +19,7 @@ LedgerIdentityProvider, KeyIdentityProvider, KeyStoreIdentityProvider from snet_cli.identity import get_kws_for_identity_type from snet_cli.utils.config import get_contract_address, get_field_from_args_or_session, read_default_contract_address -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 web3 class Command(object): @@ -75,10 +74,8 @@ def _pprint_receipt_and_events(self, receipt, events): "event_summaries": [{"args": e["args"], "event": e["event"]} for e in events]}) def _get_ipfs_client(self): - ipfs_endpoint = urlparse(self.config.get_ipfs_endpoint()) - ipfs_scheme = ipfs_endpoint.scheme if ipfs_endpoint.scheme else "http" - ipfs_port = ipfs_endpoint.port if ipfs_endpoint.port else 5001 - return ipfsapi.connect(urljoin(ipfs_scheme, ipfs_endpoint.hostname), ipfs_port) + ipfs_endpoint = self.config.get_ipfs_endpoint() + return ipfshttpclient.connect(ipfs_endpoint) class VersionCommand(Command): @@ -86,6 +83,9 @@ def show(self): self._pprint({"version": get_cli_version()}) +""" +# Temporally deprecated + class CachedGasPriceStrategy: def __init__(self, gas_price_param): self.gas_price_param = gas_price_param @@ -111,6 +111,7 @@ def calc_gas_price(self, w3, transaction_params): def is_going_to_calculate(self): return self.cached_gas_price is None and not self.gas_price_param.isdigit() +""" class BlockchainCommand(Command): @@ -118,9 +119,6 @@ def __init__(self, config, args, out_f=sys.stdout, err_f=sys.stderr, w3=None, id super(BlockchainCommand, self).__init__(config, args, out_f, err_f) self.w3 = w3 or get_web3(self.get_eth_endpoint()) self.ident = ident or self.get_identity() - if type(self.w3.eth.gasPriceStrategy) != CachedGasPriceStrategy: - self.w3.eth.setGasPriceStrategy( - CachedGasPriceStrategy(self.get_gas_price_param())) def get_eth_endpoint(self): # the only one source of eth_rpc_endpoint is the configuration file @@ -134,12 +132,18 @@ def get_gas_price_param(self): def get_gas_price_verbose(self): # gas price is not given explicitly in Wei - if self.w3.eth.gasPriceStrategy.is_going_to_calculate(): - self._printerr( - "# Calculating gas price. It might take ~60 seconds.") - g = self.w3.eth.generateGasPrice() - self._printerr("# gas_price = %f GWei" % (g * 1E-9)) - return g + self._printerr("# Calculating gas price... one moment..") + gas_price = self.w3.eth.gas_price + if gas_price <= 15000000000: + gas_price += gas_price * 1 / 3 + elif gas_price > 15000000000 and gas_price <= 50000000000: + gas_price += gas_price * 1 / 5 + elif gas_price > 50000000000 and gas_price <= 150000000000: + gas_price += 7000000000 + elif gas_price > 150000000000: + gas_price += gas_price * 1 / 10 + self._printerr("# gas_price = %f GWei" % (gas_price * 1E-9)) + return int(gas_price) def get_mpe_address(self): return get_contract_address(self, "MultiPartyEscrow") @@ -265,15 +269,17 @@ def list(self): def create(self): network_id = None + w3 = get_web3(self.args.eth_rpc_endpoint) if not self.args.skip_check: # check endpoint by getting its network_id - w3 = get_web3(self.args.eth_rpc_endpoint) - network_id = w3.version.network + network_id = w3.net.version self._printout("add network with name='%s' with networkId='%s'" % ( self.args.network_name, str(network_id))) + + default_gas_price = w3.eth.gas_price self.config.add_network( - self.args.network_name, self.args.eth_rpc_endpoint, self.args.default_gas_price) + self.args.network_name, self.args.eth_rpc_endpoint, default_gas_price) def set(self): self.config.set_session_network(self.args.network_name, self.out_f) @@ -498,7 +504,7 @@ def get_members_from_args(self): members = [m.replace("[", "").replace("]", "") for m in self.args.members.split(',')] for m in members: - if not is_checksum_address(m): + if not web3.Web3.is_checksum_address(m): raise Exception( "Member account %s is not a valid Ethereum checksum address" % m) return members @@ -535,9 +541,16 @@ def info(self): (found, org_id, org_name, owner, members, serviceNames) = self._get_organization_by_id(org_id) self.error_organization_not_found(self.args.org_id, found) + org_m = self._get_organization_metadata_from_registry(web3.Web3.to_text(org_id)) + org_name = org_m.org_name + org_type = org_m.org_type + description = org_m.description.get("description", "") + self._printout("\nOrganization Name:\n - %s" % org_name) - self._printout("\nOrganization Id:\n - %s" % bytes32_to_str(org_id)) - self._printout("\nOwner:\n - {}".format(owner)) + self._printout("\nId:\n - %s" % bytes32_to_str(org_id)) + self._printout("\nType:\n - %s" % org_type) + self._printout("\nDescription:\n - %s" % description) + if members: self._printout("\nMembers:") for idx, member in enumerate(members): @@ -649,7 +662,7 @@ def change_owner(self): self.error_organization_not_found(org_id, found) new_owner = self.args.owner - if not is_checksum_address(new_owner): + if not web3.Web3.is_checksum_address(new_owner): raise Exception( "New owner account %s is not a valid Ethereum checksum address" % new_owner) @@ -763,7 +776,7 @@ def metadata_add_asset_to_ipfs(self): metadata_file = self.args.metadata_file org_metadata = OrganizationMetadata.from_file(metadata_file) asset_file_ipfs_hash_base58 = publish_file_in_ipfs(self._get_ipfs_client(), - self.args.asset_file_path) + self.args.asset_file_path) org_metadata.add_asset(asset_file_ipfs_hash_base58, self.args.asset_type) org_metadata.save_pretty(self.args.metadata_file) diff --git a/packages/snet_cli/snet_cli/commands/mpe_account.py b/packages/snet_cli/snet_cli/commands/mpe_account.py index 3e11acdb..8820c5c7 100644 --- a/packages/snet_cli/snet_cli/commands/mpe_account.py +++ b/packages/snet_cli/snet_cli/commands/mpe_account.py @@ -1,5 +1,5 @@ from snet_cli.commands.commands import BlockchainCommand -from snet_cli.utils.agi2cogs import cogs2stragi +from snet_cli.utils.agix2cogs import cogs2stragix from snet_cli.utils.config import get_contract_address @@ -8,28 +8,28 @@ class MPEAccountCommand(BlockchainCommand): def print_account(self): self._printout(self.ident.address) - def print_agi_and_mpe_balances(self): - """ Print balance of ETH, AGI, and MPE wallet """ - if (self.args.account): + def print_agix_and_mpe_balances(self): + """ Print balance of ETH, AGIX, and MPE wallet """ + if self.args.account: account = self.args.account else: account = self.ident.address - eth_wei = self.w3.eth.getBalance(account) - agi_cogs = self.call_contract_command("SingularityNetToken", "balanceOf", [account]) - mpe_cogs = self.call_contract_command("MultiPartyEscrow", "balances", [account]) + eth_wei = self.w3.eth.get_balance(account) + agix_cogs = self.call_contract_command("SingularityNetToken", "balanceOf", [account]) + mpe_cogs = self.call_contract_command("MultiPartyEscrow", "balances", [account]) # we cannot use _pprint here because it doesn't conserve order yet self._printout(" account: %s"%account) - self._printout(" ETH: %s"%self.w3.fromWei(eth_wei, 'ether')) - self._printout(" AGI: %s"%cogs2stragi(agi_cogs)) - self._printout(" MPE: %s"%cogs2stragi(mpe_cogs)) + self._printout(" ETH: %s"%self.w3.from_wei(eth_wei, 'ether')) + self._printout(" AGIX: %s"%cogs2stragix(agix_cogs)) + self._printout(" MPE: %s"%cogs2stragix(mpe_cogs)) def deposit_to_mpe(self): - amount = self.args.amount + amount = self.args.amount mpe_address = self.get_mpe_address() already_approved = self.call_contract_command("SingularityNetToken", "allowance", [self.ident.address, mpe_address]) - if (already_approved < amount): + if already_approved < amount: self.transact_contract_command("SingularityNetToken", "approve", [mpe_address, amount]) self.transact_contract_command("MultiPartyEscrow", "deposit", [amount]) diff --git a/packages/snet_cli/snet_cli/commands/mpe_channel.py b/packages/snet_cli/snet_cli/commands/mpe_channel.py index eb35d28d..cfbdb41c 100644 --- a/packages/snet_cli/snet_cli/commands/mpe_channel.py +++ b/packages/snet_cli/snet_cli/commands/mpe_channel.py @@ -13,10 +13,9 @@ abi_decode_struct_to_dict, \ type_converter from snet_cli.commands.commands import OrganizationCommand -from snet_cli.utils.agi2cogs import cogs2stragi -from web3.utils.encoding import pad_hex -from web3.utils.events import get_event_data - +from snet_cli.utils.agix2cogs import cogs2stragix +from web3._utils.encoding import pad_hex +from web3._utils.events import get_event_data # we inherit MPEServiceCommand because we need _get_service_metadata_from_registry class MPEChannelCommand(OrganizationCommand): @@ -80,7 +79,7 @@ def _add_channel_to_initialized(self, org_id, channel): def _get_initialized_channels_dict_for_org(self, org_id): '''return {channel_id: channel}''' fn = self._get_channels_info_file(org_id) - if (os.path.isfile(fn)): + if os.path.isfile(fn): return pickle.load(open(fn, "rb")) else: return {} @@ -107,7 +106,7 @@ def is_org_initialized(self): def _check_mpe_address_metadata(self, metadata): """ we make sure that MultiPartyEscrow address from metadata is correct """ mpe_address = self.get_mpe_address() - if (str(mpe_address).lower() != str(metadata["mpe_address"]).lower()): + if str(mpe_address).lower() != str(metadata["mpe_address"]).lower(): raise Exception("MultiPartyEscrow contract address from metadata %s do not correspond to current MultiPartyEscrow address %s" % ( metadata["mpe_address"], mpe_address)) @@ -126,7 +125,7 @@ def _init_or_update_org_if_needed(self, metadata, org_registration): # self._check_mpe_address_metadata(metadata) org_dir = self.get_org_spec_dir(self.args.org_id) - if (not os.path.exists(org_dir)): + if not os.path.exists(org_dir): os.makedirs(org_dir, mode=0o700) try: @@ -144,17 +143,17 @@ def _init_or_update_registered_org_if_needed(self): similar to _init_or_update_org_if_needed but we get organization_registraion from registry, so we can update only registered organization ''' - if (self.is_org_initialized()): + if self.is_org_initialized(): old_reg = self._read_org_info(self.args.org_id) # metadataURI will be in old_reg only for service which was initilized from registry (not from metadata) # we do nothing for services which were initilized from metadata - if ("orgMetadataURI" not in old_reg): + if "orgMetadataURI" not in old_reg: return org_registration = self._get_organization_registration( self.args.org_id) # if metadataURI hasn't been changed we do nothing - if (not self.is_metadataURI_has_changed(org_registration)): + if not self.is_metadataURI_has_changed(org_registration): return else: org_registration = self._get_organization_registration( @@ -184,8 +183,7 @@ def _init_channel_from_metadata(self, metadata, org_registration): channel = self._get_channel_state_from_blockchain(channel_id) self._check_channel_is_mine(channel) group_id = metadata.get_group_id_by_group_name(self.args.group_name) - if (group_id is None): - + if group_id is None: raise Exception("Channel %i does not correspond to the given metadata.\n" % channel_id + "We can't find the following group_id in metadata: " + self.args.group_name) @@ -207,9 +205,9 @@ def init_channel_from_registry(self): def _expiration_str_to_blocks(self, expiration_str, current_block): s = expiration_str - if (s.startswith("+") and s.endswith("days")): + if s.startswith("+") and s.endswith("days"): rez = current_block + int(s[1:-4]) * 4 * 60 * 24 - elif (s.startswith("+") and s.endswith("blocks")): + elif s.startswith("+") and s.endswith("blocks"): rez = current_block + int(s[1:-6]) else: rez = int(s) @@ -225,11 +223,11 @@ def _get_expiration_from_args(self): If expiration > current_block + 1036800 (~6 month) we generate an exception if "--force" flag haven't been set """ - current_block = self.ident.w3.eth.blockNumber + current_block = self.ident.w3.eth.block_number rez = self._expiration_str_to_blocks( self.args.expiration, current_block) - if (rez > current_block + 1036800 and not self.args.force): + if rez > current_block + 1036800 and not self.args.force: d = (rez - current_block) // (4 * 60 * 24) raise Exception("You try to set expiration time too far in the future: approximately %i days. " % d + "Set --force parameter if your really want to do it.") @@ -238,9 +236,9 @@ def _get_expiration_from_args(self): def _open_channel_for_org(self, metadata): mpe_cogs = self.call_contract_command( "MultiPartyEscrow", "balances", [self.ident.address]) - if (mpe_cogs < self.args.amount): + if mpe_cogs < self.args.amount: raise Exception( - "insufficient funds. You MPE balance is %s AGI " % cogs2stragi(mpe_cogs)) + "insufficient funds. You MPE balance is %s AGIX " % cogs2stragix(mpe_cogs)) group_id = base64.b64decode( metadata.get_group_id_by_group_name(self.args.group_name)) @@ -261,7 +259,7 @@ def _open_channel_for_org(self, metadata): rez = self.transact_contract_command( "MultiPartyEscrow", "openChannel", params) - if (len(rez[1]) != 1 or rez[1][0]["event"] != "ChannelOpen"): + if len(rez[1]) != 1 or rez[1][0]["event"] != "ChannelOpen": raise Exception( "We've expected only one ChannelOpen event after openChannel. Make sure that you use correct MultiPartyEscrow address") @@ -278,7 +276,7 @@ def _initialize_already_opened_channel(self, metadata, sender, signer): sender, recipient, group_id) for i in sorted(channels_ids): channel = self._get_channel_state_from_blockchain(i) - if (channel["signer"].lower() == signer.lower()): + if channel["signer"].lower() == signer.lower(): self._printerr( "# Channel with given sender, signer and group_id is already exists we simply initialize it (channel_id = %i)" % channel["channelId"]) # self._printerr("# Please run 'snet channel extend-add %i --expiration --amount ' if necessary"%channel["channelId"]) @@ -289,13 +287,13 @@ def _initialize_already_opened_channel(self, metadata, sender, signer): def _open_init_channel_from_metadata(self, metadata, org_registration): self._init_or_update_org_if_needed(metadata, org_registration) - # Before open new channel we try to find already openned channel - if (not self.args.open_new_anyway): + # Before open new channel we try to find already opened channel + if not self.args.open_new_anyway: sender = self.ident.address signer = self.get_address_from_arg_or_ident(self.args.signer) channel = self._initialize_already_opened_channel( metadata, sender, signer) - if (channel is not None): + if channel is not None: return # open payment channel @@ -319,7 +317,7 @@ def open_init_channel_from_registry(self): def channel_claim_timeout(self): rez = self._get_channel_state_from_blockchain(self.args.channel_id) - if (rez["value"] == 0): + if rez["value"] == 0: raise Exception("Channel has 0 value. There is nothing to claim") self.transact_contract_command( "MultiPartyEscrow", "channelClaimTimeout", [self.args.channel_id]) @@ -327,25 +325,24 @@ def channel_claim_timeout(self): def channel_claim_timeout_all(self): channels_ids = self._get_all_channels_filter_sender(self.ident.address) for channel_id in channels_ids: - rez = self._get_channel_state_from_blockchain(channel_id) - if (rez["value"] > 0 and rez["expiration"] < self.ident.w3.eth.blockNumber): + response = self._get_channel_state_from_blockchain(channel_id) + if response["value"] > 0 and response["expiration"] < self.ident.w3.eth.block_number: self.transact_contract_command( "MultiPartyEscrow", "channelClaimTimeout", [channel_id]) def _channel_extend_add_funds_with_channel_id(self, channel_id): - if (self.args.amount is None and self.args.expiration is None): + if self.args.amount is None and self.args.expiration is None: raise Exception("You should specify --amount or/and --expiration") # only add funds to the channel (if --expiration hasn't been specified) - if (self.args.expiration is None): - self.transact_contract_command("MultiPartyEscrow", "channelAddFunds", [ - channel_id, self.args.amount]) + if self.args.expiration is None: + self.transact_contract_command("MultiPartyEscrow", "channelAddFunds", [channel_id, self.args.amount]) return expiration = self._get_expiration_from_args() self.check_new_expiration_from_blockchain(channel_id, expiration) # only extend channel (if --amount hasn't been specified) - if (self.args.amount is None): + if self.args.amount is None: self.transact_contract_command("MultiPartyEscrow", "channelExtend", [ channel_id, expiration]) return @@ -359,7 +356,7 @@ def channel_extend_and_add_funds(self): def check_new_expiration_from_blockchain(self, channel_id, new_expiration): channel = self._get_channel_state_from_blockchain(channel_id) - if (new_expiration < channel["expiration"]): + if new_expiration < channel["expiration"]: raise Exception("New expiration (%i) is smaller then old one (%i)" % ( new_expiration, channel["expiration"])) @@ -373,23 +370,23 @@ def _smart_get_initialized_channel_for_org(self, metadata, filter_by, is_try_ini channels = [c for c in channels if c[filter_by].lower( ) == self.ident.address.lower() and c["groupId"] == group_id] - if (len(channels) == 0 and is_try_initailize): + if len(channels) == 0 and is_try_initailize: # this will work only in simple case where signer == sender self._initialize_already_opened_channel( metadata, self.ident.address, self.ident.address) return self._smart_get_initialized_channel_for_org(metadata, filter_by, is_try_initailize=False) - if (len(channels) == 0): + if len(channels) == 0: raise Exception("Cannot find initialized channel for service with org_id=%s service_id=%s and signer=%s" % ( self.args.org_id, self.args.service_id, self.ident.address)) - if (self.args.channel_id is None): - if (len(channels) > 1): + if self.args.channel_id is None: + if len(channels) > 1: channel_ids = [channel["channelId"] for channel in channels] raise Exception( "We have several initialized channel: %s. You should use --channel-id to select one" % str(channel_ids)) return channels[0] for channel in channels: - if (channel["channelId"] == self.args.channel_id): + if channel["channelId"] == self.args.channel_id: return channel raise Exception( "Channel %i has not been initialized or your are not the sender/signer of it" % self.args.channel_id) @@ -409,7 +406,7 @@ def _get_all_initialized_channels(self): for service_base_dir in self._get_persistent_mpe_dir().glob("*/*"): org_id = service_base_dir.parent.name channels = self._get_initialized_channels_for_org(org_id) - if (channels): + if channels: channels_dict[org_id] = channels return channels_dict @@ -424,22 +421,22 @@ def _get_channel_state_from_blockchain(self, channel_id): def _read_metadata_for_org(self, org_id): sdir = self.get_org_spec_dir(org_id) - if (not os.path.exists(sdir)): + if not os.path.exists(sdir): raise Exception( "Service with org_id=%s is not initialized" % (org_id)) return OrganizationMetadata.from_file(sdir.joinpath("organization_metadata.json")) def _print_channels_from_blockchain(self, channels_ids): channels_ids = sorted(channels_ids) - if (self.args.only_id): + if self.args.only_id: self._printout("#channelId") [self._printout(str(i)) for i in channels_ids] return self._printout( - "#channelId nonce recipient groupId(base64) value(AGI) expiration(blocks)") + "#channelId nonce recipient groupId(base64) value(AGIX) expiration(blocks)") for i in channels_ids: channel = self._get_channel_state_from_blockchain(i) - value_agi = cogs2stragi(channel["value"]) + value_agi = cogs2stragix(channel["value"]) group_id_base64 = base64.b64encode( channel["groupId"]).decode("ascii") self._printout("%i %i %s %s %s %i" % (i, channel["nonce"], channel["recipient"], group_id_base64, @@ -447,11 +444,11 @@ def _print_channels_from_blockchain(self, channels_ids): def _print_channels_dict_from_blockchain(self, channels_dict): # print only caption - if (self.args.only_id): + if self.args.only_id: self._printout("#organization_id service_id channelId") else: self._printout( - "#organization_id service_id group_name channel_id nonce value(AGI) expiration(blocks)") + "#organization_id service_id group_name channel_id nonce value(AGIX) expiration(blocks)") for org_id in channels_dict: channels = self._filter_channels_sender_or_signer( channels_dict[org_id]) @@ -461,17 +458,17 @@ def _print_channels_dict_from_blockchain(self, channels_dict): group_id_base64 = base64.b64encode( channel["groupId"]).decode('ascii') group = metadata.get_group_by_group_id(group_id_base64) - if (group is None): - group_name = "UNDIFINED" + if group is None: + group_name = "UNDEFINED" else: group_name = group.group_name - if (self.args.only_id): + if self.args.only_id: self._printout("%s %s %i" % (org_id, group_name, channel_id)) else: channel_blockchain = self._get_channel_state_from_blockchain( channel_id) - value_agi = cogs2stragi(channel_blockchain["value"]) + value_agi = cogs2stragix(channel_blockchain["value"]) self._printout("%s %s %i %i %s %i" % (org_id, group_name, channel_id, channel_blockchain["nonce"], value_agi, channel_blockchain["expiration"])) @@ -480,11 +477,11 @@ def _filter_channels_sender_or_signer(self, channels): for channel in channels: not_sender = channel["sender"] != self.ident.address not_signer = channel["signer"] != self.ident.address - if (self.args.filter_sender and not_sender): + if self.args.filter_sender and not_sender: continue - if (self.args.filter_signer and not_signer): + if self.args.filter_signer and not_signer: continue - if (self.args.filter_my and not_sender and not_signer): + if self.args.filter_my and not_sender and not_signer: continue good_channels.append(channel) return good_channels @@ -500,10 +497,10 @@ def print_initialized_channels_filter_org(self): def _get_all_filtered_channels(self, topics_without_signature): """ get all filtered chanels from blockchain logs """ mpe_address = self.get_mpe_address() - event_signature = self.ident.w3.sha3( + event_signature = self.ident.w3.keccak( text="ChannelOpen(uint256,uint256,address,address,address,bytes32,uint256,uint256)").hex() topics = [event_signature] + topics_without_signature - logs = self.ident.w3.eth.getLogs( + logs = self.ident.w3.eth.get_logs( {"fromBlock": self.args.from_block, "address": mpe_address, "topics": topics}) abi = get_contract_def("MultiPartyEscrow") event_abi = abi_get_element_by_name(abi, "ChannelOpen") @@ -512,7 +509,7 @@ def _get_all_filtered_channels(self, topics_without_signature): return channels_ids def get_address_from_arg_or_ident(self, arg): - if (arg): + if arg: return arg return self.ident.address @@ -562,21 +559,21 @@ def _get_all_channels_filter_sender_recipient_group(self, sender, recipient, gro # Auxilary functions def print_block_number(self): - self._printout(self.ident.w3.eth.blockNumber) + self._printout(self.ident.w3.eth.block_number) def _get_service_registration(self): params = [type_converter("bytes32")(self.args.org_id), type_converter( "bytes32")(self.args.service_id)] - rez = self.call_contract_command( + response = self.call_contract_command( "Registry", "getServiceRegistrationById", params) - if (rez[0] == False): + if response[0] == False: raise Exception("Cannot find Service with id=%s in Organization with id=%s" % ( self.args.service_id, self.args.org_id)) - return {"metadataURI": rez[2]} + return {"metadataURI": response[2]} def _get_service_metadata_from_registry(self): - rez = self._get_service_registration() - metadata_hash = bytesuri_to_hash(rez["metadataURI"]) + response = self._get_service_registration() + metadata_hash = bytesuri_to_hash(response["metadataURI"]) metadata = get_from_ipfs_and_checkhash( self._get_ipfs_client(), metadata_hash) metadata = metadata.decode("utf-8") @@ -601,7 +598,7 @@ def _init_or_update_service_if_needed(self, metadata, service_registration): # remove old service_dir # it is relatevely safe to remove service_dir because we know that service_dir = self.get_service_spec_dir() so it is not a normal dir - if (os.path.exists(service_dir)): + if os.path.exists(service_dir): shutil.rmtree(service_dir) os.makedirs(service_dir, mode=0o700) @@ -612,7 +609,7 @@ def _init_or_update_service_if_needed(self, metadata, service_registration): self._get_ipfs_client(), metadata["model_ipfs_hash"], spec_dir) # compile .proto files - if (not compile_proto(Path(spec_dir), service_dir)): + if not compile_proto(Path(spec_dir), service_dir): raise Exception("Fail to compile %s/*.proto" % spec_dir) # save service_metadata.json in channel_dir @@ -631,18 +628,18 @@ def _init_or_update_registered_service_if_needed(self): similar to _init_or_update_service_if_needed but we get service_registraion from registry, so we can update only registered services ''' - if (self.is_service_initialized()): + if self.is_service_initialized(): old_reg = self._read_service_info( self.args.org_id, self.args.service_id) # metadataURI will be in old_reg only for service which was initilized from registry (not from metadata) # we do nothing for services which were initilized from metadata - if ("metadataURI" not in old_reg): + if "metadataURI" not in old_reg: return service_registration = self._get_service_registration() # if metadataURI hasn't been changed we do nothing - if (not self.is_service_metadataURI_has_changed(service_registration)): + if not self.is_service_metadataURI_has_changed(service_registration): return else: service_registration = self._get_service_registration() diff --git a/packages/snet_cli/snet_cli/commands/mpe_client.py b/packages/snet_cli/snet_cli/commands/mpe_client.py index b1192cf3..b5e37f86 100644 --- a/packages/snet_cli/snet_cli/commands/mpe_client.py +++ b/packages/snet_cli/snet_cli/commands/mpe_client.py @@ -3,11 +3,11 @@ import sys from pathlib import Path -from eth_account.messages import defunct_hash_message +from eth_account.messages import encode_defunct from snet.snet_cli.utils.proto_utils import import_protobuf_from_dir, switch_to_json_payload_encoding from snet.snet_cli.utils.utils import open_grpc_channel, rgetattr, RESOURCES_PATH from snet_cli.commands.mpe_channel import MPEChannelCommand -from snet_cli.utils.agi2cogs import cogs2stragi +from snet_cli.utils.agix2cogs import cogs2stragix # we inherit MPEChannelCommand because client needs channels @@ -16,27 +16,29 @@ class MPEClientCommand(MPEChannelCommand): # I. Signature related functions def _compose_message_to_sign(self, mpe_address, channel_id, nonce, amount): - return self.w3.soliditySha3( - ["string", "address", "uint256", "uint256", "uint256"], - [self.prefixInSignature, mpe_address, channel_id, nonce, amount]) + return self.w3.solidity_keccak( + ["string", "address", "uint256", "uint256", "uint256"], + [self.prefixInSignature, mpe_address, channel_id, nonce, amount]) def _sign_message(self, mpe_address, channel_id, nonce, amount): message = self._compose_message_to_sign( mpe_address, channel_id, nonce, amount) - sign = self.ident.sign_message_after_soliditySha3(message) + sign = self.ident.sign_message_after_solidity_keccak(message) return sign def _verify_my_signature(self, signature, mpe_address, channel_id, nonce, amount): message = self._compose_message_to_sign( - mpe_address, channel_id, nonce, amount) - message_hash = defunct_hash_message(message) - sign_address = self.ident.w3.eth.account.recoverHash( - message_hash, signature=signature) + mpe_address, channel_id, nonce, amount + ) + message_hash = encode_defunct(message) + sign_address = self.ident.w3.eth.account.recover_message( + message_hash, signature=signature + ) return sign_address == self.ident.address def _assert_validity_of_my_signature_or_zero_amount(self, signature, channel_id, nonce, signed_amount, error_message): - if (signed_amount > 0): - if (not self._verify_my_signature(signature, self.get_mpe_address(), channel_id, nonce, signed_amount)): + if signed_amount > 0: + if not self._verify_my_signature(signature, self.get_mpe_address(), channel_id, nonce, signed_amount): raise Exception(error_message) # II. Call related functions (low level) @@ -87,12 +89,12 @@ def _transform_call_params(self, params): k_final = k_split[-1] k_mods = k_split[:-1] for m in k_mods: - if (m == "file"): + if m == "file": with open(v, 'rb') as f: v = f.read() - elif (m == "b64encode"): + elif m == "b64encode": v = base64.b64encode(v) - elif (m == "b64decode"): + elif m == "b64decode": v = base64.b64decode(v) else: raise Exception( @@ -129,13 +131,13 @@ def _create_call_metadata(self, channel_id, nonce, amount): ("snet-payment-mpe-address", str(mpe_address))] def _deal_with_call_response(self, response): - if (self.args.save_response): + if self.args.save_response: with open(self.args.save_response, "wb") as f: f.write(response.SerializeToString()) - elif (self.args.save_field): + elif self.args.save_field: field = rgetattr(response, self.args.save_field[0]) file_name = self.args.save_field[1] - if (type(field) == bytes): + if type(field) == bytes: with open(file_name, "wb") as f: f.write(field) else: @@ -145,13 +147,13 @@ def _deal_with_call_response(self, response): self._printout(response) def _get_endpoint_from_metadata_or_args(self, metadata): - if (self.args.endpoint): + if self.args.endpoint: return self.args.endpoint endpoints = metadata.get_all_endpoints_for_group(self.args.group_name) - if (not endpoints): + if not endpoints: raise Exception( "Cannot find endpoint in metadata for the given payment group.") - if (len(endpoints) > 1): + if len(endpoints) > 1: self._printerr( "There are several endpoints for the given payment group. We will select %s" % endpoints[0]) return endpoints[0] @@ -180,13 +182,13 @@ def _get_channel_state_from_server(self, grpc_channel, channel_id): proto_dir = RESOURCES_PATH.joinpath("proto") stub_class, request_class, _ = import_protobuf_from_dir( proto_dir, "GetChannelState") - current_block = self.ident.w3.eth.blockNumber + current_block = self.ident.w3.eth.block_number mpe_address = self.get_mpe_address() - message = self.w3.soliditySha3(["string", "address", "uint256", "uint256"], + message = self.w3.solidity_keccak(["string", "address", "uint256", "uint256"], ["__get_channel_state", mpe_address, channel_id, current_block]) - signature = self.ident.sign_message_after_soliditySha3(message) + signature = self.ident.sign_message_after_solidity_keccak(message) - request = request_class(channel_id=self.w3.toBytes( + request = request_class(channel_id=self.w3.to_bytes( channel_id), signature=bytes(signature), current_block=current_block) stub = stub_class(grpc_channel) @@ -202,7 +204,7 @@ def _get_channel_state_from_server(self, grpc_channel, channel_id): self._assert_validity_of_my_signature_or_zero_amount(bytes( response.current_signature), channel_id, state["current_nonce"], state["current_signed_amount"], error_message) - if (hasattr(response, "old_nonce_signed_amount")): + if hasattr(response, "old_nonce_signed_amount"): state["old_nonce_signed_amount"] = int.from_bytes( response.old_nonce_signed_amount, byteorder='big') self._assert_validity_of_my_signature_or_zero_amount(bytes( @@ -211,13 +213,13 @@ def _get_channel_state_from_server(self, grpc_channel, channel_id): return state def _calculate_unspent_amount(self, blockchain, server): - if (server["current_nonce"] == blockchain["nonce"]): + if server["current_nonce"] == blockchain["nonce"]: return blockchain["value"] - server["current_signed_amount"] - if (server["current_nonce"] - 1 != blockchain["nonce"]): + if server["current_nonce"] - 1 != blockchain["nonce"]: raise Exception("Server nonce is different from blockchain nonce to more then 1: server_nonce = %i blockchain_nonce = %i" % ( server["current_nonce"], blockchain["nonce"])) - if ("old_nonce_signed_amount" in server): + if "old_nonce_signed_amount" in server: return blockchain["value"] - server["old_nonce_signed_amount"] - server["current_signed_amount"] self._printerr( @@ -235,7 +237,7 @@ def _get_channel_state_statelessly(self, grpc_channel, channel_id): unspent_amount = self._calculate_unspent_amount(blockchain, server) - return (server["current_nonce"], server["current_signed_amount"], unspent_amount) + return server["current_nonce"], server["current_signed_amount"], unspent_amount def print_channel_state_statelessly(self): grpc_channel = open_grpc_channel(self.args.endpoint) @@ -252,15 +254,14 @@ def _get_price_from_metadata(self, service_metadata, group_name): if group["group_name"] == group_name: pricings = group["pricing"] for pricing in pricings: - if (pricing["price_model"] == "fixed_price"): + if pricing["price_model"] == "fixed_price": return pricing["price_in_cogs"] - raise Exception("We do not support price model: %s" % - (pricing["price_model"])) + raise Exception("We do not support price model: %s" %(pricing["price_model"])) def call_server_statelessly_with_params(self, params, group_name): # if service is not initilized we will initialize it (unless we want skip registry check for update) - if (not self.args.skip_update_check): + if not self.args.skip_update_check: self._init_or_update_registered_org_if_needed() self._init_or_update_registered_service_if_needed() @@ -278,8 +279,8 @@ def call_server_statelessly_with_params(self, params, group_name): grpc_channel, channel_id) proceed = self.args.yes or input( - "Price for this call will be %s AGI (use -y to remove this warning). Proceed? (y/n): " % (cogs2stragi(price))) == "y" - if (not proceed): + "Price for this call will be %s AGIX (use -y to remove this warning). Proceed? (y/n): " % (cogs2stragix(price))) == "y" + if not proceed: self._error("Cancelled") return self._call_server_via_grpc_channel(grpc_channel, channel_id, server_state["current_nonce"], server_state["current_signed_amount"] + price, params, service_metadata) diff --git a/packages/snet_cli/snet_cli/commands/mpe_service.py b/packages/snet_cli/snet_cli/commands/mpe_service.py index ee14bb40..c67c3e86 100644 --- a/packages/snet_cli/snet_cli/commands/mpe_service.py +++ b/packages/snet_cli/snet_cli/commands/mpe_service.py @@ -113,15 +113,11 @@ def publish_proto_metadata_init(self): metadata = MPEServiceMetadata() mpe_address = self.get_mpe_address() - metadata.set_simple_field("model_ipfs_hash", - model_ipfs_hash_base58) + metadata.set_simple_field("model_ipfs_hash", model_ipfs_hash_base58) metadata.set_simple_field("mpe_address", mpe_address) - metadata.set_simple_field("display_name", - self.args.display_name) - metadata.set_simple_field("encoding", - self.args.encoding) - metadata.set_simple_field("service_type", - self.args.service_type) + metadata.set_simple_field("display_name", self.args.display_name) + metadata.set_simple_field("encoding", self.args.encoding) + metadata.set_simple_field("service_type", self.args.service_type) if self.args.group_name: metadata.add_group(self.args.group_name) @@ -229,7 +225,6 @@ def metadata_add_asset_to_ipfs(self): metadata = load_mpe_service_metadata(self.args.metadata_file) asset_file_ipfs_hash_base58 = ipfs_utils.publish_file_in_ipfs(self._get_ipfs_client(), self.args.asset_file_path) - metadata.add_asset(asset_file_ipfs_hash_base58, self.args.asset_type) metadata.save_pretty(self.args.metadata_file) @@ -318,14 +313,14 @@ def metadata_remove_contributor(self): def metadata_add_description(self): """ Metadata: add description """ service_description = {} - if (self.args.json): + if self.args.json: service_description = json.loads(self.args.json) - if (self.args.url): + if self.args.url: if "url" in service_description: raise Exception( "json service description already contains url field") service_description["url"] = self.args.url - if (self.args.description): + if self.args.description: if "description" in service_description: raise Exception( "json service description already contains description field") @@ -341,7 +336,7 @@ def metadata_add_description(self): service_description["short_description"] = self.args.short_description metadata = load_mpe_service_metadata(self.args.metadata_file) # merge with old service_description if necessary - if ("service_description" in metadata): + if "service_description" in metadata: service_description = { **metadata["service_description"], **service_description} metadata.set_simple_field("service_description", service_description) @@ -394,11 +389,11 @@ def metadata_validate(self): def _publish_metadata_in_ipfs(self, metadata_file): metadata = load_mpe_service_metadata(metadata_file) mpe_address = self.get_mpe_address() - if (self.args.update_mpe_address): + if self.args.update_mpe_address: metadata.set_simple_field("mpe_address", mpe_address) metadata.save_pretty(self.args.metadata_file) - if (mpe_address.lower() != metadata["mpe_address"].lower()): + if mpe_address.lower() != metadata["mpe_address"].lower(): raise Exception( "\n\nmpe_address in metadata does not correspond to the current MultiPartyEscrow contract address\n" + "You have two possibilities:\n" + @@ -423,12 +418,12 @@ def _get_organization_metadata_from_registry(self, org_id): def _get_organization_registration(self, org_id): params = [type_converter("bytes32")(org_id)] - rez = self.call_contract_command( + result = self.call_contract_command( "Registry", "getOrganizationById", params) - if (rez[0] == False): + if result[0] == False: raise Exception("Cannot find Organization with id=%s" % ( self.args.org_id)) - return {"orgMetadataURI": rez[2]} + return {"orgMetadataURI": result[2]} def _validate_service_group_with_org_group_and_update_group_id(self, org_id, metadata_file): org_metadata = self._get_organization_metadata_from_registry(org_id) @@ -494,7 +489,7 @@ def _get_service_registration(self): "bytes32")(self.args.service_id)] rez = self.call_contract_command( "Registry", "getServiceRegistrationById", params) - if (rez[0] == False): + if rez[0] == False: raise Exception("Cannot find Service with id=%s in Organization with id=%s" % ( self.args.service_id, self.args.org_id)) return {"metadataURI": rez[2]} @@ -526,24 +521,23 @@ def _service_status(self, url, secure=True): def print_service_status(self): metadata = self._get_service_metadata_from_registry() - groups = [] if self.args.group_name != None: groups = {self.args.group_name: metadata.get_all_endpoints_for_group( self.args.group_name)} else: groups = metadata.get_all_group_endpoints() - srvc_status = defaultdict(list) + service_status = defaultdict(list) for name, group_endpoints in groups.items(): for endpoint in group_endpoints: status = "Available" if self._service_status( url=endpoint) else "Not Available" - srvc_status[name].append( + service_status[name].append( {"endpoint": endpoint, "status": status}) - if srvc_status == {}: + if service_status == {}: self._printout( "Error: No endpoints found to check service status.") return - self._pprint(srvc_status) + self._pprint(service_status) def print_service_tags_from_registry(self): metadata = self._get_service_metadata_from_registry() diff --git a/packages/snet_cli/snet_cli/commands/mpe_treasurer.py b/packages/snet_cli/snet_cli/commands/mpe_treasurer.py index 17197c62..c14d4e2b 100644 --- a/packages/snet_cli/snet_cli/commands/mpe_treasurer.py +++ b/packages/snet_cli/snet_cli/commands/mpe_treasurer.py @@ -4,36 +4,36 @@ from snet.snet_cli.utils.proto_utils import import_protobuf_from_dir from snet.snet_cli.utils.utils import compile_proto, open_grpc_channel, int4bytes_big, RESOURCES_PATH from snet_cli.commands.mpe_client import MPEClientCommand -from snet_cli.utils.agi2cogs import cogs2stragi +from snet_cli.utils.agix2cogs import cogs2stragix class MPETreasurerCommand(MPEClientCommand): """ We inherit MPEChannelCommand because we need _get_channel_state_from_blockchain """ def _sign_message_list_unclaimed(self, mpe_address, current_block): - message = self.w3.soliditySha3( - ["string", "address", "uint256"], + message = self.w3.solidity_keccak( + ["string", "address", "uint256"], ["__list_unclaimed", mpe_address, current_block]) - return self.ident.sign_message_after_soliditySha3(message) + return self.ident.sign_message_after_solidity_keccak(message) def _sign_message_list_in_progress(self, mpe_address, current_block): - message = self.w3.soliditySha3( - ["string", "address", "uint256"], + message = self.w3.solidity_keccak( + ["string", "address", "uint256"], ["__list_in_progress", mpe_address, current_block]) - return self.ident.sign_message_after_soliditySha3(message) + return self.ident.sign_message_after_solidity_keccak(message) def _sign_message_start_claim(self, mpe_address, channel_id, channel_nonce): - message = self.w3.soliditySha3( - ["string", "address", "uint256", "uint256"], + message = self.w3.solidity_keccak( + ["string", "address", "uint256", "uint256"], ["__start_claim", mpe_address, channel_id, channel_nonce]) - return self.ident.sign_message_after_soliditySha3(message) + return self.ident.sign_message_after_solidity_keccak(message) 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 = RESOURCES_PATH.joinpath("proto") - if (not codegen_dir.joinpath("control_service_pb2.py").is_file()): + if not codegen_dir.joinpath("control_service_pb2.py").is_file(): compile_proto(proto_dir, codegen_dir, proto_file="control_service.proto") @@ -50,7 +50,7 @@ def _call_GetListUnclaimed(self, grpc_channel): stub = stub_class(grpc_channel) mpe_address = self.get_mpe_address() - current_block = self.ident.w3.eth.blockNumber + current_block = self.ident.w3.eth.block_number signature = self._sign_message_list_unclaimed( mpe_address, current_block) request = request_class( @@ -58,7 +58,7 @@ def _call_GetListUnclaimed(self, grpc_channel): response = getattr(stub, "GetListUnclaimed")(request) for p in response.payments: - if (len(p.signature) > 0): + if len(p.signature) > 0: raise Exception( "Signature was set in GetListUnclaimed. Response is invalid") @@ -70,7 +70,7 @@ def _call_GetListInProgress(self, grpc_channel): stub = stub_class(grpc_channel) mpe_address = self.get_mpe_address() - current_block = self.ident.w3.eth.blockNumber + current_block = self.ident.w3.eth.block_number signature = self._sign_message_list_in_progress( mpe_address, current_block) request = request_class( @@ -85,7 +85,7 @@ def _call_StartClaim(self, grpc_channel, channel_id, channel_nonce): mpe_address = self.get_mpe_address() signature = self._sign_message_start_claim( mpe_address, channel_id, channel_nonce) - request = request_class(mpe_address=mpe_address, channel_id=web3.Web3.toBytes( + request = request_class(mpe_address=mpe_address, channel_id=web3.Web3.to_bytes( channel_id), signature=bytes(signature)) response = getattr(stub, "StartClaim")(request) return self._decode_PaymentReply(response) @@ -93,20 +93,20 @@ def _call_StartClaim(self, grpc_channel, channel_id, channel_nonce): def print_unclaimed(self): grpc_channel = open_grpc_channel(self.args.endpoint) payments = self._call_GetListUnclaimed(grpc_channel) - self._printout("# channel_id channel_nonce signed_amount (AGI)") + self._printout("# channel_id channel_nonce signed_amount (AGIX)") total = 0 for p in payments: self._printout("%i %i %s" % ( - p["channel_id"], p["nonce"], cogs2stragi(p["amount"]))) + p["channel_id"], p["nonce"], cogs2stragix(p["amount"]))) total += p["amount"] - self._printout("# total_unclaimed_in_AGI = %s" % cogs2stragi(total)) + self._printout("# total_unclaimed_in_AGIX = %s" % cogs2stragix(total)) def _blockchain_claim(self, payments): for payment in payments: channel_id = payment["channel_id"] amount = payment["amount"] sig = payment["signature"] - if (len(sig) != 65): + if len(sig) != 65: raise Exception( "Length of signature is incorrect: %i instead of 65" % (len(sig))) v, r, s = int(sig[-1]), sig[:32], sig[32:64] @@ -123,12 +123,12 @@ def _start_claim_channels(self, grpc_channel, channels_ids): to_claim = [] for channel_id in channels_ids: - if (channel_id not in unclaimed_payments_dict or unclaimed_payments_dict[channel_id]["amount"] == 0): + if channel_id not in unclaimed_payments_dict or unclaimed_payments_dict[channel_id]["amount"] == 0: self._printout( "There is nothing to claim for channel %i, we skip it" % channel_id) continue blockchain = self._get_channel_state_from_blockchain(channel_id) - if (unclaimed_payments_dict[channel_id]["nonce"] != blockchain["nonce"]): + if unclaimed_payments_dict[channel_id]["nonce"] != blockchain["nonce"]: self._printout( "Old payment for channel %i is still in progress. Please run claim for this channel later." % channel_id) continue @@ -142,7 +142,7 @@ def _claim_in_progress_and_claim_channels(self, grpc_channel, channels): """ Claim all 'pending' payments in progress and after we claim given channels """ # first we get the list of all 'payments in progress' in case we 'lost' some payments. payments = self._call_GetListInProgress(grpc_channel) - if (len(payments) > 0): + if len(payments) > 0: self._printout( "There are %i payments in 'progress' (they haven't been claimed in blockchain). We will claim them." % len(payments)) self._blockchain_claim(payments) @@ -168,11 +168,11 @@ def claim_almost_expired_channels(self): channels = [] for p in unclaimed_payments: - if (p["amount"] == 0): + if p["amount"] == 0: continue channel_id = p["channel_id"] blockchain = self._get_channel_state_from_blockchain(channel_id) - if (blockchain["expiration"] < self.ident.w3.eth.blockNumber + self.args.expiration_threshold): + if blockchain["expiration"] < self.ident.w3.eth.block_number + self.args.expiration_threshold: self._printout("We are going to claim channel %i" % channel_id) channels.append(channel_id) self._claim_in_progress_and_claim_channels(grpc_channel, channels) diff --git a/packages/snet_cli/snet_cli/config.py b/packages/snet_cli/snet_cli/config.py index a9a04a8a..02089083 100644 --- a/packages/snet_cli/snet_cli/config.py +++ b/packages/snet_cli/snet_cli/config.py @@ -8,7 +8,7 @@ class Config(ConfigParser): def __init__(self, _snet_folder=default_snet_folder): super(Config, self).__init__(interpolation=ExtendedInterpolation(), delimiters=("=",)) self._config_file = _snet_folder.joinpath("config") - if (self._config_file.exists()): + if self._config_file.exists(): with open(self._config_file) as f: self.read_file(f) else: @@ -20,7 +20,7 @@ def get_session_network_name(self): return session_network def safe_get_session_identity_network_names(self): - if ("identity" not in self["session"]): + if "identity" not in self["session"]: first_identity_message_and_exit() session_identity = self["session"]["identity"] @@ -29,7 +29,7 @@ def safe_get_session_identity_network_names(self): session_network = self.get_session_network_name() network = self._get_identity_section(session_identity).get("network") - if (network and network != session_network): + if network and network != session_network: raise Exception("Your session identity '%s' is bind to network '%s', which is different from your" " session network '%s', please switch identity or network" % ( session_identity, network, session_network)) @@ -37,26 +37,26 @@ def safe_get_session_identity_network_names(self): def set_session_network(self, network, out_f): self._set_session_network(network, out_f) - if ("identity" in self["session"]): + if "identity" in self["session"]: session_identity = self["session"]["identity"] identity_network = self._get_identity_section(session_identity).get("network") - if (identity_network and identity_network != network): + if identity_network and identity_network != network: print("Your new session network '%s' is incompatible with your current session identity '%s' " "(which is bind to network '%s'), please switch your identity" % ( - network, session_identity, identity_network), file=out_f); + network, session_identity, identity_network), file=out_f) def _set_session_network(self, network, out_f): - if (network not in self.get_all_networks_names()): + if network not in self.get_all_networks_names(): raise Exception("Network %s is not in config" % network) print("Switch to network: %s" % network, file=out_f) self["session"]["network"] = network self._persist() def set_session_identity(self, identity, out_f): - if (identity not in self.get_all_identities_names()): + if identity not in self.get_all_identities_names(): raise Exception('Identity "%s" is not in config' % identity) network = self._get_identity_section(identity).get("network") - if (network): + if network: print('Identity "%s" is bind to network "%s"' % (identity, network), file=out_f) self._set_session_network(network, out_f) else: @@ -76,23 +76,23 @@ def get_session_field(self, key, exception_if_not_found=True): rez_network = self._get_network_section(session_network).get(key) rez_ipfs = None - if (key == "default_ipfs_endpoint"): + if key == "default_ipfs_endpoint": rez_ipfs = self.get_ipfs_endpoint() rez = rez_identity or rez_network or rez_ipfs - if (not rez and exception_if_not_found): + if not rez and exception_if_not_found: raise Exception("Cannot find %s in the session.identity and in the session.network" % key) return rez def set_session_field(self, key, value, out_f): - if (key == "default_ipfs_endpoint"): + if key == "default_ipfs_endpoint": self.set_ipfs_endpoint(value) print("set default_ipfs_endpoint=%s" % value, file=out_f) - elif (key in get_session_network_keys()): - session_network = self.get_session_network_name(); + elif key in get_session_network_keys(): + session_network = self.get_session_network_name() self.set_network_field(session_network, key, value) print("set {}={} for network={}".format(key, value, session_network), file=out_f) - elif (key in get_session_identity_keys()): + elif key in get_session_identity_keys(): session_identity, _ = self.safe_get_session_identity_network_names() self.set_identity_field(session_identity, key, value) print("set {}={} for identity={}".format(key, value, session_identity), file=out_f) @@ -101,7 +101,7 @@ def set_session_field(self, key, value, out_f): raise Exception("key {} not in {}".format(key, all_keys)) def unset_session_field(self, key, out_f): - if (key in get_session_network_keys_removable()): + if key in get_session_network_keys_removable(): print("unset %s from network %s" % (key, self["session"]["network"]), file=out_f) del self._get_network_section(self["session"]["network"])[key] self._persist() @@ -110,16 +110,17 @@ def session_to_dict(self): session_identity, session_network = self.safe_get_session_identity_network_names() show = {"session", "network.%s" % session_network, "identity.%s" % session_identity, "ipfs"} - rez = {f: dict(self[f]) for f in show} - return rez + response = {f: dict(self[f]) for f in show} + return response def add_network(self, network, rpc_endpoint, default_gas_price): network_section = "network.%s" % network - if (network_section in self): + if network_section in self: raise Exception("Network section %s already exists in config" % network) self[network_section] = {} self[network_section]["default_eth_rpc_endpoint"] = str(rpc_endpoint) + # TODO: find solution with default gas price self[network_section]["default_gas_price"] = str(default_gas_price) self._persist() @@ -129,14 +130,14 @@ def set_network_field(self, network, key, value): def add_identity(self, identity_name, identity, out_f): identity_section = "identity.%s" % identity_name - if (identity_section in self): + if identity_section in self: raise Exception("Identity section %s already exists in config" % identity_section) - if ("network" in identity and identity["network"] not in self.get_all_networks_names()): + if "network" in identity and identity["network"] not in self.get_all_networks_names(): raise Exception("Network %s is not in config" % identity["network"]) self[identity_section] = identity self._persist() # switch to it, if it was the first identity - if (len(self.get_all_identities_names()) == 1): + if len(self.get_all_identities_names()) == 1: print("You've just added your first identity %s. We will automatically switch to it!" % identity_name) self.set_session_identity(identity_name, out_f) @@ -166,11 +167,11 @@ def get_all_networks_names(self): return [x[len("network."):] for x in self.sections() if x.startswith("network.")] def delete_identity(self, identity_name): - if (identity_name not in self.get_all_identities_names()): + if identity_name not in self.get_all_identities_names(): raise Exception("identity_name {} does not exist".format(identity_name)) session_identity, _ = self.safe_get_session_identity_network_names() - if (identity_name == session_identity): + if identity_name == session_identity: raise Exception("identity_name {} is in use".format(identity_name)) self.remove_section("identity.{}".format(identity_name)) self._persist() @@ -179,25 +180,22 @@ def create_default_config(self): """ Create default configuration if config file does not exist """ # make config directory with the minimal possible permission self._config_file.parent.mkdir(mode=0o700, exist_ok=True) - self["network.kovan"] = { - "default_eth_rpc_endpoint": "https://kovan.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", - "default_gas_price": "medium"} self["network.mainnet"] = { - "default_eth_rpc_endpoint": "https://mainnet.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", - "default_gas_price": "medium"} + "default_eth_rpc_endpoint": "https://mainnet.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5" + } self["network.goerli"] = { "default_eth_rpc_endpoint": "https://goerli.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", - "default_gas_price": "medium"} - self["network.rinkeby"] = { - "default_eth_rpc_endpoint": "https://rinkeby.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", - "default_gas_price": "medium"} - self["ipfs"] = {"default_ipfs_endpoint": "http://ipfs.singularitynet.io:80"} - self["session"] = {"network": "goerli"} + } + self["network.sepolia"] = { + "default_eth_rpc_endpoint": "https://sepolia.infura.io/v3/09027f4a13e841d48dbfefc67e7685d5", + } + self["ipfs"] = {"default_ipfs_endpoint": "/dns/ipfs.singularitynet.io/tcp/80/"} + self["session"] = {"network": "sepolia"} self._persist() print("We've created configuration file with default values in: %s\n" % str(self._config_file)) def _check_section(self, s): - if (s not in self): + if s not in self: raise Exception("Config error, section %s is absent" % s) def _persist(self): diff --git a/packages/snet_cli/snet_cli/identity.py b/packages/snet_cli/snet_cli/identity.py index 74ba5ed5..0dbf28fb 100644 --- a/packages/snet_cli/snet_cli/identity.py +++ b/packages/snet_cli/snet_cli/identity.py @@ -4,22 +4,26 @@ import time import getpass -import web3 -from pycoin.key.BIP32Node import BIP32Node +from eth_account import Account import rlp -from eth_account.internal.transactions import serializable_unsigned_transaction_from_dict, encode_transaction, \ + +from eth_account._utils.legacy_transactions import ( + serializable_unsigned_transaction_from_dict, + encode_transaction, UnsignedTransaction +) + from eth_account.messages import defunct_hash_message -from mnemonic import Mnemonic -from trezorlib.client import TrezorClient, proto -from trezorlib.transport_hid import HidTransport + +from trezorlib.client import TrezorClient +from trezorlib import messages as proto +from trezorlib.transport.hid import HidTransport from ledgerblue.comm import getDongle from ledgerblue.commException import CommException from snet.snet_cli.utils.utils import get_address_from_private, normalize_private_key - BIP32_HARDEN = 0x80000000 @@ -33,7 +37,7 @@ def transact(self, transaction, out_f): raise NotImplementedError() @abc.abstractmethod - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): raise NotImplementedError() @@ -51,7 +55,7 @@ def transact(self, transaction, out_f): self.w3, self.private_key, transaction) return send_and_wait_for_transaction(raw_transaction, self.w3, out_f) - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): return sign_message_with_private_key(self.w3, self.private_key, message) @@ -61,7 +65,7 @@ def __init__(self, w3, path_to_keystore): try: with open(path_to_keystore) as keyfile: encrypted_key = keyfile.read() - self.address = self.w3.toChecksumAddress( + self.address = self.w3.to_checksum_address( json.loads(encrypted_key)["address"]) self.path_to_keystore = path_to_keystore self.private_key = None @@ -82,7 +86,7 @@ def transact(self, transaction, out_f): self.w3, self.private_key, transaction) return send_and_wait_for_transaction(raw_transaction, self.w3, out_f) - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): if self.private_key is None: self.private_key = unlock_keystore_with_password( @@ -104,22 +108,17 @@ def transact(self, transaction, out_f): txn_hash = self.w3.eth.sendTransaction(transaction) return send_and_wait_for_transaction_receipt(txn_hash, self.w3) - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): return self.w3.eth.sign(self.get_address(), message) class MnemonicIdentityProvider(IdentityProvider): def __init__(self, w3, mnemonic, index): self.w3 = w3 - master_key = BIP32Node.from_master_secret( - Mnemonic("english").to_seed(mnemonic)) - purpose_subtree = master_key.subkey(i=44, is_hardened=True) - coin_type_subtree = purpose_subtree.subkey(i=60, is_hardened=True) - account_subtree = coin_type_subtree.subkey(i=0, is_hardened=True) - 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 = get_address_from_private(self.private_key) + Account.enable_unaudited_hdwallet_features() + account = Account.from_mnemonic(mnemonic, account_path=f"m/44'/60'/0'/0/{index}") + self.private_key = account.key.hex() + self.address = account.address def get_address(self): return self.address @@ -129,7 +128,7 @@ def transact(self, transaction, out_f): self.w3, self.private_key, transaction) return send_and_wait_for_transaction(raw_transaction, self.w3, out_f) - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): return sign_message_with_private_key(self.w3, self.private_key, message) @@ -138,7 +137,7 @@ def __init__(self, w3, index): self.w3 = w3 self.client = TrezorClient(HidTransport.enumerate()[0]) self.index = index - self.address = self.w3.toChecksumAddress( + self.address = self.w3.to_checksum_address( "0x" + bytes(self.client.ethereum_get_address([44 + BIP32_HARDEN, 60 + BIP32_HARDEN, BIP32_HARDEN, 0, @@ -168,7 +167,7 @@ def transact(self, transaction, out_f): int(signature[2].hex(), 16))) return send_and_wait_for_transaction(raw_transaction, self.w3, out_f) - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): n = self.client._convert_prime([44 + BIP32_HARDEN, 60 + BIP32_HARDEN, BIP32_HARDEN, @@ -189,7 +188,7 @@ def __init__(self, w3, index): self.dongle = getDongle(False) except CommException: raise RuntimeError( - "Received commException from ledger. Are you sure your device is plugged in?") + "Received commException from Ledger. Are you sure your device is plugged in?") self.dongle_path = parse_bip32_path("44'/60'/0'/0/{}".format(index)) apdu = LedgerIdentityProvider.GET_ADDRESS_OP apdu += bytearray([len(self.dongle_path) + 1, @@ -197,12 +196,12 @@ def __init__(self, w3, index): try: result = self.dongle.exchange(apdu) except CommException: - raise RuntimeError("Received commException from ledger. Are you sure your device is unlocked and the " + raise RuntimeError("Received commException from Ledger. Are you sure your device is unlocked and the " "Ethereum app is running?") offset = 1 + result[0] - self.address = self.w3.toChecksumAddress(bytes(result[offset + 1: offset + 1 + result[offset]]) - .decode("utf-8")) + self.address = self.w3.to_checksum_address(bytes(result[offset + 1: offset + 1 + result[offset]]) + .decode("utf-8")) def get_address(self): return self.address @@ -223,14 +222,14 @@ def transact(self, transaction, out_f): if overflow > 0: encoded_tx, remaining_tx = encoded_tx[:- - overflow], encoded_tx[-overflow:] + overflow], encoded_tx[-overflow:] apdu = LedgerIdentityProvider.SIGN_TX_OP apdu += bytearray([len(self.dongle_path) + 1 + len(encoded_tx), int(len(self.dongle_path) / 4)]) apdu += self.dongle_path + encoded_tx try: - print("Sending transaction to ledger for signature...\n", file=out_f) + print("Sending transaction to Ledger for signature...\n", file=out_f) result = self.dongle.exchange(apdu) while overflow > 0: encoded_tx = remaining_tx @@ -238,15 +237,16 @@ def transact(self, transaction, out_f): if overflow > 0: encoded_tx, remaining_tx = encoded_tx[:- - overflow], encoded_tx[-overflow:] + overflow], encoded_tx[-overflow:] apdu = LedgerIdentityProvider.SIGN_TX_OP_CONT apdu += bytearray([len(encoded_tx)]) apdu += encoded_tx result = self.dongle.exchange(apdu) - except CommException: - raise RuntimeError("Received commException from ledger. Are you sure your device is unlocked and the " - "Ethereum app is running?") + except CommException as e: + if e.sw == 27013: + raise RuntimeError("Transaction denied from Ledger by user") + raise RuntimeError(e.message, e.sw) transaction.pop("from") unsigned_transaction = serializable_unsigned_transaction_from_dict( @@ -258,7 +258,7 @@ def transact(self, transaction, out_f): int.from_bytes(result[33:65], byteorder="big"))) return send_and_wait_for_transaction(raw_transaction, self.w3, out_f) - def sign_message_after_soliditySha3(self, message): + def sign_message_after_solidity_keccak(self, message): apdu = LedgerIdentityProvider.SIGN_MESSAGE_OP apdu += bytearray([len(self.dongle_path) + 1 + len(message) + 4, int(len(self.dongle_path) / 4)]) @@ -266,7 +266,7 @@ def sign_message_after_soliditySha3(self, message): try: result = self.dongle.exchange(apdu) except CommException: - raise RuntimeError("Received commException from ledger. Are you sure your device is unlocked and the " + raise RuntimeError("Received commException from Ledger. Are you sure your device is unlocked and the " "Ethereum app is running?") return result[1:] + result[0:1] @@ -277,15 +277,18 @@ def send_and_wait_for_transaction_receipt(txn_hash, w3): receipt = dict() while not receipt: time.sleep(1) - receipt = w3.eth.getTransactionReceipt(txn_hash) - if receipt and "blockHash" in receipt and receipt["blockHash"] is None: + try: + receipt = w3.eth.get_transaction_receipt(txn_hash) + if receipt and "blockHash" in receipt and receipt["blockHash"] is None: + receipt = dict() + except: receipt = dict() return receipt def send_and_wait_for_transaction(raw_transaction, w3, out_f): print("Submitting transaction...\n", file=out_f) - txn_hash = w3.eth.sendRawTransaction(raw_transaction) + txn_hash = w3.eth.send_raw_transaction(raw_transaction) return send_and_wait_for_transaction_receipt(txn_hash, w3) @@ -329,7 +332,7 @@ def get_identity_types(): def sign_transaction_with_private_key(w3, private_key, transaction): - return w3.eth.account.signTransaction(transaction, private_key).rawTransaction + return w3.eth.account.sign_transaction(transaction, private_key).rawTransaction def sign_message_with_private_key(w3, private_key, message): diff --git a/packages/snet_cli/snet_cli/utils/agi2cogs.py b/packages/snet_cli/snet_cli/utils/agi2cogs.py deleted file mode 100644 index 5c5c305e..00000000 --- a/packages/snet_cli/snet_cli/utils/agi2cogs.py +++ /dev/null @@ -1,24 +0,0 @@ -""" Safe conversion between agi(string) and cogs(int) """ -import decimal - -AGI_TOKEN_DECIMALS = 8 - - -def stragi2cogs(stragi): - if type(stragi) != str: - raise Exception("Parameter should be string") - - # in case user write something stupid we set very big precision - decimal.getcontext().prec = 1000 - cogs_decimal = decimal.Decimal(stragi) * 10 ** AGI_TOKEN_DECIMALS - cogs_int = int(cogs_decimal) - if cogs_int != cogs_decimal: - raise Exception("AGI token has only %i decimals" % AGI_TOKEN_DECIMALS) - return cogs_int - - -def cogs2stragi(cogs_int): - # presicison should be higer then INITIAL_SUPPLY + 1, we set it to 1000 be consistent with stragi2cogs - decimal.getcontext().prec = 1000 - agi_decimal = decimal.Decimal(cogs_int) / 10 ** AGI_TOKEN_DECIMALS - return format(agi_decimal, 'f') diff --git a/packages/snet_cli/snet_cli/utils/agix2cogs.py b/packages/snet_cli/snet_cli/utils/agix2cogs.py new file mode 100644 index 00000000..382750fe --- /dev/null +++ b/packages/snet_cli/snet_cli/utils/agix2cogs.py @@ -0,0 +1,24 @@ +""" Safe conversion between agix(string) and cogs(int) """ +import decimal + +AGIX_TOKEN_DECIMALS = 8 + + +def stragix2cogs(stragix): + if type(stragix) != str: + raise Exception("Parameter should be string") + + # in case user write something stupid we set very big precision + decimal.getcontext().prec = 1000 + cogs_decimal = decimal.Decimal(stragix) * 10 ** AGIX_TOKEN_DECIMALS + cogs_int = int(cogs_decimal) + if cogs_int != cogs_decimal: + raise Exception("AGIX token has only %i decimals" % AGIX_TOKEN_DECIMALS) + return cogs_int + + +def cogs2stragix(cogs_int): + # presicison should be higer then INITIAL_SUPPLY + 1, we set it to 1000 be consistent with stragix2cogs + decimal.getcontext().prec = 1000 + agix_decimal = decimal.Decimal(cogs_int) / 10 ** AGIX_TOKEN_DECIMALS + return format(agix_decimal, 'f') diff --git a/packages/snet_cli/snet_cli/utils/config.py b/packages/snet_cli/snet_cli/utils/config.py index 1eb23ae6..659ad15c 100644 --- a/packages/snet_cli/snet_cli/utils/config.py +++ b/packages/snet_cli/snet_cli/utils/config.py @@ -13,18 +13,18 @@ def get_contract_address(cmd, contract_name, error_message=None): # try to get from command line argument at or contractname_at a = "at" - if (hasattr(cmd.args, a) and getattr(cmd.args, a)): - return cmd.w3.toChecksumAddress(getattr(cmd.args, a)) + if hasattr(cmd.args, a) and getattr(cmd.args, a): + return cmd.w3.to_checksum_address(getattr(cmd.args, a)) # try to get from command line argument contractname_at a = "%s_at" % contract_name.lower() - if (hasattr(cmd.args, a) and getattr(cmd.args, a)): - return cmd.w3.toChecksumAddress(getattr(cmd.args, a)) + if hasattr(cmd.args, a) and getattr(cmd.args, a): + return cmd.w3.to_checksum_address(getattr(cmd.args, a)) # try to get from current session configuration rez = cmd.config.get_session_field("current_%s_at" % (contract_name.lower()), exception_if_not_found=False) if rez: - return cmd.w3.toChecksumAddress(rez) + return cmd.w3.to_checksum_address(rez) error_message = error_message or "Fail to read %s address from \"networks\", you should " \ "specify address by yourself via --%s_at parameter" % ( @@ -34,13 +34,13 @@ def get_contract_address(cmd, contract_name, error_message=None): def read_default_contract_address(w3, contract_name): - chain_id = w3.version.network # this will raise exception if endpoint is invalid + chain_id = w3.net.version # this will raise exception if endpoint is invalid contract_def = get_contract_def(contract_name) networks = contract_def["networks"] contract_address = networks.get(chain_id, {}).get("address", None) if not contract_address: raise Exception() - contract_address = w3.toChecksumAddress(contract_address) + contract_address = w3.to_checksum_address(contract_address) return contract_address diff --git a/packages/snet_cli/test/functional_tests/mint/mint.py b/packages/snet_cli/test/functional_tests/mint/mint.py index ff0139de..11e17e9d 100644 --- a/packages/snet_cli/test/functional_tests/mint/mint.py +++ b/packages/snet_cli/test/functional_tests/mint/mint.py @@ -16,7 +16,7 @@ def _get_nonce(web3, address): - nonce = web3.eth.getTransactionCount(address) + nonce = web3.eth.get_transaction_count(address) if initialNonce >= nonce: nonce = initialNonce + 1 nonce = nonce @@ -25,30 +25,28 @@ def _get_nonce(web3, address): def send_transaction(web3, contract_fn, *args): txn_hash = _send_signed_transaction(web3, contract_fn, *args) - return web3.eth.waitForTransactionReceipt(txn_hash, TRANSACTION_TIMEOUT) + return web3.eth.wait_for_transaction_receipt(txn_hash, TRANSACTION_TIMEOUT) def _send_signed_transaction(web3, wallet_address, contract_fn, *args): - web3.eth.setGasPriceStrategy(medium_gas_price_strategy) - transaction = contract_fn(*args).buildTransaction( { "chainId": int(web3.version.network), "gas": DEFAULT_GAS, - "gasPrice": web3.eth.generateGasPrice(), + "gasPrice": web3.eth.gas_price * 4 / 3, "nonce": _get_nonce(web3, wallet_address), } ) - signed_txn = web3.eth.account.signTransaction( + signed_txn = web3.eth.account.sign_transaction( transaction, private_key=signer_private_key ) - return web3.toHex(web3.eth.sendRawTransaction(signed_txn.rawTransaction)) + return web3.to_hex(web3.eth.send_raw_transaction(signed_txn.rawTransaction)) def mint_token(): w3 = get_web3(HTTP_PROVIDER) - address_1 = w3.toChecksumAddress(wallet_address_1) + address_1 = w3.to_checksum_address(wallet_address_1) contract = get_contract_object( w3, contract_file="SingularityNetToken.json", address=contract_address )