@@ -4,10 +4,10 @@ Python SDK for interacting with [Mina Protocol](https://minaprotocol.com) nodes.
44
55## Features
66
7- - ** Daemon GraphQL client** — query node status, accounts, blocks; send payments and delegations
7+ - ** Daemon GraphQL client** -- query node status, accounts, blocks; send payments and delegations
88- Typed response objects with ` Currency ` arithmetic
99- Automatic retry with configurable backoff
10- - Context manager support
10+ - Context manager support for clean resource management
1111
1212## Installation
1313
@@ -49,34 +49,34 @@ with MinaDaemonClient() as client:
4949``` python
5050client = MinaDaemonClient(
5151 graphql_uri = " http://127.0.0.1:3085/graphql" , # default
52- retries = 3 , # retry failed requests
53- retry_delay = 5.0 , # seconds between retries
54- timeout = 30.0 , # HTTP timeout in seconds
52+ retries = 3 , # retry failed requests (must be >= 1)
53+ retry_delay = 5.0 , # seconds between retries (must be >= 0)
54+ timeout = 30.0 , # HTTP timeout in seconds (must be > 0)
5555)
5656```
5757
5858## API Reference
5959
6060### Queries
6161
62- | Method | Description |
63- | --------| -------------|
64- | ` get_sync_status() ` | Node sync status (SYNCED, BOOTSTRAP, etc.) |
65- | ` get_daemon_status() ` | Comprehensive daemon status |
66- | ` get_network_id() ` | Network identifier |
67- | ` get_account(public_key) ` | Account balance, nonce, delegate |
68- | ` get_best_chain(max_length) ` | Recent blocks from best chain |
69- | ` get_peers() ` | Connected peers |
70- | ` get_pooled_user_commands(public_key) ` | Pending transactions |
62+ | Method | Returns | Description |
63+ | --------| ---------| --------- ----|
64+ | ` get_sync_status() ` | ` str ` | Node sync status (SYNCED, BOOTSTRAP, etc.) |
65+ | ` get_daemon_status() ` | ` DaemonStatus ` | Comprehensive daemon status |
66+ | ` get_network_id() ` | ` str ` | Network identifier |
67+ | ` get_account(public_key) ` | ` AccountData ` | Account balance, nonce, delegate |
68+ | ` get_best_chain(max_length) ` | ` list[BlockInfo] ` | Recent blocks from best chain |
69+ | ` get_peers() ` | ` list[PeerInfo] ` | Connected peers |
70+ | ` get_pooled_user_commands(public_key) ` | ` list[dict] ` | Pending transactions |
7171
7272### Mutations
7373
74- | Method | Description |
75- | --------| -------------|
76- | ` send_payment(sender, receiver, amount, fee) ` | Send a payment |
77- | ` send_delegation(sender, delegate_to, fee) ` | Delegate stake |
78- | ` set_snark_worker(public_key) ` | Set/unset SNARK worker |
79- | ` set_snark_work_fee(fee) ` | Set SNARK work fee |
74+ | Method | Returns | Description |
75+ | --------| ---------| --------- ----|
76+ | ` send_payment(sender, receiver, amount, fee) ` | ` SendPaymentResult ` | Send a payment |
77+ | ` send_delegation(sender, delegate_to, fee) ` | ` SendDelegationResult ` | Delegate stake |
78+ | ` set_snark_worker(public_key) ` | ` str \| None ` | Set/unset SNARK worker |
79+ | ` set_snark_work_fee(fee) ` | ` str ` | Set SNARK work fee |
8080
8181### Currency
8282
@@ -90,6 +90,51 @@ c = Currency.from_nanomina(1_000_000_000) # 1 MINA
9090print (a + b) # 11.500000000
9191print (a.nanomina) # 10000000000
9292print (a > b) # True
93+ print (3 * b) # 4.500000000
94+ ```
95+
96+ ### Error Handling
97+
98+ ``` python
99+ from mina_sdk import MinaDaemonClient, GraphQLError, DaemonConnectionError, CurrencyUnderflow
100+
101+ with MinaDaemonClient(retries = 3 , retry_delay = 2.0 ) as client:
102+ try :
103+ account = client.get_account(" B62q..." )
104+ except ValueError as e:
105+ # Account not found on ledger
106+ print (f " Account does not exist: { e} " )
107+ except GraphQLError as e:
108+ # Daemon returned a GraphQL-level error
109+ print (f " GraphQL error: { e} " )
110+ print (f " Raw errors: { e.errors} " )
111+ except DaemonConnectionError as e:
112+ # All retry attempts exhausted
113+ print (f " Cannot reach daemon after retries: { e} " )
114+
115+ # Currency underflow
116+ from mina_sdk import Currency, CurrencyUnderflow
117+
118+ try :
119+ result = Currency(1 ) - Currency(2 )
120+ except CurrencyUnderflow:
121+ print (" Subtraction would result in negative balance" )
122+ ```
123+
124+ ### Data Types
125+
126+ All response types are importable from the top-level package:
127+
128+ ``` python
129+ from mina_sdk import (
130+ AccountBalance, # total, liquid, locked balances
131+ AccountData, # public_key, nonce, balance, delegate, token_id
132+ BlockInfo, # state_hash, height, slots, creator, tx count
133+ DaemonStatus, # sync_status, chain height, peers, uptime
134+ PeerInfo, # peer_id, host, port
135+ SendPaymentResult, # id, hash, nonce
136+ SendDelegationResult, # id, hash, nonce
137+ )
93138```
94139
95140## Development
@@ -102,6 +147,34 @@ pip install -e ".[dev]"
102147pytest
103148```
104149
150+ ### Running integration tests
151+
152+ Integration tests require a running Mina daemon:
153+
154+ ``` bash
155+ MINA_GRAPHQL_URI=http://127.0.0.1:3085/graphql \
156+ MINA_TEST_SENDER_KEY=B62q... \
157+ MINA_TEST_RECEIVER_KEY=B62q... \
158+ pytest tests/test_integration.py -v
159+ ```
160+
161+ ## Troubleshooting
162+
163+ ** Connection refused / DaemonConnectionError**
164+
165+ The daemon is not running or not reachable at the configured URI. Check:
166+ - Is the daemon running? (` mina client status ` )
167+ - Is the GraphQL port open? (default: 3085)
168+ - Is ` --insecure-rest-server ` set if connecting from a different host?
169+
170+ ** GraphQLError: field not found**
171+
172+ The SDK's queries may be out of sync with the daemon's GraphQL schema. This can happen after a daemon upgrade. Check the [ schema drift CI] ( https://github.com/MinaProtocol/mina-sdk-python/actions/workflows/schema-drift.yml ) for compatibility status.
173+
174+ ** Account not found**
175+
176+ ` get_account() ` raises ` ValueError ` when the account doesn't exist on the ledger. This is normal for new accounts that haven't received any transactions yet.
177+
105178## License
106179
107180Apache License 2.0
0 commit comments