@sfpro/sdk

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