The Community Uniswap SDK - Ship V4 Apps Without Re-Implementing the Protocol
By Twade
Zaha Studio, with BootNode and the Uniswap Foundation, shipped a community-built TypeScript SDK that turns V4 integration from an eight-thing-you-write-first marathon into npm install + go. A look at what it gives you, the design choices behind it, and why it ships AI agent skills out of the box.
Picture the start of any V4 integration. You want to add a swap to your app. Or a deposit. Or an "earn" feature that opens an LP position on the user's behalf. Conceptually it's four lines of code. In practice, before you ship a single feature, you write:
- The Permit2 EIP-712 signature flow (typed-data domain, types, message)
- The deadline and slippage maths
- The approval-state tracking (does the user have allowance? do we batch the approve?)
- The transaction lifecycle UI (pending, mined, confirmed, error)
- The pool-key construction and token sorting (
currency0 < currency1) - The multicall against
StateViewfor live pool state - The Quoter contract calls (and the
callStaticrevert dance to get a price) - The Universal Router command-encoding for the actual swap
That's eight things before you've solved any of the problems your app exists to solve. Most V4 integrations stall at step four.
The Community Uniswap SDK, shipped by Zaha Studio with BootNode and support from the Uniswap Foundation, exists to collapse that list to npm install. It's a TypeScript monorepo (a framework-agnostic core SDK plus a React hooks layer) that handles Permit2, deadlines, slippage, pool keys, multicalling, Quoter, and Universal Router for you, then exposes a clean API that says "give me a swap" or "open me a position" and gets out of the way.
Worth saying up front: I'm not an arm's-length observer here. Akshat from Zaha Studio and I co-presented this SDK at an Atrium Academy public event, and the recording is embedded further down. Read this as a tour from someone who's spent time inside it, not a review from the outside.
This piece covers what the SDK gives you, when to reach for the core package versus the React hooks, why the AI agent integration is the cleverest design decision in the project, and how the v1.0.0 release that shipped in May fits into the wider V4 tooling story.
What it is, in one paragraph
Two TypeScript packages.
@zahastudio/uniswap-sdk is the core. Framework-agnostic, built on viem, works wherever JavaScript runs. Pool queries, swap quotes, swap execution, full position lifecycle (mint, increase, decrease, collect fees), Permit2 batch approvals, and EIP-5792 wallet batches when the connected wallet supports them.
@zahastudio/uniswap-sdk-react is the React layer. Provider plus hooks built on wagmi and @tanstack/react-query, covering twelve operations from useSwap and useCreatePosition down to primitives like useTokenApproval. Designed so that "the user wants to swap" maps to a single hook with the full lifecycle behind it.
Both packages hit v1.0.0 in May 2026 and have iterated steadily since, with 259 commits and twelve releases as of late July. The repo is MIT-licensed, includes a Next.js example app that demonstrates the full swap and position-management flows, and ships TanStack Intent skills so AI coding agents can wire up integrations on your behalf. More on that last part shortly.
Insight #1
The Uniswap Trading API gives you swaps as a hosted service. The official v4 SDK gives you the protocol primitives. The Community SDK sits between them: client-side, no hosted dependency, but opinionated about the integration patterns so you don't have to invent them. For most V4 apps, that's the sweet spot.
Why this exists
The story is the one every V4 app developer recognises. The protocol is brilliant; the integration is gnarly. Permit2 alone is a multi-day project if you've never wired it up before, once you factor in batch approvals, EIP-712 domain construction, and the difference between allowance-based and signature-based transfers. The community had been waiting for someone to do the work properly, version it, ship it, and maintain it.
"We built the community SDK because we kept seeing teams, including ourselves, solve the same integration problems over and over again. Uniswap v4 is incredibly powerful, but that flexibility also introduces complexity. The SDK abstracts away the AMM-specific details so builders can focus on the product experience they want to create, rather than reimplementing the same v4 plumbing from scratch."
The collaboration shape matters too. Zaha Studio leads, BootNode contributes, the Uniswap Foundation supports. This is the model the V4 ecosystem will probably see more of: community teams shipping production tooling with Foundation backing, rather than the Foundation trying to ship every piece itself.
The pieces, by category
The README lists seven feature areas, and each maps to a step on the "eight things you write before shipping" list above.
Pool queries come through sdk.getPool(poolKey), which returns live slot0 and liquidity in a single multicall. No manual StateView reads, no batching by hand.
Swap execution splits across two calls. sdk.getQuote(...) simulates, and sdk.buildSwapCallData(...) returns Universal Router calldata plus native value. Quotes use callStatic against the Quoter; swap calldata uses the command-encoding pattern the Universal Router expects, fully built for you.
Liquidity management covers mint, increase, decrease, and collect on positions, using the same calldata-builder pattern. The SDK constructs what the Position Manager needs and you broadcast it. The lifecycle for a created position (fetch metadata, derive token amounts at the current price, fetch uncollected fees) is exposed as a handful of clean methods.
Permit2 support means sdk.preparePermit2BatchData(...) returns the typed-data structure ready to sign. Batch multiple token approvals into a single signature; the SDK constructs the domain, types, and message in the format Permit2 expects.
EIP-5792 wallet batches are the UX upgrade. When the connected wallet supports batching, the React layer sends approval plus action as a single atomic call. Two transactions become one, with no separate confirmation for the approve step. It falls back to the standard two-transaction flow when the wallet doesn't support batching, so users on capable wallets get the better experience automatically.
Metadata reuse caches token metadata and pool keys in memory across calls within a session. Saves RPC churn on UIs that touch the same tokens repeatedly, like swap pages and position lists.
React hooks give every operation a corresponding hook with the full step-by-step lifecycle. That's the layer most developers will spend most of their time in, so it gets its own section below.
Architecture: core vs. React
The split is deliberate, and knowing which side you're on saves you picking the wrong package.
The core SDK is framework-agnostic. It accepts any viem PublicClient you give it (mainnet, testnet, your local Anvil fork) and returns data and calldata. It does no signing, no broadcasting, no UI state. If you're building a backend, a bot, a CLI, or an agent, this is what you want.
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
import { sortTokens, UniswapSDK } from "@zahastudio/uniswap-sdk";
const client = createPublicClient({ chain: mainnet, transport: http() });
const sdk = UniswapSDK.create(client, mainnet.id);
const WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const [currency0, currency1] = sortTokens(WETH, USDC);
const [weth, usdc] = await sdk.getTokens({ addresses: [WETH, USDC] });
const quote = await sdk.getQuote({
route: [
{
poolKey: {
currency0,
currency1,
fee: 3000,
tickSpacing: 60,
hooks: "0x0000000000000000000000000000000000000000",
},
hookData: "0x", // per-hop bytes for hooked pools
},
],
exactInput: { currency: WETH, amount: 1_000000000000000000n }, // 1 ETH
});Look closely at the hookData parameter on each route hop. It's how the SDK lets you swap through hooked V4 pools: pass whatever bytes the hook expects on that hop, and the SDK forwards them unchanged into the quote and swap-path encoding. If you're building against an Atrium Academy alumni hook, a Bunni pool, or any other custom-curve hook, this is the integration point.
The React layer sits on top, adding wagmi and @tanstack/react-query. Same SDK underneath, with connected-wallet awareness, query caching, transaction lifecycle state, and the step-by-step hooks layered over it. If you're shipping a frontend, this is the package you reach for.
import {
UniswapSDKProvider,
useSwap,
usePosition,
} from "@zahastudio/uniswap-sdk-react";
function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<UniswapSDKProvider>
<SwapPage />
</UniswapSDKProvider>
</QueryClientProvider>
</WagmiProvider>
);
}The twelve hooks split into three categories. Workflow hooks like useSwap and useCreatePosition handle a full multi-step operation (quote, approve, sign Permit2, execute) as a single state machine you can drive from one component. Query hooks like usePosition, usePoolState, and useToken are read-only and TanStack-Query-backed, so they cache, refetch, and deduplicate. Primitive hooks like useTokenApproval, usePermit2, and useTransaction give you the building blocks if your flow needs something the workflow hooks don't cover.
Insight #2
A swap in raw V4 runs to hundreds of lines once you've written the Permit2 flow, the pool-key construction, the Quoter calls, and the Universal Router encoding. useSwap() is one line. The work moved to the SDK, where it gets written once, tested properly, versioned, and maintained. That's the entire reason to use a community SDK.
A real swap, end to end
Here's a swap using the React hook. Most app developers will live in this layer most of the time.
import { useSwap } from "@zahastudio/uniswap-sdk-react";
import { parseUnits } from "viem";
function SwapButton() {
const swap = useSwap();
async function onClick() {
// 1. Quote: does this trade make sense at the current price?
const quote = await swap.quote({
route: [
{
poolKey: {
currency0: WETH,
currency1: USDC,
fee: 3000,
tickSpacing: 60,
hooks: "0x0000000000000000000000000000000000000000",
},
hookData: "0x",
},
],
exactInput: { currency: WETH, amount: parseUnits("1", 18) },
slippageToleranceBps: 50, // 0.5%
});
// 2. Execute. This single call:
// a) takes ERC20 approvals if needed
// b) signs Permit2 if needed
// c) batches both with the swap call (EIP-5792 when supported)
// d) tracks the tx lifecycle and returns when settled
const result = await swap.execute(quote);
console.log(`Settled. Tx: ${result.transactionHash}`);
}
return <button onClick={onClick}>Swap 1 ETH for USDC</button>;
}That's the whole flow. Behind those two calls the SDK is doing all eight of the things from the opening list, plus the EIP-5792 batching upgrade for wallets that support it. The state machine inside useSwap exposes progress (status, currentStep, pendingTx) if you want to render a stepper UI; if you don't, the imperative API above is enough.
Position management follows the same shape. useCreatePosition handles the full mint flow. usePositionIncreaseLiquidity, usePositionRemoveLiquidity, and usePositionCollectFees handle the lifecycle. usePosition(tokenId) is the read-only counterpart for displaying position state.
One basis-points convention to keep in mind, because the SDK exposes it everywhere slippage shows up:
1 bps = 0.01%
50 bps = 0.5% (typical default slippage)
10000 bps = 100%Pass slippage as integer basis points (slippageToleranceBps: 50) rather than as a percentage. The SDK is consistent about this across every method that takes a tolerance.
AI agent integration: the design choice that matters
The most interesting part of this SDK is how it handles AI coding agents.
The packages ship TanStack Intent skills alongside the npm releases. Skills are versioned with the package, so bumping the SDK from 1.0.0 to 1.0.1 brings the skill with it. They're also discovered from your installed dependencies, which means an agent looking at your package.json already knows what skills it should load. An AI agent (Codex, Cursor, Claude Code, Copilot, Amp) can then wire up a Uniswap integration in your codebase by loading the right skill rather than guessing from documentation snippets.
The install flow is two commands. After installing the SDK:
npx @tanstack/intent@latest list
npx @tanstack/intent@latest installOr you can load skills directly without installing the package first:
npx @tanstack/intent@latest load @zahastudio/uniswap-sdk
npx @tanstack/intent@latest load @zahastudio/uniswap-sdk-reactThe skill teaches the agent the SDK's surface: which method to use for which operation, the shape of PoolKey, how to handle Permit2, the React provider pattern, the slippage convention. Open Claude Code with the skill loaded and "add a Uniswap swap to my Next.js app" becomes a single-prompt task.
This puts the Community SDK in the same design lineage as Uniswap's own npx skills add uniswap/uniswap-ai --skill swap-integration. Both are built for a developer population that Uniswap Labs found to be 85% experienced with agent-assisted building, per the survey they published alongside the developer platform launch. Two paths to the same idea: integrations get easier when the docs are machine-readable and the SDK ships an agent-ready skill alongside the code.
Insight #3
Versioning agent skills with the package is the move other SDK authors should be copying. The skill stays coherent with the code it teaches, and the agent doesn't have to guess which version of the SDK it's writing for. That's the right shape for SDK-shipped AI integration.
The example app, briefly
The monorepo ships apps/example, a Next.js demo wired up to mainnet pools that demonstrates the full swap and position-management flows. If you learn best by reading code that runs, this is where to start.
The dev setup is friction-free for local experimentation. Spin up Anvil with a mainnet fork, point the example app at it, and you can swap and add liquidity against real pool state without spending real gas.
# Terminal 1: fork mainnet locally
pnpm anvil
# Terminal 2: point the app at the fork and run dev
export NEXT_PUBLIC_MAINNET_RPC_URL="http://127.0.0.1:8545"
pnpm devImport one of Anvil's pre-funded private keys into your browser wallet, set the RPC to http://127.0.0.1:8545, and you're swapping against a forked Uniswap V4 state in about two minutes.
Watch the live walkthrough
Akshat and I ran through the SDK end to end at an Atrium Academy public event: why it exists (raw V4 means touching four or more contracts to execute a single swap), what it gives you out of the box, the core SDK versus React hooks distinction and when to reach for each, and a live code tour of the example app's swap and liquidity flows.
Fastest path through the SDK if you'd rather watch than read.
What it doesn't do (yet)
Being explicit about scope: the Community SDK is V4-focused. It isn't a multi-protocol router and doesn't try to be the Uniswap Trading API. If you need routing across V2, V3, V4, and UniswapX, the Uniswap Trading API is the right tool. If you need to write a hook, the SDK is adjacent rather than central, and you'd still write Solidity directly against v4-core and v4-hooks-public.
The sweet spot is client-side V4 application integration: a wallet adding swap functionality, a vault contract's frontend that opens positions on behalf of users, an analytics dashboard reading live pool state, an agent placing trades against V4 pools. Anything that says "I want to interact with V4 from JavaScript and I don't want to write the plumbing first," the Community SDK is built for.
Recap
- Two packages.
@zahastudio/uniswap-sdkis framework-agnostic and returns data and calldata;@zahastudio/uniswap-sdk-reactadds twelve hooks over wagmi and TanStack Query for frontend work. - It collapses the eight-step integration list. Permit2, deadlines, slippage, pool keys, multicalling, Quoter, and Universal Router encoding are all handled, leaving you with
useSwap(). hookDatais the V4-native part. Per-hop bytes forwarded unchanged means hooked pools work through the same interface as vanilla ones.- The agent skills ship with the package. Versioned alongside the code, discovered from your dependencies, loadable into any compatible coding agent with one command.
Where to go next
The fastest path:
# Core only
pnpm install @zahastudio/uniswap-sdk viem
# React layer
pnpm install @zahastudio/uniswap-sdk-react @zahastudio/uniswap-sdk \
viem wagmi @tanstack/react-queryThen, with the SDK installed, load the agent skill if you're using one:
npx @tanstack/intent@latest installAnd start from one of:
- The monorepo: github.com/ZahaStudio/uniswap-sdk-monorepo. README is current; the
docs/directory is the canonical reference for the API surface. - The example Next.js app:
apps/example. Reads cleanly; clone and run it before you read the docs. - The release notes: Releases. Twelve releases since launch, with Changesets-formatted notes. Good signal for what's stable and what's moving.
Companion reading from ticks.wtf:
- The Uniswap API - Built for Agents, Useful for Everyone: sibling tooling on the Uniswap Labs side. The Community SDK and the Trading API solve adjacent problems; reading them together gives you the full picture of V4 integration paths in 2026.
- Every Hook in V4: if the
hookDataparameter caught your eye and you want to understand what hooks are doing on the protocol side.
If you ship something with the SDK, or hit a rough edge worth feeding back, Zaha Studio welcomes contributions on the monorepo. You can find me on X or in the Atrium Academy Discord for the broader V4 community conversation. Office hours run there.
- Twade
