Skip to main content

Add your description here

Project description

MMN SDK for Python

Python SDK for interacting with the MMN blockchain. This SDK provides three main clients for comprehensive blockchain interaction:

  • IndexerClient: Query blockchain data (transactions, wallets)
  • ZkClient: Generate zero-knowledge proofs for authentication
  • MmnClient: Send transactions and manage accounts

Features

  • Async/await support with aiohttp
  • Type-safe models using Pydantic
  • Ed25519 cryptographic signing
  • Zero-knowledge proof generation
  • Comprehensive transaction management
  • Wallet and transaction querying

Installation

# Install from source
pip install -e .

# Or with development dependencies
pip install -e ".[dev]"

Requirements

  • Python 3.8+
  • aiohttp >= 3.8.0
  • pynacl >= 1.5.0
  • base58 >= 2.1.1
  • pycryptodome >= 3.18.0
  • pydantic >= 2.0.0

Quick Start

Complete Example - Sending Tokens

This example demonstrates the complete workflow of sending tokens using all three clients:

import asyncio
from mmn import (
    IndexerClient,
    IndexerClientConfig,
    MmnClient,
    ZkClient,
    MmnClientConfig,
    ZkClientConfig,
    SendTransactionRequest,
    ExtraInfo,
    TransferType,
    ZkClientType,
)

async def main():
    # Initialize clients
    mmn_client = MmnClient(MmnClientConfig(
        base_url="https://dong.mezon.ai/mmn-api/",
        timeout=30000,
    ))

    indexer_client = IndexerClient(IndexerClientConfig(
        endpoint="https://dong.mezon.ai/indexer-api/",
        chain_id="1337",
    ))

    zk_client = ZkClient(ZkClientConfig(
        endpoint="https://dong.mezon.ai/zk-api/",
        timeout=30000,
    ))

    sender_id = "1982293985808355328"
    receiver_id = "1831510214096982016"

    # Generate ephemeral key pair
    keypair = mmn_client.generate_ephemeral_key_pair()

    # Get sender address
    sender_address = mmn_client.get_address_from_user_id(sender_id)

    # Get ZK proofs
    zk_proofs = await zk_client.get_zk_proofs(
        user_id=sender_id,
        ephemeral_public_key=keypair.public_key,
        jwt="your_jwt_token",
        address=sender_address,
        client_type=ZkClientType.MEZON,
    )

    # Get current nonce
    nonce_response = await mmn_client.get_current_nonce(sender_id, "pending")

    # Prepare transaction
    extra_info = ExtraInfo(
        type=TransferType.TRANSFER_TOKEN.value,
        UserSenderId=sender_id,
        UserSenderUsername="Python SDK User",
        UserReceiverId=receiver_id,
    )

    tx_request = SendTransactionRequest(
        sender=sender_id,
        recipient=receiver_id,
        amount=mmn_client.scale_amount_to_decimals(1),  # 1 token
        nonce=nonce_response.nonce + 1,
        text_data="Sending 1 token",
        extra_info=extra_info,
        public_key=keypair.public_key,
        private_key=keypair.private_key,
        zk_proof=zk_proofs.proof,
        zk_pub=zk_proofs.public_input,
    )

    # Send transaction
    result = await mmn_client.send_transaction(tx_request)

    if result.ok:
        print(f"Transaction hash: {result.tx_hash}")

        # Query transaction by hash
        tx_detail = await indexer_client.get_transaction_by_hash(result.tx_hash)
        print(f"Transaction details: {tx_detail}")
    else:
        print(f"Transaction failed: {result.error}")

asyncio.run(main())

IndexerClient

Query blockchain data like transactions and wallet information:

import asyncio
from mmn import IndexerClient, IndexerClientConfig, FilterParams

async def main():
    indexer_client = IndexerClient(IndexerClientConfig(
        endpoint="https://dong.mezon.ai/indexer-api/",
        chain_id="1337",
    ))

    # Get transaction by hash
    tx = await indexer_client.get_transaction_by_hash("tx_hash_here")
    print(f"Transaction: {tx}")

    # Get wallet details
    wallet = await indexer_client.get_wallet_detail("wallet_address")
    print(f"Balance: {wallet.balance}")

    # Get transactions by wallet
    result = await indexer_client.get_transaction_by_wallet(
        wallet="wallet_address",
        page=1,
        limit=10,
        filter_type=FilterParams.ALL,
    )
    print(f"Total transactions: {result.meta.total_items}")

asyncio.run(main())

ZkClient

Generate zero-knowledge proofs for secure authentication:

import asyncio
from mmn import ZkClient, ZkClientConfig, ZkClientType

async def main():
    zk_client = ZkClient(ZkClientConfig(
        endpoint="https://dong.mezon.ai/zk-api/",
        timeout=30000,
    ))

    proof = await zk_client.get_zk_proofs(
        user_id="user123",
        ephemeral_public_key="ephemeral_pub_key",
        jwt="jwt_token",
        address="wallet_address",
        client_type=ZkClientType.MEZON,
    )
    print(f"Proof: {proof.proof}")
    print(f"Public input: {proof.public_input}")

asyncio.run(main())

MmnClient

Send transactions and manage blockchain accounts:

import asyncio
from mmn import (
    MmnClient,
    MmnClientConfig,
    SendTransactionRequest,
    ExtraInfo,
    TransferType,
)

async def main():
    mmn_client = MmnClient(MmnClientConfig(
        base_url="https://dong.mezon.ai/mmn-api/",
        timeout=30000,
    ))

    # Generate ephemeral key pair
    keypair = mmn_client.generate_ephemeral_key_pair()

    # Get address from user ID
    address = mmn_client.get_address_from_user_id("user123")

    # Get current nonce
    nonce_resp = await mmn_client.get_current_nonce("user123", "pending")

    # Scale amount to decimals (1 token = 1000000 with 6 decimals)
    amount = mmn_client.scale_amount_to_decimals(1)

    # Send transaction
    extra_info = ExtraInfo(
        type=TransferType.TRANSFER_TOKEN.value,
        UserSenderId="sender_id",
        UserSenderUsername="sender",
        UserReceiverId="receiver_id",
    )

    tx_request = SendTransactionRequest(
        sender="sender_user_id",
        recipient="recipient_user_id",
        amount=amount,
        nonce=nonce_resp.nonce + 1,
        text_data="Payment note",
        public_key=keypair.public_key,
        private_key=keypair.private_key,
        zk_proof="zk_proof",
        zk_pub="zk_public_input",
        extra_info=extra_info,
    )

    response = await mmn_client.send_transaction(tx_request)
    if response.ok:
        print(f"Transaction hash: {response.tx_hash}")
    else:
        print(f"Error: {response.error}")

asyncio.run(main())

Complete Workflow Example

The complete workflow for sending a token transaction involves:

  1. Initialize clients: Create MmnClient, IndexerClient, and ZkClient
  2. Generate ephemeral key pair: Temporary keys for transaction signing
  3. Convert user ID to address: Derive blockchain address from user ID
  4. Get ZK proofs: Generate zero-knowledge proof for authentication
  5. Get current nonce: Retrieve the account's transaction nonce
  6. Prepare transaction: Create transaction with all required fields
  7. Send transaction: Submit to the blockchain
  8. Query transaction: Verify transaction status with IndexerClient

See the complete example above or main.py for a full implementation.

API Reference

IndexerClient

Methods

  • get_transaction_by_hash(hash: str) -> Transaction

    • Get transaction details by hash
  • get_transaction_by_wallet(wallet: str, page: int = 1, limit: int = 50, filter_type: int = 0, sort_by: str = "transaction_timestamp", sort_order: str = "desc") -> ListTransactionResponse

    • Get transactions for a wallet with filtering and pagination
  • get_wallet_detail(wallet: str) -> WalletDetail

    • Get wallet balance and nonce

Filter Types

  • FilterParams.ALL (0): All transactions
  • FilterParams.SENT (2): Sent transactions only
  • FilterParams.RECEIVED (1): Received transactions only

ZkClient

Methods

  • get_zk_proofs(user_id: str, ephemeral_public_key: str, jwt: str, address: str, client_type: ZkClientType = ZkClientType.MEZON) -> ZkProof
    • Generate zero-knowledge proof

Client Types

  • ZkClientType.MEZON: Mezon authentication
  • ZkClientType.OAUTH: OAuth authentication

MmnClient

Methods

  • generate_ephemeral_key_pair() -> EphemeralKeyPair

    • Generate temporary Ed25519 key pair
  • get_address_from_user_id(user_id: str) -> str

    • Convert user ID to blockchain address using SHA-256
  • send_transaction(params: SendTransactionRequest) -> AddTxResponse

    • Send transaction using user IDs (auto-converts to addresses)
  • send_transaction_by_address(params: SendTransactionRequest) -> AddTxResponse

    • Send transaction using addresses directly
  • get_current_nonce(user_id: str, tag: str = "latest") -> GetCurrentNonceResponse

    • Get current nonce for an account
  • get_account_by_user_id(user_id: str) -> GetAccountByAddressResponse

    • Get account information by user ID
  • scale_amount_to_decimals(original_amount: int, decimals: int = 6) -> str

    • Scale amount to blockchain decimals (default 6)
  • validate_address(address: str) -> bool

    • Validate blockchain address format
  • validate_amount(balance: str, amount: str) -> bool

    • Check if amount doesn't exceed balance

Examples

See main.py for a complete working example that demonstrates:

  • Initializing all three clients (MmnClient, ZkClient, IndexerClient)
  • Generating ephemeral key pairs
  • Getting ZK proofs for authentication
  • Sending token transactions
  • Querying transactions by hash and wallet

Run the example:

python main.py

Development

Setup

# Clone repository
git clone <repository-url>
cd mmn-sdk-python

# Install in development mode
pip install -e ".[dev]"

Running Tests

pytest

Code Formatting

This project uses Ruff for linting and formatting:

# Format code
ruff format .

# Check for linting issues
ruff check .

# Auto-fix linting issues
ruff check --fix .

Type Checking

mypy mmn/

Release Process

This project uses Python Semantic Release for automated versioning and releases. Please refer to the documentation for details on commit message conventions and release workflows.

Architecture

The SDK is organized into three main components:

mmn/
├── __init__.py          # Public API exports
├── types.py             # Pydantic models and type definitions
├── indexer_client.py    # Blockchain data queries
├── zk_client.py         # Zero-knowledge proof generation
└── mmn_client.py        # Transaction and account management

Key Features

  • Async/Await: All I/O operations are asynchronous using aiohttp
  • Simple API: No context managers required - clients create new sessions per request
  • Type Safety: Pydantic models for validation and serialization
  • Cryptography: Ed25519 signing with pynacl
  • Error Handling: Comprehensive error messages and validation

Security Considerations

  • Private keys are handled securely and cleared from memory after use
  • PKCS#8 format for Ed25519 private keys
  • Zero-knowledge proofs for authentication without revealing secrets
  • Secure random number generation for key pairs

License

Apache 2.0

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions, please open an issue on GitHub.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mmn_sdk-1.0.0.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mmn_sdk-1.0.0-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file mmn_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: mmn_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mmn_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0404bb2a936c8cc2e72e00bf148d5d979f8e8a6be21889f21b3fe61aa4a2680e
MD5 dfa9251285f6ae3610a699c5596b475f
BLAKE2b-256 2eb0cf084b8f8bdd90edc199b99622342b41ae2c21e95387b96bcbe66ca616cb

See more details on using hashes here.

File details

Details for the file mmn_sdk-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: mmn_sdk-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mmn_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 af73d9adef239fabe90f3eed867d9e1d7f6cd1c86153a8877c27650ad5c81799
MD5 db105c1df1823652ec474a5ba8434a70
BLAKE2b-256 d518a2c6f1950aede48a8693ab8508ea1baf4d59496fad67f28ff6dfbe0a2f0a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page