diff --git a/README.md b/README.md index 13a6e92..80eb3de 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The package is published in PyPI at the following link: The SingularityNET SDK allows you to make calls to SingularityNET services programmatically from your application. To communicate between clients and services, SingularityNET uses [gRPC](https://grpc.io/). To handle payment of services, SingularityNET uses -[Ethereum state channels](https://dev.singularitynet.io/docs/ai-consumers/mpe/). +[Ethereum state channels](https://dev.singularitynet.io/docs/products/DecentralizedAIPlatform/CoreConcepts/SmartContracts/mpe). The SingularityNET SDK abstracts and manages state channels with service providers on behalf of the user and handles authentication with the SingularityNET services. @@ -27,7 +27,7 @@ These instructions are for the development and use of the SingularityNET SDK for ### Usage To call a service on a SingularityNET platform, 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. +[Multi-Party Escrow](https://dev.singularitynet.io/docs/products/DecentralizedAIPlatform/CoreConcepts/SmartContracts/mpe) Smart Contract. To deposit these tokens or do any other transaction on the Ethereum blockchain. Once you have installed snet-sdk in your current environment, you can import it into your Python script and create an @@ -35,22 +35,31 @@ instance of the base sdk class: ```python from snet import sdk -config = sdk.config.Config(private_key="YOUR_PRIVATE_KEY", - eth_rpc_endpoint=f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", - concurrency=False, - force_update=False) - +""" +SDK configuration provided by the application provider. +To run the application, replace 'private_key' and 'eth_rpc_endpoint' with your values. +""" +config = sdk.config.Config( + private_key="YOUR_PRIVATE_KEY", # Replace with your Ethereum private key + eth_rpc_endpoint="https://eth-sepolia.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY", # Replace with your Alchemy API key + concurrency=False, + force_update=False +) + +# Initialize the SnetSDK instance snet_sdk = sdk.SnetSDK(config) ``` The `config` parameter is an instance of the `Config` class. -See [config.py](https://github.com/singnet/snet-sdk-python/blob/master/docs/main/config.md) +See [config.py](https://dev.singularitynet.io/docs/products/DecentralizedAIPlatform/SDK/PythonSDK/Documentation/config/) for a reference. -##### Config parameters description +#### Config parameters description - `private_key`: Your wallet's private key that will be used to pay for calls. Is **required** in config; - `eth_rpc_endpoint`: RPC endpoint that is used to access the Ethereum network. Is **required** in config; +> To get your **Alchemy API Key**, follow [this guide](https://dev.singularitynet.io/docs/products/DecentralizedAIPlatform/Daemon/alchemy-api/). + - `wallet_index`: The index of the wallet that will be used to pay for calls; - `ipfs_endpoint`: IPFS endpoint that is used to access IPFS; - `concurrency`: If set to True, will enable concurrency for the SDK; @@ -198,6 +207,31 @@ payment_channel.extend_expiration(expiration=33333) payment_channel.extend_and_add_funds(amount=123456, expiration=33333) ``` +### Concurrent (Prepaid) call + +Concurrent (prepaid) calls allow you to prepay for a batch of service calls in advance. This off-chain strategy is ideal for scenarios requiring high throughput and low latency. Unlike regular paid calls, the payment is done once upfront, and the SDK automatically manages the channel during usage. + +To use concurrent prepaid calls, specify the `concurrent_calls` parameter when creating a service client: + +```python +service_client = snet_sdk.create_service_client( + org_id="26072b8b6a0e448180f8c0e702ab6d2f", + service_id="Exampleservice", + group_name="default_group", + concurrent_calls=5 # Number of prepaid calls to allocate +) +``` + +Then you can make service calls as usual, and the SDK will use the prepaid pool internally: + +```python +for i in range(5): + response = service_client.call_rpc("add", "Numbers", a=1, b=2) + print(f"Concurrent call {i+1} result:", response) +``` + +This model is especially useful for batch inference or rapid sequential calls without incurring on-chain transaction costs for each invocation. + ### Train call Some of the training methods, namely `upload_and_validate` and `train_model`, are paid as well as the regular service call. diff --git a/requirements.txt b/requirements.txt index ea58b08..4d81ede 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,6 +17,6 @@ argcomplete==3.1.2 grpcio-health-checking==1.59.0 jsonschema==4.0.0 eth-account==0.9.0 -snet-contracts==0.2.1 +snet-contracts==1.0.0 lighthouseweb3==0.1.4 zipp>=3.19.1 diff --git a/snet/sdk/account.py b/snet/sdk/account.py index 745bf3b..fa88ceb 100644 --- a/snet/sdk/account.py +++ b/snet/sdk/account.py @@ -38,10 +38,10 @@ def __init__(self, w3: web3.Web3, config: Config, ) if _token_contract_address is None: self.token_contract = get_contract_object( - self.web3, "SingularityNetToken") + self.web3, "FetchToken") else: self.token_contract = get_contract_object( - self.web3, "SingularityNetToken", _token_contract_address) + self.web3, "FetchToken", _token_contract_address) if config.get("private_key") is not None: self.private_key = normalize_private_key(config.get("private_key")) diff --git a/snet/sdk/mpe/payment_channel_provider.py b/snet/sdk/mpe/payment_channel_provider.py index 48ff5e6..1948abd 100644 --- a/snet/sdk/mpe/payment_channel_provider.py +++ b/snet/sdk/mpe/payment_channel_provider.py @@ -25,7 +25,7 @@ def __init__(self, w3, mpe_contract): def update_cache(self): channels = [] - last_read_block = self.deployment_block + last_read_block = self.deployment_block - 1 if not self.channels_file.exists(): print(f"Channels cache is empty. Caching may take some time when first accessing channels.\nCaching in progress...") @@ -45,7 +45,7 @@ def update_cache(self): current_block_number = self.web3.eth.block_number if last_read_block < current_block_number: - new_channels = self._get_all_channels_from_blockchain_logs_to_dicts(last_read_block, current_block_number) + new_channels = self._get_all_channels_from_blockchain_logs_to_dicts(last_read_block + 1, current_block_number) channels = channels + new_channels last_read_block = current_block_number diff --git a/version.py b/version.py index 3bdbbae..ce1305b 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -__version__ = "3.7.2" +__version__ = "4.0.0"