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.
- ault_sdk/__init__.py +205 -0
- ault_sdk/_version.py +9 -0
- ault_sdk/agent/__init__.py +31 -0
- ault_sdk/agent/create_agent_client.py +172 -0
- ault_sdk/agent/sign_and_broadcast.py +237 -0
- ault_sdk/agent/tx_executor.py +94 -0
- ault_sdk/client.py +131 -0
- ault_sdk/core/__init__.py +0 -0
- ault_sdk/core/address.py +42 -0
- ault_sdk/core/base64.py +24 -0
- ault_sdk/core/clob_msgs.py +77 -0
- ault_sdk/core/errors.py +86 -0
- ault_sdk/core/http.py +267 -0
- ault_sdk/core/network.py +204 -0
- ault_sdk/core/pagination.py +91 -0
- ault_sdk/core/query.py +31 -0
- ault_sdk/core/with_status_fallback.py +35 -0
- ault_sdk/eip712/__init__.py +0 -0
- ault_sdk/eip712/builder.py +723 -0
- ault_sdk/eip712/field_order.py +81 -0
- ault_sdk/eip712/msg_encoders_generated.py +257 -0
- ault_sdk/eip712/msg_generated.py +300 -0
- ault_sdk/eip712/registry.py +53 -0
- ault_sdk/eip712/registry_generated.py +1189 -0
- ault_sdk/eip712/sign_and_broadcast.py +487 -0
- ault_sdk/eip712/signers.py +271 -0
- ault_sdk/eip712/types.py +84 -0
- ault_sdk/evm/__init__.py +51 -0
- ault_sdk/evm/_gas.py +22 -0
- ault_sdk/evm/_tx.py +49 -0
- ault_sdk/evm/bridge.py +96 -0
- ault_sdk/evm/client.py +113 -0
- ault_sdk/evm/erc20.py +219 -0
- ault_sdk/evm/precompile.py +38 -0
- ault_sdk/evm/registry.py +132 -0
- ault_sdk/evm/scaling.py +66 -0
- ault_sdk/high_level/__init__.py +7 -0
- ault_sdk/high_level/create_client.py +168 -0
- ault_sdk/high_level/evm_account.py +42 -0
- ault_sdk/high_level/query_helpers.py +109 -0
- ault_sdk/high_level/signer.py +40 -0
- ault_sdk/high_level/tx/__init__.py +39 -0
- ault_sdk/high_level/tx/agent.py +63 -0
- ault_sdk/high_level/tx/authority.py +44 -0
- ault_sdk/high_level/tx/clob.py +90 -0
- ault_sdk/high_level/tx/context.py +16 -0
- ault_sdk/high_level/tx/license.py +151 -0
- ault_sdk/high_level/tx/market.py +87 -0
- ault_sdk/high_level/tx/miner.py +176 -0
- ault_sdk/high_level/tx/ratelimit.py +34 -0
- ault_sdk/high_level/tx/reward.py +95 -0
- ault_sdk/high_level/tx/staking.py +88 -0
- ault_sdk/high_level/tx/tokenregistry.py +79 -0
- ault_sdk/high_level/tx_executor.py +99 -0
- ault_sdk/proto/__init__.py +0 -0
- ault_sdk/proto/duration_json.py +76 -0
- ault_sdk/proto/gen/__init__.py +0 -0
- ault_sdk/proto/gen/amino/__init__.py +8 -0
- ault_sdk/proto/gen/ault/__init__.py +0 -0
- ault_sdk/proto/gen/ault/agent/__init__.py +0 -0
- ault_sdk/proto/gen/ault/agent/v1/__init__.py +553 -0
- ault_sdk/proto/gen/ault/authority/__init__.py +0 -0
- ault_sdk/proto/gen/ault/authority/v1/__init__.py +307 -0
- ault_sdk/proto/gen/ault/clob/__init__.py +0 -0
- ault_sdk/proto/gen/ault/clob/v1/__init__.py +536 -0
- ault_sdk/proto/gen/ault/license/__init__.py +0 -0
- ault_sdk/proto/gen/ault/license/v1/__init__.py +2159 -0
- ault_sdk/proto/gen/ault/market/__init__.py +0 -0
- ault_sdk/proto/gen/ault/market/v1/__init__.py +583 -0
- ault_sdk/proto/gen/ault/miner/__init__.py +0 -0
- ault_sdk/proto/gen/ault/miner/v1/__init__.py +2013 -0
- ault_sdk/proto/gen/ault/ratelimit/__init__.py +0 -0
- ault_sdk/proto/gen/ault/ratelimit/v1/__init__.py +215 -0
- ault_sdk/proto/gen/ault/reward/__init__.py +0 -0
- ault_sdk/proto/gen/ault/reward/v1/__init__.py +871 -0
- ault_sdk/proto/gen/ault/spot/__init__.py +0 -0
- ault_sdk/proto/gen/ault/spot/v1/__init__.py +69 -0
- ault_sdk/proto/gen/ault/tokenregistry/__init__.py +0 -0
- ault_sdk/proto/gen/ault/tokenregistry/v1/__init__.py +872 -0
- ault_sdk/proto/gen/cosmos/__init__.py +0 -0
- ault_sdk/proto/gen/cosmos/base/__init__.py +0 -0
- ault_sdk/proto/gen/cosmos/base/query/__init__.py +0 -0
- ault_sdk/proto/gen/cosmos/base/query/v1beta1/__init__.py +80 -0
- ault_sdk/proto/gen/cosmos/base/v1beta1/__init__.py +54 -0
- ault_sdk/proto/gen/cosmos/distribution/__init__.py +0 -0
- ault_sdk/proto/gen/cosmos/distribution/v1beta1/__init__.py +620 -0
- ault_sdk/proto/gen/cosmos/msg/__init__.py +0 -0
- ault_sdk/proto/gen/cosmos/msg/v1/__init__.py +8 -0
- ault_sdk/proto/gen/cosmos/staking/__init__.py +0 -0
- ault_sdk/proto/gen/cosmos/staking/v1beta1/__init__.py +888 -0
- ault_sdk/proto/gen/cosmos_proto/__init__.py +73 -0
- ault_sdk/proto/gen/gogoproto/__init__.py +8 -0
- ault_sdk/proto/gen/google/__init__.py +0 -0
- ault_sdk/proto/gen/google/api/__init__.py +387 -0
- ault_sdk/proto/gen/tendermint/__init__.py +0 -0
- ault_sdk/proto/gen/tendermint/abci/__init__.py +1262 -0
- ault_sdk/proto/gen/tendermint/crypto/__init__.py +61 -0
- ault_sdk/proto/gen/tendermint/types/__init__.py +359 -0
- ault_sdk/proto/gen/tendermint/version/__init__.py +32 -0
- ault_sdk/proto/tx_encode.py +355 -0
- ault_sdk/rest/__init__.py +0 -0
- ault_sdk/rest/agent.py +46 -0
- ault_sdk/rest/authority.py +53 -0
- ault_sdk/rest/bank.py +69 -0
- ault_sdk/rest/clob.py +49 -0
- ault_sdk/rest/context.py +134 -0
- ault_sdk/rest/dex.py +176 -0
- ault_sdk/rest/dex_generated/__init__.py +8 -0
- ault_sdk/rest/dex_generated/api/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/balance/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/balance/get_balance.py +187 -0
- ault_sdk/rest/dex_generated/api/currencies/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/currencies/list_currencies.py +146 -0
- ault_sdk/rest/dex_generated/api/fees/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/fees/get_trading_fees.py +146 -0
- ault_sdk/rest/dex_generated/api/health/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/health/get_health.py +137 -0
- ault_sdk/rest/dex_generated/api/health/get_live.py +133 -0
- ault_sdk/rest/dex_generated/api/health/get_open_api_spec.py +127 -0
- ault_sdk/rest/dex_generated/api/health/get_ready.py +138 -0
- ault_sdk/rest/dex_generated/api/markets/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/markets/list_markets.py +151 -0
- ault_sdk/rest/dex_generated/api/my_trades/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/my_trades/list_my_trades.py +241 -0
- ault_sdk/rest/dex_generated/api/ohlcv/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/ohlcv/get_ohlcv.py +225 -0
- ault_sdk/rest/dex_generated/api/orderbook/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/orderbook/get_orderbook.py +191 -0
- ault_sdk/rest/dex_generated/api/orders/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/orders/get_order.py +183 -0
- ault_sdk/rest/dex_generated/api/orders/list_orders.py +260 -0
- ault_sdk/rest/dex_generated/api/status/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/status/get_status.py +138 -0
- ault_sdk/rest/dex_generated/api/ticker/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/ticker/get_all_tickers.py +138 -0
- ault_sdk/rest/dex_generated/api/ticker/get_ticker.py +170 -0
- ault_sdk/rest/dex_generated/api/trades/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/trades/list_trades.py +211 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/__init__.py +1 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_config.py +133 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_history.py +245 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_marks.py +231 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_quotes.py +183 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_symbol.py +175 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_time.py +131 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/get_udf_timescale_marks.py +236 -0
- ault_sdk/rest/dex_generated/api/trading_view_udf/search_udf_symbols.py +223 -0
- ault_sdk/rest/dex_generated/client.py +272 -0
- ault_sdk/rest/dex_generated/errors.py +16 -0
- ault_sdk/rest/dex_generated/models/__init__.py +135 -0
- ault_sdk/rest/dex_generated/models/balances_response.py +142 -0
- ault_sdk/rest/dex_generated/models/balances_response_free.py +46 -0
- ault_sdk/rest/dex_generated/models/balances_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/balances_response_total.py +46 -0
- ault_sdk/rest/dex_generated/models/balances_response_used.py +46 -0
- ault_sdk/rest/dex_generated/models/currency_response.py +209 -0
- ault_sdk/rest/dex_generated/models/currency_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/currency_response_limits.py +90 -0
- ault_sdk/rest/dex_generated/models/currency_response_networks.py +46 -0
- ault_sdk/rest/dex_generated/models/error_response.py +67 -0
- ault_sdk/rest/dex_generated/models/error_response_error.py +69 -0
- ault_sdk/rest/dex_generated/models/get_all_tickers_response_200.py +59 -0
- ault_sdk/rest/dex_generated/models/get_trading_fees_response_200.py +59 -0
- ault_sdk/rest/dex_generated/models/get_udf_history_resolution.py +15 -0
- ault_sdk/rest/dex_generated/models/health_response.py +72 -0
- ault_sdk/rest/dex_generated/models/health_response_database.py +9 -0
- ault_sdk/rest/dex_generated/models/health_response_status.py +9 -0
- ault_sdk/rest/dex_generated/models/list_currencies_response_200.py +59 -0
- ault_sdk/rest/dex_generated/models/list_orders_status.py +10 -0
- ault_sdk/rest/dex_generated/models/live_response.py +63 -0
- ault_sdk/rest/dex_generated/models/live_response_status.py +8 -0
- ault_sdk/rest/dex_generated/models/market_limits.py +122 -0
- ault_sdk/rest/dex_generated/models/market_precision.py +79 -0
- ault_sdk/rest/dex_generated/models/market_response.py +450 -0
- ault_sdk/rest/dex_generated/models/market_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/market_response_type.py +8 -0
- ault_sdk/rest/dex_generated/models/min_max.py +93 -0
- ault_sdk/rest/dex_generated/models/order_response.py +350 -0
- ault_sdk/rest/dex_generated/models/order_response_fee.py +80 -0
- ault_sdk/rest/dex_generated/models/order_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/order_response_side.py +9 -0
- ault_sdk/rest/dex_generated/models/order_response_status.py +10 -0
- ault_sdk/rest/dex_generated/models/order_response_trades_item.py +46 -0
- ault_sdk/rest/dex_generated/models/order_response_type.py +9 -0
- ault_sdk/rest/dex_generated/models/orderbook_response.py +121 -0
- ault_sdk/rest/dex_generated/models/ready_response.py +63 -0
- ault_sdk/rest/dex_generated/models/ready_response_status.py +9 -0
- ault_sdk/rest/dex_generated/models/status_response.py +71 -0
- ault_sdk/rest/dex_generated/models/ticker_response.py +403 -0
- ault_sdk/rest/dex_generated/models/ticker_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/trade_response.py +267 -0
- ault_sdk/rest/dex_generated/models/trade_response_fee.py +80 -0
- ault_sdk/rest/dex_generated/models/trade_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/trade_response_side.py +9 -0
- ault_sdk/rest/dex_generated/models/trade_response_taker_or_maker.py +8 -0
- ault_sdk/rest/dex_generated/models/trade_response_type_type_1.py +9 -0
- ault_sdk/rest/dex_generated/models/trade_response_type_type_2_type_1.py +9 -0
- ault_sdk/rest/dex_generated/models/trade_response_type_type_3_type_1.py +9 -0
- ault_sdk/rest/dex_generated/models/trading_fee_response.py +107 -0
- ault_sdk/rest/dex_generated/models/trading_fee_response_info.py +46 -0
- ault_sdk/rest/dex_generated/models/udf_config.py +141 -0
- ault_sdk/rest/dex_generated/models/udf_exchange.py +77 -0
- ault_sdk/rest/dex_generated/models/udf_history_response.py +148 -0
- ault_sdk/rest/dex_generated/models/udf_history_response_s.py +10 -0
- ault_sdk/rest/dex_generated/models/udf_marks_response.py +109 -0
- ault_sdk/rest/dex_generated/models/udf_quote_data.py +85 -0
- ault_sdk/rest/dex_generated/models/udf_quote_data_s.py +9 -0
- ault_sdk/rest/dex_generated/models/udf_quote_values.py +280 -0
- ault_sdk/rest/dex_generated/models/udf_quotes_response.py +95 -0
- ault_sdk/rest/dex_generated/models/udf_quotes_response_s.py +9 -0
- ault_sdk/rest/dex_generated/models/udf_search_result.py +101 -0
- ault_sdk/rest/dex_generated/models/udf_symbol_info.py +191 -0
- ault_sdk/rest/dex_generated/models/udf_symbol_info_data_status.py +11 -0
- ault_sdk/rest/dex_generated/models/udf_symbol_type.py +69 -0
- ault_sdk/rest/dex_generated/models/udf_timescale_mark.py +93 -0
- ault_sdk/rest/dex_generated/types.py +54 -0
- ault_sdk/rest/license.py +107 -0
- ault_sdk/rest/market.py +42 -0
- ault_sdk/rest/miner.py +111 -0
- ault_sdk/rest/ratelimit.py +26 -0
- ault_sdk/rest/reward.py +61 -0
- ault_sdk/rest/staking.py +70 -0
- ault_sdk/rest/tokenregistry.py +35 -0
- ault_sdk/utils/__init__.py +0 -0
- ault_sdk/utils/address.py +125 -0
- ault_sdk/utils/chain_id.py +22 -0
- ault_sdk/utils/cosmos_dec.py +95 -0
- ault_sdk/ws/__init__.py +24 -0
- ault_sdk/ws/client.py +378 -0
- ault_sdk/ws/types.py +76 -0
- ault_sdk-0.0.1a1.dist-info/METADATA +702 -0
- ault_sdk-0.0.1a1.dist-info/RECORD +233 -0
- 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
|
+
]
|