Seismic Python
CLAUDE.md template for Python dapp development with seismic-web3
The template
# [Your Project Name]
## Seismic Overview
Seismic is an EVM-compatible L1 with on-chain privacy. Nodes run inside TEEs (Intel TDX). The Solidity compiler adds shielded types (`suint256`, `saddress`, `sbool`) that are invisible outside the TEE. Client libraries handle transaction encryption and signed reads automatically.
## Key Concepts
- **Shielded types**: `suint256`, `saddress`, `sbool` — on-chain private state, only readable via signed reads
- **TxSeismic (type 0x4A)**: Encrypts calldata before broadcast. The SDK handles this automatically.
- **Signed reads**: `eth_call` zeroes `msg.sender` on Seismic. Use `.read` namespace on ShieldedContract for reads that need a valid sender.
- **Encryption pubkeys**: 33-byte compressed secp256k1 keys. The client fetches and manages these on construction.
- **Legacy gas**: Seismic transactions use `gas_price` + `gas_limit`, NOT EIP-1559.
## SDK: seismic-web3
### Install
```bash
pip install seismic-web3
# or with uv
uv add seismic-web3
```
The PyPI package is `seismic-web3`. The import is `from seismic_web3 import ...`.
### Key imports
```python
from seismic_web3 import (
SEISMIC_TESTNET, # Chain config for devnet
SANVIL, # Chain config for local sanvil
PrivateKey,
create_wallet_client,
create_public_client,
create_async_wallet_client,
create_async_public_client,
)
```
## Core Patterns
### Create a wallet client (sync)
```python
from seismic_web3 import SEISMIC_TESTNET, PrivateKey
pk = PrivateKey(bytes.fromhex("YOUR_PRIVATE_KEY_HEX"))
w3 = SEISMIC_TESTNET.wallet_client(pk)
# Standard web3.py methods work
block = w3.eth.get_block("latest")
```
### Create a wallet client (async)
```python
from seismic_web3 import SEISMIC_TESTNET, PrivateKey
pk = PrivateKey(bytes.fromhex("YOUR_PRIVATE_KEY_HEX"))
# HTTP
w3 = await SEISMIC_TESTNET.async_wallet_client(pk)
# WebSocket
w3 = await SEISMIC_TESTNET.async_wallet_client(pk, ws=True)
```
### Create a public client (read-only)
```python
from seismic_web3 import SEISMIC_TESTNET
# Sync
public = SEISMIC_TESTNET.public_client()
# Async
public = await SEISMIC_TESTNET.async_public_client()
```
### Create a client with a URL
```python
from seismic_web3 import create_wallet_client, create_public_client, PrivateKey
pk = PrivateKey(bytes.fromhex("YOUR_PRIVATE_KEY_HEX"))
w3 = create_wallet_client("http://127.0.0.1:8545", private_key=pk)
public = create_public_client("http://127.0.0.1:8545")
```
### Shielded contract interaction
```python
contract = w3.seismic.contract(
address="0xCONTRACT_ADDRESS",
abi=my_contract_abi,
)
# Shielded write — sends a type 0x4A transaction with encrypted calldata
tx_hash = contract.write.transfer(recipient_address, amount)
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
# Signed read — proves identity so msg.sender is set correctly
balance = contract.read.getBalance(user_address)
# Transparent write (standard tx, no encryption)
tx_hash = contract.twrite.setPublicValue(42)
# Transparent read (standard eth_call, no signing)
value = contract.tread.getPublicValue()
```
### Contract namespaces
| Namespace | Description | When to use |
| --------- | ---------------------------------------- | ------------------------------------------ |
| `.write` | Shielded write (encrypted calldata) | Functions that write shielded state |
| `.read` | Signed read (proves msg.sender) | View functions that check msg.sender |
| `.twrite` | Transparent write (standard tx) | Functions that only write public state |
| `.tread` | Transparent read (standard call) | View functions that don't check msg.sender |
| `.dwrite` | Debug write (shielded + verbose logging) | Development/debugging |
### Encryption
The wallet client automatically handles encryption. On creation, it fetches the node's TEE public key and derives a shared AES-GCM key via ECDH. The encryption state is accessible at `w3.seismic.encryption` if needed.
## Common Mistakes
1. **Using standard web3.py contract calls** — `contract.functions.transfer(...).transact()` sends a standard Ethereum transaction. It won't encrypt calldata. Use `contract.write.transfer(...)` from the Seismic contract instance.
2. **Wrong package name** — The PyPI package is `seismic-web3`, not `seismic-python` or `seismic-py`. The import is `from seismic_web3 import ...`.
3. **Using EIP-1559 gas params** — Seismic uses legacy gas. Do NOT pass `maxFeePerGas`/`maxPriorityFeePerGas`.
4. **Using `.tread` when `.read` is needed** — If the contract function checks `msg.sender`, you must use `.read` (signed read). Using `.tread` zeroes the sender and the `require` will fail.
5. **Forgetting `await` on async clients** — `SEISMIC_TESTNET.async_wallet_client(pk)` is async. Missing `await` gives a coroutine, not a client.
6. **PrivateKey format** — Use `PrivateKey(bytes.fromhex("..."))`, not a hex string directly. The key should NOT include the `0x` prefix when using `fromhex`.
## Networks
| Network | Chain ID | Chain config | RPC URL |
| -------------- | -------- | ----------------- | ----------------------------------- |
| Testnet | 5124 | `SEISMIC_TESTNET` | `https://gcp-1.seismictest.net/rpc` |
| Testnet (WS) | 5124 | `SEISMIC_TESTNET` | `wss://gcp-1.seismictest.net/ws` |
| Local (sanvil) | 31337 | `SANVIL` | `http://127.0.0.1:8545` |
Faucet: https://faucet.seismictest.net/
## Links
- [Client Documentation](https://docs.seismic.systems/client-libraries/seismic-python/)
- [ShieldedContract](https://docs.seismic.systems/client-libraries/seismic-python/contract/shielded-contract)
- [Contract Namespaces](https://docs.seismic.systems/client-libraries/seismic-python/contract/namespaces/)
- [Shielded Write Guide](https://docs.seismic.systems/client-libraries/seismic-python/guides/shielded-write)
- [Signed Reads Guide](https://docs.seismic.systems/client-libraries/seismic-python/guides/signed-reads)
- [GitHub: seismic-py](https://github.com/SeismicSystems/seismic-py)What this teaches Claude
Customizing
Last updated

