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.
Files changed (78) hide show
  1. nado_protocol/__init__.py +0 -0
  2. nado_protocol/client/__init__.py +200 -0
  3. nado_protocol/client/apis/__init__.py +26 -0
  4. nado_protocol/client/apis/base.py +42 -0
  5. nado_protocol/client/apis/market/__init__.py +23 -0
  6. nado_protocol/client/apis/market/execute.py +192 -0
  7. nado_protocol/client/apis/market/query.py +310 -0
  8. nado_protocol/client/apis/perp/__init__.py +18 -0
  9. nado_protocol/client/apis/perp/query.py +30 -0
  10. nado_protocol/client/apis/rewards/__init__.py +6 -0
  11. nado_protocol/client/apis/rewards/execute.py +131 -0
  12. nado_protocol/client/apis/rewards/query.py +12 -0
  13. nado_protocol/client/apis/spot/__init__.py +23 -0
  14. nado_protocol/client/apis/spot/base.py +32 -0
  15. nado_protocol/client/apis/spot/execute.py +117 -0
  16. nado_protocol/client/apis/spot/query.py +79 -0
  17. nado_protocol/client/apis/subaccount/__init__.py +24 -0
  18. nado_protocol/client/apis/subaccount/execute.py +54 -0
  19. nado_protocol/client/apis/subaccount/query.py +145 -0
  20. nado_protocol/client/context.py +90 -0
  21. nado_protocol/contracts/__init__.py +377 -0
  22. nado_protocol/contracts/abis/Endpoint.json +636 -0
  23. nado_protocol/contracts/abis/FQuerier.json +1909 -0
  24. nado_protocol/contracts/abis/IClearinghouse.json +876 -0
  25. nado_protocol/contracts/abis/IERC20.json +185 -0
  26. nado_protocol/contracts/abis/IEndpoint.json +250 -0
  27. nado_protocol/contracts/abis/IFoundationRewardsAirdrop.json +76 -0
  28. nado_protocol/contracts/abis/IOffchainBook.json +536 -0
  29. nado_protocol/contracts/abis/IPerpEngine.json +931 -0
  30. nado_protocol/contracts/abis/IProductEngine.json +352 -0
  31. nado_protocol/contracts/abis/ISpotEngine.json +813 -0
  32. nado_protocol/contracts/abis/IStaking.json +288 -0
  33. nado_protocol/contracts/abis/IVrtxAirdrop.json +138 -0
  34. nado_protocol/contracts/abis/MockERC20.json +311 -0
  35. nado_protocol/contracts/deployments/deployment.test.json +18 -0
  36. nado_protocol/contracts/eip712/__init__.py +16 -0
  37. nado_protocol/contracts/eip712/domain.py +36 -0
  38. nado_protocol/contracts/eip712/sign.py +79 -0
  39. nado_protocol/contracts/eip712/types.py +154 -0
  40. nado_protocol/contracts/loader.py +55 -0
  41. nado_protocol/contracts/types.py +141 -0
  42. nado_protocol/engine_client/__init__.py +35 -0
  43. nado_protocol/engine_client/execute.py +416 -0
  44. nado_protocol/engine_client/query.py +481 -0
  45. nado_protocol/engine_client/types/__init__.py +113 -0
  46. nado_protocol/engine_client/types/execute.py +680 -0
  47. nado_protocol/engine_client/types/models.py +247 -0
  48. nado_protocol/engine_client/types/query.py +516 -0
  49. nado_protocol/engine_client/types/stream.py +6 -0
  50. nado_protocol/indexer_client/__init__.py +28 -0
  51. nado_protocol/indexer_client/query.py +466 -0
  52. nado_protocol/indexer_client/types/__init__.py +122 -0
  53. nado_protocol/indexer_client/types/models.py +364 -0
  54. nado_protocol/indexer_client/types/query.py +819 -0
  55. nado_protocol/trigger_client/__init__.py +17 -0
  56. nado_protocol/trigger_client/execute.py +118 -0
  57. nado_protocol/trigger_client/query.py +61 -0
  58. nado_protocol/trigger_client/types/__init__.py +7 -0
  59. nado_protocol/trigger_client/types/execute.py +89 -0
  60. nado_protocol/trigger_client/types/models.py +44 -0
  61. nado_protocol/trigger_client/types/query.py +77 -0
  62. nado_protocol/utils/__init__.py +37 -0
  63. nado_protocol/utils/backend.py +111 -0
  64. nado_protocol/utils/bytes32.py +159 -0
  65. nado_protocol/utils/enum.py +6 -0
  66. nado_protocol/utils/exceptions.py +58 -0
  67. nado_protocol/utils/execute.py +403 -0
  68. nado_protocol/utils/expiration.py +45 -0
  69. nado_protocol/utils/interest.py +66 -0
  70. nado_protocol/utils/math.py +67 -0
  71. nado_protocol/utils/model.py +79 -0
  72. nado_protocol/utils/nonce.py +33 -0
  73. nado_protocol/utils/subaccount.py +18 -0
  74. nado_protocol/utils/time.py +21 -0
  75. nado_protocol-0.1.0.dist-info/METADATA +157 -0
  76. nado_protocol-0.1.0.dist-info/RECORD +78 -0
  77. nado_protocol-0.1.0.dist-info/WHEEL +4 -0
  78. nado_protocol-0.1.0.dist-info/entry_points.txt +11 -0
@@ -0,0 +1,117 @@
1
+ from typing import Optional
2
+ from nado_protocol.contracts.types import DepositCollateralParams
3
+ from eth_account.signers.local import LocalAccount
4
+ from nado_protocol.client.apis.spot.base import BaseSpotAPI
5
+ from nado_protocol.engine_client.types.execute import (
6
+ ExecuteResponse,
7
+ WithdrawCollateralParams,
8
+ )
9
+ from nado_protocol.utils.exceptions import MissingSignerException
10
+
11
+
12
+ class SpotExecuteAPI(BaseSpotAPI):
13
+ """
14
+ Class providing execution operations for the spot market in the Nado Protocol.
15
+
16
+ This class provides functionality for executing transactions related to spot products,
17
+ such as depositing a specified amount into a spot product.
18
+
19
+ Inheritance:
20
+ BaseSpotAPI: Base class for Spot operations. Inherits connectivity context and base functionalities.
21
+ """
22
+
23
+ def deposit(
24
+ self, params: DepositCollateralParams, signer: Optional[LocalAccount] = None
25
+ ) -> str:
26
+ """
27
+ Executes the operation of depositing a specified amount into a spot product.
28
+
29
+ Args:
30
+ params (DepositCollateralParams): Parameters required for depositing collateral.
31
+
32
+ signer (LocalAccount, optional): The account that will sign the deposit transaction. If no signer is provided, the signer set in the client context will be used.
33
+
34
+ Raises:
35
+ MissingSignerException: Raised when there is no signer provided and no signer set in the client context.
36
+
37
+ Returns:
38
+ str: The deposit collateral transaction hash.
39
+ """
40
+ signer = signer if signer else self.context.signer
41
+ if not signer:
42
+ raise MissingSignerException(
43
+ "A signer must be provided or set via the context."
44
+ )
45
+ return self.context.contracts.deposit_collateral(params, signer)
46
+
47
+ def withdraw(self, params: WithdrawCollateralParams) -> ExecuteResponse:
48
+ """
49
+ Executes a withdrawal for the specified spot product via the off-chain engine.
50
+
51
+ Args:
52
+ params (WithdrawCollateralParams): Parameters needed to execute the withdrawal.
53
+
54
+ Returns:
55
+ ExecuteResponse: The response from the engine execution.
56
+
57
+ Raises:
58
+ Exception: If there is an error during the execution or the response status is not "success".
59
+ """
60
+ return self.context.engine_client.withdraw_collateral(params)
61
+
62
+ def approve_allowance(
63
+ self, product_id: int, amount: int, signer: Optional[LocalAccount] = None
64
+ ) -> str:
65
+ """
66
+ Approves an allowance for a certain amount of tokens for a spot product.
67
+
68
+ Args:
69
+ product_id (int): The identifier of the spot product for which to approve an allowance.
70
+
71
+ amount (int): The amount of the tokens to be approved.
72
+
73
+ signer (LocalAccount, optional): The account that will sign the approval transaction. If no signer is provided, the signer set in the client context will be used.
74
+
75
+ Returns:
76
+ str: The approve allowance transaction hash.
77
+
78
+ Raises:
79
+ MissingSignerException: Raised when there is no signer provided and no signer set in the client context.
80
+ InvalidProductId: If the provided product ID is not valid.
81
+ """
82
+ signer = signer if signer else self.context.signer
83
+ if not signer:
84
+ raise MissingSignerException(
85
+ "A signer must be provided or set via the context."
86
+ )
87
+ token = self.get_token_contract_for_product(product_id)
88
+ return self.context.contracts.approve_allowance(token, amount, signer)
89
+
90
+ def _mint_mock_erc20(
91
+ self, product_id: int, amount: int, signer: Optional[LocalAccount] = None
92
+ ):
93
+ """
94
+ Mints a specified amount of mock ERC20 tokens for testing purposes.
95
+
96
+ Args:
97
+ product_id (int): The identifier for the spot product.
98
+
99
+ amount (int): The amount of mock ERC20 tokens to mint.
100
+
101
+ signer (LocalAccount, optional): The account that will sign the mint transaction.
102
+ If no signer is provided, the signer set in the client context will be used.
103
+
104
+ Returns:
105
+ str: The mock ERC20 mint transaction hash.
106
+
107
+ Raises:
108
+ MissingSignerException: Raised when there is no signer provided and no signer set in the client context.
109
+ InvalidProductId: If the provided product ID is not valid.
110
+ """
111
+ signer = signer if signer else self.context.signer
112
+ if not signer:
113
+ raise MissingSignerException(
114
+ "A signer must be provided or set via the context."
115
+ )
116
+ token = self.get_token_contract_for_product(product_id)
117
+ return self.context.contracts._mint_mock_erc20(token, amount, signer)
@@ -0,0 +1,79 @@
1
+ from typing import Optional
2
+ from nado_protocol.client.apis.spot.base import BaseSpotAPI
3
+ from nado_protocol.engine_client.types.query import MaxWithdrawableData
4
+ from nado_protocol.utils.math import from_pow_10
5
+
6
+
7
+ class SpotQueryAPI(BaseSpotAPI):
8
+ """
9
+ Class providing querying operations for the spot market in the Nado Protocol.
10
+
11
+ This class allows for retrieval of various kinds of information related to spot products,
12
+ such as getting wallet token balance of a given spot product.
13
+
14
+ Inheritance:
15
+ BaseSpotAPI: Base class for Spot operations. Inherits connectivity context and base functionalities.
16
+ """
17
+
18
+ def get_max_withdrawable(
19
+ self, product_id: int, sender: str, spot_leverage: Optional[bool] = None
20
+ ) -> MaxWithdrawableData:
21
+ """
22
+ Retrieves the estimated maximum withdrawable amount for a provided spot product.
23
+
24
+ Args:
25
+ product_id (int): The identifier for the spot product.
26
+
27
+ sender (str): The address and subaccount identifier in a bytes32 hex string.
28
+
29
+ spot_leverage (Optional[bool]): If False, calculates max amount without considering leverage. Defaults to True.
30
+
31
+ Returns:
32
+ MaxWithdrawableData: The maximum withdrawable amount for the spot product.
33
+ """
34
+ return self.context.engine_client.get_max_withdrawable(
35
+ product_id, sender, spot_leverage
36
+ )
37
+
38
+ def get_token_wallet_balance(self, product_id: int, address: str) -> float:
39
+ """
40
+ Retrieves the balance of a specific token in the user's wallet (i.e. not in a Nado subaccount)
41
+
42
+ Args:
43
+ product_id (int): Identifier for the spot product.
44
+
45
+ address (str): User's wallet address.
46
+
47
+ Returns:
48
+ float: The balance of the token in the user's wallet in decimal form.
49
+
50
+ Raises:
51
+ InvalidProductId: If the provided product ID is not valid.
52
+ """
53
+ token = self.get_token_contract_for_product(product_id)
54
+ decimals = token.functions.decimals().call()
55
+ return from_pow_10(token.functions.balanceOf(address).call(), decimals)
56
+
57
+ def get_token_allowance(self, product_id: int, address: str) -> float:
58
+ """
59
+ Retrieves the current token allowance of a specified spot product.
60
+
61
+ Args:
62
+ product_id (int): Identifier for the spot product.
63
+
64
+ address (str): The user's wallet address.
65
+
66
+ Returns:
67
+ float: The current token allowance of the user's wallet address to the associated spot product.
68
+
69
+ Raises:
70
+ InvalidProductId: If the provided product ID is not valid.
71
+ """
72
+ token = self.get_token_contract_for_product(product_id)
73
+ decimals = token.functions.decimals().call()
74
+ return from_pow_10(
75
+ token.functions.allowance(
76
+ address, self.context.contracts.endpoint.address
77
+ ).call(),
78
+ decimals,
79
+ )
@@ -0,0 +1,24 @@
1
+ from nado_protocol.client.apis.subaccount.execute import SubaccountExecuteAPI
2
+ from nado_protocol.client.apis.subaccount.query import SubaccountQueryAPI
3
+
4
+
5
+ class SubaccountAPI(SubaccountExecuteAPI, SubaccountQueryAPI):
6
+ """
7
+ A unified interface for subaccount operations in the Nado Protocol.
8
+
9
+ This class combines functionalities from both SubaccountExecuteAPI and SubaccountQueryAPI
10
+ into a single interface, providing a simpler and more consistent way to perform subaccount operations.
11
+ It allows for both query (data retrieval) and execution (transaction) operations for subaccounts.
12
+
13
+ Inheritance:
14
+ SubaccountExecuteAPI: This provides functionalities to execute various operations related to subaccounts.
15
+ These include actions like liquidating a subaccount or linking a signer to a subaccount.
16
+
17
+ SubaccountQueryAPI: This provides functionalities to retrieve various kinds of information related to subaccounts.
18
+ These include operations like retrieving a summary of a subaccount's state, retrieving the fee rates associated with a
19
+ subaccount, querying token rewards for a wallet, and getting linked signer rate limits for a subaccount.
20
+
21
+ Attributes and Methods: Inherited from SubaccountExecuteAPI and SubaccountQueryAPI.
22
+ """
23
+
24
+ pass
@@ -0,0 +1,54 @@
1
+ from nado_protocol.client.apis.base import NadoBaseAPI
2
+ from nado_protocol.engine_client.types.execute import (
3
+ ExecuteResponse,
4
+ LinkSignerParams,
5
+ LiquidateSubaccountParams,
6
+ )
7
+
8
+
9
+ class SubaccountExecuteAPI(NadoBaseAPI):
10
+ """
11
+ Provides functionalities for executing operations related to subaccounts in the Nado Protocol.
12
+
13
+ Inherits from NadoBaseAPI, which provides a basic context setup for accessing Nado.
14
+ This class extends the base class to provide specific functionalities for executing actions related to subaccounts.
15
+
16
+ The provided methods include:
17
+ - `liquidate_subaccount`: Performs the liquidation of a subaccount.
18
+ - `link_signer`: Links a signer to a subaccount, granting them transaction signing permissions.
19
+
20
+ Attributes:
21
+ context (NadoClientContext): Provides connectivity details for accessing Nado APIs.
22
+ """
23
+
24
+ def liquidate_subaccount(
25
+ self, params: LiquidateSubaccountParams
26
+ ) -> ExecuteResponse:
27
+ """
28
+ Liquidates a subaccount through the engine.
29
+
30
+ Args:
31
+ params (LiquidateSubaccountParams): Parameters for liquidating the subaccount.
32
+
33
+ Returns:
34
+ ExecuteResponse: Execution response from the engine.
35
+
36
+ Raises:
37
+ Exception: If there is an error during the execution or the response status is not "success".
38
+ """
39
+ return self.context.engine_client.liquidate_subaccount(params)
40
+
41
+ def link_signer(self, params: LinkSignerParams) -> ExecuteResponse:
42
+ """
43
+ Links a signer to a subaccount to allow them to sign transactions on behalf of the subaccount.
44
+
45
+ Args:
46
+ params (LinkSignerParams): Parameters for linking a signer to a subaccount.
47
+
48
+ Returns:
49
+ ExecuteResponse: Execution response from the engine.
50
+
51
+ Raises:
52
+ Exception: If there is an error during the execution or the response status is not "success".
53
+ """
54
+ return self.context.engine_client.link_signer(params)
@@ -0,0 +1,145 @@
1
+ from typing import Optional
2
+ from nado_protocol.client.apis.base import NadoBaseAPI
3
+ from nado_protocol.engine_client.types.query import (
4
+ FeeRatesData,
5
+ QuerySubaccountInfoTx,
6
+ SubaccountInfoData,
7
+ )
8
+ from nado_protocol.indexer_client.types.query import (
9
+ IndexerLinkedSignerRateLimitData,
10
+ IndexerReferralCodeData,
11
+ IndexerSubaccountsData,
12
+ IndexerSubaccountsParams,
13
+ IndexerTokenRewardsData,
14
+ IndexerInterestAndFundingParams,
15
+ IndexerInterestAndFundingData,
16
+ )
17
+
18
+
19
+ class SubaccountQueryAPI(NadoBaseAPI):
20
+ """
21
+ Provides functionalities for querying data related to subaccounts in the Nado Protocol.
22
+
23
+ Inherits from NadoBaseAPI, which provides a basic context setup for accessing Nado Clearinghouse.
24
+ This class extends the base class to provide specific functionalities for querying data related to subaccounts.
25
+
26
+ Attributes:
27
+ context (NadoClientContext): Provides connectivity details for accessing Nado APIs.
28
+ """
29
+
30
+ def get_engine_subaccount_summary(
31
+ self, subaccount: str, txs: Optional[list[QuerySubaccountInfoTx]] = None
32
+ ) -> SubaccountInfoData:
33
+ """
34
+ Retrieve a comprehensive summary of the specified subaccount's state as per the off-chain engine.
35
+
36
+ You can optionally provide a list of txs to get an estimated view of your subaccount.
37
+
38
+ Args:
39
+ subaccount (str): Unique identifier for the subaccount.
40
+
41
+ txs (list[QuerySubaccountInfoTx], optional): Optional list of transactions for the subaccount.
42
+
43
+ Returns:
44
+ SubaccountInfoData: A data class object containing detailed state information about the queried subaccount.
45
+ """
46
+ return self.context.engine_client.get_subaccount_info(subaccount, txs)
47
+
48
+ def get_subaccount_fee_rates(self, subaccount: str) -> FeeRatesData:
49
+ """
50
+ Retrieve the fee rates associated with a specific subaccount from the off-chain engine.
51
+
52
+ Args:
53
+ subaccount (str): Unique identifier for the subaccount.
54
+
55
+ Returns:
56
+ FeeRatesData: A data class object containing detailed fee rates data for the specified subaccount.
57
+ """
58
+ return self.context.engine_client.get_fee_rates(subaccount)
59
+
60
+ def get_subaccount_token_rewards(self, address: str) -> IndexerTokenRewardsData:
61
+ """
62
+ Query the $VRTX token rewards accumulated per epoch for a specified wallet from the indexer.
63
+
64
+ Args:
65
+ address (str): Wallet address to be queried.
66
+
67
+ Returns:
68
+ IndexerTokenRewardsData: A data class object containing detailed information about the accrued token rewards.
69
+ """
70
+ return self.context.indexer_client.get_token_rewards(address)
71
+
72
+ def get_subaccount_linked_signer_rate_limits(
73
+ self, subaccount: str
74
+ ) -> IndexerLinkedSignerRateLimitData:
75
+ """
76
+ Retrieve the current linked signer and their rate limit for a specified subaccount from the indexer.
77
+
78
+ Args:
79
+ subaccount (str): Unique identifier for the subaccount.
80
+
81
+ Returns:
82
+ IndexerLinkedSignerRateLimitData: A data class object containing information about the current linked signer and their rate limits for the queried subaccount.
83
+ """
84
+ return self.context.indexer_client.get_linked_signer_rate_limits(subaccount)
85
+
86
+ def get_referral_code(self, subaccount: str) -> IndexerReferralCodeData:
87
+ """
88
+ Query the referral code for the specified wallet from the indexer.
89
+
90
+ Args:
91
+ subaccount (str): Unique identifier for the subaccount.
92
+
93
+ Returns:
94
+ IndexerReferralCodeData: A data class object containing the wallet's referral code.
95
+ """
96
+ return self.context.indexer_client.get_referral_code(subaccount)
97
+
98
+ def get_subaccounts(
99
+ self,
100
+ address: Optional[str] = None,
101
+ start_idx: Optional[int] = None,
102
+ limit: Optional[int] = None,
103
+ ) -> IndexerSubaccountsData:
104
+ """
105
+ List nado subaccounts via the indexer.
106
+
107
+ Args:
108
+ address (Optional[str]): An optional wallet address to find all subaccounts associated to it.
109
+ start_idx (Optional[int]): Optional subaccount id to start from. Used for pagination. Defaults to 0.
110
+ limit (Optional[int]): Maximum number of subaccounts to return. Defaults to 100. Max of 500.
111
+
112
+ Returns:
113
+ IndexerSubaccountsData: A data class object containing the list of subaccounts found.
114
+ """
115
+ return self.context.indexer_client.get_subaccounts(
116
+ IndexerSubaccountsParams(address=address, start=start_idx, limit=limit)
117
+ )
118
+
119
+ def get_interest_and_funding_payments(
120
+ self,
121
+ subaccount: str,
122
+ product_ids: list[int],
123
+ limit: int,
124
+ max_idx: Optional[int] = None,
125
+ ) -> IndexerInterestAndFundingData:
126
+ """
127
+ List interests and funding payments for a subaccount and provided products from the indexer.
128
+
129
+ Args:
130
+ subaccount (str): Subaccount to fetch interest / funding payments for.
131
+ product_ids (list[int]): List of product IDs to fetch interest / funding payments for.
132
+ limit (int): Max number of records to return. Max possible of 100.
133
+ max_idx (Optional[int]): When provided, only return records with idx <= max_idx. Used for pagination.
134
+
135
+ Returns:
136
+ IndexerInterestAndFundingData: A data class object containing the list of interest / funding payments found.
137
+ """
138
+ return self.context.indexer_client.get_interest_and_funding_payments(
139
+ IndexerInterestAndFundingParams(
140
+ subaccount=subaccount,
141
+ product_ids=product_ids,
142
+ limit=limit,
143
+ max_idx=max_idx,
144
+ )
145
+ )
@@ -0,0 +1,90 @@
1
+ import logging
2
+ from dataclasses import dataclass
3
+ from typing import Optional
4
+ from eth_account import Account
5
+
6
+ from pydantic import AnyUrl, BaseModel
7
+ from nado_protocol.contracts import NadoContracts, NadoContractsContext
8
+ from eth_account.signers.local import LocalAccount
9
+ from nado_protocol.engine_client import EngineClient
10
+ from nado_protocol.engine_client.types import EngineClientOpts
11
+ from nado_protocol.utils.backend import Signer
12
+ from nado_protocol.indexer_client import IndexerClient
13
+ from nado_protocol.trigger_client import TriggerClient
14
+ from nado_protocol.indexer_client.types import IndexerClientOpts
15
+ from nado_protocol.trigger_client.types import TriggerClientOpts
16
+
17
+
18
+ @dataclass
19
+ class NadoClientContext:
20
+ """
21
+ Context required to use the Nado client.
22
+ """
23
+
24
+ signer: Optional[LocalAccount]
25
+ engine_client: EngineClient
26
+ indexer_client: IndexerClient
27
+ trigger_client: Optional[TriggerClient]
28
+ contracts: NadoContracts
29
+
30
+
31
+ class NadoClientContextOpts(BaseModel):
32
+ contracts_context: Optional[NadoContractsContext]
33
+ rpc_node_url: Optional[AnyUrl]
34
+ engine_endpoint_url: Optional[AnyUrl]
35
+ indexer_endpoint_url: Optional[AnyUrl]
36
+ trigger_endpoint_url: Optional[AnyUrl]
37
+
38
+
39
+ def create_nado_client_context(
40
+ opts: NadoClientContextOpts, signer: Optional[Signer] = None
41
+ ) -> NadoClientContext:
42
+ """
43
+ Initializes a NadoClientContext instance with the provided signer and options.
44
+
45
+ Args:
46
+ opts (NadoClientContextOpts): Options including endpoints for the engine and indexer clients.
47
+
48
+ signer (Signer, optional): An instance of LocalAccount or a private key string for signing transactions.
49
+
50
+ Returns:
51
+ NadoClientContext: The initialized Nado client context.
52
+
53
+ Note:
54
+ This helper attempts to fully set up the engine, indexer and trigger clients, including the necessary verifying contracts
55
+ to correctly sign executes. If this step fails, it is skipped and can be set up later, while logging the error.
56
+ """
57
+ assert opts.contracts_context is not None, "Missing contracts context"
58
+ assert opts.rpc_node_url is not None, "Missing RPC node URL"
59
+ assert opts.engine_endpoint_url is not None, "Missing engine endpoint URL"
60
+ assert opts.indexer_endpoint_url is not None, "Missing indexer endpoint URL"
61
+
62
+ signer = Account.from_key(signer) if isinstance(signer, str) else signer
63
+ engine_client = EngineClient(
64
+ EngineClientOpts(url=opts.engine_endpoint_url, signer=signer)
65
+ )
66
+ trigger_client = None
67
+ try:
68
+ contracts = engine_client.get_contracts()
69
+ engine_client.endpoint_addr = contracts.endpoint_addr
70
+ engine_client.book_addrs = contracts.book_addrs
71
+ engine_client.chain_id = int(contracts.chain_id)
72
+
73
+ if opts.trigger_endpoint_url is not None:
74
+ trigger_client = TriggerClient(
75
+ TriggerClientOpts(url=opts.trigger_endpoint_url, signer=signer)
76
+ )
77
+ trigger_client.endpoint_addr = contracts.endpoint_addr
78
+ trigger_client.book_addrs = contracts.book_addrs
79
+ trigger_client.chain_id = int(contracts.chain_id)
80
+ except Exception as e:
81
+ logging.warning(
82
+ f"Failed to setup engine client verifying contracts with error: {e}"
83
+ )
84
+ return NadoClientContext(
85
+ signer=signer,
86
+ engine_client=engine_client,
87
+ trigger_client=trigger_client,
88
+ indexer_client=IndexerClient(IndexerClientOpts(url=opts.indexer_endpoint_url)),
89
+ contracts=NadoContracts(opts.rpc_node_url, opts.contracts_context),
90
+ )