Python SDK for Signic email - sign in with Ethereum, read and manage emails
Project description
signic-sdk
Python SDK for the Signic decentralized email platform. Authenticate with an Ethereum wallet via SIWE (Sign-In with Ethereum) and read emails from a WildDuck mail server.
Installation
pip install signic-sdk
Requirements: Python >= 3.11
Quick Start
import asyncio
from signic_sdk import SignicClient, SignicClientConfig
async def main():
config = SignicClientConfig(
private_key="0xac09...",
indexer_url="https://api.signic.email/idx",
wildduck_url="https://api.signic.email/api",
)
async with SignicClient(config) as client:
# Derive addresses (no auth needed)
print(client.get_address()) # "0xf39F..."
print(client.get_email_address()) # "0xf39F...@signic.email"
# Authenticate via SIWE
await client.connect()
# Fetch unread emails
result = await client.get_unread_emails(10)
print(f"{result.total} unread emails")
# Get full email content
full = await client.get_email(result.emails[0].id)
print(full.subject, full.text)
# Mark as read
await client.mark_as_read(result.emails[0].id)
asyncio.run(main())
API Reference
SignicClient(config)
Create a new client instance.
| Parameter | Type | Required | Description |
|---|---|---|---|
private_key |
str |
Yes | EVM private key (hex with 0x prefix) |
indexer_url |
str |
Yes | Indexer API base URL |
wildduck_url |
str |
Yes | WildDuck API base URL |
email_domain |
str |
No | Email domain (default: signic.email) |
chain_id |
int |
No | EVM chain ID for SIWE (default: 1) |
Supports async with for automatic resource cleanup:
async with SignicClient(config) as client:
await client.connect()
...
# httpx client is automatically closed
Or close manually:
client = SignicClient(config)
try:
await client.connect()
...
finally:
await client.aclose()
Methods
get_address() -> str
Returns the EVM wallet address derived from the private key. Does not require authentication.
get_email_address() -> str
Returns the Signic email address (e.g. 0xabc...@signic.email). Does not require authentication.
is_connected() -> bool
Returns True if connect() has completed successfully.
async connect() -> None
Authenticate with the Signic platform via SIWE. Must be called before any email methods.
Performs a 6-step flow:
- Fetch a SIWE message from the Indexer
- Sign the message with the wallet's private key
- Convert the signature to base64
- Verify the signature with the Indexer
- Authenticate with WildDuck to get an access token
- Locate the INBOX mailbox
Raises: SignicAuthError on auth failure, SignicNetworkError on network failure.
async get_unread_emails(limit: int = 50) -> UnreadEmailsResult
Fetch unread emails from the inbox. Returns summary objects (use get_email() for full content).
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
int |
50 |
Maximum number of emails to return |
Returns: UnreadEmailsResult with .emails: list[SignicEmail] and .total: int
async get_email(email_id: int, mailbox_id: str | None = None) -> SignicEmailDetail
Fetch the complete email by ID, including HTML/text body, all recipients, attachments, and flags.
| Parameter | Type | Default | Description |
|---|---|---|---|
email_id |
int |
- | Message UID from SignicEmail.id |
mailbox_id |
str | None |
INBOX | Mailbox to fetch from |
Returns: SignicEmailDetail with html, text, cc, bcc, reply_to, attachments, verification_results, and all message flags.
async mark_as_read(message_id: int, mailbox_id: str | None = None) -> MarkAsReadResult
Mark a message as read (sets the \Seen flag).
| Parameter | Type | Default | Description |
|---|---|---|---|
message_id |
int |
- | Message UID |
mailbox_id |
str | None |
INBOX | Mailbox containing the message |
Returns: MarkAsReadResult with .success: bool and .updated: int
async aclose() -> None
Close the underlying HTTP client. Called automatically when using async with.
Types
All types are frozen dataclasses.
SignicEmail
Summary email object returned by get_unread_emails().
@dataclass(frozen=True)
class SignicEmail:
id: int # Message UID
mailbox_id: str # Mailbox ID
from_: SignicEmailAddress # Sender (from_ because from is reserved)
to: list[SignicEmailAddress] # Recipients
subject: str # Subject line
date: str # ISO 8601 date
intro: str # Preview (~128 chars)
seen: bool # Read status
has_attachments: bool # Has file attachments
SignicEmailDetail
Full email object returned by get_email().
@dataclass(frozen=True)
class SignicEmailDetail:
id: int
mailbox_id: str
thread: str # Conversation thread ID
from_: SignicEmailAddress
to: list[SignicEmailAddress]
cc: list[SignicEmailAddress]
bcc: list[SignicEmailAddress]
subject: str
message_id: str # Message-ID header
date: str # Date header (ISO 8601)
idate: str # Server receive date (ISO 8601)
size: int # Size in bytes
seen: bool
flagged: bool
deleted: bool
draft: bool
answered: bool
forwarded: bool
html: list[str] # HTML body parts
text: str # Plain text body
attachments: list[SignicEmailAttachment] # File attachments
reply_to: SignicEmailAddress | None = None
verification_results: VerificationResults | None = None
SignicEmailAttachment
@dataclass(frozen=True)
class SignicEmailAttachment:
id: str # Attachment ID
hash: str # SHA-256 hash (hex)
filename: str # Original filename
content_type: str # MIME type
disposition: str # "attachment" or "inline"
transfer_encoding: str # Transfer encoding
related: bool # Inline/embedded image
size_kb: int # Approximate size in KB
Error Classes
All errors extend SignicError which carries operation and status_code attributes.
| Error | When |
|---|---|
SignicError |
Base class for all SDK errors |
SignicAuthError |
Authentication failure (401/403) or calling methods before connect() |
SignicNetworkError |
Network failure (DNS, timeout, no response) |
SignicValidationError |
Input validation failure (400/422) |
from signic_sdk import SignicError, SignicAuthError
try:
await client.get_unread_emails()
except SignicAuthError as err:
print(f"Auth failed: {err.operation} {err.status_code}")
except SignicError as err:
print(f"SDK error: {err}")
License
BUSL-1.1
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file signic_sdk-0.1.3.tar.gz.
File metadata
- Download URL: signic_sdk-0.1.3.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33fc5ed15bc295aec4a3f6977f59d1b47b82271aa370220eb9ff41711799b906
|
|
| MD5 |
a6644b07b323d912d04fb238dc3ee862
|
|
| BLAKE2b-256 |
6be2f633ec9af5695cc40c27fd1ce36a8490fe8919a787aedbaa59744b98585b
|
File details
Details for the file signic_sdk-0.1.3-py3-none-any.whl.
File metadata
- Download URL: signic_sdk-0.1.3-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a49b671d79f7bffced99b738a2525c4bf61c4ba878839d6e4e9323b308f3ff0
|
|
| MD5 |
05569a623b80198e783ff46cbbb82e7a
|
|
| BLAKE2b-256 |
d62c61633a764e2168542aa6f09537f153f14f7109ba9bad65685c6b91f5f772
|