Seismic Alloy (Rust)
CLAUDE.md template for Rust dapp development with seismic-alloy
Use this template when your project uses seismic-alloy to interact with Seismic contracts from Rust. This SDK extends Alloy with Seismic transaction types, encrypted calldata, and signed reads.
The template
Copy the entire block below and save it as CLAUDE.md in your project root.
# [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 provider handles this automatically via the filler pipeline.
- **Signed reads**: `eth_call` zeroes `msg.sender` on Seismic. Use `seismic_call()` (via `SeismicProviderExt` trait) for reads that need a valid sender.
- **Encryption pubkeys**: 33-byte compressed secp256k1 keys. The provider fetches and manages these on construction.
- **Legacy gas**: Seismic transactions use `gas_price` + `gas_limit`, NOT EIP-1559.
## SDK: seismic-alloy
### Install
Add to `Cargo.toml`:
```toml
[dependencies]
seismic-alloy = { git = "https://github.com/SeismicSystems/seismic-alloy" }
alloy-signer-local = "1.1"
tokio = { version = "1", features = ["full"] }
```
Requires **Rust 1.82+** and OpenSSL.
### Key imports
```rust
use seismic_alloy::prelude::*;
use alloy_signer_local::PrivateKeySigner;
```
The prelude re-exports:
- `SeismicSignedProvider`, `SeismicUnsignedProvider`
- `SeismicWallet`
- `SeismicReth`, `SeismicFoundry`, `SeismicNetwork`
- `SeismicProviderExt` trait
- Convenience functions: `sreth_signed_provider()`, `sfoundry_signed_provider()`, `sreth_unsigned_provider()`, `sfoundry_unsigned_provider()`
- Seismic transaction types and RPC types
## Core Patterns
### Create a signed provider (full capabilities)
```rust
use seismic_alloy::prelude::*;
use alloy_signer_local::PrivateKeySigner;
let signer: PrivateKeySigner = "0xYOUR_PRIVATE_KEY".parse()?;
let wallet = SeismicWallet::from(signer);
let url = "https://testnet-1.seismictest.net/rpc".parse()?;
let provider = SeismicSignedProvider::<SeismicReth>::new(wallet, url).await?;
```
### Create an unsigned provider (read-only)
```rust
use seismic_alloy::prelude::*;
let url = "https://testnet-1.seismictest.net/rpc".parse()?;
let provider = sreth_unsigned_provider(url);
```
### Convenience constructors
```rust
// For SeismicReth (devnet/testnet/mainnet)
let provider = sreth_signed_provider(wallet, url).await?;
let provider = sreth_unsigned_provider(url);
// For SeismicFoundry (local sanvil)
let provider = sfoundry_signed_provider(wallet, url).await?;
let provider = sfoundry_unsigned_provider(url);
```
### Contract interaction (shielded write)
```rust
use alloy::sol;
sol! {
#[sol(rpc)]
contract MyContract {
function transfer(address to, uint256 amount) external;
function getBalance(address account) external view returns (uint256);
}
}
let contract = MyContract::new(contract_address, &provider);
// Shielded write — calldata is automatically encrypted
let tx_hash = contract.transfer(recipient, amount)
.gas(500_000)
.send()
.await?
.watch()
.await?;
```
### Signed read
```rust
// Use seismic_call via SeismicProviderExt for reads that check msg.sender
use seismic_alloy::prelude::SeismicProviderExt;
let balance = provider.seismic_call(
contract.getBalance(user_address)
).await?;
```
### Network types
| Network type | Use with | Description |
| ---------------- | ---------------------- | ------------------- |
| `SeismicReth` | Devnet/testnet/mainnet | Production networks |
| `SeismicFoundry` | Local `sanvil` | Development network |
### Filler pipeline
The `SeismicSignedProvider` automatically applies fillers in order:
```
WalletFiller → NonceFiller + ChainIdFiller → SeismicElementsFiller → SeismicGasFiller → encrypt → send → decrypt
```
You do not need to manually encrypt calldata or set Seismic-specific transaction fields.
## Common Mistakes
1. **Using standard Alloy providers** — `ProviderBuilder::new()` creates a regular Ethereum provider. It won't encrypt calldata. Use `SeismicSignedProvider::new()` or the convenience constructors.
2. **Using EIP-1559 gas params** — Seismic uses legacy gas. Use `.gas(amount)`, not `.max_fee_per_gas()`.
3. **Using plain `eth_call` for shielded reads** — Standard calls zero the sender. Use `provider.seismic_call()` from the `SeismicProviderExt` trait.
4. **Wrong network type** — Use `SeismicReth` for devnet/testnet and `SeismicFoundry` for local `sanvil`. Using the wrong type causes deserialization errors.
5. **Forgetting `.await` on provider creation** — `SeismicSignedProvider::new()` is async (fetches TEE public key). Missing `.await` gives a future, not a provider.
6. **Missing OpenSSL** — The `seismic-enclave` crate requires OpenSSL. Install `libssl-dev` (Debian/Ubuntu) or `openssl` (macOS via brew).
## Networks
| Network | Chain ID | RPC URL | Network type |
| -------------- | -------- | ----------------------------------- | ---------------- |
| Testnet | 5124 | `https://testnet-1.seismictest.net/rpc` | `SeismicReth` |
| Testnet (WS) | 5124 | `wss://testnet-1.seismictest.net/ws` | `SeismicReth` |
| Local (sanvil) | 31337 | `http://127.0.0.1:8545` | `SeismicFoundry` |
Faucet: https://faucet.seismictest.net/
## Links
- [seismic-alloy Installation](https://docs.seismic.systems/client-libraries/seismic-alloy/installation)
- [SeismicSignedProvider](https://docs.seismic.systems/client-libraries/seismic-alloy/provider/seismic-signed-provider)
- [SeismicUnsignedProvider](https://docs.seismic.systems/client-libraries/seismic-alloy/provider/seismic-unsigned-provider)
- [Shielded Write Guide](https://docs.seismic.systems/client-libraries/seismic-alloy/guides/shielded-write)
- [Signed Reads Guide](https://docs.seismic.systems/client-libraries/seismic-alloy/guides/signed-reads)
- [GitHub: seismic-alloy](https://github.com/SeismicSystems/seismic-alloy)What this teaches Claude
Correct crate names and import paths — Claude will use
seismic_alloy::prelude::*instead of guessing crate namesProvider construction — Claude will use
SeismicSignedProvider::new()with the correct generic network typeSigned reads — Claude will use
provider.seismic_call()fromSeismicProviderExtinstead of standardeth_callNetwork type selection — Claude will pick
SeismicRethvs.SeismicFoundrybased on the target networkFiller pipeline — Claude understands that encryption is handled automatically
Customizing
After pasting the template:
Replace
[Your Project Name]with your project nameAdd your
sol!macro contract definitionsAdd deployed contract addresses
If you pin to a specific revision, update the
Cargo.tomlexample accordingly
Last updated

