From 7ddfa2881762fc73c0d1a42981140d66e13277a1 Mon Sep 17 00:00:00 2001 From: freqnik Date: Fri, 24 Oct 2025 01:56:48 -0400 Subject: [PATCH 01/15] Add Price dataclass to types. Add StartSession() to subscription module. Rewrite SubscribeToNode() in node module --- src/sentinel_sdk/modules/node.py | 16 ++++++++++++++-- src/sentinel_sdk/modules/subscription.py | 8 ++++++++ src/sentinel_sdk/types.py | 6 ++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/sentinel_sdk/modules/node.py b/src/sentinel_sdk/modules/node.py index 5df66f3..8f78919 100755 --- a/src/sentinel_sdk/modules/node.py +++ b/src/sentinel_sdk/modules/node.py @@ -14,10 +14,11 @@ import sentinel_protobuf.sentinel.node.v2.querier_pb2 as sentinel_node_v2_querier_pb2 import sentinel_protobuf.sentinel.node.v2.querier_pb2_grpc as sentinel_node_v2_querier_pb2_grpc import sentinel_protobuf.sentinel.node.v2.msg_pb2 as msg_pb2 +import sentinel_protobuf.sentinel.node.v3.msg_pb2 as msg_pb2_3 from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor -from sentinel_sdk.types import PageRequest, TxParams, NodeType +from sentinel_sdk.types import PageRequest, TxParams, NodeType, Price from .wireguard import WgKey @@ -129,6 +130,7 @@ def RegisterNode(self, gigabyte_prices: int, hourly_prices: int, remote_url: str ) return self.transaction([msg], tx_params) + ''' def SubscribeToNode(self, node_address: str, gigabytes: int = 0, hours: int = 0, denom: str = "udvpn", tx_params: TxParams = TxParams()): msg = msg_pb2.MsgSubscribeRequest( frm = self._account.address, @@ -138,7 +140,17 @@ def SubscribeToNode(self, node_address: str, gigabytes: int = 0, hours: int = 0, node_address = node_address, ) return self.transaction([msg], tx_params) - + ''' + + def SubscribeToNode(self, node_address: str, gigabytes: int = 0, hours: int = 0, price: Price = Price(), tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgStartSessionRequest( + frm = self._account.address, + gigabytes = gigabytes, + hours = hours, + node_address = node_address, + max_price = price, + ) + return self.transaction([msg], tx_params) def UpdateNodeDetails(self, gigabyte_prices: int, hourly_prices: int, remote_url: str, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgUpdateDetailsRequest( frm = self._account.address, diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index 81b0c7f..5ac75df 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -5,6 +5,7 @@ import sentinel_protobuf.sentinel.subscription.v2.querier_pb2_grpc as sentinel_subscription_v2_querier_pb2_grpc import sentinel_protobuf.sentinel.subscription.v2.subscription_pb2 as subscription_pb2 import sentinel_protobuf.sentinel.subscription.v2.msg_pb2 as msg_pb2 +import sentinel_protobuf.sentinel.subscription.v3.msg_pb2 as msg_pb2_3 from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor @@ -168,6 +169,13 @@ def Cancel(self, id: int, tx_params: TxParams = TxParams()): ) return self.transaction([msg], tx_params) + def StartSession(self, address: str, subscription_id: int, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgStartSessionRequest( + frm = self._account.address, + id = subscription_id, + address = address + ) + return self.transaction([msg], tx_params) # Node subscriptions are returned by grpc querier in google's 'Any' type and need to be converted into desired protobuf type # # diff --git a/src/sentinel_sdk/types.py b/src/sentinel_sdk/types.py index b5d1809..805c189 100755 --- a/src/sentinel_sdk/types.py +++ b/src/sentinel_sdk/types.py @@ -25,6 +25,12 @@ class TxParams: fee_amount: int = 31415 gas: float = 0 gas_multiplier: float = 1.5 + +@dataclass +class Price: + denom: str = "udvpn" + base_value: str = "0" + quote_value: str = "0" class PageRequest: From 98818b38244fe0d5d01db34e95496e00d4546153 Mon Sep 17 00:00:00 2001 From: freqnik Date: Sat, 25 Oct 2025 16:59:47 -0400 Subject: [PATCH 02/15] Update plan, node, subscription modules. Create lease module. At renewal policy to types. --- src/sentinel_sdk/modules/lease.py | 63 ++++++++++++++++++++++++ src/sentinel_sdk/modules/plan.py | 5 +- src/sentinel_sdk/modules/subscription.py | 52 +++++++++++++++++-- src/sentinel_sdk/types.py | 10 ++++ 4 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/sentinel_sdk/modules/lease.py diff --git a/src/sentinel_sdk/modules/lease.py b/src/sentinel_sdk/modules/lease.py new file mode 100644 index 0000000..f8506e5 --- /dev/null +++ b/src/sentinel_sdk/modules/lease.py @@ -0,0 +1,63 @@ + +import grpc +import sentinel_protobuf.sentinel.leace.v1.lease_pb2 as lease_pb2 +import sentinel_protobuf.sentinel.lease.v1.querier_pb2 as sentinel_subscription_v2_querier_pb2 +import sentinel_protobuf.sentinel.lease.v1.querier_pb2_grpc as sentinel_subscription_v2_querier_pb2_grpc +import sentinel_protobuf.sentinel.subscription.v2.subscription_pb2 as subscription_pb2 +import sentinel_protobuf.sentinel.lease.v1.msg_pb2 as msg_pb2 + +from sentinel_sdk.querier.querier import Querier +from sentinel_sdk.transactor.transactor import Transactor +from sentinel_sdk.types import PageRequest, TxParams, Price, RenewalPricePolicy + +class LeaseModule(Querier, Transactor): + def __init__(self, channel: grpc.Channel, account, provider_account, client): + self.__stub = sentinel_subscription_v2_querier_pb2_grpc.QueryServiceStub( + channel + ) + self._account = account + self._client = client + self._provider_account = provider_account + + def EndLease(self, subscription_id: int, tx_params: TxParams = TxParams()): + msg = msg_pb2.MsgSubscribeRequest( + frm = self._account.address, + id = subscription_id, + ) + + return self.transaction([msg], tx_params) + + def RenewLease(self, subscription_id: int, hours: int, max_price: Price = Price(), tx_params: TxParams = TxParams()): + msg = msg_pb2.MsgSubscribeRequest( + frm = self._account.address, + id = subscription_id, + hours = hours, + max_price = max_price, + ) + + return self.transaction([msg], tx_params) + + def StartLease(self, node: str, hours: int, max_price: Price = Price(), renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): + msg = msg_pb2.MsgSubscribeRequest( + frm = self._account.address, + node_address = node, + hours = hours, + max_price = max_price, + renewal_price_policy = renewal, + ) + + return self.transaction([msg], tx_params) + + def UpdateLease(self, subscription_id: int, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): + msg = msg_pb2.MsgSubscribeRequest( + frm = self._account.address, + id = subscription_id, + renewal_price_policy = renewal, + ) + + return self.transaction([msg], tx_params) + + + + + \ No newline at end of file diff --git a/src/sentinel_sdk/modules/plan.py b/src/sentinel_sdk/modules/plan.py index ea91c2e..44486fd 100755 --- a/src/sentinel_sdk/modules/plan.py +++ b/src/sentinel_sdk/modules/plan.py @@ -4,6 +4,7 @@ import sentinel_protobuf.sentinel.plan.v2.querier_pb2 as sentinel_plan_v2_querier_pb2 import sentinel_protobuf.sentinel.plan.v2.querier_pb2_grpc as sentinel_plan_v2_querier_pb2_grpc import sentinel_protobuf.sentinel.plan.v2.msg_pb2 as msg_pb2 +import sentinel_protobuf.sentinel.plan.v3.msg_pb2 as msg_pb2_3 from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor @@ -59,7 +60,7 @@ def Create(self, duration: int, gigabytes: int, prices: int, tx_params: TxParams return self.transaction([msg], tx_params) def LinkNode(self, plan_id: int, node_address: str, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgLinkNodeRequest( + msg = msg_pb2_3.MsgLinkNodeRequest( frm = self._provider_account.address, id = plan_id, node_address = node_address, @@ -75,7 +76,7 @@ def Subscribe(self, denom: str, plan_id: int, tx_params: TxParams = TxParams()): return self.transaction([msg], tx_params) def UnlinkNode(self, plan_id: int, node_address: str, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgUnlinkNodeRequest( + msg = msg_pb2_3.MsgUnlinkNodeRequest( frm = self._provider_account.address, id = plan_id, node_address = node_address, diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index 5ac75df..cd09378 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -9,7 +9,7 @@ from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor -from sentinel_sdk.types import PageRequest, TxParams +from sentinel_sdk.types import PageRequest, TxParams, RenewalPricePolicy class SubscriptionModule(Querier, Transactor): @@ -162,18 +162,64 @@ def Allocate(self, address: str, bytes: str, id: int, tx_params: TxParams = TxPa ) return self.transaction([msg], tx_params) + ''' def Cancel(self, id: int, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgCancelRequest( frm = self._account.address, id = id, ) return self.transaction([msg], tx_params) - + ''' + + def Cancel(self, id: int, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgCancelSubscriptionRequest( + frm = self._account.address, + id = id, + ) + return self.transaction([msg], tx_params) + + # Used for plan subs def StartSession(self, address: str, subscription_id: int, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgStartSessionRequest( frm = self._account.address, id = subscription_id, - address = address + node_address = address + ) + return self.transaction([msg], tx_params) + + def ShareSubscription(self, subscription_id: int, wallet_address: str, bytes: str, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgShareSubscriptionRequest( + frm = self._account.address, + id = subscription_id, + acc_address = address, + bytes = bytes, + ) + return self.transaction([msg], tx_params) + + def RenewSubscription(self, subscription_id: int, denom: str, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgRenewSubscriptionRequest( + frm = self._account.address, + id = subscription_id, + denom = denom, + ) + return self.transaction([msg], tx_params) + + # id is plan_id + + def StartSubscription(self, plan_id: int, denom: str, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgStartSubscriptionRequest( + frm = self._account.address, + id = plan_id, + denom = denom, + renewal_price_polilcy = renewal, + ) + return self.transaction([msg], tx_params) + + def UpdateSubscription(self, subscription_id: int, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgUpdateSubscriptionRequest( + frm = self._account.address, + id = id, + renewal_price_policy = renewal, ) return self.transaction([msg], tx_params) # Node subscriptions are returned by grpc querier in google's 'Any' type and need to be converted into desired protobuf type diff --git a/src/sentinel_sdk/types.py b/src/sentinel_sdk/types.py index 805c189..c052938 100755 --- a/src/sentinel_sdk/types.py +++ b/src/sentinel_sdk/types.py @@ -19,6 +19,16 @@ class NodeType(Enum): WIREGUARD = 1 V2RAY = 2 +class RenewalPricePolicy(Enum): + RENEWAL_PRICE_POLICY_UNSPECIFIED = 0 + RENEWAL_PRICE_POLICY_IF_LESSER = 1 + RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL = 2 + RENEWAL_PRICE_POLICY_IF_EQUAL = 3 + RENEWAL_PRICE_POLICY_IF_NOT_EQUAL = 4 + RENEWAL_PRICE_POLICY_IF_GREATER = 5 + RENEWAL_PRICE_POLICY_IF_GREATER_OR_EQUAL = 6 + RENEWAL_PRICE_POLICY_ALWAYS = 7 + @dataclass class TxParams: denom: str = "udvpn" From a772f3f126f1d16e7cfd79e8fd29a6c347903a6f Mon Sep 17 00:00:00 2001 From: freqnik Date: Sat, 25 Oct 2025 17:04:54 -0400 Subject: [PATCH 03/15] Fix ShareSub --- src/sentinel_sdk/modules/subscription.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index cd09378..6f04416 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -191,7 +191,7 @@ def ShareSubscription(self, subscription_id: int, wallet_address: str, bytes: st msg = msg_pb2_3.MsgShareSubscriptionRequest( frm = self._account.address, id = subscription_id, - acc_address = address, + acc_address = wallet_address, bytes = bytes, ) return self.transaction([msg], tx_params) From 58d8379ef96bfa59dd3dcd684087ac59068ada32 Mon Sep 17 00:00:00 2001 From: freqnik Date: Mon, 27 Oct 2025 14:20:18 -0400 Subject: [PATCH 04/15] Update node module for v3. Comment out v2 code --- src/sentinel_sdk/modules/node.py | 18 ++++++------- src/sentinel_sdk/modules/plan.py | 4 ++- src/sentinel_sdk/modules/subscription.py | 33 +++++++++++++----------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/sentinel_sdk/modules/node.py b/src/sentinel_sdk/modules/node.py index 8f78919..333b307 100755 --- a/src/sentinel_sdk/modules/node.py +++ b/src/sentinel_sdk/modules/node.py @@ -10,9 +10,9 @@ import hashlib import ecdsa import grpc -import sentinel_protobuf.sentinel.node.v2.node_pb2 as node_pb2 -import sentinel_protobuf.sentinel.node.v2.querier_pb2 as sentinel_node_v2_querier_pb2 -import sentinel_protobuf.sentinel.node.v2.querier_pb2_grpc as sentinel_node_v2_querier_pb2_grpc +import sentinel_protobuf.sentinel.node.v3.node_pb2 as node_pb2 +import sentinel_protobuf.sentinel.node.v3.querier_pb2 as sentinel_node_v3_querier_pb2 +import sentinel_protobuf.sentinel.node.v3.querier_pb2_grpc as sentinel_node_v3_querier_pb2_grpc import sentinel_protobuf.sentinel.node.v2.msg_pb2 as msg_pb2 import sentinel_protobuf.sentinel.node.v3.msg_pb2 as msg_pb2_3 @@ -26,7 +26,7 @@ class NodeModule(Querier, Transactor): def __init__(self, channel: grpc.Channel, node_timeout: int, account, client): self.node_timeout = node_timeout - self.__stub = sentinel_node_v2_querier_pb2_grpc.QueryServiceStub(channel) + self.__stub = sentinel_node_v3_querier_pb2_grpc.QueryServiceStub(channel) # Disable SSL verification self.__ssl_ctx = ssl.create_default_context() @@ -39,18 +39,18 @@ def __init__(self, channel: grpc.Channel, node_timeout: int, account, client): self.__nodes_status_cache = {} def QueryParams(self) -> Any: - return self.__stub.QueryParams(sentinel_node_v2_querier_pb2.QueryParamsRequest()).params + return self.__stub.QueryParams(sentinel_node_v3_querier_pb2.QueryParamsRequest()).params def QueryNode(self, address: str) -> Any: r = self.__stub.QueryNode( - sentinel_node_v2_querier_pb2.QueryNodeRequest(address=address) + sentinel_node_v3_querier_pb2.QueryNodeRequest(address=address) ) return r.node def QueryNodes(self, status: int, pagination: PageRequest = None) -> list: return self.QueryAll( query=self.__stub.QueryNodes, - request=sentinel_node_v2_querier_pb2.QueryNodesRequest, + request=sentinel_node_v3_querier_pb2.QueryNodesRequest, attribute="nodes", status=status.value, pagination=pagination, @@ -58,7 +58,7 @@ def QueryNodes(self, status: int, pagination: PageRequest = None) -> list: def QueryNumOfNodesWithStatus(self, status: int) -> int: r = self.__stub.QueryNodes( - sentinel_node_v2_querier_pb2.QueryNodesRequest(status=status.value) + sentinel_node_v3_querier_pb2.QueryNodesRequest(status=status.value) ) return r.pagination.total @@ -104,7 +104,7 @@ def QueryNodesForPlan( ) -> list: return self.QueryAll( query=self.__stub.QueryNodesForPlan, - request=sentinel_node_v2_querier_pb2.QueryNodesForPlanRequest, + request=sentinel_node_v3_querier_pb2.QueryNodesForPlanRequest, attribute="nodes", status=status.value, id=plan_id, diff --git a/src/sentinel_sdk/modules/plan.py b/src/sentinel_sdk/modules/plan.py index 44486fd..9843bcb 100755 --- a/src/sentinel_sdk/modules/plan.py +++ b/src/sentinel_sdk/modules/plan.py @@ -66,7 +66,8 @@ def LinkNode(self, plan_id: int, node_address: str, tx_params: TxParams = TxPara node_address = node_address, ) return self.transaction([msg], tx_params) - + + ''' def Subscribe(self, denom: str, plan_id: int, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgSubscribeRequest( frm = self._account.address, @@ -74,6 +75,7 @@ def Subscribe(self, denom: str, plan_id: int, tx_params: TxParams = TxParams()): denom = denom, ) return self.transaction([msg], tx_params) + ''' def UnlinkNode(self, plan_id: int, node_address: str, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgUnlinkNodeRequest( diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index 6f04416..117299c 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -152,7 +152,9 @@ def QuerySubscriptionsForPlan( self.__ConvertAnyToPlanSubscription(subscription.value) for subscription in subscriptions ] - + + # not in use anymore + ''' def Allocate(self, address: str, bytes: str, id: int, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgAllocateRequest( frm = self._account.address, @@ -162,7 +164,7 @@ def Allocate(self, address: str, bytes: str, id: int, tx_params: TxParams = TxPa ) return self.transaction([msg], tx_params) - ''' + def Cancel(self, id: int, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgCancelRequest( frm = self._account.address, @@ -171,6 +173,7 @@ def Cancel(self, id: int, tx_params: TxParams = TxParams()): return self.transaction([msg], tx_params) ''' + # id is subscription id def Cancel(self, id: int, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgCancelSubscriptionRequest( frm = self._account.address, @@ -178,12 +181,11 @@ def Cancel(self, id: int, tx_params: TxParams = TxParams()): ) return self.transaction([msg], tx_params) - # Used for plan subs - def StartSession(self, address: str, subscription_id: int, tx_params: TxParams = TxParams()): - msg = msg_pb2_3.MsgStartSessionRequest( + def RenewSubscription(self, subscription_id: int, denom: str, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgRenewSubscriptionRequest( frm = self._account.address, id = subscription_id, - node_address = address + denom = denom, ) return self.transaction([msg], tx_params) @@ -196,16 +198,7 @@ def ShareSubscription(self, subscription_id: int, wallet_address: str, bytes: st ) return self.transaction([msg], tx_params) - def RenewSubscription(self, subscription_id: int, denom: str, tx_params: TxParams = TxParams()): - msg = msg_pb2_3.MsgRenewSubscriptionRequest( - frm = self._account.address, - id = subscription_id, - denom = denom, - ) - return self.transaction([msg], tx_params) - # id is plan_id - def StartSubscription(self, plan_id: int, denom: str, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgStartSubscriptionRequest( frm = self._account.address, @@ -222,6 +215,16 @@ def UpdateSubscription(self, subscription_id: int, renewal: int = RenewalPriceP renewal_price_policy = renewal, ) return self.transaction([msg], tx_params) + + # Used for plan subs + def StartSession(self, address: str, subscription_id: int, tx_params: TxParams = TxParams()): + msg = msg_pb2_3.MsgStartSessionRequest( + frm = self._account.address, + id = subscription_id, + node_address = address + ) + return self.transaction([msg], tx_params) + # Node subscriptions are returned by grpc querier in google's 'Any' type and need to be converted into desired protobuf type # # From 084c9069c102c4f013ef5fabf34d7d157b16fa2c Mon Sep 17 00:00:00 2001 From: freqnik Date: Tue, 28 Oct 2025 04:20:06 -0400 Subject: [PATCH 05/15] Update node modules - QueryNodeStatus() to include prices. Update types. Update subscription module --- pyproject.toml | 6 +++--- requirements.txt | 4 ++-- src/sentinel_sdk/modules/node.py | 33 ++++++++++++++++++++++++----- src/sentinel_sdk/querier/querier.py | 2 +- src/sentinel_sdk/types.py | 1 + 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3236323..81a18a1 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "sentinel_sdk" -version = "0.0.5" +version = "0.1.0" description = "A Sentinel SDK Written in Python" authors = [ { name = "NAST0R" }, @@ -13,7 +13,7 @@ authors = [ ] readme = "README.md" requires-python = ">=3.10" -keywords = ["sentinel_sdk", "mospy", "sentinel", "cosmos", "protobuf", "sentinel_protobuf"] +keywords = ["sentinel_sdk", "mospy", "sentinel", "dvpn", "cosmos", "protobuf", "sentinel_protobuf"] license = {text = "GPL-3.0 license"} classifiers = [ "Development Status :: 3 - Alpha", @@ -22,7 +22,7 @@ classifiers = [ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", ] dependencies = [ - "sentinel-protobuf==0.3.3", + "sentinel-protobuf==0.4.3", "grpcio>=1.51.1", "bip-utils==2.9.0", "mospy-wallet==0.6.0", diff --git a/requirements.txt b/requirements.txt index e706fa9..720a7ef 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -sentinel-protobuf==0.3.3 +sentinel-protobuf==0.4.3 grpcio>=1.51.1 bip-utils==2.9.0 -mospy-wallet @ git+https://github.com/Tkd-Alex/mospy.git@development +mospy-wallet==0.6.0 diff --git a/src/sentinel_sdk/modules/node.py b/src/sentinel_sdk/modules/node.py index 333b307..00dcae3 100755 --- a/src/sentinel_sdk/modules/node.py +++ b/src/sentinel_sdk/modules/node.py @@ -37,10 +37,10 @@ def __init__(self, channel: grpc.Channel, node_timeout: int, account, client): self._client = client self.__nodes_status_cache = {} - + def QueryParams(self) -> Any: return self.__stub.QueryParams(sentinel_node_v3_querier_pb2.QueryParamsRequest()).params - + def QueryNode(self, address: str) -> Any: r = self.__stub.QueryNode( sentinel_node_v3_querier_pb2.QueryNodeRequest(address=address) @@ -63,15 +63,33 @@ def QueryNumOfNodesWithStatus(self, status: int) -> int: return r.pagination.total def QueryNodeStatus(self, node: node_pb2.Node, is_in_thread: bool = False) -> str: - node_endpoint = node.remote_url + node_endpoint = "https://" + node.remote_addrs[0] + gb_price = "" + hr_price = "" + if node.gigabyte_prices: + for prices in node.gigabyte_prices: + gb_price = gb_price + prices.quote_value + prices.denom + ',' + else: + gb_price = "0.0udvpn" + if node.hourly_prices: + for prices in node.hourly_prices: + hr_price = hr_price + prices.quote_value + prices.denom + ',' + else: + hr_price = "0.0udvpn" + + gb_price = gb_price.rstrip(',') + hr_price = hr_price.rstrip(',') + print(f"GB Prices: {gb_price}\n Hourly Prices: {hr_price}") + print(f"Node Endpoint: {node_endpoint}") try: contents = urllib.request.urlopen( - f"{node_endpoint}/status", + f"{node_endpoint}", context=self.__ssl_ctx, timeout=self.node_timeout, ).read() contents = contents.decode("utf-8") - except urllib.error.URLError: + except urllib.error.URLError as E: + print(str(E)) contents = '{"success":false,"urllib-error":"URLError encountered"}' except TimeoutError: contents = '{"success":false,"urllib-error":"Data reading timed out"}' @@ -79,6 +97,11 @@ def QueryNodeStatus(self, node: node_pb2.Node, is_in_thread: bool = False) -> st contents = '{"success":false,"http-error":"Remote endpoint closed connection"}' except: contents = '{"success":false,"error":"Unrecognizable error encountered"}' + contents = json.loads(contents) + contents['gigabyte_prices'] = gb_price + contents['hourly_prices'] = hr_price + contents = json.dumps(contents) + if is_in_thread: self.__nodes_status_cache[node.address] = contents else: diff --git a/src/sentinel_sdk/querier/querier.py b/src/sentinel_sdk/querier/querier.py index 67113cc..b131a04 100755 --- a/src/sentinel_sdk/querier/querier.py +++ b/src/sentinel_sdk/querier/querier.py @@ -12,6 +12,7 @@ def QueryAll( pagination: PageRequest = None, **kwargs, ) -> list: + # ["status", "address", "id"] are the only valid kwargs request_arguments = { k: kwargs[k] for k in kwargs if k in ["status", "address", "id"] @@ -34,5 +35,4 @@ def QueryAll( # Stop iteration if PageRequest contain a offset value if pagination.offset is not None: break - return items \ No newline at end of file diff --git a/src/sentinel_sdk/types.py b/src/sentinel_sdk/types.py index c052938..ed9b79e 100755 --- a/src/sentinel_sdk/types.py +++ b/src/sentinel_sdk/types.py @@ -18,6 +18,7 @@ def __str__(self): class NodeType(Enum): WIREGUARD = 1 V2RAY = 2 + OPENVPN = 3 class RenewalPricePolicy(Enum): RENEWAL_PRICE_POLICY_UNSPECIFIED = 0 From a8a914fe6465bc5b2a91619a0316d7781c6a0e1a Mon Sep 17 00:00:00 2001 From: freqnik Date: Wed, 29 Oct 2025 17:20:01 -0400 Subject: [PATCH 06/15] Add sdk.lease --- src/sentinel_sdk/modules/node.py | 4 ++-- src/sentinel_sdk/sdk.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sentinel_sdk/modules/node.py b/src/sentinel_sdk/modules/node.py index 00dcae3..95dbb0d 100755 --- a/src/sentinel_sdk/modules/node.py +++ b/src/sentinel_sdk/modules/node.py @@ -70,12 +70,12 @@ def QueryNodeStatus(self, node: node_pb2.Node, is_in_thread: bool = False) -> st for prices in node.gigabyte_prices: gb_price = gb_price + prices.quote_value + prices.denom + ',' else: - gb_price = "0.0udvpn" + gb_price = "0udvpn" if node.hourly_prices: for prices in node.hourly_prices: hr_price = hr_price + prices.quote_value + prices.denom + ',' else: - hr_price = "0.0udvpn" + hr_price = "0udvpn" gb_price = gb_price.rstrip(',') hr_price = hr_price.rstrip(',') diff --git a/src/sentinel_sdk/sdk.py b/src/sentinel_sdk/sdk.py index d84a6c5..13c722c 100755 --- a/src/sentinel_sdk/sdk.py +++ b/src/sentinel_sdk/sdk.py @@ -11,6 +11,7 @@ from sentinel_sdk.modules.provider import ProviderModule from sentinel_sdk.modules.session import SessionModule from sentinel_sdk.modules.subscription import SubscriptionModule +from sentinel_sdk.modules.lease import LeaseModule from mospy import Account from mospy.clients import GRPCClient @@ -138,6 +139,7 @@ def __load_modules(self): self.nodes = NodeModule(self._channel, 10, self._account, self._client) self.deposits = DepositModule(self._channel) self.plans = PlanModule(self._channel, self._account, self._provider_account, self._client) + self.lease = LeaseModule(self._channel, self._account, self._provider_account, self._client) self.providers = ProviderModule(self._channel, self._account, self._client) self.sessions = SessionModule(self._channel, self._account, self._client) self.subscriptions = SubscriptionModule(self._channel, self._account, self._client) From 8d7bf67d2e26e546ee92550dd3d6b8250ff86970 Mon Sep 17 00:00:00 2001 From: freqnik Date: Wed, 29 Oct 2025 17:21:47 -0400 Subject: [PATCH 07/15] Fix typo --- src/sentinel_sdk/modules/lease.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sentinel_sdk/modules/lease.py b/src/sentinel_sdk/modules/lease.py index f8506e5..19f1832 100644 --- a/src/sentinel_sdk/modules/lease.py +++ b/src/sentinel_sdk/modules/lease.py @@ -1,6 +1,6 @@ import grpc -import sentinel_protobuf.sentinel.leace.v1.lease_pb2 as lease_pb2 +import sentinel_protobuf.sentinel.lease.v1.lease_pb2 as lease_pb2 import sentinel_protobuf.sentinel.lease.v1.querier_pb2 as sentinel_subscription_v2_querier_pb2 import sentinel_protobuf.sentinel.lease.v1.querier_pb2_grpc as sentinel_subscription_v2_querier_pb2_grpc import sentinel_protobuf.sentinel.subscription.v2.subscription_pb2 as subscription_pb2 From 7e8dfc10a9e0fd8a33bb52674a568a48b6b4841a Mon Sep 17 00:00:00 2001 From: freqnik Date: Wed, 29 Oct 2025 17:27:56 -0400 Subject: [PATCH 08/15] Update lease module --- src/sentinel_sdk/modules/lease.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sentinel_sdk/modules/lease.py b/src/sentinel_sdk/modules/lease.py index 19f1832..57f4852 100644 --- a/src/sentinel_sdk/modules/lease.py +++ b/src/sentinel_sdk/modules/lease.py @@ -20,7 +20,7 @@ def __init__(self, channel: grpc.Channel, account, provider_account, client): self._provider_account = provider_account def EndLease(self, subscription_id: int, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgSubscribeRequest( + msg = msg_pb2.MsgEndLeaseRequest( frm = self._account.address, id = subscription_id, ) @@ -28,7 +28,7 @@ def EndLease(self, subscription_id: int, tx_params: TxParams = TxParams()): return self.transaction([msg], tx_params) def RenewLease(self, subscription_id: int, hours: int, max_price: Price = Price(), tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgSubscribeRequest( + msg = msg_pb2.MsgRenewLeaseRequest( frm = self._account.address, id = subscription_id, hours = hours, @@ -38,7 +38,7 @@ def RenewLease(self, subscription_id: int, hours: int, max_price: Price = Price( return self.transaction([msg], tx_params) def StartLease(self, node: str, hours: int, max_price: Price = Price(), renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgSubscribeRequest( + msg = msg_pb2.MsgStartLeaseRequest( frm = self._account.address, node_address = node, hours = hours, @@ -49,7 +49,7 @@ def StartLease(self, node: str, hours: int, max_price: Price = Price(), renewal: return self.transaction([msg], tx_params) def UpdateLease(self, subscription_id: int, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgSubscribeRequest( + msg = msg_pb2.MsgUpdateLeaseRequest( frm = self._account.address, id = subscription_id, renewal_price_policy = renewal, From c036b24072224e1cb212d7c9122ed416c905b164 Mon Sep 17 00:00:00 2001 From: freqnik Date: Wed, 29 Oct 2025 21:09:17 -0400 Subject: [PATCH 09/15] Update utils module. Remove base64. Add OrderedDict parsing. --- src/sentinel_sdk/modules/lease.py | 16 +++++++++------- src/sentinel_sdk/modules/node.py | 5 +++-- src/sentinel_sdk/modules/subscription.py | 3 ++- src/sentinel_sdk/types.py | 19 +------------------ src/sentinel_sdk/utils.py | 10 ++++++++-- 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/sentinel_sdk/modules/lease.py b/src/sentinel_sdk/modules/lease.py index 57f4852..a3dfb16 100644 --- a/src/sentinel_sdk/modules/lease.py +++ b/src/sentinel_sdk/modules/lease.py @@ -5,10 +5,12 @@ import sentinel_protobuf.sentinel.lease.v1.querier_pb2_grpc as sentinel_subscription_v2_querier_pb2_grpc import sentinel_protobuf.sentinel.subscription.v2.subscription_pb2 as subscription_pb2 import sentinel_protobuf.sentinel.lease.v1.msg_pb2 as msg_pb2 +from sentinel_protobuf.sentinel.types.v1.price_pb2 import Price +from sentinel_protobuf.sentinel.types.v1.renewal_pb2 import RenewalPricePolicy from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor -from sentinel_sdk.types import PageRequest, TxParams, Price, RenewalPricePolicy +from sentinel_sdk.types import PageRequest, TxParams class LeaseModule(Querier, Transactor): def __init__(self, channel: grpc.Channel, account, provider_account, client): @@ -21,15 +23,15 @@ def __init__(self, channel: grpc.Channel, account, provider_account, client): def EndLease(self, subscription_id: int, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgEndLeaseRequest( - frm = self._account.address, + frm = self._provider_account.address, id = subscription_id, ) return self.transaction([msg], tx_params) - def RenewLease(self, subscription_id: int, hours: int, max_price: Price = Price(), tx_params: TxParams = TxParams()): + def RenewLease(self, subscription_id: int, hours: int, max_price: Price = Price, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgRenewLeaseRequest( - frm = self._account.address, + frm = self._provider_account.address, id = subscription_id, hours = hours, max_price = max_price, @@ -37,9 +39,9 @@ def RenewLease(self, subscription_id: int, hours: int, max_price: Price = Price( return self.transaction([msg], tx_params) - def StartLease(self, node: str, hours: int, max_price: Price = Price(), renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): + def StartLease(self, node: str, hours: int, max_price: Price, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgStartLeaseRequest( - frm = self._account.address, + frm = self._provider_account.address, node_address = node, hours = hours, max_price = max_price, @@ -50,7 +52,7 @@ def StartLease(self, node: str, hours: int, max_price: Price = Price(), renewal: def UpdateLease(self, subscription_id: int, renewal: int = RenewalPricePolicy.RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgUpdateLeaseRequest( - frm = self._account.address, + frm = self._provider_account.address, id = subscription_id, renewal_price_policy = renewal, ) diff --git a/src/sentinel_sdk/modules/node.py b/src/sentinel_sdk/modules/node.py index 95dbb0d..2ea8688 100755 --- a/src/sentinel_sdk/modules/node.py +++ b/src/sentinel_sdk/modules/node.py @@ -15,10 +15,11 @@ import sentinel_protobuf.sentinel.node.v3.querier_pb2_grpc as sentinel_node_v3_querier_pb2_grpc import sentinel_protobuf.sentinel.node.v2.msg_pb2 as msg_pb2 import sentinel_protobuf.sentinel.node.v3.msg_pb2 as msg_pb2_3 +from sentinel_protobuf.sentinel.types.v1.price_pb2 import Price from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor -from sentinel_sdk.types import PageRequest, TxParams, NodeType, Price +from sentinel_sdk.types import PageRequest, TxParams, NodeType from .wireguard import WgKey @@ -165,7 +166,7 @@ def SubscribeToNode(self, node_address: str, gigabytes: int = 0, hours: int = 0, return self.transaction([msg], tx_params) ''' - def SubscribeToNode(self, node_address: str, gigabytes: int = 0, hours: int = 0, price: Price = Price(), tx_params: TxParams = TxParams()): + def SubscribeToNode(self, node_address: str, price: Price, gigabytes: int = 0, hours: int = 0, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgStartSessionRequest( frm = self._account.address, gigabytes = gigabytes, diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index 117299c..c3dec4f 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -6,10 +6,11 @@ import sentinel_protobuf.sentinel.subscription.v2.subscription_pb2 as subscription_pb2 import sentinel_protobuf.sentinel.subscription.v2.msg_pb2 as msg_pb2 import sentinel_protobuf.sentinel.subscription.v3.msg_pb2 as msg_pb2_3 +from sentinel_protobuf.sentinel.types.v1.renewal_pb2 import RenewalPricePolicy from sentinel_sdk.querier.querier import Querier from sentinel_sdk.transactor.transactor import Transactor -from sentinel_sdk.types import PageRequest, TxParams, RenewalPricePolicy +from sentinel_sdk.types import PageRequest, TxParams class SubscriptionModule(Querier, Transactor): diff --git a/src/sentinel_sdk/types.py b/src/sentinel_sdk/types.py index ed9b79e..7a5423c 100755 --- a/src/sentinel_sdk/types.py +++ b/src/sentinel_sdk/types.py @@ -18,17 +18,7 @@ def __str__(self): class NodeType(Enum): WIREGUARD = 1 V2RAY = 2 - OPENVPN = 3 - -class RenewalPricePolicy(Enum): - RENEWAL_PRICE_POLICY_UNSPECIFIED = 0 - RENEWAL_PRICE_POLICY_IF_LESSER = 1 - RENEWAL_PRICE_POLICY_IF_LESSER_OR_EQUAL = 2 - RENEWAL_PRICE_POLICY_IF_EQUAL = 3 - RENEWAL_PRICE_POLICY_IF_NOT_EQUAL = 4 - RENEWAL_PRICE_POLICY_IF_GREATER = 5 - RENEWAL_PRICE_POLICY_IF_GREATER_OR_EQUAL = 6 - RENEWAL_PRICE_POLICY_ALWAYS = 7 + OPENVPN = 3 @dataclass class TxParams: @@ -36,13 +26,6 @@ class TxParams: fee_amount: int = 31415 gas: float = 0 gas_multiplier: float = 1.5 - -@dataclass -class Price: - denom: str = "udvpn" - base_value: str = "0" - quote_value: str = "0" - class PageRequest: """ diff --git a/src/sentinel_sdk/utils.py b/src/sentinel_sdk/utils.py index 9bb611d..101cc7e 100755 --- a/src/sentinel_sdk/utils.py +++ b/src/sentinel_sdk/utils.py @@ -1,14 +1,20 @@ import json import base64 +from collections import OrderedDict # TODO: we want to move this method (?) # In the latest version of mospy the response was converted as dict # from google.protobuf.json_format import MessageToDict # https://github.com/ctrl-Felix/mospy/blob/ea07705b6ec4c76cc355b7dc933fae7c09fd8429/src/mospy/clients/GRPCClient.py#L155 def search_attribute(tx_response: dict, event_type: str, attribute_key: str) -> dict: + tx_response = ordered_dict_to_dict(tx_response) for event in tx_response.get("txResponse", tx_response).get("events", []): if event["type"] == event_type: for attribute in event["attributes"]: - if base64.b64decode(attribute["key"]) == attribute_key.encode(): - return json.loads(base64.b64decode(attribute["value"]).decode("utf-8")) + if attribute["key"] == attribute_key: + return json.loads(attribute["value"]) return None + + +def ordered_dict_to_dict(od): + return {k: (ordered_dict_to_dict(v) if isinstance(v, OrderedDict) else v) for k, v in od.items()} From 8620d9eae09da82954b4bd261189400276eb16f6 Mon Sep 17 00:00:00 2001 From: freqnik Date: Wed, 28 Jan 2026 04:24:57 -0500 Subject: [PATCH 10/15] Add next_sequence to StartSession and Transactor to enable multiple concurrent sessions --- pyproject.toml | 2 +- src/sentinel_sdk/modules/subscription.py | 4 ++-- src/sentinel_sdk/transactor/transactor.py | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 81a18a1..5938724 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "sentinel_sdk" -version = "0.1.0" +version = "0.1.1" description = "A Sentinel SDK Written in Python" authors = [ { name = "NAST0R" }, diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index c3dec4f..4477074 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -218,13 +218,13 @@ def UpdateSubscription(self, subscription_id: int, renewal: int = RenewalPriceP return self.transaction([msg], tx_params) # Used for plan subs - def StartSession(self, address: str, subscription_id: int, tx_params: TxParams = TxParams()): + def StartSession(self, address: str, subscription_id: int, next_sequence: bool = False, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgStartSessionRequest( frm = self._account.address, id = subscription_id, node_address = address ) - return self.transaction([msg], tx_params) + return self.transaction([msg], tx_params, next_sequence) # Node subscriptions are returned by grpc querier in google's 'Any' type and need to be converted into desired protobuf type # diff --git a/src/sentinel_sdk/transactor/transactor.py b/src/sentinel_sdk/transactor/transactor.py index cbe0d6a..f2ebc78 100755 --- a/src/sentinel_sdk/transactor/transactor.py +++ b/src/sentinel_sdk/transactor/transactor.py @@ -38,6 +38,7 @@ def transaction( self, messages: list, tx_params: TxParams = TxParams(), + next_sequence: bool = False ) -> dict: if self._account is None or self._client is None: raise ValueError("Transactor was not initialized due missing secret, unable to transact") @@ -57,7 +58,10 @@ def transaction( tx.add_raw_msg(message, type_url=f"/{message.DESCRIPTOR.full_name}") # Required before each tx of we get account sequence mismatch, expected 945, got 944: incorrect account sequence - self._client.load_account_data(account=self._account) + #self._client.load_account_data(account=self._account) + + if next_sequence: + self._account.increase_sequence() # inplace, auto-update gas with update=True # auto calculate the gas only if was not already passed as args: From e4c28c0002a690c4f55e670acbdfb7f980d54757 Mon Sep 17 00:00:00 2001 From: freqnik Date: Thu, 29 Jan 2026 20:34:11 -0500 Subject: [PATCH 11/15] update deps in pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5938724..4daa833 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", ] dependencies = [ - "sentinel-protobuf==0.4.3", + "sentinel-protobuf==0.5.1", "grpcio>=1.51.1", "bip-utils==2.9.0", "mospy-wallet==0.6.0", From c4c37837b5301e9627192ff85f75f2d4c9200df4 Mon Sep 17 00:00:00 2001 From: NAST0R <92294244+NAST0R@users.noreply.github.com> Date: Sun, 1 Mar 2026 17:05:50 +0100 Subject: [PATCH 12/15] Updated session.py for sentinel protobuf v3 compatibility Removed UpdateDetails, Proof, StartSession methods; Modified EndSession to use MsgCancelSessionRequest, it now fully terminates a session onchain; Implemented UpdateSession and UpdateParams per v3 protobuf; Updated all necessary imports from v2 to v3; --- src/sentinel_sdk/modules/session.py | 68 ++++++++++++++--------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/sentinel_sdk/modules/session.py b/src/sentinel_sdk/modules/session.py index 87bee9b..96ec55d 100755 --- a/src/sentinel_sdk/modules/session.py +++ b/src/sentinel_sdk/modules/session.py @@ -1,12 +1,10 @@ from typing import Any import grpc -import sentinel_protobuf.sentinel.session.v2.querier_pb2 as sentinel_session_v2_querier_pb2 -import sentinel_protobuf.sentinel.session.v2.querier_pb2_grpc as sentinel_session_v2_querier_pb2_grpc -import sentinel_protobuf.sentinel.session.v2.msg_pb2 as msg_pb2 +import sentinel_protobuf.sentinel.session.v3.querier_pb2 as sentinel_session_v3_querier_pb2 +import sentinel_protobuf.sentinel.session.v3.querier_pb2_grpc as sentinel_session_v3_querier_pb2_grpc +import sentinel_protobuf.sentinel.session.v3.msg_pb2 as msg_pb2 -from sentinel_protobuf.sentinel.session.v2 import proof_pb2 -from sentinel_protobuf.sentinel.types.v1.bandwidth_pb2 import Bandwidth from google.protobuf.duration_pb2 import Duration from sentinel_sdk.querier.querier import Querier @@ -16,14 +14,14 @@ class SessionModule(Querier, Transactor): def __init__(self, channel: grpc.Channel, account, client): - self.__stub = sentinel_session_v2_querier_pb2_grpc.QueryServiceStub(channel) + self.__stub = sentinel_session_v3_querier_pb2_grpc.QueryServiceStub(channel) self._account = account self._client = client def QuerySession(self, session_id: int) -> Any: try: r = self.__stub.QuerySession( - sentinel_session_v2_querier_pb2.QuerySessionRequest(id=session_id) + sentinel_session_v3_querier_pb2.QuerySessionRequest(id=session_id) ) except grpc._channel._InactiveRpcError as e: print(e) @@ -34,7 +32,7 @@ def QuerySession(self, session_id: int) -> Any: def QuerySessions(self, pagination: PageRequest = None) -> list: return self.QueryAll( query=self.__stub.QuerySessions, - request=sentinel_session_v2_querier_pb2.QuerySessionsRequest, + request=sentinel_session_v3_querier_pb2.QuerySessionsRequest, attribute="sessions", pagination=pagination, ) @@ -44,7 +42,7 @@ def QuerySessionsForAccount( ) -> list: return self.QueryAll( query=self.__stub.QuerySessionsForAccount, - request=sentinel_session_v2_querier_pb2.QuerySessionsForAccountRequest, + request=sentinel_session_v3_querier_pb2.QuerySessionsForAccountRequest, attribute="sessions", address=address, pagination=pagination, @@ -55,7 +53,7 @@ def QuerySessionsForAllocation( ) -> list: return self.QueryAll( query=self.__stub.QuerySessionsForAllocation, - request=sentinel_session_v2_querier_pb2.QuerySessionsForAllocationRequest, + request=sentinel_session_v3_querier_pb2.QuerySessionsForAllocationRequest, attribute="sessions", id=allocation_id, address=address, @@ -67,7 +65,7 @@ def QuerySessionsForNode( ) -> list: return self.QueryAll( query=self.__stub.QuerySessionsForNode, - request=sentinel_session_v2_querier_pb2.QuerySessionsForNodeRequest, + request=sentinel_session_v3_querier_pb2.QuerySessionsForNodeRequest, attribute="sessions", address=address, pagination=pagination, @@ -78,39 +76,41 @@ def QuerySessionsForSubscription( ) -> list: return self.QueryAll( query=self.__stub.QuerySessionsForSubscription, - request=sentinel_session_v2_querier_pb2.QuerySessionsForSubscriptionRequest, + request=sentinel_session_v3_querier_pb2.QuerySessionsForSubscriptionRequest, attribute="sessions", id=subscription_id, pagination=pagination, ) - def StartSession(self, address: str, subscription_id: int, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgStartRequest( - frm = self._account.address, - id = subscription_id, - address = address + def EndSession(self, session_id: int, tx_params: TxParams = TxParams()): + msg = msg_pb2.MsgCancelSessionRequest( + frm=self._account.address, + id=session_id, ) return self.transaction([msg], tx_params) - def EndSession(self, session_id: int, rating: int, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgEndRequest( - frm = self._account.address, - id = session_id, - rating = rating, + def UpdateSession( + self, + session_id: int, + download_bytes: int, + upload_bytes: int, + duration_seconds: int, + signature: bytes, + tx_params: TxParams = TxParams(), + ): + msg = msg_pb2.MsgUpdateSessionRequest( + frm=self._account.address, + id=session_id, + download_bytes=str(download_bytes), + upload_bytes=str(upload_bytes), + duration=Duration(seconds=duration_seconds), + signature=signature, ) return self.transaction([msg], tx_params) - def UpdateDetails(self, proof: proof_pb2.Proof, signature: bytes, tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgUpdateDetailsRequest( - frm = self._account.address, - proof = proof, - signature = signature, + def UpdateParams(self, params, tx_params: TxParams = TxParams()): + msg = msg_pb2.MsgUpdateParamsRequest( + frm=self._account.address, + params=params, ) return self.transaction([msg], tx_params) - - def Proof(self, session_id: int, bandwidth: Bandwidth, duration: Duration) -> proof_pb2.Proof: - return proof_pb2.Proof( - id=session_id, - bandwidth=bandwidth, - duration=duration - ) \ No newline at end of file From cf7dfc1bcdfe9d5e9ea293f71f29a6c9cb71875d Mon Sep 17 00:00:00 2001 From: freqnik Date: Mon, 9 Mar 2026 23:35:24 -0400 Subject: [PATCH 13/15] Update subscription module. Change v2 -> v3. Remove deprecated queries. --- src/sentinel_sdk/modules/subscription.py | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/sentinel_sdk/modules/subscription.py b/src/sentinel_sdk/modules/subscription.py index 4477074..4675acd 100755 --- a/src/sentinel_sdk/modules/subscription.py +++ b/src/sentinel_sdk/modules/subscription.py @@ -1,10 +1,9 @@ from typing import Any import grpc -import sentinel_protobuf.sentinel.subscription.v2.querier_pb2 as sentinel_subscription_v2_querier_pb2 -import sentinel_protobuf.sentinel.subscription.v2.querier_pb2_grpc as sentinel_subscription_v2_querier_pb2_grpc -import sentinel_protobuf.sentinel.subscription.v2.subscription_pb2 as subscription_pb2 -import sentinel_protobuf.sentinel.subscription.v2.msg_pb2 as msg_pb2 +import sentinel_protobuf.sentinel.subscription.v3.querier_pb2 as sentinel_subscription_v3_querier_pb2 +import sentinel_protobuf.sentinel.subscription.v3.querier_pb2_grpc as sentinel_subscription_v3_querier_pb2_grpc +import sentinel_protobuf.sentinel.subscription.v3.subscription_pb2 as subscription_pb2 import sentinel_protobuf.sentinel.subscription.v3.msg_pb2 as msg_pb2_3 from sentinel_protobuf.sentinel.types.v1.renewal_pb2 import RenewalPricePolicy @@ -15,7 +14,7 @@ class SubscriptionModule(Querier, Transactor): def __init__(self, channel: grpc.Channel, account, client): - self.__stub = sentinel_subscription_v2_querier_pb2_grpc.QueryServiceStub( + self.__stub = sentinel_subscription_v3_querier_pb2_grpc.QueryServiceStub( channel ) self._account = account @@ -24,7 +23,7 @@ def __init__(self, channel: grpc.Channel, account, client): def QuerySubscription(self, subscription_id: int) -> Any: try: r = self.__stub.QuerySubscription( - sentinel_subscription_v2_querier_pb2.QuerySubscriptionRequest( + sentinel_subscription_v3_querier_pb2.QuerySubscriptionRequest( id=subscription_id ) ) @@ -37,7 +36,7 @@ def QuerySubscription(self, subscription_id: int) -> Any: def QuerySubscriptions(self, pagination: PageRequest = None) -> list: subscriptions = self.QueryAll( query=self.__stub.QuerySubscriptions, - request=sentinel_subscription_v2_querier_pb2.QuerySubscriptionsRequest, + request=sentinel_subscription_v3_querier_pb2.QuerySubscriptionsRequest, attribute="subscriptions", pagination=pagination, ) @@ -45,7 +44,9 @@ def QuerySubscriptions(self, pagination: PageRequest = None) -> list: self.__ConvertAnyToNodeSubscription(subscription.value) for subscription in subscriptions ] - + + # not in subscription/v3/querier.proto + ''' def QueryAllocation(self, address: str, subscription_id: int) -> list: try: r = self.__stub.QueryAllocation( @@ -108,13 +109,13 @@ def QueryPayoutsForNode(self, address: str, pagination: PageRequest = None) -> l address=address, pagination=pagination, ) - + ''' def QuerySubscriptionsForAccount( self, address: str, pagination: PageRequest = None ) -> list: subscriptions = self.QueryAll( query=self.__stub.QuerySubscriptionsForAccount, - request=sentinel_subscription_v2_querier_pb2.QuerySubscriptionsForAccountRequest, + request=sentinel_subscription_v3_querier_pb2.QuerySubscriptionsForAccountRequest, attribute="subscriptions", address=address, pagination=pagination, @@ -123,13 +124,15 @@ def QuerySubscriptionsForAccount( self.__ConvertAnyToNodeSubscription(subscription.value) for subscription in subscriptions ] - + + # deprecated + ''' def QuerySubscriptionsForNode( self, address: str, pagination: PageRequest = None ) -> list: subscriptions = self.QueryAll( query=self.__stub.QuerySubscriptionsForNode, - request=sentinel_subscription_v2_querier_pb2.QuerySubscriptionsForNodeRequest, + request=sentinel_subscription_v3_querier_pb2.QuerySubscriptionsForNodeRequest, attribute="subscriptions", address=address, pagination=pagination, @@ -138,13 +141,14 @@ def QuerySubscriptionsForNode( self.__ConvertAnyToNodeSubscription(subscription.value) for subscription in subscriptions ] - + ''' + def QuerySubscriptionsForPlan( self, plan_id: int, pagination: PageRequest = None ) -> list: subscriptions = self.QueryAll( query=self.__stub.QuerySubscriptionsForPlan, - request=sentinel_subscription_v2_querier_pb2.QuerySubscriptionsForPlanRequest, + request=sentinel_subscription_v3_querier_pb2.QuerySubscriptionsForPlanRequest, attribute="subscriptions", id=plan_id, pagination=pagination, @@ -174,7 +178,7 @@ def Cancel(self, id: int, tx_params: TxParams = TxParams()): return self.transaction([msg], tx_params) ''' - # id is subscription id + # id is subscription id i.e., lease ID def Cancel(self, id: int, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgCancelSubscriptionRequest( frm = self._account.address, From 8b78d8a55fc2a35e492ef09b205c2ee0511c2978 Mon Sep 17 00:00:00 2001 From: freqnik Date: Mon, 9 Mar 2026 23:36:30 -0400 Subject: [PATCH 14/15] Bump to v0.1.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4daa833..d116c00 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "sentinel_sdk" -version = "0.1.1" +version = "0.1.2" description = "A Sentinel SDK Written in Python" authors = [ { name = "NAST0R" }, From f517bc9a390c77066b350df25ab1dc8044ca1cd3 Mon Sep 17 00:00:00 2001 From: freqnik Date: Thu, 23 Apr 2026 17:52:16 -0400 Subject: [PATCH 15/15] Add next_sequence to node.SubscribeToNode --- pyproject.toml | 2 +- src/sentinel_sdk/modules/node.py | 16 ++-------------- src/sentinel_sdk/sdk.py | 2 +- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d116c00..89a3885 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "sentinel_sdk" -version = "0.1.2" +version = "0.1.3" description = "A Sentinel SDK Written in Python" authors = [ { name = "NAST0R" }, diff --git a/src/sentinel_sdk/modules/node.py b/src/sentinel_sdk/modules/node.py index 2ea8688..1e45d73 100755 --- a/src/sentinel_sdk/modules/node.py +++ b/src/sentinel_sdk/modules/node.py @@ -153,20 +153,8 @@ def RegisterNode(self, gigabyte_prices: int, hourly_prices: int, remote_url: str remote_url=remote_url, ) return self.transaction([msg], tx_params) - - ''' - def SubscribeToNode(self, node_address: str, gigabytes: int = 0, hours: int = 0, denom: str = "udvpn", tx_params: TxParams = TxParams()): - msg = msg_pb2.MsgSubscribeRequest( - frm = self._account.address, - denom = denom, - gigabytes = gigabytes, - hours = hours, - node_address = node_address, - ) - return self.transaction([msg], tx_params) - ''' - def SubscribeToNode(self, node_address: str, price: Price, gigabytes: int = 0, hours: int = 0, tx_params: TxParams = TxParams()): + def SubscribeToNode(self, node_address: str, price: Price, gigabytes: int = 0, hours: int = 0, next_sequence: bool = False, tx_params: TxParams = TxParams()): msg = msg_pb2_3.MsgStartSessionRequest( frm = self._account.address, gigabytes = gigabytes, @@ -174,7 +162,7 @@ def SubscribeToNode(self, node_address: str, price: Price, gigabytes: int = 0, h node_address = node_address, max_price = price, ) - return self.transaction([msg], tx_params) + return self.transaction([msg], tx_params, next_sequence) def UpdateNodeDetails(self, gigabyte_prices: int, hourly_prices: int, remote_url: str, tx_params: TxParams = TxParams()): msg = msg_pb2.MsgUpdateDetailsRequest( frm = self._account.address, diff --git a/src/sentinel_sdk/sdk.py b/src/sentinel_sdk/sdk.py index 13c722c..f7d0140 100755 --- a/src/sentinel_sdk/sdk.py +++ b/src/sentinel_sdk/sdk.py @@ -151,7 +151,7 @@ def renew_account(self, secret: str): self.__load_modules() def renew_grpc(self, grpcaddr: str, grpcport: int, use_ssl: bool = False): - self._client = self.__create_client(grpcaddr, grpcport) + self._client = self.__create_client(grpcaddr, grpcport, use_ssl) self._client.load_account_data(account=self._account) self.__load_modules()