This release is a pre-release and may not be stable for production use.
Mina Python SDK
Python SDK for interacting with Mina Protocol nodes.
Features
- Daemon GraphQL client -- query node status, accounts, blocks; send payments and delegations
- Typed response objects with
Currencyarithmetic - Automatic retry with configurable backoff
- Context manager support for clean resource management
Installation
pip install mina-sdk
For archive database support (coming soon):
pip install mina-sdk[archive]
Quick Start
from mina_sdk import MinaDaemonClient, Currency
with MinaDaemonClient() as client:
# Check sync status
print(client.get_sync_status()) # "SYNCED"
# Query an account
account = client.get_account("B62q...")
print(f"Balance: {account.balance.total} MINA")
# Send a payment
result = client.send_payment(
sender="B62qsender...",
receiver="B62qreceiver...",
amount=Currency("1.5"),
fee=Currency("0.01"),
)
print(f"Tx hash: {result.hash}")
Configuration
client = MinaDaemonClient(
graphql_uri="http://127.0.0.1:3085/graphql", # default
retries=3, # retry failed requests (must be >= 1)
retry_delay=5.0, # seconds between retries (must be >= 0)
timeout=30.0, # HTTP timeout in seconds (must be > 0)
)
API Reference
The Mina SDKs have the same API, defined in
mina-sdk-spec. spec/ is a copy
of it at the tag in spec/VERSION. tests/test_spec.py checks that this
SDK's queries are the specification's documents, and CI checks that spec/
is the tag's copy.
Queries
| Method | Returns | Description |
|---|---|---|
get_sync_status() |
str |
Node sync status (SYNCED, BOOTSTRAP, etc.) |
get_daemon_status() |
DaemonStatus |
Daemon status: chain length, peers, addresses, block production keys |
get_daemon_metrics() |
DaemonMetrics |
Transaction and snark pool metrics, block production delay |
get_network_id() |
str |
Network identifier |
get_account(public_key, token_id=None) |
AccountData |
Balance, nonce, delegate, timing, permissions, zkApp state |
get_best_chain(max_length=None) |
list[BlockInfo] |
Recent blocks from the best chain |
get_genesis_block() |
BlockInfo |
The genesis block |
get_block(state_hash=None, height=None) |
BlockInfo |
One block; give exactly one of the two |
get_peers() |
list[PeerInfo] |
Connected peers |
get_pooled_user_commands(public_key=None) |
list[PooledUserCommand] |
Pending payments and delegations |
get_pooled_zkapp_commands(public_key=None) |
list[ZkappCommandResult] |
Pending zkApp commands |
get_transaction_status(payment=None, zkapp_transaction=None) |
TransactionStatus |
PENDING, INCLUDED or UNKNOWN; give exactly one ID |
get_genesis_constants() |
GenesisConstants |
Genesis timestamp, coinbase, account creation fee |
get_tracked_accounts() |
list[TrackedAccount] |
Accounts in the daemon's keystore |
get_snark_pool() |
list[CompletedWork] |
Completed snark work |
get_fork_config() |
Any |
The daemon's fork configuration (JSON) |
execute_query(query, variables=None, query_name="custom") |
dict |
Run a custom GraphQL query |
Mutations
| Method | Returns | Description |
|---|---|---|
send_payment(sender, receiver, amount, fee, signature=None) |
SendPaymentResult |
Send a payment; signature for one made outside the daemon |
send_delegation(sender, delegate_to, fee, signature=None) |
SendDelegationResult |
Delegate stake; signature likewise |
send_zkapp(zkapp_command) |
ZkappCommandResult |
Send a signed zkApp command (JSON) |
unlock_account(public_key, password) |
str |
Unlock a keystore account so the daemon can sign with it |
set_snark_worker(public_key) |
str | None |
Set/unset SNARK worker |
set_snark_work_fee(fee) |
str |
Set SNARK work fee |
ITN server (mina_sdk.itn)
A daemon started with ITN_FEATURES=1, --itn-graphql-port and --itn-keys
serves a second GraphQL API, which load testing tools use. ItnClient signs
each request with an ed25519 ItnKey whose public half must be in
--itn-keys, and it handles the daemon's sequence numbers (a new auth
after a daemon restart, HTTP 412). It needs the itn extra:
pip install 'mina-sdk[itn]'
from mina_sdk.itn import ItnClient, ItnKey
key = ItnKey.from_base64(open("itn_sk").read())
print("start the daemon with --itn-keys", key.public_key_base64())
with ItnClient("http://127.0.0.1:3086/graphql", key) as itn:
logs = itn.internal_logs(0)
if logs:
itn.flush_internal_logs(logs[-1].id)
| Method | GraphQL |
|---|---|
auth() |
auth (server UUID, sequence number, peer ID, block producer) |
slots_won() |
slotsWon |
internal_logs(start) / flush_internal_logs(end) |
internalLogs / flushInternalLogs |
schedule_payments(PaymentsDetails) |
schedulePayments |
schedule_zkapp_commands(ZkappCommandsDetails) |
scheduleZkappCommands |
stop_scheduled_transactions(handle) |
stopScheduledTransactions |
update_gating(GatingUpdate) |
updateGating |
stop_daemon(delay_seconds=None, clean_config=None) |
stopDaemon |
set_zkapp_command_limit(limit) |
zkAppCommandLimit |
execute_query(query, variables, query_name) |
any document, sequenced and signed |
These need a daemon with MinaProtocol/mina#19616; older daemons answer them with a GraphQL error:
| Method | GraphQL |
|---|---|
commit_id() |
auth { commitId }: the daemon's git commit |
scheduled_transactions() |
scheduledTransactions: handles of the running schedulers |
schedule_payments_with_handle(PaymentsDetails, handle) |
schedulePayments with a caller-chosen handle |
schedule_zkapp_commands_with_handle(ZkappCommandsDetails, handle) |
scheduleZkappCommands with a caller-chosen handle |
create_accounts(CreateAccountsDetails, handle=None) |
createAccounts: keys at once, funding in the background under the handle |
A handle is a UUID that the caller chooses and records before the call. A call with the handle of a running scheduler starts nothing and returns that handle, so these calls may be repeated after a transport error.
Requests of one client are sent one at a time, because the daemon accepts
only its exact next sequence number; the client is safe to share between
threads. A sequenced request is never repeated after a transport error,
because the daemon may already have run it. Errors: ItnUnauthorizedError
(401), ItnSequencingError (412 after a new auth), InvalidItnKeyError, and
DaemonConnectionError whose __cause__ is an ItnHttpError with the
status. The documents are those of spec/itn-operations.graphql. Integration
tests: set MINA_ITN_URI and MINA_ITN_KEY and run
pytest tests/test_itn_integration.py.
Currency
from mina_sdk import Currency
a = Currency(10) # 10 MINA
b = Currency("1.5") # 1.5 MINA
c = Currency.from_nanomina(1_000_000_000) # 1 MINA
print(a + b) # 11.500000000
print(a.nanomina) # 10000000000
print(a > b) # True
print(3 * b) # 4.500000000
Error Handling
from mina_sdk import MinaDaemonClient, GraphQLError, DaemonConnectionError, CurrencyUnderflow
with MinaDaemonClient(retries=3, retry_delay=2.0) as client:
try:
account = client.get_account("B62q...")
except ValueError as e:
# Account not found on ledger
print(f"Account does not exist: {e}")
except GraphQLError as e:
# Daemon returned a GraphQL-level error
print(f"GraphQL error: {e}")
print(f"Raw errors: {e.errors}")
except DaemonConnectionError as e:
# All retry attempts exhausted
print(f"Cannot reach daemon after retries: {e}")
# Currency underflow
from mina_sdk import Currency, CurrencyUnderflow
try:
result = Currency(1) - Currency(2)
except CurrencyUnderflow:
print("Subtraction would result in negative balance")
Data Types
All response types are importable from the top-level package:
from mina_sdk import (
AccountBalance, # total, liquid, locked balances, block height
AccountData, # public_key, nonce, balance, delegate, timing, permissions, zkApp state
BlockInfo, # state_hash, height, slots, creator, epochs, ledger hashes, transactions
DaemonStatus, # sync_status, chain height, peers, uptime, addresses
DaemonMetrics, # pool sizes and diffs, block production delay
PeerInfo, # peer_id, host, port
PooledUserCommand, # a pending payment or delegation
SubmittedCommand, # result of send_payment / send_delegation
ZkappCommandResult, # a pending or sent zkApp command
CompletedWork, # snark pool entry
GenesisConstants,
TrackedAccount,
TransactionStatus,
SignatureInput, # field, scalar
)
Development
git clone https://github.com/MinaProtocol/mina-sdk-python.git
cd mina-sdk-python
python3 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest
Running integration tests
Integration tests require a running Mina daemon:
MINA_GRAPHQL_URI=http://127.0.0.1:3085/graphql \
MINA_TEST_SENDER_KEY=B62q... \
MINA_TEST_RECEIVER_KEY=B62q... \
pytest tests/test_integration.py -v
Troubleshooting
Connection refused / DaemonConnectionError
The daemon is not running or not reachable at the configured URI. Check:
- Is the daemon running? (
mina client status) - Is the GraphQL port open? (default: 3085)
- Is
--insecure-rest-serverset if connecting from a different host?
GraphQLError: field not found
The SDK's queries may be out of sync with the daemon's GraphQL schema. This can happen after a daemon upgrade. Check the documents against your node with mina-sdk-spec: python3 scripts/check.py --endpoint http://your-node:3085/graphql (in a clone of mina-sdk-spec).
Account not found
get_account() raises AccountNotFoundError (a ValueError) when the account doesn't exist on the ledger. This is normal for new accounts that haven't received any transactions yet.
License
Apache License 2.0
Metadata
Release files for mina-sdk 0.4.0rc2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mina_sdk-0.4.0rc2.tar.gz | 55.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mina_sdk-0.4.0rc2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 89.7 kB
Release files / mina_sdk-0.4.0rc2.tar.gz
| Download URL | mina_sdk-0.4.0rc2.tar.gz |
|---|---|
| Size | 55.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
217434a9709870929dac53f83e54147a73ba71721f25ef612e48fd9bedf1c34d
|
|
BLAKE2b-256 checksum How to use checksums |
8d17d44f7d9823c6ff9c97ab46a75a33b9b8b2c5f156bdb01592ab821093a211
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / mina_sdk-0.4.0rc2-py3-none-any.whl
| Download URL | mina_sdk-0.4.0rc2-py3-none-any.whl |
|---|---|
| Size | 34.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
770f25e973af6edb923dc2e8502552e0ae04f3d8dc67a28defd4b3973ac65e94
|
|
BLAKE2b-256 checksum How to use checksums |
077558513afbc2ef9ca70294e494e4112e3741747a1608f53d8667d37d883b43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logSecurity for mina-sdk 0.4.0rc2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for mina_sdk-0.4.0rc2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.