nado-protocol 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nado_protocol/__init__.py +0 -0
- nado_protocol/client/__init__.py +200 -0
- nado_protocol/client/apis/__init__.py +26 -0
- nado_protocol/client/apis/base.py +42 -0
- nado_protocol/client/apis/market/__init__.py +23 -0
- nado_protocol/client/apis/market/execute.py +192 -0
- nado_protocol/client/apis/market/query.py +310 -0
- nado_protocol/client/apis/perp/__init__.py +18 -0
- nado_protocol/client/apis/perp/query.py +30 -0
- nado_protocol/client/apis/rewards/__init__.py +6 -0
- nado_protocol/client/apis/rewards/execute.py +131 -0
- nado_protocol/client/apis/rewards/query.py +12 -0
- nado_protocol/client/apis/spot/__init__.py +23 -0
- nado_protocol/client/apis/spot/base.py +32 -0
- nado_protocol/client/apis/spot/execute.py +117 -0
- nado_protocol/client/apis/spot/query.py +79 -0
- nado_protocol/client/apis/subaccount/__init__.py +24 -0
- nado_protocol/client/apis/subaccount/execute.py +54 -0
- nado_protocol/client/apis/subaccount/query.py +145 -0
- nado_protocol/client/context.py +90 -0
- nado_protocol/contracts/__init__.py +377 -0
- nado_protocol/contracts/abis/Endpoint.json +636 -0
- nado_protocol/contracts/abis/FQuerier.json +1909 -0
- nado_protocol/contracts/abis/IClearinghouse.json +876 -0
- nado_protocol/contracts/abis/IERC20.json +185 -0
- nado_protocol/contracts/abis/IEndpoint.json +250 -0
- nado_protocol/contracts/abis/IFoundationRewardsAirdrop.json +76 -0
- nado_protocol/contracts/abis/IOffchainBook.json +536 -0
- nado_protocol/contracts/abis/IPerpEngine.json +931 -0
- nado_protocol/contracts/abis/IProductEngine.json +352 -0
- nado_protocol/contracts/abis/ISpotEngine.json +813 -0
- nado_protocol/contracts/abis/IStaking.json +288 -0
- nado_protocol/contracts/abis/IVrtxAirdrop.json +138 -0
- nado_protocol/contracts/abis/MockERC20.json +311 -0
- nado_protocol/contracts/deployments/deployment.test.json +18 -0
- nado_protocol/contracts/eip712/__init__.py +16 -0
- nado_protocol/contracts/eip712/domain.py +36 -0
- nado_protocol/contracts/eip712/sign.py +79 -0
- nado_protocol/contracts/eip712/types.py +154 -0
- nado_protocol/contracts/loader.py +55 -0
- nado_protocol/contracts/types.py +141 -0
- nado_protocol/engine_client/__init__.py +35 -0
- nado_protocol/engine_client/execute.py +416 -0
- nado_protocol/engine_client/query.py +481 -0
- nado_protocol/engine_client/types/__init__.py +113 -0
- nado_protocol/engine_client/types/execute.py +680 -0
- nado_protocol/engine_client/types/models.py +247 -0
- nado_protocol/engine_client/types/query.py +516 -0
- nado_protocol/engine_client/types/stream.py +6 -0
- nado_protocol/indexer_client/__init__.py +28 -0
- nado_protocol/indexer_client/query.py +466 -0
- nado_protocol/indexer_client/types/__init__.py +122 -0
- nado_protocol/indexer_client/types/models.py +364 -0
- nado_protocol/indexer_client/types/query.py +819 -0
- nado_protocol/trigger_client/__init__.py +17 -0
- nado_protocol/trigger_client/execute.py +118 -0
- nado_protocol/trigger_client/query.py +61 -0
- nado_protocol/trigger_client/types/__init__.py +7 -0
- nado_protocol/trigger_client/types/execute.py +89 -0
- nado_protocol/trigger_client/types/models.py +44 -0
- nado_protocol/trigger_client/types/query.py +77 -0
- nado_protocol/utils/__init__.py +37 -0
- nado_protocol/utils/backend.py +111 -0
- nado_protocol/utils/bytes32.py +159 -0
- nado_protocol/utils/enum.py +6 -0
- nado_protocol/utils/exceptions.py +58 -0
- nado_protocol/utils/execute.py +403 -0
- nado_protocol/utils/expiration.py +45 -0
- nado_protocol/utils/interest.py +66 -0
- nado_protocol/utils/math.py +67 -0
- nado_protocol/utils/model.py +79 -0
- nado_protocol/utils/nonce.py +33 -0
- nado_protocol/utils/subaccount.py +18 -0
- nado_protocol/utils/time.py +21 -0
- nado_protocol-0.1.0.dist-info/METADATA +157 -0
- nado_protocol-0.1.0.dist-info/RECORD +78 -0
- nado_protocol-0.1.0.dist-info/WHEEL +4 -0
- nado_protocol-0.1.0.dist-info/entry_points.txt +11 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from nado_protocol.trigger_client.types import TriggerClientOpts
|
|
2
|
+
from nado_protocol.trigger_client.execute import TriggerExecuteClient
|
|
3
|
+
from nado_protocol.trigger_client.query import TriggerQueryClient
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TriggerClient(TriggerQueryClient, TriggerExecuteClient): # type: ignore
|
|
7
|
+
def __init__(self, opts: TriggerClientOpts):
|
|
8
|
+
TriggerQueryClient.__init__(self, opts)
|
|
9
|
+
TriggerExecuteClient.__init__(self, opts)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"TriggerClient",
|
|
14
|
+
"TriggerClientOpts",
|
|
15
|
+
"TriggerExecuteClient",
|
|
16
|
+
"TriggerQueryClient",
|
|
17
|
+
]
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from functools import singledispatchmethod
|
|
3
|
+
from typing import Union
|
|
4
|
+
from nado_protocol.contracts.types import NadoExecuteType
|
|
5
|
+
from nado_protocol.trigger_client.types.execute import (
|
|
6
|
+
TriggerExecuteParams,
|
|
7
|
+
TriggerExecuteRequest,
|
|
8
|
+
PlaceTriggerOrderParams,
|
|
9
|
+
CancelTriggerOrdersParams,
|
|
10
|
+
CancelProductTriggerOrdersParams,
|
|
11
|
+
to_trigger_execute_request,
|
|
12
|
+
)
|
|
13
|
+
from nado_protocol.engine_client.types.execute import ExecuteResponse
|
|
14
|
+
from nado_protocol.trigger_client.types import TriggerClientOpts
|
|
15
|
+
from nado_protocol.utils.exceptions import (
|
|
16
|
+
BadStatusCodeException,
|
|
17
|
+
ExecuteFailedException,
|
|
18
|
+
)
|
|
19
|
+
from nado_protocol.utils.execute import NadoBaseExecute
|
|
20
|
+
from nado_protocol.utils.model import NadoBaseModel, is_instance_of_union
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TriggerExecuteClient(NadoBaseExecute):
|
|
24
|
+
def __init__(self, opts: TriggerClientOpts):
|
|
25
|
+
super().__init__(opts)
|
|
26
|
+
self._opts: TriggerClientOpts = TriggerClientOpts.parse_obj(opts)
|
|
27
|
+
self.url: str = self._opts.url
|
|
28
|
+
self.session = requests.Session()
|
|
29
|
+
|
|
30
|
+
def tx_nonce(self, _: str) -> int:
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
@singledispatchmethod
|
|
34
|
+
def execute(
|
|
35
|
+
self, params: Union[TriggerExecuteParams, TriggerExecuteRequest]
|
|
36
|
+
) -> ExecuteResponse:
|
|
37
|
+
"""
|
|
38
|
+
Executes the operation defined by the provided parameters.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
params (ExecuteParams): The parameters for the operation to execute. This can represent a variety of operations, such as placing orders, cancelling orders, and more.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
ExecuteResponse: The response from the executed operation.
|
|
45
|
+
"""
|
|
46
|
+
req: TriggerExecuteRequest = (
|
|
47
|
+
params if is_instance_of_union(params, TriggerExecuteRequest) else to_trigger_execute_request(params) # type: ignore
|
|
48
|
+
)
|
|
49
|
+
return self._execute(req)
|
|
50
|
+
|
|
51
|
+
@execute.register
|
|
52
|
+
def _(self, req: dict) -> ExecuteResponse:
|
|
53
|
+
"""
|
|
54
|
+
Overloaded method to execute the operation defined by the provided request.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
req (dict): The request data for the operation to execute. Can be a dictionary or an instance of ExecuteRequest.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
ExecuteResponse: The response from the executed operation.
|
|
61
|
+
"""
|
|
62
|
+
parsed_req: TriggerExecuteRequest = NadoBaseModel.parse_obj(req) # type: ignore
|
|
63
|
+
return self._execute(parsed_req)
|
|
64
|
+
|
|
65
|
+
def _execute(self, req: TriggerExecuteRequest) -> ExecuteResponse:
|
|
66
|
+
"""
|
|
67
|
+
Internal method to execute the operation. Sends request to the server.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
req (TriggerExecuteRequest): The request data for the operation to execute.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
ExecuteResponse: The response from the executed operation.
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
BadStatusCodeException: If the server response status code is not 200.
|
|
77
|
+
ExecuteFailedException: If there's an error in the execution or the response status is not "success".
|
|
78
|
+
"""
|
|
79
|
+
res = self.session.post(f"{self.url}/execute", json=req.dict())
|
|
80
|
+
if res.status_code != 200:
|
|
81
|
+
raise BadStatusCodeException(res.text)
|
|
82
|
+
try:
|
|
83
|
+
execute_res = ExecuteResponse(**res.json(), req=req.dict())
|
|
84
|
+
except Exception:
|
|
85
|
+
raise ExecuteFailedException(res.text)
|
|
86
|
+
if execute_res.status != "success":
|
|
87
|
+
raise ExecuteFailedException(res.text)
|
|
88
|
+
return execute_res
|
|
89
|
+
|
|
90
|
+
def place_trigger_order(self, params: PlaceTriggerOrderParams) -> ExecuteResponse:
|
|
91
|
+
params = PlaceTriggerOrderParams.parse_obj(params)
|
|
92
|
+
params.order = self.prepare_execute_params(params.order, True, True)
|
|
93
|
+
params.signature = params.signature or self._sign(
|
|
94
|
+
NadoExecuteType.PLACE_ORDER, params.order.dict(), params.product_id
|
|
95
|
+
)
|
|
96
|
+
return self.execute(params)
|
|
97
|
+
|
|
98
|
+
def cancel_trigger_orders(
|
|
99
|
+
self, params: CancelTriggerOrdersParams
|
|
100
|
+
) -> ExecuteResponse:
|
|
101
|
+
params = self.prepare_execute_params(
|
|
102
|
+
CancelTriggerOrdersParams.parse_obj(params), True
|
|
103
|
+
)
|
|
104
|
+
params.signature = params.signature or self._sign(
|
|
105
|
+
NadoExecuteType.CANCEL_ORDERS, params.dict()
|
|
106
|
+
)
|
|
107
|
+
return self.execute(params)
|
|
108
|
+
|
|
109
|
+
def cancel_product_trigger_orders(
|
|
110
|
+
self, params: CancelProductTriggerOrdersParams
|
|
111
|
+
) -> ExecuteResponse:
|
|
112
|
+
params = self.prepare_execute_params(
|
|
113
|
+
CancelProductTriggerOrdersParams.parse_obj(params), True
|
|
114
|
+
)
|
|
115
|
+
params.signature = params.signature or self._sign(
|
|
116
|
+
NadoExecuteType.CANCEL_PRODUCT_ORDERS, params.dict()
|
|
117
|
+
)
|
|
118
|
+
return self.execute(params)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from nado_protocol.contracts.types import NadoTxType
|
|
3
|
+
from nado_protocol.trigger_client.types import TriggerClientOpts
|
|
4
|
+
from nado_protocol.trigger_client.types.query import (
|
|
5
|
+
ListTriggerOrdersParams,
|
|
6
|
+
ListTriggerOrdersRequest,
|
|
7
|
+
TriggerQueryResponse,
|
|
8
|
+
)
|
|
9
|
+
from nado_protocol.utils.exceptions import (
|
|
10
|
+
BadStatusCodeException,
|
|
11
|
+
QueryFailedException,
|
|
12
|
+
)
|
|
13
|
+
from nado_protocol.utils.execute import NadoBaseExecute
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TriggerQueryClient(NadoBaseExecute):
|
|
17
|
+
"""
|
|
18
|
+
Client class for querying the trigger service.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, opts: TriggerClientOpts):
|
|
22
|
+
self._opts: TriggerClientOpts = TriggerClientOpts.parse_obj(opts)
|
|
23
|
+
self.url: str = self._opts.url
|
|
24
|
+
self.session = requests.Session() # type: ignore
|
|
25
|
+
|
|
26
|
+
def tx_nonce(self, _: str) -> int:
|
|
27
|
+
raise NotImplementedError
|
|
28
|
+
|
|
29
|
+
def query(self, req: dict) -> TriggerQueryResponse:
|
|
30
|
+
"""
|
|
31
|
+
Send a query to the trigger service.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
req (QueryRequest): The query request parameters.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
QueryResponse: The response from the engine.
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
BadStatusCodeException: If the response status code is not 200.
|
|
41
|
+
QueryFailedException: If the query status is not "success".
|
|
42
|
+
"""
|
|
43
|
+
res = self.session.post(f"{self.url}/query", json=req)
|
|
44
|
+
if res.status_code != 200:
|
|
45
|
+
raise BadStatusCodeException(res.text)
|
|
46
|
+
try:
|
|
47
|
+
query_res = TriggerQueryResponse(**res.json())
|
|
48
|
+
except Exception:
|
|
49
|
+
raise QueryFailedException(res.text)
|
|
50
|
+
if query_res.status != "success":
|
|
51
|
+
raise QueryFailedException(res.text)
|
|
52
|
+
return query_res
|
|
53
|
+
|
|
54
|
+
def list_trigger_orders(
|
|
55
|
+
self, params: ListTriggerOrdersParams
|
|
56
|
+
) -> TriggerQueryResponse:
|
|
57
|
+
params = ListTriggerOrdersParams.parse_obj(params)
|
|
58
|
+
params.signature = params.signature or self._sign(
|
|
59
|
+
NadoTxType.LIST_TRIGGER_ORDERS, params.tx.dict()
|
|
60
|
+
)
|
|
61
|
+
return self.query(ListTriggerOrdersRequest.parse_obj(params).dict())
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
from pydantic import validator
|
|
3
|
+
from nado_protocol.contracts.types import NadoExecuteType
|
|
4
|
+
from nado_protocol.utils.bytes32 import bytes32_to_hex
|
|
5
|
+
from nado_protocol.utils.model import NadoBaseModel
|
|
6
|
+
from nado_protocol.engine_client.types.execute import (
|
|
7
|
+
PlaceOrderParams,
|
|
8
|
+
CancelOrdersParams,
|
|
9
|
+
CancelProductOrdersParams,
|
|
10
|
+
CancelOrdersRequest,
|
|
11
|
+
CancelProductOrdersRequest,
|
|
12
|
+
)
|
|
13
|
+
from nado_protocol.trigger_client.types.models import TriggerCriteria
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PlaceTriggerOrderParams(PlaceOrderParams):
|
|
17
|
+
trigger: TriggerCriteria
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
CancelTriggerOrdersParams = CancelOrdersParams
|
|
21
|
+
CancelProductTriggerOrdersParams = CancelProductOrdersParams
|
|
22
|
+
|
|
23
|
+
TriggerExecuteParams = Union[
|
|
24
|
+
PlaceTriggerOrderParams, CancelTriggerOrdersParams, CancelProductTriggerOrdersParams
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PlaceTriggerOrderRequest(NadoBaseModel):
|
|
29
|
+
"""
|
|
30
|
+
Parameters for a request to place an order.
|
|
31
|
+
|
|
32
|
+
Attributes:
|
|
33
|
+
place_order (PlaceOrderParams): The parameters for the order to be placed.
|
|
34
|
+
|
|
35
|
+
Methods:
|
|
36
|
+
serialize: Validates and serializes the order parameters.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
place_order: PlaceTriggerOrderParams
|
|
40
|
+
|
|
41
|
+
@validator("place_order")
|
|
42
|
+
def serialize(cls, v: PlaceTriggerOrderParams) -> PlaceTriggerOrderParams:
|
|
43
|
+
if v.order.nonce is None:
|
|
44
|
+
raise ValueError("Missing order `nonce`")
|
|
45
|
+
if v.signature is None:
|
|
46
|
+
raise ValueError("Missing `signature")
|
|
47
|
+
if isinstance(v.order.sender, bytes):
|
|
48
|
+
v.order.serialize_dict(["sender"], bytes32_to_hex)
|
|
49
|
+
v.order.serialize_dict(["nonce", "priceX18", "amount", "expiration"], str)
|
|
50
|
+
return v
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
CancelTriggerOrdersRequest = CancelOrdersRequest
|
|
54
|
+
CancelProductTriggerOrdersRequest = CancelProductOrdersRequest
|
|
55
|
+
|
|
56
|
+
TriggerExecuteRequest = Union[
|
|
57
|
+
PlaceTriggerOrderRequest,
|
|
58
|
+
CancelTriggerOrdersRequest,
|
|
59
|
+
CancelProductTriggerOrdersRequest,
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def to_trigger_execute_request(params: TriggerExecuteParams) -> TriggerExecuteRequest:
|
|
64
|
+
"""
|
|
65
|
+
Maps `TriggerExecuteParams` to its corresponding `TriggerExecuteRequest` object based on the parameter type.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
params (TriggerExecuteParams): The parameters to be executed.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
TriggerExecuteRequest: The corresponding `TriggerExecuteRequest` object.
|
|
72
|
+
"""
|
|
73
|
+
execute_request_mapping = {
|
|
74
|
+
PlaceTriggerOrderParams: (
|
|
75
|
+
PlaceTriggerOrderRequest,
|
|
76
|
+
NadoExecuteType.PLACE_ORDER.value,
|
|
77
|
+
),
|
|
78
|
+
CancelTriggerOrdersParams: (
|
|
79
|
+
CancelTriggerOrdersRequest,
|
|
80
|
+
NadoExecuteType.CANCEL_ORDERS.value,
|
|
81
|
+
),
|
|
82
|
+
CancelProductTriggerOrdersParams: (
|
|
83
|
+
CancelProductTriggerOrdersRequest,
|
|
84
|
+
NadoExecuteType.CANCEL_PRODUCT_ORDERS.value,
|
|
85
|
+
),
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
RequestClass, field_name = execute_request_mapping[type(params)]
|
|
89
|
+
return RequestClass(**{field_name: params}) # type: ignore
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from typing import Optional, Union
|
|
2
|
+
from nado_protocol.utils.model import NadoBaseModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class PriceAboveTrigger(NadoBaseModel):
|
|
6
|
+
price_above: str
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PriceBelowTrigger(NadoBaseModel):
|
|
10
|
+
price_below: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LastPriceAboveTrigger(NadoBaseModel):
|
|
14
|
+
last_price_above: str
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class LastPriceBelowTrigger(NadoBaseModel):
|
|
18
|
+
last_price_below: str
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
TriggerCriteria = Union[
|
|
22
|
+
PriceAboveTrigger, PriceBelowTrigger, LastPriceAboveTrigger, LastPriceBelowTrigger
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class OrderData(NadoBaseModel):
|
|
27
|
+
sender: str
|
|
28
|
+
priceX18: str
|
|
29
|
+
amount: str
|
|
30
|
+
expiration: str
|
|
31
|
+
nonce: str
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TriggerOrderData(NadoBaseModel):
|
|
35
|
+
"""
|
|
36
|
+
Data model for details of a trigger order.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
product_id: int
|
|
40
|
+
order: OrderData
|
|
41
|
+
signature: str
|
|
42
|
+
spot_leverage: Optional[bool]
|
|
43
|
+
digest: Optional[str]
|
|
44
|
+
trigger: TriggerCriteria
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import validator
|
|
4
|
+
|
|
5
|
+
from nado_protocol.engine_client.types.models import ResponseStatus
|
|
6
|
+
from nado_protocol.trigger_client.types.models import TriggerOrderData
|
|
7
|
+
from nado_protocol.utils.bytes32 import bytes32_to_hex
|
|
8
|
+
from nado_protocol.utils.execute import BaseParams, SignatureParams
|
|
9
|
+
from nado_protocol.utils.model import NadoBaseModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ListTriggerOrdersTx(BaseParams):
|
|
13
|
+
recvTime: int
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ListTriggerOrdersParams(NadoBaseModel):
|
|
17
|
+
"""
|
|
18
|
+
Parameters for listing trigger orders
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
type = "list_trigger_orders"
|
|
22
|
+
tx: ListTriggerOrdersTx
|
|
23
|
+
product_id: Optional[int]
|
|
24
|
+
pending: bool
|
|
25
|
+
max_update_time: Optional[str]
|
|
26
|
+
max_digest: Optional[str]
|
|
27
|
+
digests: Optional[list[str]]
|
|
28
|
+
limit: Optional[int]
|
|
29
|
+
signature: Optional[str]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TriggerOrder(NadoBaseModel):
|
|
33
|
+
order: TriggerOrderData
|
|
34
|
+
status: str
|
|
35
|
+
updated_at: int
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TriggerOrdersData(NadoBaseModel):
|
|
39
|
+
"""
|
|
40
|
+
Data model for trigger orders
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
orders: list[TriggerOrder]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ListTriggerOrdersRequest(ListTriggerOrdersParams):
|
|
47
|
+
tx: ListTriggerOrdersTx
|
|
48
|
+
|
|
49
|
+
@validator("tx")
|
|
50
|
+
def serialize(cls, v: ListTriggerOrdersTx) -> ListTriggerOrdersTx:
|
|
51
|
+
if isinstance(v.sender, bytes):
|
|
52
|
+
v.serialize_dict(["sender"], bytes32_to_hex)
|
|
53
|
+
v.serialize_dict(["recvTime"], str)
|
|
54
|
+
return v
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class TriggerQueryResponse(NadoBaseModel):
|
|
58
|
+
"""
|
|
59
|
+
Represents a response to a query request.
|
|
60
|
+
|
|
61
|
+
Attributes:
|
|
62
|
+
status (ResponseStatus): The status of the query response.
|
|
63
|
+
|
|
64
|
+
data (Optional[QueryResponseData]): The data returned from the query, or an error message if the query failed.
|
|
65
|
+
|
|
66
|
+
error (Optional[str]): The error message, if any error occurred during the query.
|
|
67
|
+
|
|
68
|
+
error_code (Optional[int]): The error code, if any error occurred during the query.
|
|
69
|
+
|
|
70
|
+
request_type (Optional[str]): Type of the request.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
status: ResponseStatus
|
|
74
|
+
data: Optional[TriggerOrdersData]
|
|
75
|
+
error: Optional[str]
|
|
76
|
+
error_code: Optional[int]
|
|
77
|
+
request_type: Optional[str]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from nado_protocol.utils.backend import *
|
|
2
|
+
from nado_protocol.utils.bytes32 import *
|
|
3
|
+
from nado_protocol.utils.subaccount import *
|
|
4
|
+
from nado_protocol.utils.expiration import *
|
|
5
|
+
from nado_protocol.utils.math import *
|
|
6
|
+
from nado_protocol.utils.nonce import *
|
|
7
|
+
from nado_protocol.utils.exceptions import *
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"NadoBackendURL",
|
|
11
|
+
"NadoClientOpts",
|
|
12
|
+
"SubaccountParams",
|
|
13
|
+
"Subaccount",
|
|
14
|
+
"subaccount_to_bytes32",
|
|
15
|
+
"subaccount_to_hex",
|
|
16
|
+
"subaccount_name_to_bytes12",
|
|
17
|
+
"hex_to_bytes32",
|
|
18
|
+
"hex_to_bytes12",
|
|
19
|
+
"hex_to_bytes",
|
|
20
|
+
"str_to_hex",
|
|
21
|
+
"bytes32_to_hex",
|
|
22
|
+
"zero_subaccount",
|
|
23
|
+
"zero_address",
|
|
24
|
+
"OrderType",
|
|
25
|
+
"get_expiration_timestamp",
|
|
26
|
+
"gen_order_nonce",
|
|
27
|
+
"decode_expiration",
|
|
28
|
+
"to_pow_10",
|
|
29
|
+
"to_x18",
|
|
30
|
+
"from_pow_10",
|
|
31
|
+
"from_x18",
|
|
32
|
+
"ExecuteFailedException",
|
|
33
|
+
"QueryFailedException",
|
|
34
|
+
"BadStatusCodeException",
|
|
35
|
+
"MissingSignerException",
|
|
36
|
+
"InvalidProductId",
|
|
37
|
+
]
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from nado_protocol.utils.enum import StrEnum
|
|
2
|
+
from eth_account import Account
|
|
3
|
+
from eth_account.signers.local import LocalAccount
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
from pydantic import BaseModel, AnyUrl, validator, root_validator
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class NadoBackendURL(StrEnum):
|
|
9
|
+
"""Enum representing different Nado backend URLs."""
|
|
10
|
+
|
|
11
|
+
# dev
|
|
12
|
+
DEVNET_GATEWAY = "http://localhost:80"
|
|
13
|
+
DEVNET_INDEXER = "http://localhost:8000"
|
|
14
|
+
DEVNET_TRIGGER = "http://localhost:8080"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
PrivateKey = str
|
|
18
|
+
Signer = Union[LocalAccount, PrivateKey]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class NadoClientOpts(BaseModel):
|
|
22
|
+
"""
|
|
23
|
+
Model defining the configuration options for execute Nado Clients (e.g: Engine, Trigger). It includes various parameters such as the URL,
|
|
24
|
+
the signer, the linked signer, the chain ID, and others.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
url (AnyUrl): The URL of the server.
|
|
28
|
+
signer (Optional[Signer]): The signer for the client, if any. It can either be a `LocalAccount` or a private key.
|
|
29
|
+
linked_signer (Optional[Signer]): An optional signer linked the main subaccount to perform executes on it's behalf.
|
|
30
|
+
chain_id (Optional[int]): An optional network chain ID.
|
|
31
|
+
endpoint_addr (Optional[str]): Nado's endpoint address used for verifying executes.
|
|
32
|
+
book_addrs (Optional[list[str]]): Nado's book addresses used for verifying order placement.
|
|
33
|
+
|
|
34
|
+
Notes:
|
|
35
|
+
- The class also includes several methods for validating and sanitizing the input values.
|
|
36
|
+
- "linked_signer" cannot be set if "signer" is not set.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
url: AnyUrl
|
|
40
|
+
signer: Optional[Union[LocalAccount, PrivateKey]] = None
|
|
41
|
+
linked_signer: Optional[Signer] = None
|
|
42
|
+
chain_id: Optional[int] = None
|
|
43
|
+
endpoint_addr: Optional[str] = None
|
|
44
|
+
book_addrs: Optional[list[str]] = None
|
|
45
|
+
|
|
46
|
+
class Config:
|
|
47
|
+
arbitrary_types_allowed = True
|
|
48
|
+
|
|
49
|
+
@root_validator
|
|
50
|
+
def check_linked_signer(cls, values: dict):
|
|
51
|
+
"""
|
|
52
|
+
Validates that if a linked_signer is set, a signer must also be set.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
values (dict): The input values to be validated.
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
ValueError: If linked_signer is set but signer is not.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
dict: The validated values.
|
|
62
|
+
"""
|
|
63
|
+
signer, linked_signer = values.get("signer"), values.get("linked_signer")
|
|
64
|
+
if linked_signer and not signer:
|
|
65
|
+
raise ValueError("linked_signer cannot be set if signer is not set")
|
|
66
|
+
return values
|
|
67
|
+
|
|
68
|
+
@validator("url")
|
|
69
|
+
def clean_url(cls, v: AnyUrl) -> str:
|
|
70
|
+
"""
|
|
71
|
+
Cleans the URL input by removing trailing slashes.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
v (AnyUrl): The input URL.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
str: The cleaned URL.
|
|
78
|
+
"""
|
|
79
|
+
return v.rstrip("/")
|
|
80
|
+
|
|
81
|
+
@validator("signer")
|
|
82
|
+
def signer_to_local_account(cls, v: Optional[Signer]) -> Optional[LocalAccount]:
|
|
83
|
+
"""
|
|
84
|
+
Validates and converts the signer to a LocalAccount instance.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
v (Optional[Signer]): The signer instance or None.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Optional[LocalAccount]: The LocalAccount instance or None.
|
|
91
|
+
"""
|
|
92
|
+
if v is None or isinstance(v, LocalAccount):
|
|
93
|
+
return v
|
|
94
|
+
return Account.from_key(v)
|
|
95
|
+
|
|
96
|
+
@validator("linked_signer")
|
|
97
|
+
def linked_signer_to_local_account(
|
|
98
|
+
cls, v: Optional[Signer]
|
|
99
|
+
) -> Optional[LocalAccount]:
|
|
100
|
+
"""
|
|
101
|
+
Validates and converts the linked_signer to a LocalAccount instance.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
v (Optional[Signer]): The linked_signer instance or None.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Optional[LocalAccount]: The LocalAccount instance or None.
|
|
108
|
+
"""
|
|
109
|
+
if v is None or isinstance(v, LocalAccount):
|
|
110
|
+
return v
|
|
111
|
+
return Account.from_key(v)
|