Wallet API Reference
The wallet module handles key derivation, signature generation, and address management for unshielded and shielded transactions on the Midnight Network.
Midnight Wallet
noxipher.wallet.wallet.MidnightWallet
Unified wallet facade for Midnight 3-token system.
Addresses
wallet.unshielded.address → mn_addr_preprod1... wallet.shielded.address → mn_shield-addr_preprod1... wallet.dust.address → mn_dust_preprod1...
Source code in src/noxipher/wallet/wallet.py
dust
property
DUST fee wallet.
network
property
Current network.
shielded
property
Shielded privacy wallet.
shielded_state
property
Access local ZSwap shielded state.
unshielded
property
Unshielded NIGHT wallet.
from_mnemonic(mnemonic, network)
classmethod
generate(network)
classmethod
Generate new random wallet.
Returns:
| Type | Description |
|---|---|
tuple[MidnightWallet, str]
|
(wallet, mnemonic) — SAVE the mnemonic immediately! |
Source code in src/noxipher/wallet/wallet.py
Unshielded Wallet
noxipher.wallet.unshielded.UnshieldedWallet
NIGHT token wallet — unshielded UTxO model. Signing: sr25519 (py-sr25519-bindings).
Balance is computed from: unshieldedCreatedOutputs - unshieldedSpentOutputs (Indexer has no direct balance query — must compute from UTxO set)
Source code in src/noxipher/wallet/unshielded.py
address
property
Bech32m unshielded address.
public_key
property
32-byte sr25519 public key.
as_substrate_keypair()
get_balance(indexer)
async
Returns {token_type_hex: amount_specks}. NIGHT native token type = "0000...00" (32 zero bytes).
Source code in src/noxipher/wallet/unshielded.py
get_utxos(indexer)
async
sign(data)
sign_pre_proof(data)
sign_seg_intent(data_to_sign)
Signs the serialized SegIntent data for an unshielded offer. The data should already include the 'midnight:hash-intent:' prefix.
Shielded Wallet
noxipher.wallet.shielded.ShieldedWallet
Privacy-preserving shielded wallet. Keys: JubJub curve via py_ecc (ZswapSecretKeys).
Shielded address = Bech32m(ShieldedAddress(coinPublicKey, encryptionPublicKey))
CONFIRMED from Counter CLI (Apr 2026): coinPubKey = ShieldedCoinPublicKey.fromHexString( state.shielded.coinPublicKey ) encPubKey = ShieldedEncryptionPublicKey.fromHexString( state.shielded.encryptionPublicKey ) shieldedAddress = MidnightBech32m.encode( networkId, new ShieldedAddress(coinPubKey, encPubKey) )
Source code in src/noxipher/wallet/shielded.py
address
property
Bech32m shielded address.
viewing_key
property
Viewing key for Indexer connect() mutation.
CONFIRMED from Counter CLI source
state.shielded.coinPublicKey.toHexString() + state.shielded.encryptionPublicKey.toHexString()
= hex-encoded 64 bytes (coinPK 32B + encPK 32B)
Format: "aabb...cc" (128 hex chars, no separator)
close_session(indexer, session_id)
async
open_session(indexer)
async
Open shielded session with Indexer to scan shielded transactions.
sync_coins(indexer, session_id)
async
Stream shielded transactions, collect unspent coins.
Source code in src/noxipher/wallet/shielded.py
Dust Wallet
noxipher.wallet.dust.DustWallet
DUST fee token wallet.
DUST mechanics (from official Counter CLI): 1. User holds NIGHT UTxOs 2. Register UTxOs: wallet.registerNightUtxosForDustGeneration(utxos, pubkey, signFn) 3. Wait: DUST balance increases over time 4. Spend: Automatic when submitting transaction (no manual handling needed)
DUST cost parameters (from official source): additionalFeeOverhead: 300_000_000_000_000 (300T Specks) feeBlocksMargin: 5 blocks
Source code in src/noxipher/wallet/dust.py
address
property
DUST address = Bech32m with HRP mn_dust_
public_key
property
32-byte DUST public key (sr25519).
can_transfer()
get_generation_status(indexer, cardano_stake_key)
async
Query DUST generation status for Cardano stake key.
Source code in src/noxipher/wallet/dust.py
get_utxos(indexer)
async
register_night_utxos(utxos, tx_builder, unshielded_wallet)
async
Register NIGHT UTxOs for DUST generation.
Must be called before DUST starts generating. Creates an on-chain transaction to register UTxOs.
Source code in src/noxipher/wallet/dust.py
sign_seg_intent(data_to_sign)
Signs the serialized SegIntent data for an unshielded offer. Uses sr25519 for protocol compatibility with unshielded segments.
transfer(*args, **kwargs)
DUST is non-transferable. Raises WalletError.
Source code in src/noxipher/wallet/dust.py
Wallet State & Syncing
noxipher.wallet.sync.WalletSyncer
Sync wallet balances and state from Indexer.
Handles both unshielded (UTxO scan) and shielded (session-based) sync.
Source code in src/noxipher/wallet/sync.py
sync_all()
async
Sync all wallet components.
Source code in src/noxipher/wallet/sync.py
sync_shielded()
async
Sync shielded coins via Indexer session.
Source code in src/noxipher/wallet/sync.py
sync_unshielded()
async
Sync unshielded NIGHT balance from Indexer.
Source code in src/noxipher/wallet/sync.py
noxipher.wallet.balance.WalletState
Bases: BaseModel
Aggregated wallet state.
Source code in src/noxipher/wallet/balance.py
Keystore
noxipher.wallet.keystore.Keystore
Encrypted keystore using Argon2id + AES-256-GCM.
Stores encrypted mnemonic/private keys safely on disk.
Source code in src/noxipher/wallet/keystore.py
decrypt(keystore, password)
staticmethod
Decrypt keystore with password.
Returns: decrypted data bytes
Source code in src/noxipher/wallet/keystore.py
encrypt(data, password)
staticmethod
Encrypt data with password.
Returns: keystore dict[str, Any] (JSON-serializable)