Skip to main content

CircuitPython_MiniEthers

Introduction

Documentation Status Discord Build Status Code Style: Ruff

Circuitpython module for ethereum wallet creation and signing

Dependencies

This driver depends on:

Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle or individual libraries can be installed using circup.

Installing from PyPI

On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally from PyPI. To install for current user:

pip3 install circuitpython-miniethers

To install system-wide (this may be required in some cases):

sudo pip3 install circuitpython-miniethers

To install in a virtual environment in your current project:

mkdir project-name && cd project-name
python3 -m venv .venv
source .env/bin/activate
pip3 install circuitpython-miniethers

Installing to a Connected CircuitPython Device with Circup

Make sure that you have circup installed in your Python environment. Install it with the following command if necessary:

pip3 install circup

With circup installed and your CircuitPython device connected use the following command to install:

circup install miniethers

Or the following command to update an existing version:

circup update

Usage Example

Simple example showcasing wallet creation and message signing.

from circuitpython_miniethers import Signature, Wallet

# The private key is used for both signing methods
# IMPORTANT: In a real app, never hardcode private keys.
# Use environment variables or a secure wallet connection.
privateKey = "0x022b99092266a16a949e6a450f0e88a8288d39d5f1d75c00575a35a0ba270dbc"

# Create a wallet instance from the private key
wallet = Wallet(privateKey)


def generateFlatSignature():
    """
    Signs a simple string message (ERC-191).
    """
    print("--- Signing a Flat String (ERC-191) ---")

    # The message to sign
    message = "hello"

    print(f'Signing message: "{message}"')
    print(f"Signer Address: {wallet.address}")
    print("---")

    flatSignature = wallet.signMessage(message)

    print("Full Flat Signature:", flatSignature)

    # For comparison, let's split the signature into its components
    signature = getattr(Signature, "from")(flatSignature)
    print("Signature Components:")
    print("  r:", signature.r)
    print("  s:", signature.s)
    print("  v:", signature.v)
    print("-----------------------------------------\n")


def signTypedDataMail():
    """
    Signs structured typed data (EIP-712).
    This provides more readable and secure signing prompts in wallets like MetaMask.
    """
    print("--- Signing Typed Data (EIP-712) ---")

    # 1. The Domain Separator: Defines the context of the signature.
    # This prevents a signature from being valid in a different application.
    domain = {
        # The user-friendly name of the signing domain
        "name": "Ether Mail",
        # The current version of the signing domain
        "version": "1",
        # The chain ID of the intended network (1 for Ethereum Mainnet)
        "chainId": 1,
        # The address of the contract that will verify the signature
        "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
    }

    # 2. The Types: Defines the structure of the data being signed.
    # You define your primary type ("Mail") and any custom nested types ("Person").
    types = {
        "Person": [
            {"name": "name", "type": "string"},
            {"name": "wallet", "type": "address"},
        ],
        "Mail": [
            {"name": "from", "type": "Person"},  # Nested custom type
            {"name": "to", "type": "Person"},  # Nested custom type
            {"name": "contents", "type": "string"},
        ],
    }

    # 3. The Value: The actual data object to be signed.
    # This object must match the structure defined in `types`.
    value = {
        "from": {
            "name": "Cow",
            "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
        },
        "to": {
            "name": "Bob",
            "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
        },
        "contents": "Hello, Bob! This is a typed message.",
    }

    print("Signing EIP-712 data for address:", wallet.address)
    print("Domain:", domain)
    print("Value:", value)
    print("---")

    # The `_signTypedData` method handles hashing the structured data according to the EIP-712 spec.
    signature = wallet._signTypedData(domain, types, value)

    print("EIP-712 Signature:", signature)
    print("------------------------------------\n")


# Run both signing functions
def main():
    print("CircuitPython MiniEthers - Ethers.js Compatibility Test\n")
    print(f"Wallet Address: {wallet.address}")
    print(f"Private Key: {wallet.privateKey}")
    print(f"Public Key: {wallet.publicKey}\n")

    generateFlatSignature()
    signTypedDataMail()

    print("\n✅ All tests completed successfully!")


if __name__ == "__main__":
    main()

Documentation

API documentation for this library can be found on Read the Docs.

For information on building library documentation, please check out this guide.

Contributing

Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.

PS

I participated in EthGlobal New Delhi this year where me and my team created a hardware wallet for our project. For that purpose we chose a Raspberry Pi Pico. And that is when we realised that the hardware is pretty constrained which doesnt allow existing libraries to work. So I wrote a package that worked on the Pico.

And after some time I decided that I should package this properly and share it as a library, so that people can use this if they want to. That’s the story behind this package.

Metadata

Release files for circuitpython-miniethers 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for circuitpython-miniethers 1.0.0
File Size Uploaded Provenance
circuitpython_miniethers-1.0.0.tar.gz 43.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for circuitpython-miniethers 1.0.0
File Interpreter ABI Platform
circuitpython_miniethers-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 62.4 kB

Release files / circuitpython_miniethers-1.0.0.tar.gz

Download URL circuitpython_miniethers-1.0.0.tar.gz
Size 43.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1cf845e80abe2a8b21ed123bfcde46c3fe50cb15f9ad8aa2537fad13cb57a43f
BLAKE2b-256 checksum
How to use checksums
14cdbfc0f3dd279a660aa24501bf3f6ef436fdb778cad21c503998cece0c8bf4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 15, 2025.

Transparency log

Release files / circuitpython_miniethers-1.0.0-py3-none-any.whl

Download URL circuitpython_miniethers-1.0.0-py3-none-any.whl
Size 18.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bb8ca38f8b69aef219f88d3b1caf99884d424a0498c46f8e34f2bc097954db2d
BLAKE2b-256 checksum
How to use checksums
293aab42bec746ea557e154827e0b40a43ec333de05a228ec00ed1173ceabf30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 15, 2025.

Transparency log

Security for circuitpython-miniethers 1.0.0

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.

Select from 2 files

Attestation for circuitpython_miniethers-1.0.0.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 15, 2025.

Transparency log

A 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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page