wagmi & viem
Understanding the type-safe foundation of the Superfluid SDK
The Superfluid SDK is built on top of wagmi and viem, providing type-safe interactions with the Superfluid Protocol.
Type Safety Through Metaprogramming
The SDK uses wagmi-cli to generate TypeScript bindings from Solidity ABIs, ensuring:
- Compile-time type checking for function names and arguments
- Autocomplete in your IDE
- Runtime validation of inputs
- Type-safe error handling
Anatomy of an ABI
ABIs (Application Binary Interfaces) define how to interact with smart contracts:
import { superTokenAbi } from "@sfpro/sdk/abi"
// The ABI is a typed array of function and event definitions
const abi = superTokenAbi
// Usage with viem
import { createPublicClient, http } from "viem"
import { mainnet } from "viem/chains"
const client = createPublicClient({
chain: mainnet,
transport: http()
})
// Type-safe contract reads
const balance = await client.readContract({
address: "0x...",
abi: superTokenAbi,
functionName: "balanceOf", // Autocomplete available!
args: ["0x..."] // Type-checked arguments
})
Key benefits:
- Function names are validated at compile time
- Arguments are type-checked
- Return types are inferred automatically
Anatomy of an Action
Actions are wagmi core functions for non-React environments:
import { readSuperToken } from "@sfpro/sdk/action"
import { createConfig } from "@wagmi/core"
import { mainnet } from "viem/chains"
import { http } from "viem"
const config = createConfig({
chains: [mainnet],
transports: {
[mainnet.id]: http()
}
})
// Actions provide a cleaner API
const balance = await readSuperToken(config, {
chainId: mainnet.id,
address: "0x...",
functionName: "balanceOf",
args: ["0x..."]
})
Benefits of actions:
- Simplified API compared to raw viem
- Automatic chain and transport handling
- Consistent error handling
- Works in any JavaScript environment
Anatomy of a Hook
Hooks provide React integration with built-in state management:
import { useReadSuperToken } from "@sfpro/sdk/hook"
function BalanceDisplay({ address }: { address: `0x${string}` }) {
const { data: balance, isLoading, error } = useReadSuperToken({
chainId: 1,
address: "0x...",
functionName: "balanceOf",
args: [address]
})
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>Balance: {balance?.toString()}</div>
}
Hook features:
- Automatic re-fetching and caching
- Loading and error states
- Real-time updates with WebSocket transport
- Optimistic updates for write operations
Type Safety Examples
The SDK's type generation ensures you can't make common mistakes:
// @errors: 2345
import { cfaForwarderAbi } from "@sfpro/sdk/abi"
import { createPublicClient, http } from "viem"
const client = createPublicClient({
chain: { id: 1, name: "mainnet", nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, rpcUrls: { default: { http: ["https://eth.llamarpc.com"] } } },
transport: http()
})
// TypeScript will catch these errors:
await client.readContract({
address: "0x...",
abi: cfaForwarderAbi,
functionName: "nonExistentFunction", // Error: not a valid function
args: []
})
await client.readContract({
address: "0x...",
abi: cfaForwarderAbi,
functionName: "getAccountFlowrate",
args: ["not-an-address"] // Error: invalid address format
})
Next Steps
- Explore the SDK architecture
- Learn protocol concepts in the glossary
- Start building with use-case guides