ault-sdk 0.0.1a1__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 (233) hide show
  1. ault_sdk/__init__.py +205 -0
  2. ault_sdk/_version.py +9 -0
  3. ault_sdk/agent/__init__.py +31 -0
  4. ault_sdk/agent/create_agent_client.py +172 -0
  5. ault_sdk/agent/sign_and_broadcast.py +237 -0
  6. ault_sdk/agent/tx_executor.py +94 -0
  7. ault_sdk/client.py +131 -0
  8. ault_sdk/core/__init__.py +0 -0
  9. ault_sdk/core/address.py +42 -0
  10. ault_sdk/core/base64.py +24 -0
  11. ault_sdk/core/clob_msgs.py +77 -0
  12. ault_sdk/core/errors.py +86 -0
  13. ault_sdk/core/http.py +267 -0
  14. ault_sdk/core/network.py +204 -0
  15. ault_sdk/core/pagination.py +91 -0
  16. ault_sdk/core/query.py +31 -0
  17. ault_sdk/core/with_status_fallback.py +35 -0
  18. ault_sdk/eip712/__init__.py +0 -0
  19. ault_sdk/eip712/builder.py +723 -0
  20. ault_sdk/eip712/field_order.py +81 -0
  21. ault_sdk/eip712/msg_encoders_generated.py +257 -0
  22. ault_sdk/eip712/msg_generated.py +300 -0
  23. ault_sdk/eip712/registry.py +53 -0
  24. ault_sdk/eip712/registry_generated.py +1189 -0
  25. ault_sdk/eip712/sign_and_broadcast.py +487 -0
  26. ault_sdk/eip712/signers.py +271 -0
  27. ault_sdk/eip712/types.py +84 -0
  28. ault_sdk/evm/__init__.py +51 -0
  29. ault_sdk/evm/_gas.py +22 -0
  30. ault_sdk/evm/_tx.py +49 -0
  31. ault_sdk/evm/bridge.py +96 -0
  32. ault_sdk/evm/client.py +113 -0
  33. ault_sdk/evm/erc20.py +219 -0
  34. ault_sdk/evm/precompile.py +38 -0
  35. ault_sdk/evm/registry.py +132 -0
  36. ault_sdk/evm/scaling.py +66 -0
  37. ault_sdk/high_level/__init__.py +7 -0
  38. ault_sdk/high_level/create_client.py +168 -0
  39. ault_sdk/high_level/evm_account.py +42 -0
  40. ault_sdk/high_level/query_helpers.py +109 -0
  41. ault_sdk/high_level/signer.py +40 -0
  42. ault_sdk/high_level/tx/__init__.py +39 -0
  43. ault_sdk/high_level/tx/agent.py +63 -0
  44. ault_sdk/high_level/tx/authority.py +44 -0
  45. ault_sdk/high_level/tx/clob.py +90 -0
  46. ault_sdk/high_level/tx/context.py +16 -0
  47. ault_sdk/high_level/tx/license.py +151 -0
  48. ault_sdk/high_level/tx/market.py +87 -0
  49. ault_sdk/high_level/tx/miner.py +176 -0
  50. ault_sdk/high_level/tx/ratelimit.py +34 -0
  51. ault_sdk/high_level/tx/reward.py +95 -0
  52. ault_sdk/high_level/tx/staking.py +88 -0
  53. ault_sdk/high_level/tx/tokenregistry.py +79 -0
  54. ault_sdk/high_level/tx_executor.py +99 -0
  55. ault_sdk/proto/__init__.py +0 -0
  56. ault_sdk/proto/duration_json.py +76 -0
  57. ault_sdk/proto/gen/__init__.py +0 -0
  58. ault_sdk/proto/gen/amino/__init__.py +8 -0
  59. ault_sdk/proto/gen/ault/__init__.py +0 -0
  60. ault_sdk/proto/gen/ault/agent/__init__.py +0 -0
  61. ault_sdk/proto/gen/ault/agent/v1/__init__.py +553 -0
  62. ault_sdk/proto/gen/ault/authority/__init__.py +0 -0
  63. ault_sdk/proto/gen/ault/authority/v1/__init__.py +307 -0
  64. ault_sdk/proto/gen/ault/clob/__init__.py +0 -0
  65. ault_sdk/proto/gen/ault/clob/v1/__init__.py +536 -0
  66. ault_sdk/proto/gen/ault/license/__init__.py +0 -0
  67. ault_sdk/proto/gen/ault/license/v1/__init__.py +2159 -0
  68. ault_sdk/proto/gen/ault/market/__init__.py +0 -0
  69. ault_sdk/proto/gen/ault/market/v1/__init__.py +583 -0
  70. ault_sdk/proto/gen/ault/miner/__init__.py +0 -0
  71. ault_sdk/proto/gen/ault/miner/v1/__init__.py +2013 -0
  72. ault_sdk/proto/gen/ault/ratelimit/__init__.py +0 -0
  73. ault_sdk/proto/gen/ault/ratelimit/v1/__init__.py +215 -0
  74. ault_sdk/proto/gen/ault/reward/__init__.py +0 -0
  75. ault_sdk/proto/gen/ault/reward/v1/__init__.py +871 -0
  76. ault_sdk/proto/gen/ault/spot/__init__.py +0 -0
  77. ault_sdk/proto/gen/ault/spot/v1/__init__.py +69 -0
  78. ault_sdk/proto/gen/ault/tokenregistry/__init__.py +0 -0
  79. ault_sdk/proto/gen/ault/tokenregistry/v1/__init__.py +872 -0
  80. ault_sdk/proto/gen/cosmos/__init__.py +0 -0
  81. ault_sdk/proto/gen/cosmos/base/__init__.py +0 -0
  82. ault_sdk/proto/gen/cosmos/base/query/__init__.py +0 -0
  83. ault_sdk/proto/gen/cosmos/base/query/v1beta1/__init__.py +80 -0
  84. ault_sdk/proto/gen/cosmos/base/v1beta1/__init__.py +54 -0
  85. ault_sdk/proto/gen/cosmos/distribution/__init__.py +0 -0
  86. ault_sdk/proto/gen/cosmos/distribution/v1beta1/__init__.py +620 -0
  87. ault_sdk/proto/gen/cosmos/msg/__init__.py +0 -0
  88. ault_sdk/proto/gen/cosmos/msg/v1/__init__.py +8 -0
  89. ault_sdk/proto/gen/cosmos/staking/__init__.py +0 -0
  90. ault_sdk/proto/gen/cosmos/staking/v1beta1/__init__.py +888 -0
  91. ault_sdk/proto/gen/cosmos_proto/__init__.py +73 -0
  92. ault_sdk/proto/gen/gogoproto/__init__.py +8 -0
  93. ault_sdk/proto/gen/google/__init__.py +0 -0
  94. ault_sdk/proto/gen/google/api/__init__.py +387 -0
  95. ault_sdk/proto/gen/tendermint/__init__.py +0 -0
  96. ault_sdk/proto/gen/tendermint/abci/__init__.py +1262 -0
  97. ault_sdk/proto/gen/tendermint/crypto/__init__.py +61 -0
  98. ault_sdk/proto/gen/tendermint/types/__init__.py +359 -0
  99. ault_sdk/proto/gen/tendermint/version/__init__.py +32 -0
  100. ault_sdk/proto/tx_encode.py +355 -0
  101. ault_sdk/rest/__init__.py +0 -0
  102. ault_sdk/rest/agent.py +46 -0
  103. ault_sdk/rest/authority.py +53 -0
  104. ault_sdk/rest/bank.py +69 -0
  105. ault_sdk/rest/clob.py +49 -0
  106. ault_sdk/rest/context.py +134 -0
  107. ault_sdk/rest/dex.py +176 -0
  108. ault_sdk/rest/dex_generated/__init__.py +8 -0
  109. ault_sdk/rest/dex_generated/api/__init__.py +1 -0
  110. ault_sdk/rest/dex_generated/api/balance/__init__.py +1 -0
  111. ault_sdk/rest/dex_generated/api/balance/get_balance.py +187 -0
  112. ault_sdk/rest/dex_generated/api/currencies/__init__.py +1 -0
  113. ault_sdk/rest/dex_generated/api/currencies/list_currencies.py +146 -0
  114. ault_sdk/rest/dex_generated/api/fees/__init__.py +1 -0
  115. ault_sdk/rest/dex_generated/api/fees/get_trading_fees.py +146 -0
  116. ault_sdk/rest/dex_generated/api/health/__init__.py +1 -0
  117. ault_sdk/rest/dex_generated/api/health/get_health.py +137 -0
  118. ault_sdk/rest/dex_generated/api/health/get_live.py +133 -0
  119. ault_sdk/rest/dex_generated/api/health/get_open_api_spec.py +127 -0
  120. ault_sdk/rest/dex_generated/api/health/get_ready.py +138 -0
  121. ault_sdk/rest/dex_generated/api/markets/__init__.py +1 -0
  122. ault_sdk/rest/dex_generated/api/markets/list_markets.py +151 -0
  123. ault_sdk/rest/dex_generated/api/my_trades/__init__.py +1 -0
  124. ault_sdk/rest/dex_generated/api/my_trades/list_my_trades.py +241 -0
  125. ault_sdk/rest/dex_generated/api/ohlcv/__init__.py +1 -0
  126. ault_sdk/rest/dex_generated/api/ohlcv/get_ohlcv.py +225 -0
  127. ault_sdk/rest/dex_generated/api/orderbook/__init__.py +1 -0
  128. ault_sdk/rest/dex_generated/api/orderbook/get_orderbook.py +191 -0
  129. ault_sdk/rest/dex_generated/api/orders/__init__.py +1 -0
  130. ault_sdk/rest/dex_generated/api/orders/get_order.py +183 -0
  131. ault_sdk/rest/dex_generated/api/orders/list_orders.py +260 -0
  132. ault_sdk/rest/dex_generated/api/status/__init__.py +1 -0
  133. ault_sdk/rest/dex_generated/api/status/get_status.py +138 -0
  134. ault_sdk/rest/dex_generated/api/ticker/__init__.py +1 -0
  135. ault_sdk/rest/dex_generated/api/ticker/get_all_tickers.py +138 -0
  136. ault_sdk/rest/dex_generated/api/ticker/get_ticker.py +170 -0
  137. ault_sdk/rest/dex_generated/api/trades/__init__.py +1 -0
  138. ault_sdk/rest/dex_generated/api/trades/list_trades.py +211 -0
  139. ault_sdk/rest/dex_generated/api/trading_view_udf/__init__.py +1 -0
  140. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_config.py +133 -0
  141. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_history.py +245 -0
  142. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_marks.py +231 -0
  143. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_quotes.py +183 -0
  144. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_symbol.py +175 -0
  145. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_time.py +131 -0
  146. ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_timescale_marks.py +236 -0
  147. ault_sdk/rest/dex_generated/api/trading_view_udf/search_udf_symbols.py +223 -0
  148. ault_sdk/rest/dex_generated/client.py +272 -0
  149. ault_sdk/rest/dex_generated/errors.py +16 -0
  150. ault_sdk/rest/dex_generated/models/__init__.py +135 -0
  151. ault_sdk/rest/dex_generated/models/balances_response.py +142 -0
  152. ault_sdk/rest/dex_generated/models/balances_response_free.py +46 -0
  153. ault_sdk/rest/dex_generated/models/balances_response_info.py +46 -0
  154. ault_sdk/rest/dex_generated/models/balances_response_total.py +46 -0
  155. ault_sdk/rest/dex_generated/models/balances_response_used.py +46 -0
  156. ault_sdk/rest/dex_generated/models/currency_response.py +209 -0
  157. ault_sdk/rest/dex_generated/models/currency_response_info.py +46 -0
  158. ault_sdk/rest/dex_generated/models/currency_response_limits.py +90 -0
  159. ault_sdk/rest/dex_generated/models/currency_response_networks.py +46 -0
  160. ault_sdk/rest/dex_generated/models/error_response.py +67 -0
  161. ault_sdk/rest/dex_generated/models/error_response_error.py +69 -0
  162. ault_sdk/rest/dex_generated/models/get_all_tickers_response_200.py +59 -0
  163. ault_sdk/rest/dex_generated/models/get_trading_fees_response_200.py +59 -0
  164. ault_sdk/rest/dex_generated/models/get_udf_history_resolution.py +15 -0
  165. ault_sdk/rest/dex_generated/models/health_response.py +72 -0
  166. ault_sdk/rest/dex_generated/models/health_response_database.py +9 -0
  167. ault_sdk/rest/dex_generated/models/health_response_status.py +9 -0
  168. ault_sdk/rest/dex_generated/models/list_currencies_response_200.py +59 -0
  169. ault_sdk/rest/dex_generated/models/list_orders_status.py +10 -0
  170. ault_sdk/rest/dex_generated/models/live_response.py +63 -0
  171. ault_sdk/rest/dex_generated/models/live_response_status.py +8 -0
  172. ault_sdk/rest/dex_generated/models/market_limits.py +122 -0
  173. ault_sdk/rest/dex_generated/models/market_precision.py +79 -0
  174. ault_sdk/rest/dex_generated/models/market_response.py +450 -0
  175. ault_sdk/rest/dex_generated/models/market_response_info.py +46 -0
  176. ault_sdk/rest/dex_generated/models/market_response_type.py +8 -0
  177. ault_sdk/rest/dex_generated/models/min_max.py +93 -0
  178. ault_sdk/rest/dex_generated/models/order_response.py +350 -0
  179. ault_sdk/rest/dex_generated/models/order_response_fee.py +80 -0
  180. ault_sdk/rest/dex_generated/models/order_response_info.py +46 -0
  181. ault_sdk/rest/dex_generated/models/order_response_side.py +9 -0
  182. ault_sdk/rest/dex_generated/models/order_response_status.py +10 -0
  183. ault_sdk/rest/dex_generated/models/order_response_trades_item.py +46 -0
  184. ault_sdk/rest/dex_generated/models/order_response_type.py +9 -0
  185. ault_sdk/rest/dex_generated/models/orderbook_response.py +121 -0
  186. ault_sdk/rest/dex_generated/models/ready_response.py +63 -0
  187. ault_sdk/rest/dex_generated/models/ready_response_status.py +9 -0
  188. ault_sdk/rest/dex_generated/models/status_response.py +71 -0
  189. ault_sdk/rest/dex_generated/models/ticker_response.py +403 -0
  190. ault_sdk/rest/dex_generated/models/ticker_response_info.py +46 -0
  191. ault_sdk/rest/dex_generated/models/trade_response.py +267 -0
  192. ault_sdk/rest/dex_generated/models/trade_response_fee.py +80 -0
  193. ault_sdk/rest/dex_generated/models/trade_response_info.py +46 -0
  194. ault_sdk/rest/dex_generated/models/trade_response_side.py +9 -0
  195. ault_sdk/rest/dex_generated/models/trade_response_taker_or_maker.py +8 -0
  196. ault_sdk/rest/dex_generated/models/trade_response_type_type_1.py +9 -0
  197. ault_sdk/rest/dex_generated/models/trade_response_type_type_2_type_1.py +9 -0
  198. ault_sdk/rest/dex_generated/models/trade_response_type_type_3_type_1.py +9 -0
  199. ault_sdk/rest/dex_generated/models/trading_fee_response.py +107 -0
  200. ault_sdk/rest/dex_generated/models/trading_fee_response_info.py +46 -0
  201. ault_sdk/rest/dex_generated/models/udf_config.py +141 -0
  202. ault_sdk/rest/dex_generated/models/udf_exchange.py +77 -0
  203. ault_sdk/rest/dex_generated/models/udf_history_response.py +148 -0
  204. ault_sdk/rest/dex_generated/models/udf_history_response_s.py +10 -0
  205. ault_sdk/rest/dex_generated/models/udf_marks_response.py +109 -0
  206. ault_sdk/rest/dex_generated/models/udf_quote_data.py +85 -0
  207. ault_sdk/rest/dex_generated/models/udf_quote_data_s.py +9 -0
  208. ault_sdk/rest/dex_generated/models/udf_quote_values.py +280 -0
  209. ault_sdk/rest/dex_generated/models/udf_quotes_response.py +95 -0
  210. ault_sdk/rest/dex_generated/models/udf_quotes_response_s.py +9 -0
  211. ault_sdk/rest/dex_generated/models/udf_search_result.py +101 -0
  212. ault_sdk/rest/dex_generated/models/udf_symbol_info.py +191 -0
  213. ault_sdk/rest/dex_generated/models/udf_symbol_info_data_status.py +11 -0
  214. ault_sdk/rest/dex_generated/models/udf_symbol_type.py +69 -0
  215. ault_sdk/rest/dex_generated/models/udf_timescale_mark.py +93 -0
  216. ault_sdk/rest/dex_generated/types.py +54 -0
  217. ault_sdk/rest/license.py +107 -0
  218. ault_sdk/rest/market.py +42 -0
  219. ault_sdk/rest/miner.py +111 -0
  220. ault_sdk/rest/ratelimit.py +26 -0
  221. ault_sdk/rest/reward.py +61 -0
  222. ault_sdk/rest/staking.py +70 -0
  223. ault_sdk/rest/tokenregistry.py +35 -0
  224. ault_sdk/utils/__init__.py +0 -0
  225. ault_sdk/utils/address.py +125 -0
  226. ault_sdk/utils/chain_id.py +22 -0
  227. ault_sdk/utils/cosmos_dec.py +95 -0
  228. ault_sdk/ws/__init__.py +24 -0
  229. ault_sdk/ws/client.py +378 -0
  230. ault_sdk/ws/types.py +76 -0
  231. ault_sdk-0.0.1a1.dist-info/METADATA +702 -0
  232. ault_sdk-0.0.1a1.dist-info/RECORD +233 -0
  233. ault_sdk-0.0.1a1.dist-info/WHEEL +4 -0
ault_sdk/__init__.py ADDED
@@ -0,0 +1,205 @@
1
+ """Ault SDK for Python.
2
+
3
+ Public API mirrors ``ault-sdk-ts``'s ``src/index.ts`` with Python
4
+ naming conventions (snake_case methods, dataclasses where TS uses
5
+ object-literal types). See ``DECISIONS.md`` for the deviations.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from ault_sdk._version import SDK_VERSION
11
+
12
+ # Core
13
+ from ault_sdk.agent import (
14
+ AGENT_DEFAULTS,
15
+ AgentClient,
16
+ AgentClientOptions,
17
+ AgentKeyMaterial,
18
+ AgentSignAndBroadcastParams,
19
+ compute_agent_key_material,
20
+ create_agent_client,
21
+ sign_and_broadcast_agent_tx,
22
+ )
23
+ from ault_sdk.client import AultClient, create_ault_client
24
+ from ault_sdk.core.base64 import base64_to_bytes, bytes_to_base64
25
+ from ault_sdk.core.errors import (
26
+ ApiError,
27
+ AultError,
28
+ NetworkError,
29
+ TimeoutError,
30
+ WebSocketError,
31
+ )
32
+ from ault_sdk.core.http import (
33
+ FetchOptions,
34
+ HttpContext,
35
+ fetch_json,
36
+ fetch_with_retry,
37
+ post_json,
38
+ )
39
+ from ault_sdk.core.network import (
40
+ DEFAULT_CHAIN_ID,
41
+ GAS_CONSTANTS,
42
+ NETWORKS,
43
+ TIMING_CONSTANTS,
44
+ NetworkConfig,
45
+ compute_fee_free_gas,
46
+ compute_fee_free_gas_compound,
47
+ get_network_config,
48
+ )
49
+ from ault_sdk.core.pagination import PaginationResult, paginate_all
50
+ from ault_sdk.eip712.builder import (
51
+ Eip712Msg,
52
+ Eip712TxContext,
53
+ build_eip712_amino_msg,
54
+ build_eip712_amino_sign_doc,
55
+ build_eip712_typed_data,
56
+ )
57
+ from ault_sdk.eip712.msg_encoders_generated import MSG_ENCODERS
58
+ from ault_sdk.eip712.msg_generated import msg
59
+ from ault_sdk.eip712.registry import EIP712_MSG_TYPES, Eip712MsgTypeConfig, FieldSemantics
60
+ from ault_sdk.eip712.sign_and_broadcast import (
61
+ AccountCache,
62
+ BroadcastResult,
63
+ SignAndBroadcastParams,
64
+ create_account_cache,
65
+ query_account,
66
+ sign_and_broadcast_eip712,
67
+ )
68
+ from ault_sdk.eip712.signers import (
69
+ Eip1193Signer,
70
+ PrivateKeySigner,
71
+ SignerInput,
72
+ TypedDataSigner,
73
+ normalize_signer,
74
+ resolve_signer_address,
75
+ )
76
+ from ault_sdk.eip712.types import Eip712TypedData
77
+ from ault_sdk.evm import (
78
+ BANK_DECIMALS,
79
+ BridgeParams,
80
+ CreateEvmClientOptions,
81
+ Erc20Metadata,
82
+ Erc20Reader,
83
+ Erc20TransferParams,
84
+ Erc20Writer,
85
+ EvmClient,
86
+ TokenBridge,
87
+ TokenInfo,
88
+ TokenRegistryEvm,
89
+ create_erc20_reader,
90
+ create_erc20_writer,
91
+ create_evm_client,
92
+ create_token_bridge,
93
+ create_token_registry_evm,
94
+ format_bank_amount,
95
+ format_token_units,
96
+ parse_bank_amount,
97
+ parse_token_units,
98
+ )
99
+ from ault_sdk.high_level import Client, ClientOptions, create_client
100
+ from ault_sdk.utils.address import (
101
+ ault_to_evm,
102
+ evm_to_ault,
103
+ is_valid_ault_address,
104
+ is_valid_evm_address,
105
+ resolve_address_to_bech32,
106
+ resolve_address_to_evm,
107
+ )
108
+ from ault_sdk.utils.chain_id import parse_evm_chain_id_from_cosmos_chain_id
109
+ from ault_sdk.utils.cosmos_dec import cosmos_dec_to_decimal_string, cosmos_dec_to_proto_int
110
+ from ault_sdk.ws import DexWsClient, DexWsOptions, SubscriptionHandlers, create_dex_ws
111
+
112
+ __all__ = [
113
+ "AGENT_DEFAULTS",
114
+ "BANK_DECIMALS",
115
+ "DEFAULT_CHAIN_ID",
116
+ "EIP712_MSG_TYPES",
117
+ "GAS_CONSTANTS",
118
+ "MSG_ENCODERS",
119
+ "NETWORKS",
120
+ "SDK_VERSION",
121
+ "TIMING_CONSTANTS",
122
+ "AccountCache",
123
+ "AgentClient",
124
+ "AgentClientOptions",
125
+ "AgentKeyMaterial",
126
+ "AgentSignAndBroadcastParams",
127
+ "ApiError",
128
+ "AultClient",
129
+ "AultError",
130
+ "BridgeParams",
131
+ "BroadcastResult",
132
+ "Client",
133
+ "ClientOptions",
134
+ "CreateEvmClientOptions",
135
+ "DexWsClient",
136
+ "DexWsOptions",
137
+ "Eip712Msg",
138
+ "Eip712MsgTypeConfig",
139
+ "Eip712TxContext",
140
+ "Eip712TypedData",
141
+ "Eip1193Signer",
142
+ "Erc20Metadata",
143
+ "Erc20Reader",
144
+ "Erc20TransferParams",
145
+ "Erc20Writer",
146
+ "EvmClient",
147
+ "FetchOptions",
148
+ "FieldSemantics",
149
+ "HttpContext",
150
+ "NetworkConfig",
151
+ "NetworkError",
152
+ "PaginationResult",
153
+ "PrivateKeySigner",
154
+ "SignAndBroadcastParams",
155
+ "SignerInput",
156
+ "SubscriptionHandlers",
157
+ "TimeoutError",
158
+ "TokenBridge",
159
+ "TokenInfo",
160
+ "TokenRegistryEvm",
161
+ "TypedDataSigner",
162
+ "WebSocketError",
163
+ "ault_to_evm",
164
+ "base64_to_bytes",
165
+ "build_eip712_amino_msg",
166
+ "build_eip712_amino_sign_doc",
167
+ "build_eip712_typed_data",
168
+ "bytes_to_base64",
169
+ "compute_agent_key_material",
170
+ "compute_fee_free_gas",
171
+ "compute_fee_free_gas_compound",
172
+ "cosmos_dec_to_decimal_string",
173
+ "cosmos_dec_to_proto_int",
174
+ "create_account_cache",
175
+ "create_agent_client",
176
+ "create_ault_client",
177
+ "create_client",
178
+ "create_dex_ws",
179
+ "create_erc20_reader",
180
+ "create_erc20_writer",
181
+ "create_evm_client",
182
+ "create_token_bridge",
183
+ "create_token_registry_evm",
184
+ "evm_to_ault",
185
+ "fetch_json",
186
+ "fetch_with_retry",
187
+ "format_bank_amount",
188
+ "format_token_units",
189
+ "get_network_config",
190
+ "is_valid_ault_address",
191
+ "is_valid_evm_address",
192
+ "msg",
193
+ "normalize_signer",
194
+ "paginate_all",
195
+ "parse_bank_amount",
196
+ "parse_evm_chain_id_from_cosmos_chain_id",
197
+ "parse_token_units",
198
+ "post_json",
199
+ "query_account",
200
+ "resolve_address_to_bech32",
201
+ "resolve_address_to_evm",
202
+ "resolve_signer_address",
203
+ "sign_and_broadcast_agent_tx",
204
+ "sign_and_broadcast_eip712",
205
+ ]
ault_sdk/_version.py ADDED
@@ -0,0 +1,9 @@
1
+ """Single source of truth for the SDK version string.
2
+
3
+ Kept separate from ``__init__.py`` so codegen scripts and build tooling can
4
+ read the version without importing the full package.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ SDK_VERSION: str = "0.0.1a0"
@@ -0,0 +1,31 @@
1
+ """Agent client + agent-specific tx signing. Mirrors ``src/agent``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ault_sdk.agent.create_agent_client import AgentClient, AgentClientOptions, create_agent_client
6
+ from ault_sdk.agent.sign_and_broadcast import (
7
+ AGENT_DEFAULTS,
8
+ AgentKeyMaterial,
9
+ AgentSignAndBroadcastParams,
10
+ compute_agent_key_material,
11
+ sign_and_broadcast_agent_tx,
12
+ )
13
+ from ault_sdk.agent.tx_executor import (
14
+ AgentTxExecutor,
15
+ AgentTxExecutorOptions,
16
+ create_agent_tx_executor,
17
+ )
18
+
19
+ __all__ = [
20
+ "AGENT_DEFAULTS",
21
+ "AgentClient",
22
+ "AgentClientOptions",
23
+ "AgentKeyMaterial",
24
+ "AgentSignAndBroadcastParams",
25
+ "AgentTxExecutor",
26
+ "AgentTxExecutorOptions",
27
+ "compute_agent_key_material",
28
+ "create_agent_client",
29
+ "create_agent_tx_executor",
30
+ "sign_and_broadcast_agent_tx",
31
+ ]
@@ -0,0 +1,172 @@
1
+ """Agent client factory."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any
7
+
8
+ import httpx
9
+ from eth_keys import keys
10
+ from eth_utils import keccak, to_checksum_address
11
+
12
+ from ault_sdk.agent.tx_executor import (
13
+ AgentTxExecutor,
14
+ AgentTxExecutorOptions,
15
+ AgentTxOptions,
16
+ create_agent_tx_executor,
17
+ )
18
+ from ault_sdk.client import AultClient, create_ault_client
19
+ from ault_sdk.core.address import normalize_address
20
+ from ault_sdk.core.clob_msgs import (
21
+ build_cancel_orders_msg,
22
+ build_limit_order_msg,
23
+ build_market_order_msg,
24
+ build_scale_order_msg,
25
+ )
26
+ from ault_sdk.core.http import FetchOptions
27
+ from ault_sdk.core.network import (
28
+ GAS_CONSTANTS,
29
+ NetworkConfig,
30
+ compute_fee_free_gas,
31
+ compute_fee_free_gas_compound,
32
+ )
33
+ from ault_sdk.high_level.tx_executor import TxResult
34
+ from ault_sdk.utils.address import evm_to_ault
35
+
36
+
37
+ def _derive_agent_address(agent_private_key: str) -> str:
38
+ """Derive the bech32 address from a secp256k1 private key."""
39
+
40
+ normalized = (
41
+ agent_private_key[2:] if agent_private_key.startswith(("0x", "0X")) else agent_private_key
42
+ )
43
+ private_key = keys.PrivateKey(bytes.fromhex(normalized))
44
+ uncompressed = private_key.public_key.to_bytes() # 64 bytes (x || y)
45
+ evm_address = "0x" + keccak(uncompressed)[-20:].hex()
46
+ return evm_to_ault(to_checksum_address(evm_address))
47
+
48
+
49
+ @dataclass(slots=True)
50
+ class AgentClientOptions:
51
+ network: NetworkConfig
52
+ master_address: str
53
+ agent_private_key: str
54
+ client: httpx.AsyncClient | None = None
55
+ fetch_options: FetchOptions | None = None
56
+ default_gas_limit: str | None = None
57
+ default_memo: str = ""
58
+ default_confirmation_timeout_ms: int | None = None
59
+ default_timeout_seconds: int | None = None
60
+
61
+
62
+ class AgentClient:
63
+ __slots__ = (
64
+ "_exec",
65
+ "_low_level",
66
+ "agent",
67
+ "agent_address",
68
+ "clob",
69
+ "market",
70
+ "master_address",
71
+ "network",
72
+ )
73
+
74
+ def __init__(
75
+ self,
76
+ *,
77
+ low_level: AultClient,
78
+ master_address: str,
79
+ agent_address: str,
80
+ exec_: AgentTxExecutor,
81
+ ) -> None:
82
+ self.network = low_level.network
83
+ self.master_address = master_address
84
+ self.agent_address = agent_address
85
+ self._low_level = low_level
86
+ self._exec = exec_
87
+ self.agent = low_level.rest.agent
88
+ self.clob = low_level.rest.clob
89
+ self.market = low_level.rest.market
90
+
91
+ async def place_limit_order(self, **params: Any) -> TxResult:
92
+ gas = params.pop("gas_limit", None) or compute_fee_free_gas(GAS_CONSTANTS.LIMIT_ORDER, 1)
93
+ opts = AgentTxOptions(
94
+ gas_limit=gas,
95
+ memo=params.pop("memo", None),
96
+ confirmation_timeout_ms=params.pop("confirmation_timeout_ms", None),
97
+ timeout_seconds=params.pop("timeout_seconds", None),
98
+ )
99
+ return await self._exec([build_limit_order_msg(self.master_address, params)], opts)
100
+
101
+ async def place_market_order(self, **params: Any) -> TxResult:
102
+ gas = params.pop("gas_limit", None) or compute_fee_free_gas(GAS_CONSTANTS.MARKET_ORDER, 1)
103
+ opts = AgentTxOptions(
104
+ gas_limit=gas,
105
+ memo=params.pop("memo", None),
106
+ confirmation_timeout_ms=params.pop("confirmation_timeout_ms", None),
107
+ timeout_seconds=params.pop("timeout_seconds", None),
108
+ )
109
+ return await self._exec([build_market_order_msg(self.master_address, params)], opts)
110
+
111
+ async def cancel_orders(self, *, order_ids: list[bytes], **opts: Any) -> TxResult:
112
+ gas = opts.pop("gas_limit", None) or compute_fee_free_gas_compound(
113
+ GAS_CONSTANTS.CANCEL_ORDER_BASE,
114
+ GAS_CONSTANTS.CANCEL_ORDER_PER_ID,
115
+ len(order_ids),
116
+ )
117
+ agent_opts = AgentTxOptions(
118
+ gas_limit=gas,
119
+ memo=opts.pop("memo", None),
120
+ confirmation_timeout_ms=opts.pop("confirmation_timeout_ms", None),
121
+ timeout_seconds=opts.pop("timeout_seconds", None),
122
+ )
123
+ return await self._exec(
124
+ [build_cancel_orders_msg(self.master_address, order_ids)], agent_opts
125
+ )
126
+
127
+ async def place_scale_order(self, **params: Any) -> TxResult:
128
+ weights = params.get("weights", [])
129
+ gas = params.pop("gas_limit", None) or compute_fee_free_gas_compound(
130
+ GAS_CONSTANTS.SCALE_ORDER_BASE,
131
+ GAS_CONSTANTS.SCALE_ORDER_PER_SUB,
132
+ len(weights),
133
+ )
134
+ opts = AgentTxOptions(
135
+ gas_limit=gas,
136
+ memo=params.pop("memo", None),
137
+ confirmation_timeout_ms=params.pop("confirmation_timeout_ms", None),
138
+ timeout_seconds=params.pop("timeout_seconds", None),
139
+ )
140
+ return await self._exec([build_scale_order_msg(self.master_address, params)], opts)
141
+
142
+
143
+ async def create_agent_client(options: AgentClientOptions) -> AgentClient:
144
+ master_address = normalize_address(options.master_address)
145
+ agent_address = _derive_agent_address(options.agent_private_key)
146
+ low_level = create_ault_client(
147
+ network=options.network,
148
+ client=options.client,
149
+ options=options.fetch_options,
150
+ )
151
+ exec_ = create_agent_tx_executor(
152
+ AgentTxExecutorOptions(
153
+ network=options.network,
154
+ agent_private_key=options.agent_private_key,
155
+ master_address=master_address,
156
+ client=options.client,
157
+ fetch_options=options.fetch_options,
158
+ default_gas_limit=options.default_gas_limit,
159
+ default_memo=options.default_memo,
160
+ default_confirmation_timeout_ms=options.default_confirmation_timeout_ms,
161
+ default_timeout_seconds=options.default_timeout_seconds,
162
+ )
163
+ )
164
+ return AgentClient(
165
+ low_level=low_level,
166
+ master_address=master_address,
167
+ agent_address=agent_address,
168
+ exec_=exec_,
169
+ )
170
+
171
+
172
+ __all__ = ["AgentClient", "AgentClientOptions", "create_agent_client"]
@@ -0,0 +1,237 @@
1
+ """Agent transaction signing (SIGN_MODE_DIRECT + agent extension option).
2
+
3
+ Mirrors ``src/agent/sign-and-broadcast.ts``. Agent txs carry a
4
+ ``tokenregistry.v1.ExtensionOptionsAgentTx`` and are signed with raw
5
+ secp256k1 over the keccak256 of the SignDoc.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import time
11
+ from collections.abc import Sequence
12
+ from dataclasses import dataclass
13
+ from typing import Any
14
+
15
+ import httpx
16
+ from eth_keys import keys
17
+ from eth_utils import keccak
18
+
19
+ from ault_sdk.core.base64 import bytes_to_base64
20
+ from ault_sdk.core.http import FetchOptions, post_json
21
+ from ault_sdk.core.network import NetworkConfig
22
+ from ault_sdk.eip712.builder import Eip712Msg
23
+ from ault_sdk.eip712.msg_encoders_generated import MSG_ENCODERS
24
+ from ault_sdk.eip712.sign_and_broadcast import (
25
+ AccountCache,
26
+ BroadcastResult,
27
+ poll_tx_inclusion,
28
+ query_account,
29
+ )
30
+ from ault_sdk.proto.tx_encode import (
31
+ SIGN_MODE_DIRECT,
32
+ AgentTxBody,
33
+ AnyMsg,
34
+ AuthInfo,
35
+ SignDoc,
36
+ SignerInfo,
37
+ TimeoutTimestamp,
38
+ TxFee,
39
+ TxRaw,
40
+ encode_auth_info,
41
+ encode_eth_secp256k1_pubkey,
42
+ encode_sign_doc,
43
+ encode_tx_body_agent,
44
+ encode_tx_raw,
45
+ )
46
+
47
+
48
+ @dataclass(frozen=True, slots=True)
49
+ class _AgentDefaults:
50
+ GAS_LIMIT: str = "147600"
51
+ TIMEOUT_SECONDS: int = 300
52
+ EXTENSION_TYPE_URL: str = "/ault.agent.v1.ExtensionOptionsAgentTx"
53
+ PUBKEY_TYPE_URL: str = "/cosmos.evm.crypto.v1.ethsecp256k1.PubKey"
54
+
55
+
56
+ AGENT_DEFAULTS = _AgentDefaults()
57
+
58
+
59
+ @dataclass(slots=True)
60
+ class AgentKeyMaterial:
61
+ priv_key_bytes: bytes
62
+ compressed_pubkey: bytes
63
+
64
+
65
+ def compute_agent_key_material(agent_private_key: str) -> AgentKeyMaterial:
66
+ normalized = (
67
+ agent_private_key[2:] if agent_private_key.startswith(("0x", "0X")) else agent_private_key
68
+ )
69
+ priv = bytes.fromhex(normalized)
70
+ private_key = keys.PrivateKey(priv)
71
+ return AgentKeyMaterial(
72
+ priv_key_bytes=priv,
73
+ compressed_pubkey=private_key.public_key.to_compressed_bytes(),
74
+ )
75
+
76
+
77
+ @dataclass(slots=True)
78
+ class AgentSignAndBroadcastParams:
79
+ network: NetworkConfig
80
+ key_material: AgentKeyMaterial
81
+ master_address: str
82
+ msgs: Sequence[Eip712Msg]
83
+ memo: str = ""
84
+ gas_limit: str | None = None
85
+ confirmation_timeout_ms: int | None = None
86
+ timeout_seconds: int | None = None
87
+ timeout_timestamp: TimeoutTimestamp | None = None
88
+ client: httpx.AsyncClient | None = None
89
+ fetch_options: FetchOptions | None = None
90
+ cache: AccountCache | None = None
91
+
92
+
93
+ def _compute_timeout_timestamp(timeout_seconds: int) -> TimeoutTimestamp:
94
+ now_ms = int(time.time() * 1000)
95
+ deadline_ms = now_ms + timeout_seconds * 1000
96
+ return TimeoutTimestamp(
97
+ seconds=deadline_ms // 1000,
98
+ nanos=(deadline_ms % 1000) * 1_000_000,
99
+ )
100
+
101
+
102
+ async def sign_and_broadcast_agent_tx(
103
+ params: AgentSignAndBroadcastParams,
104
+ ) -> BroadcastResult:
105
+ key_material = params.key_material
106
+ cache = params.cache
107
+
108
+ # Agent txs use master's accountNumber + sequence=0; we only need
109
+ # accountNumber which we can cache.
110
+ if cache is not None and cache.account_number is not None:
111
+ account_number = cache.account_number
112
+ else:
113
+ info = await query_account(
114
+ params.network,
115
+ params.master_address,
116
+ client=params.client,
117
+ fetch_options=params.fetch_options,
118
+ )
119
+ account_number = info.account_number
120
+ if cache is not None:
121
+ cache.account_number = account_number
122
+
123
+ gas_limit = params.gas_limit or AGENT_DEFAULTS.GAS_LIMIT
124
+ timeout_seconds = (
125
+ params.timeout_seconds
126
+ if params.timeout_seconds is not None
127
+ else AGENT_DEFAULTS.TIMEOUT_SECONDS
128
+ )
129
+ timeout_ts = params.timeout_timestamp or _compute_timeout_timestamp(timeout_seconds)
130
+
131
+ encoded_messages: list[AnyMsg] = []
132
+ for m in params.msgs:
133
+ encoder = MSG_ENCODERS.get(m.type_url)
134
+ if encoder is None:
135
+ raise ValueError(f"No encoder found for message type: {m.type_url}")
136
+ encoded_messages.append(AnyMsg(type_url=m.type_url, value=encoder(m.value)))
137
+
138
+ body_bytes = encode_tx_body_agent(
139
+ AgentTxBody(
140
+ messages=encoded_messages,
141
+ memo=params.memo,
142
+ unordered=True,
143
+ timeout_timestamp=timeout_ts,
144
+ extension_options=[
145
+ AnyMsg(type_url=AGENT_DEFAULTS.EXTENSION_TYPE_URL, value=b""),
146
+ ],
147
+ )
148
+ )
149
+
150
+ pubkey_proto = encode_eth_secp256k1_pubkey(key_material.compressed_pubkey)
151
+ auth_info_bytes = encode_auth_info(
152
+ AuthInfo(
153
+ signer_infos=[
154
+ SignerInfo(
155
+ public_key=AnyMsg(type_url=AGENT_DEFAULTS.PUBKEY_TYPE_URL, value=pubkey_proto),
156
+ mode=SIGN_MODE_DIRECT,
157
+ sequence=0,
158
+ )
159
+ ],
160
+ fee=TxFee(amount=[], gas_limit=int(gas_limit)),
161
+ )
162
+ )
163
+
164
+ sign_doc_bytes = encode_sign_doc(
165
+ SignDoc(
166
+ body_bytes=body_bytes,
167
+ auth_info_bytes=auth_info_bytes,
168
+ chain_id=params.network.chain_id,
169
+ account_number=int(account_number),
170
+ )
171
+ )
172
+
173
+ msg_hash = keccak(sign_doc_bytes)
174
+ private_key = keys.PrivateKey(key_material.priv_key_bytes)
175
+ signature = private_key.sign_msg_hash(msg_hash)
176
+ signature_bytes = signature.to_bytes()[:64]
177
+
178
+ tx_raw_bytes = encode_tx_raw(
179
+ TxRaw(
180
+ body_bytes=body_bytes,
181
+ auth_info_bytes=auth_info_bytes,
182
+ signatures=[signature_bytes],
183
+ )
184
+ )
185
+ tx_bytes_b64 = bytes_to_base64(tx_raw_bytes)
186
+
187
+ # Agent txs are unordered (line above sets `unordered=True`), so any
188
+ # successfully delivered duplicate broadcast becomes a duplicate
189
+ # on-chain action. Force `retries=0` here, matching the EIP-712
190
+ # broadcast path (eip712/sign_and_broadcast.py:419).
191
+ result = await post_json(
192
+ f"{params.network.rest_url}/cosmos/tx/v1beta1/txs",
193
+ {"tx_bytes": tx_bytes_b64, "mode": "BROADCAST_MODE_SYNC"},
194
+ options=FetchOptions(retries=0),
195
+ client=params.client,
196
+ )
197
+ tx_response: dict[str, Any] = (result or {}).get("tx_response") or {}
198
+ tx_hash = str(tx_response.get("txhash", ""))
199
+ check_code = int(tx_response.get("code", 0))
200
+
201
+ if check_code != 0:
202
+ return BroadcastResult(
203
+ tx_hash=tx_hash,
204
+ code=check_code,
205
+ raw_log=tx_response.get("raw_log"),
206
+ confirmed=True,
207
+ )
208
+
209
+ deliver = await poll_tx_inclusion(
210
+ params.network,
211
+ tx_hash,
212
+ client=params.client,
213
+ fetch_options=params.fetch_options,
214
+ timeout_ms=params.confirmation_timeout_ms,
215
+ )
216
+ if deliver.confirmed is None:
217
+ return BroadcastResult(
218
+ tx_hash=tx_hash,
219
+ code=check_code,
220
+ raw_log=deliver.raw_log or tx_response.get("raw_log"),
221
+ confirmed=None,
222
+ )
223
+ return BroadcastResult(
224
+ tx_hash=tx_hash,
225
+ code=deliver.code,
226
+ raw_log=deliver.raw_log,
227
+ confirmed=deliver.confirmed,
228
+ )
229
+
230
+
231
+ __all__ = [
232
+ "AGENT_DEFAULTS",
233
+ "AgentKeyMaterial",
234
+ "AgentSignAndBroadcastParams",
235
+ "compute_agent_key_material",
236
+ "sign_and_broadcast_agent_tx",
237
+ ]