Seismic Viem
CLAUDE.md template for TypeScript dapp development with seismic-viem
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 shielded wallet client handles this automatically.
- **Signed reads**: `eth_call` zeroes `msg.sender` on Seismic. For view functions that check `msg.sender`, use `contract.read.*` from a shielded contract instance — it sends a signed read automatically.
- **Encryption pubkeys**: 33-byte compressed secp256k1 public keys. The SDK fetches the TEE public key and derives a shared AES-GCM key via ECDH.
- **Legacy gas**: Seismic transactions use `gas_price` + `gas_limit` (legacy style), NOT EIP-1559 (`maxFeePerGas`/`maxPriorityFeePerGas`).
## SDK: seismic-viem
### Install
```bash
npm install seismic-viem
# or
bun add seismic-viem
```
### Key exports
```typescript
import {
createShieldedWalletClient,
createShieldedPublicClient,
getShieldedContract,
seismicTestnet, // Chain definition (chainId: 5124)
} from "seismic-viem";
```
## Core Patterns
### Create a shielded wallet client
```typescript
import { createShieldedWalletClient, seismicTestnet } from "seismic-viem";
import { http } from "viem";
const walletClient = await createShieldedWalletClient({
chain: seismicTestnet,
transport: http("https://gcp-1.seismictest.net/rpc"),
privateKey: "0xYOUR_PRIVATE_KEY",
});
```
### Create a shielded public client (read-only)
```typescript
import { createShieldedPublicClient, seismicTestnet } from "seismic-viem";
import { http } from "viem";
const publicClient = await createShieldedPublicClient({
chain: seismicTestnet,
transport: http("https://gcp-1.seismictest.net/rpc"),
});
```
### Get a shielded contract instance
```typescript
import { getShieldedContract } from "seismic-viem";
const contract = getShieldedContract({
abi: myContractAbi,
address: "0xCONTRACT_ADDRESS",
client: walletClient,
});
```
### Shielded write (encrypted transaction)
```typescript
// Sends a type 0x4A transaction with encrypted calldata
const hash = await contract.write.transfer([recipientAddress, amount], {
gas: 500_000n,
});
```
### Signed read
```typescript
// Sends a signed eth_call so msg.sender is set correctly
const balance = await contract.read.getBalance([userAddress]);
```
### Wait for transaction receipt
```typescript
import { createPublicClient, http } from "viem";
// Use a standard viem public client for receipt watching
const publicClient = createPublicClient({
chain: seismicTestnet,
transport: http("https://gcp-1.seismictest.net/rpc"),
});
const receipt = await publicClient.waitForTransactionReceipt({ hash });
```
## Common Mistakes
1. **Using standard viem `createWalletClient`** — This creates a regular Ethereum client. It won't encrypt calldata or handle signed reads. Always use `createShieldedWalletClient`.
2. **Using EIP-1559 gas params** — Seismic transactions use legacy gas (`gas` field). Do NOT pass `maxFeePerGas` or `maxPriorityFeePerGas`.
3. **Calling view functions with `publicClient.readContract()`** — If the contract function checks `msg.sender`, a standard read will fail (sender is zeroed). Use `contract.read.*` from a shielded contract instance instead.
4. **Forgetting `await` on client creation** — `createShieldedWalletClient` is async (it fetches the TEE public key). Missing `await` gives you a Promise, not a client.
5. **Wrong import path** — The package is `seismic-viem`, not `@seismic/viem` or `viem/seismic`.
## Networks
| Network | Chain ID | RPC URL | Chain export |
| -------------- | -------- | ----------------------------------- | --------------- |
| Testnet | 5124 | `https://gcp-1.seismictest.net/rpc` | `seismicTestnet` |
| Testnet (WS) | 5124 | `wss://gcp-1.seismictest.net/ws` | `seismicTestnet` |
| Local (sanvil) | 31337 | `http://127.0.0.1:8545` | — |
Faucet: https://faucet.seismictest.net/
## Links
- [seismic-viem Installation](https://docs.seismic.systems/client-libraries/seismic-viem/installation)
- [Shielded Wallet Client](https://docs.seismic.systems/client-libraries/seismic-viem/shielded-wallet-client)
- [Contract Instance](https://docs.seismic.systems/client-libraries/seismic-viem/contract-instance)
- [Signed Reads](https://docs.seismic.systems/client-libraries/seismic-viem/signed-reads)
- [GitHub: seismic-client](https://github.com/SeismicSystems/seismic-client)What this teaches Claude
Customizing
Last updated

